xref: /llvm-project-15.0.7/libcxx/include/tuple (revision 2b6f2008)
1// -*- C++ -*-
2//===--------------------------- tuple ------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_TUPLE
11#define _LIBCPP_TUPLE
12
13/*
14    tuple synopsis
15
16namespace std
17{
18
19template <class... T>
20class tuple {
21public:
22    explicit(see-below) constexpr tuple();
23    explicit(see-below) tuple(const T&...);  // constexpr in C++14
24    template <class... U>
25        explicit(see-below) tuple(U&&...);  // constexpr in C++14
26    tuple(const tuple&) = default;
27    tuple(tuple&&) = default;
28    template <class... U>
29        explicit(see-below) tuple(const tuple<U...>&);  // constexpr in C++14
30    template <class... U>
31        explicit(see-below) tuple(tuple<U...>&&);  // constexpr in C++14
32    template <class U1, class U2>
33        explicit(see-below) tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
34    template <class U1, class U2>
35        explicit(see-below) tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2  // constexpr in C++14
36
37    // allocator-extended constructors
38    template <class Alloc>
39        tuple(allocator_arg_t, const Alloc& a);
40    template <class Alloc>
41        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...);          // constexpr in C++20
42    template <class Alloc, class... U>
43        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...);               // constexpr in C++20
44    template <class Alloc>
45        tuple(allocator_arg_t, const Alloc& a, const tuple&);                             // constexpr in C++20
46    template <class Alloc>
47        tuple(allocator_arg_t, const Alloc& a, tuple&&);                                  // constexpr in C++20
48    template <class Alloc, class... U>
49        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);   // constexpr in C++20
50    template <class Alloc, class... U>
51        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);        // constexpr in C++20
52    template <class Alloc, class U1, class U2>
53        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);  // constexpr in C++20
54    template <class Alloc, class U1, class U2>
55        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);       // constexpr in C++20
56
57    tuple& operator=(const tuple&);                                                       // constexpr in C++20
58    tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...);           // constexpr in C++20
59    template <class... U>
60        tuple& operator=(const tuple<U...>&);                                             // constexpr in C++20
61    template <class... U>
62        tuple& operator=(tuple<U...>&&);                                                  // constexpr in C++20
63    template <class U1, class U2>
64        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2                   // constexpr in C++20
65    template <class U1, class U2>
66        tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2                        // constexpr in C++20
67
68    template<class U, size_t N>
69        tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION
70    template<class U, size_t N>
71        tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION
72
73    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));               // constexpr in C++20
74};
75
76template <class ...T>
77tuple(T...) -> tuple<T...>;                                         // since C++17
78template <class T1, class T2>
79tuple(pair<T1, T2>) -> tuple<T1, T2>;                               // since C++17
80template <class Alloc, class ...T>
81tuple(allocator_arg_t, Alloc, T...) -> tuple<T...>;                 // since C++17
82template <class Alloc, class T1, class T2>
83tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;       // since C++17
84template <class Alloc, class ...T>
85tuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>;          // since C++17
86
87inline constexpr unspecified ignore;
88
89template <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
90template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
91template <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14
92template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
93
94// [tuple.apply], calling a function with a tuple of arguments:
95template <class F, class Tuple>
96  constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17
97template <class T, class Tuple>
98  constexpr T make_from_tuple(Tuple&& t); // C++17
99
100// 20.4.1.4, tuple helper classes:
101template <class T> struct tuple_size; // undefined
102template <class... T> struct tuple_size<tuple<T...>>;
103template <class T>
104 inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17
105template <size_t I, class T> struct tuple_element; // undefined
106template <size_t I, class... T> struct tuple_element<I, tuple<T...>>;
107template <size_t I, class T>
108  using tuple_element_t = typename tuple_element <I, T>::type; // C++14
109
110// 20.4.1.5, element access:
111template <size_t I, class... T>
112    typename tuple_element<I, tuple<T...>>::type&
113    get(tuple<T...>&) noexcept; // constexpr in C++14
114template <size_t I, class... T>
115    const typename tuple_element<I, tuple<T...>>::type&
116    get(const tuple<T...>&) noexcept; // constexpr in C++14
117template <size_t I, class... T>
118    typename tuple_element<I, tuple<T...>>::type&&
119    get(tuple<T...>&&) noexcept; // constexpr in C++14
120template <size_t I, class... T>
121    const typename tuple_element<I, tuple<T...>>::type&&
122    get(const tuple<T...>&&) noexcept; // constexpr in C++14
123
124template <class T1, class... T>
125    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
126template <class T1, class... T>
127    constexpr const T1& get(const tuple<T...>&) noexcept;   // C++14
128template <class T1, class... T>
129    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
130template <class T1, class... T>
131    constexpr const T1&& get(const tuple<T...>&&) noexcept;   // C++14
132
133// 20.4.1.6, relational operators:
134template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
135template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
136template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
137template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
138template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
139template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
140
141template <class... Types, class Alloc>
142  struct uses_allocator<tuple<Types...>, Alloc>;
143
144template <class... Types>
145  void
146  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
147
148}  // std
149
150*/
151
152#include <__config>
153#include <__tuple>
154#include <compare>
155#include <cstddef>
156#include <type_traits>
157#include <__functional_base>
158#include <utility>
159#include <version>
160
161#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
162#pragma GCC system_header
163#endif
164
165_LIBCPP_BEGIN_NAMESPACE_STD
166
167#ifndef _LIBCPP_CXX03_LANG
168
169
170// __tuple_leaf
171
172template <size_t _Ip, class _Hp,
173          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
174         >
175class __tuple_leaf;
176
177template <size_t _Ip, class _Hp, bool _Ep>
178inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
179void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
180    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
181{
182    swap(__x.get(), __y.get());
183}
184
185template <size_t _Ip, class _Hp, bool>
186class __tuple_leaf
187{
188    _Hp __value_;
189
190    template <class _Tp>
191    static constexpr bool __can_bind_reference() {
192#if __has_keyword(__reference_binds_to_temporary)
193      return !__reference_binds_to_temporary(_Hp, _Tp);
194#else
195      return true;
196#endif
197    }
198
199    _LIBCPP_CONSTEXPR_AFTER_CXX11
200    __tuple_leaf& operator=(const __tuple_leaf&);
201public:
202    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
203             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
204       {static_assert(!is_reference<_Hp>::value,
205              "Attempted to default construct a reference element in a tuple");}
206
207    template <class _Alloc>
208        _LIBCPP_INLINE_VISIBILITY constexpr
209        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
210            : __value_()
211        {static_assert(!is_reference<_Hp>::value,
212              "Attempted to default construct a reference element in a tuple");}
213
214    template <class _Alloc>
215        _LIBCPP_INLINE_VISIBILITY constexpr
216        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
217            : __value_(allocator_arg_t(), __a)
218        {static_assert(!is_reference<_Hp>::value,
219              "Attempted to default construct a reference element in a tuple");}
220
221    template <class _Alloc>
222        _LIBCPP_INLINE_VISIBILITY constexpr
223        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
224            : __value_(__a)
225        {static_assert(!is_reference<_Hp>::value,
226              "Attempted to default construct a reference element in a tuple");}
227
228    template <class _Tp,
229              class = _EnableIf<
230                  _And<
231                      _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
232                      is_constructible<_Hp, _Tp>
233                    >::value
234                >
235            >
236        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
237        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
238            : __value_(_VSTD::forward<_Tp>(__t))
239        {static_assert(__can_bind_reference<_Tp&&>(),
240       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
241
242    template <class _Tp, class _Alloc>
243        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
244        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
245            : __value_(_VSTD::forward<_Tp>(__t))
246        {static_assert(__can_bind_reference<_Tp&&>(),
247       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
248
249    template <class _Tp, class _Alloc>
250        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
251        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
252            : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
253        {static_assert(!is_reference<_Hp>::value,
254            "Attempted to uses-allocator construct a reference element in a tuple");}
255
256    template <class _Tp, class _Alloc>
257        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
258        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
259            : __value_(_VSTD::forward<_Tp>(__t), __a)
260        {static_assert(!is_reference<_Hp>::value,
261           "Attempted to uses-allocator construct a reference element in a tuple");}
262
263    __tuple_leaf(const __tuple_leaf& __t) = default;
264    __tuple_leaf(__tuple_leaf&& __t) = default;
265
266    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
267    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
268    {
269        _VSTD::swap(*this, __t);
270        return 0;
271    }
272
273    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return __value_;}
274    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;}
275};
276
277template <size_t _Ip, class _Hp>
278class __tuple_leaf<_Ip, _Hp, true>
279    : private _Hp
280{
281    _LIBCPP_CONSTEXPR_AFTER_CXX11
282    __tuple_leaf& operator=(const __tuple_leaf&);
283public:
284    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
285             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
286
287    template <class _Alloc>
288        _LIBCPP_INLINE_VISIBILITY constexpr
289        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
290
291    template <class _Alloc>
292        _LIBCPP_INLINE_VISIBILITY constexpr
293        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
294            : _Hp(allocator_arg_t(), __a) {}
295
296    template <class _Alloc>
297        _LIBCPP_INLINE_VISIBILITY constexpr
298        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
299            : _Hp(__a) {}
300
301    template <class _Tp,
302              class = _EnableIf<
303                  _And<
304                    _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
305                    is_constructible<_Hp, _Tp>
306                  >::value
307                >
308            >
309        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
310        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
311            : _Hp(_VSTD::forward<_Tp>(__t)) {}
312
313    template <class _Tp, class _Alloc>
314        _LIBCPP_INLINE_VISIBILITY constexpr
315        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
316            : _Hp(_VSTD::forward<_Tp>(__t)) {}
317
318    template <class _Tp, class _Alloc>
319        _LIBCPP_INLINE_VISIBILITY constexpr
320        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
321            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
322
323    template <class _Tp, class _Alloc>
324        _LIBCPP_INLINE_VISIBILITY constexpr
325        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
326            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
327
328    __tuple_leaf(__tuple_leaf const &) = default;
329    __tuple_leaf(__tuple_leaf &&) = default;
330
331    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
332    int
333    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
334    {
335        _VSTD::swap(*this, __t);
336        return 0;
337    }
338
339    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
340    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
341};
342
343template <class ..._Tp>
344_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
345void __swallow(_Tp&&...) _NOEXCEPT {}
346
347template <class _Tp>
348struct __all_default_constructible;
349
350template <class ..._Tp>
351struct __all_default_constructible<__tuple_types<_Tp...>>
352    : __all<is_default_constructible<_Tp>::value...>
353{ };
354
355// __tuple_impl
356
357template<class _Indx, class ..._Tp> struct __tuple_impl;
358
359template<size_t ..._Indx, class ..._Tp>
360struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
361    : public __tuple_leaf<_Indx, _Tp>...
362{
363    _LIBCPP_INLINE_VISIBILITY
364    constexpr __tuple_impl()
365        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
366
367    template <size_t ..._Uf, class ..._Tf,
368              size_t ..._Ul, class ..._Tl, class ..._Up>
369        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
370        explicit
371        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
372                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
373                     _Up&&... __u)
374                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
375                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
376            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
377            __tuple_leaf<_Ul, _Tl>()...
378            {}
379
380    template <class _Alloc, size_t ..._Uf, class ..._Tf,
381              size_t ..._Ul, class ..._Tl, class ..._Up>
382        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
383        explicit
384        __tuple_impl(allocator_arg_t, const _Alloc& __a,
385                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
386                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
387                     _Up&&... __u) :
388            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
389            _VSTD::forward<_Up>(__u))...,
390            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
391            {}
392
393    template <class _Tuple,
394              class = typename enable_if
395                      <
396                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
397                      >::type
398             >
399        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
400        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
401                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
402            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
403                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
404            {}
405
406    template <class _Alloc, class _Tuple,
407              class = typename enable_if
408                      <
409                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
410                      >::type
411             >
412        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
413        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
414            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
415                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
416                                       _VSTD::forward<typename tuple_element<_Indx,
417                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
418            {}
419
420    __tuple_impl(const __tuple_impl&) = default;
421    __tuple_impl(__tuple_impl&&) = default;
422
423    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
424    void swap(__tuple_impl& __t)
425        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
426    {
427        _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
428    }
429};
430
431template<class _Dest, class _Source, size_t ..._Np>
432_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
433void __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
434    _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
435}
436
437template<class _Dest, class _Source, class ..._Up, size_t ..._Np>
438_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
439void __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
440    _VSTD::__swallow(((
441        _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
442    ), void(), 0)...);
443}
444
445template <class ..._Tp>
446class _LIBCPP_TEMPLATE_VIS tuple
447{
448    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
449
450    _BaseT __base_;
451
452#if defined(_LIBCPP_ENABLE_TUPLE_IMPLICIT_REDUCED_ARITY_EXTENSION)
453    static constexpr bool _EnableImplicitReducedArityExtension = true;
454#else
455    static constexpr bool _EnableImplicitReducedArityExtension = false;
456#endif
457
458    template <class ..._Args>
459    struct _PackExpandsToThisTuple : false_type {};
460
461    template <class _Arg>
462    struct _PackExpandsToThisTuple<_Arg>
463        : is_same<typename __uncvref<_Arg>::type, tuple> {};
464
465    template <bool _MaybeEnable, class _Dummy = void>
466    struct _CheckArgsConstructor : __check_tuple_constructor_fail {};
467
468    template <class _Dummy>
469    struct _CheckArgsConstructor<true, _Dummy>
470    {
471        template <int&...>
472        static constexpr bool __enable_implicit_default() {
473           return __all<__is_implicitly_default_constructible<_Tp>::value... >::value;
474        }
475
476        template <int&...>
477        static constexpr bool __enable_explicit_default() {
478            return
479                __all<is_default_constructible<_Tp>::value...>::value &&
480                !__enable_implicit_default< >();
481        }
482
483
484        template <class ..._Args>
485        static constexpr bool __enable_explicit() {
486            return
487                __tuple_constructible<
488                    tuple<_Args...>,
489                    typename __make_tuple_types<tuple,
490                             sizeof...(_Args) < sizeof...(_Tp) ?
491                                 sizeof...(_Args) :
492                                 sizeof...(_Tp)>::type
493                >::value &&
494                !__tuple_convertible<
495                    tuple<_Args...>,
496                    typename __make_tuple_types<tuple,
497                             sizeof...(_Args) < sizeof...(_Tp) ?
498                                 sizeof...(_Args) :
499                                 sizeof...(_Tp)>::type
500                >::value &&
501                __all_default_constructible<
502                    typename __make_tuple_types<tuple, sizeof...(_Tp),
503                             sizeof...(_Args) < sizeof...(_Tp) ?
504                                 sizeof...(_Args) :
505                                 sizeof...(_Tp)>::type
506                >::value;
507        }
508
509        template <class ..._Args>
510        static constexpr bool __enable_implicit() {
511            return
512               __tuple_constructible<
513                    tuple<_Args...>,
514                    typename __make_tuple_types<tuple,
515                             sizeof...(_Args) < sizeof...(_Tp) ?
516                                 sizeof...(_Args) :
517                                 sizeof...(_Tp)>::type
518                >::value &&
519                __tuple_convertible<
520                    tuple<_Args...>,
521                    typename __make_tuple_types<tuple,
522                             sizeof...(_Args) < sizeof...(_Tp) ?
523                                 sizeof...(_Args) :
524                                 sizeof...(_Tp)>::type
525                >::value &&
526                __all_default_constructible<
527                    typename __make_tuple_types<tuple, sizeof...(_Tp),
528                             sizeof...(_Args) < sizeof...(_Tp) ?
529                                 sizeof...(_Args) :
530                                 sizeof...(_Tp)>::type
531                >::value;
532        }
533    };
534
535    template <bool _MaybeEnable,
536              bool = sizeof...(_Tp) == 1,
537              class _Dummy = void>
538    struct _CheckTupleLikeConstructor : __check_tuple_constructor_fail {};
539
540    template <class _Dummy>
541    struct _CheckTupleLikeConstructor<true, false, _Dummy>
542    {
543        template <class _Tuple>
544        static constexpr bool __enable_implicit() {
545            return __tuple_constructible<_Tuple, tuple>::value
546                && __tuple_convertible<_Tuple, tuple>::value;
547        }
548
549        template <class _Tuple>
550        static constexpr bool __enable_explicit() {
551            return __tuple_constructible<_Tuple, tuple>::value
552               && !__tuple_convertible<_Tuple, tuple>::value;
553        }
554    };
555
556    template <class _Dummy>
557    struct _CheckTupleLikeConstructor<true, true, _Dummy>
558    {
559        // This trait is used to disable the tuple-like constructor when
560        // the UTypes... constructor should be selected instead.
561        // See LWG issue #2549.
562        template <class _Tuple>
563        using _PreferTupleLikeConstructor = _Or<
564            // Don't attempt the two checks below if the tuple we are given
565            // has the same type as this tuple.
566            _IsSame<__uncvref_t<_Tuple>, tuple>,
567            _Lazy<_And,
568                _Not<is_constructible<_Tp..., _Tuple>>,
569                _Not<is_convertible<_Tuple, _Tp...>>
570            >
571        >;
572
573        template <class _Tuple>
574        static constexpr bool __enable_implicit() {
575            return _And<
576                __tuple_constructible<_Tuple, tuple>,
577                __tuple_convertible<_Tuple, tuple>,
578                _PreferTupleLikeConstructor<_Tuple>
579            >::value;
580        }
581
582        template <class _Tuple>
583        static constexpr bool __enable_explicit() {
584            return _And<
585                __tuple_constructible<_Tuple, tuple>,
586                _PreferTupleLikeConstructor<_Tuple>,
587                _Not<__tuple_convertible<_Tuple, tuple>>
588            >::value;
589        }
590    };
591
592    template <class _Tuple, bool _DisableIfLValue>
593    using _EnableImplicitTupleLikeConstructor = _EnableIf<
594                         _CheckTupleLikeConstructor<
595                             __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
596                             && !_PackExpandsToThisTuple<_Tuple>::value
597                             && (!is_lvalue_reference<_Tuple>::value || !_DisableIfLValue)
598                         >::template __enable_implicit<_Tuple>(),
599                         bool
600                      >;
601
602    template <class _Tuple, bool _DisableIfLValue>
603    using _EnableExplicitTupleLikeConstructor = _EnableIf<
604                         _CheckTupleLikeConstructor<
605                             __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
606                             && !_PackExpandsToThisTuple<_Tuple>::value
607                             && (!is_lvalue_reference<_Tuple>::value || !_DisableIfLValue)
608                         >::template __enable_explicit<_Tuple>(),
609                         bool
610                      >;
611    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
612        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
613    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
614        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
615    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
616        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
617    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
618        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
619public:
620
621    template <bool _Dummy = true, _EnableIf<
622        _CheckArgsConstructor<_Dummy>::__enable_implicit_default()
623    , void*> = nullptr>
624    _LIBCPP_INLINE_VISIBILITY constexpr
625    tuple()
626        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
627
628    template <bool _Dummy = true, _EnableIf<
629        _CheckArgsConstructor<_Dummy>::__enable_explicit_default()
630    , void*> = nullptr>
631    explicit _LIBCPP_INLINE_VISIBILITY constexpr
632    tuple()
633        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
634
635    tuple(tuple const&) = default;
636    tuple(tuple&&) = default;
637
638    template <class _AllocArgT, class _Alloc, _EnableIf<
639             _CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::value >::__enable_implicit_default()
640      , void*> = nullptr
641    >
642    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
643    tuple(_AllocArgT, _Alloc const& __a)
644      : __base_(allocator_arg_t(), __a,
645                    __tuple_indices<>(), __tuple_types<>(),
646                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
647                    __tuple_types<_Tp...>()) {}
648
649    template <class _AllocArgT, class _Alloc, _EnableIf<
650             _CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::value>::__enable_explicit_default()
651      , void*> = nullptr
652    >
653    explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
654    tuple(_AllocArgT, _Alloc const& __a)
655      : __base_(allocator_arg_t(), __a,
656                    __tuple_indices<>(), __tuple_types<>(),
657                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
658                    __tuple_types<_Tp...>()) {}
659
660    template <bool _Dummy = true,
661              typename enable_if
662                      <
663                         _CheckArgsConstructor<
664                            _Dummy
665                         >::template __enable_implicit<_Tp const&...>(),
666                         bool
667                      >::type = false
668        >
669    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
670    tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
671        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
672                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
673                typename __make_tuple_indices<0>::type(),
674                typename __make_tuple_types<tuple, 0>::type(),
675                __t...
676               ) {}
677
678    template <bool _Dummy = true,
679              typename enable_if
680                      <
681                         _CheckArgsConstructor<
682                            _Dummy
683                         >::template __enable_explicit<_Tp const&...>(),
684                         bool
685                      >::type = false
686        >
687    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
688    explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
689        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
690                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
691                typename __make_tuple_indices<0>::type(),
692                typename __make_tuple_types<tuple, 0>::type(),
693                __t...
694               ) {}
695
696    template <class _Alloc, bool _Dummy = true,
697              typename enable_if
698                      <
699                         _CheckArgsConstructor<
700                            _Dummy
701                         >::template __enable_implicit<_Tp const&...>(),
702                         bool
703                      >::type = false
704        >
705      _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
706      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
707        : __base_(allocator_arg_t(), __a,
708                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
709                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
710                typename __make_tuple_indices<0>::type(),
711                typename __make_tuple_types<tuple, 0>::type(),
712                __t...
713               ) {}
714
715    template <class _Alloc, bool _Dummy = true,
716              typename enable_if
717                      <
718                         _CheckArgsConstructor<
719                            _Dummy
720                         >::template __enable_explicit<_Tp const&...>(),
721                         bool
722                      >::type = false
723        >
724      _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
725      explicit
726      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
727        : __base_(allocator_arg_t(), __a,
728                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
729                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
730                typename __make_tuple_indices<0>::type(),
731                typename __make_tuple_types<tuple, 0>::type(),
732                __t...
733               ) {}
734
735    template <class ..._Up,
736              bool _PackIsTuple = _PackExpandsToThisTuple<_Up...>::value,
737              typename enable_if
738                      <
739                         _CheckArgsConstructor<
740                             sizeof...(_Up) == sizeof...(_Tp)
741                             && !_PackIsTuple
742                         >::template __enable_implicit<_Up...>() ||
743                        _CheckArgsConstructor<
744                            _EnableImplicitReducedArityExtension
745                            && sizeof...(_Up) < sizeof...(_Tp)
746                            && !_PackIsTuple
747                         >::template __enable_implicit<_Up...>(),
748                         bool
749                      >::type = false
750             >
751        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
752        tuple(_Up&&... __u)
753            _NOEXCEPT_((
754                is_nothrow_constructible<_BaseT,
755                    typename __make_tuple_indices<sizeof...(_Up)>::type,
756                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
757                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
758                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
759                    _Up...
760                >::value
761            ))
762            : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
763                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
764                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
765                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
766                    _VSTD::forward<_Up>(__u)...) {}
767
768    template <class ..._Up,
769              typename enable_if
770                      <
771                         _CheckArgsConstructor<
772                             sizeof...(_Up) <= sizeof...(_Tp)
773                             && !_PackExpandsToThisTuple<_Up...>::value
774                         >::template __enable_explicit<_Up...>() ||
775                         _CheckArgsConstructor<
776                            !_EnableImplicitReducedArityExtension
777                            && sizeof...(_Up) < sizeof...(_Tp)
778                            && !_PackExpandsToThisTuple<_Up...>::value
779                         >::template __enable_implicit<_Up...>(),
780                         bool
781                      >::type = false
782             >
783        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
784        explicit
785        tuple(_Up&&... __u)
786            _NOEXCEPT_((
787                is_nothrow_constructible<_BaseT,
788                    typename __make_tuple_indices<sizeof...(_Up)>::type,
789                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
790                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
791                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
792                    _Up...
793                >::value
794            ))
795            : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
796                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
797                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
798                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
799                    _VSTD::forward<_Up>(__u)...) {}
800
801    template <class _Alloc, class ..._Up,
802              typename enable_if
803                      <
804                         _CheckArgsConstructor<
805                             sizeof...(_Up) == sizeof...(_Tp) &&
806                             !_PackExpandsToThisTuple<_Up...>::value
807                         >::template __enable_implicit<_Up...>(),
808                         bool
809                      >::type = false
810             >
811        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
812        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
813            : __base_(allocator_arg_t(), __a,
814                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
815                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
816                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
817                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
818                    _VSTD::forward<_Up>(__u)...) {}
819
820    template <class _Alloc, class ..._Up,
821              typename enable_if
822                      <
823                         _CheckArgsConstructor<
824                             sizeof...(_Up) == sizeof...(_Tp) &&
825                             !_PackExpandsToThisTuple<_Up...>::value
826                         >::template __enable_explicit<_Up...>(),
827                         bool
828                      >::type = false
829             >
830        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
831        explicit
832        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
833            : __base_(allocator_arg_t(), __a,
834                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
835                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
836                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
837                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
838                    _VSTD::forward<_Up>(__u)...) {}
839
840    template <class _Tuple, _EnableImplicitTupleLikeConstructor<_Tuple, true> = false>
841        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
842        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, _Tuple>::value))
843            : __base_(_VSTD::forward<_Tuple>(__t)) {}
844
845    template <class _Tuple, _EnableImplicitTupleLikeConstructor<const _Tuple&, false> = false>
846        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
847        tuple(const _Tuple& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, const _Tuple&>::value))
848            : __base_(__t) {}
849    template <class _Tuple, _EnableExplicitTupleLikeConstructor<_Tuple, true> = false>
850        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
851        explicit
852        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, _Tuple>::value))
853            : __base_(_VSTD::forward<_Tuple>(__t)) {}
854
855    template <class _Tuple, _EnableExplicitTupleLikeConstructor<const _Tuple&, false> = false>
856        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
857        explicit
858        tuple(const _Tuple& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, const _Tuple&>::value))
859            : __base_(__t) {}
860
861    template <class _Alloc, class _Tuple,
862              typename enable_if
863                      <
864                         _CheckTupleLikeConstructor<
865                             __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
866                         >::template __enable_implicit<_Tuple>(),
867                         bool
868                      >::type = false
869             >
870        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
871        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
872            : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
873
874    template <class _Alloc, class _Tuple,
875              typename enable_if
876                      <
877                         _CheckTupleLikeConstructor<
878                             __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
879                         >::template __enable_explicit<_Tuple>(),
880                         bool
881                      >::type = false
882             >
883        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
884        explicit
885        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
886            : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
887
888    // [tuple.assign]
889    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
890    tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
891        _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
892    {
893        _VSTD::__memberwise_copy_assign(*this, __tuple,
894            typename __make_tuple_indices<sizeof...(_Tp)>::type());
895        return *this;
896    }
897
898    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
899    tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
900        _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
901    {
902        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
903            __tuple_types<_Tp...>(),
904            typename __make_tuple_indices<sizeof...(_Tp)>::type());
905        return *this;
906    }
907
908    template<class... _Up, _EnableIf<
909        _And<
910            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
911            is_assignable<_Tp&, _Up const&>...
912        >::value
913    ,int> = 0>
914    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
915    tuple& operator=(tuple<_Up...> const& __tuple)
916        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
917    {
918        _VSTD::__memberwise_copy_assign(*this, __tuple,
919            typename __make_tuple_indices<sizeof...(_Tp)>::type());
920        return *this;
921    }
922
923    template<class... _Up, _EnableIf<
924        _And<
925            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
926            is_assignable<_Tp&, _Up>...
927        >::value
928    ,int> = 0>
929    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
930    tuple& operator=(tuple<_Up...>&& __tuple)
931        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
932    {
933        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
934            __tuple_types<_Up...>(),
935            typename __make_tuple_indices<sizeof...(_Tp)>::type());
936        return *this;
937    }
938
939    template<class _Up1, class _Up2, class _Dep = true_type, _EnableIf<
940        _And<_Dep,
941            _BoolConstant<sizeof...(_Tp) == 2>,
942            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1 const&>,
943            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2 const&>
944        >::value
945    ,int> = 0>
946    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
947    tuple& operator=(pair<_Up1, _Up2> const& __pair)
948        _NOEXCEPT_((_And<
949            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1 const&>,
950            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2 const&>
951        >::value))
952    {
953        _VSTD::get<0>(*this) = __pair.first;
954        _VSTD::get<1>(*this) = __pair.second;
955        return *this;
956    }
957
958    template<class _Up1, class _Up2, class _Dep = true_type, _EnableIf<
959        _And<_Dep,
960            _BoolConstant<sizeof...(_Tp) == 2>,
961            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1>,
962            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2>
963        >::value
964    ,int> = 0>
965    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
966    tuple& operator=(pair<_Up1, _Up2>&& __pair)
967        _NOEXCEPT_((_And<
968            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1>,
969            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2>
970        >::value))
971    {
972        _VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first);
973        _VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second);
974        return *this;
975    }
976
977    // EXTENSION
978    template<class _Up, size_t _Np, class = _EnableIf<
979        _And<
980            _BoolConstant<_Np == sizeof...(_Tp)>,
981            is_assignable<_Tp&, _Up const&>...
982        >::value
983    > >
984    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
985    tuple& operator=(array<_Up, _Np> const& __array)
986        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
987    {
988        _VSTD::__memberwise_copy_assign(*this, __array,
989            typename __make_tuple_indices<sizeof...(_Tp)>::type());
990        return *this;
991    }
992
993    // EXTENSION
994    template<class _Up, size_t _Np, class = void, class = _EnableIf<
995        _And<
996            _BoolConstant<_Np == sizeof...(_Tp)>,
997            is_assignable<_Tp&, _Up>...
998        >::value
999    > >
1000    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1001    tuple& operator=(array<_Up, _Np>&& __array)
1002        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1003    {
1004        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__array),
1005            __tuple_types<_If<true, _Up, _Tp>...>(),
1006            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1007        return *this;
1008    }
1009
1010    // [tuple.swap]
1011    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1012    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
1013        {__base_.swap(__t.__base_);}
1014};
1015
1016template <>
1017class _LIBCPP_TEMPLATE_VIS tuple<>
1018{
1019public:
1020    _LIBCPP_INLINE_VISIBILITY constexpr
1021        tuple() _NOEXCEPT = default;
1022    template <class _Alloc>
1023    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1024        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
1025    template <class _Alloc>
1026    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1027        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
1028    template <class _Up>
1029    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1030        tuple(array<_Up, 0>) _NOEXCEPT {}
1031    template <class _Alloc, class _Up>
1032    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1033        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
1034    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1035    void swap(tuple&) _NOEXCEPT {}
1036};
1037
1038#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1039template <class ..._Tp>
1040tuple(_Tp...) -> tuple<_Tp...>;
1041template <class _Tp1, class _Tp2>
1042tuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1043template <class _Alloc, class ..._Tp>
1044tuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>;
1045template <class _Alloc, class _Tp1, class _Tp2>
1046tuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1047template <class _Alloc, class ..._Tp>
1048tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
1049#endif
1050
1051template <class ..._Tp>
1052inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1053typename enable_if
1054<
1055    __all<__is_swappable<_Tp>::value...>::value,
1056    void
1057>::type
1058swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
1059                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
1060    {__t.swap(__u);}
1061
1062// get
1063
1064template <size_t _Ip, class ..._Tp>
1065inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1066typename tuple_element<_Ip, tuple<_Tp...> >::type&
1067get(tuple<_Tp...>& __t) _NOEXCEPT
1068{
1069    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1070    return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
1071}
1072
1073template <size_t _Ip, class ..._Tp>
1074inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1075const typename tuple_element<_Ip, tuple<_Tp...> >::type&
1076get(const tuple<_Tp...>& __t) _NOEXCEPT
1077{
1078    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1079    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
1080}
1081
1082template <size_t _Ip, class ..._Tp>
1083inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1084typename tuple_element<_Ip, tuple<_Tp...> >::type&&
1085get(tuple<_Tp...>&& __t) _NOEXCEPT
1086{
1087    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1088    return static_cast<type&&>(
1089             static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1090}
1091
1092template <size_t _Ip, class ..._Tp>
1093inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1094const typename tuple_element<_Ip, tuple<_Tp...> >::type&&
1095get(const tuple<_Tp...>&& __t) _NOEXCEPT
1096{
1097    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1098    return static_cast<const type&&>(
1099             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1100}
1101
1102#if _LIBCPP_STD_VER > 11
1103
1104namespace __find_detail {
1105
1106static constexpr size_t __not_found = -1;
1107static constexpr size_t __ambiguous = __not_found - 1;
1108
1109inline _LIBCPP_INLINE_VISIBILITY
1110constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
1111    return !__matches ? __res :
1112        (__res == __not_found ? __curr_i : __ambiguous);
1113}
1114
1115template <size_t _Nx>
1116inline _LIBCPP_INLINE_VISIBILITY
1117constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
1118  return __i == _Nx ? __not_found :
1119      __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
1120}
1121
1122template <class _T1, class ..._Args>
1123struct __find_exactly_one_checked {
1124    static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
1125    static constexpr size_t value = __find_detail::__find_idx(0, __matches);
1126    static_assert(value != __not_found, "type not found in type list" );
1127    static_assert(value != __ambiguous, "type occurs more than once in type list");
1128};
1129
1130template <class _T1>
1131struct __find_exactly_one_checked<_T1> {
1132    static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
1133};
1134
1135} // namespace __find_detail;
1136
1137template <typename _T1, typename... _Args>
1138struct __find_exactly_one_t
1139    : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
1140};
1141
1142template <class _T1, class... _Args>
1143inline _LIBCPP_INLINE_VISIBILITY
1144constexpr _T1& get(tuple<_Args...>& __tup) noexcept
1145{
1146    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1147}
1148
1149template <class _T1, class... _Args>
1150inline _LIBCPP_INLINE_VISIBILITY
1151constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
1152{
1153    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1154}
1155
1156template <class _T1, class... _Args>
1157inline _LIBCPP_INLINE_VISIBILITY
1158constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
1159{
1160    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1161}
1162
1163template <class _T1, class... _Args>
1164inline _LIBCPP_INLINE_VISIBILITY
1165constexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
1166{
1167    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1168}
1169
1170#endif
1171
1172// tie
1173
1174template <class ..._Tp>
1175inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1176tuple<_Tp&...>
1177tie(_Tp&... __t) _NOEXCEPT
1178{
1179    return tuple<_Tp&...>(__t...);
1180}
1181
1182template <class _Up>
1183struct __ignore_t
1184{
1185    template <class _Tp>
1186    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1187    const __ignore_t& operator=(_Tp&&) const {return *this;}
1188};
1189
1190namespace {
1191  _LIBCPP_INLINE_VAR constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
1192}
1193
1194template <class... _Tp>
1195inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1196tuple<typename __unwrap_ref_decay<_Tp>::type...>
1197make_tuple(_Tp&&... __t)
1198{
1199    return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
1200}
1201
1202template <class... _Tp>
1203inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1204tuple<_Tp&&...>
1205forward_as_tuple(_Tp&&... __t) _NOEXCEPT
1206{
1207    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
1208}
1209
1210template <size_t _Ip>
1211struct __tuple_equal
1212{
1213    template <class _Tp, class _Up>
1214    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1215    bool operator()(const _Tp& __x, const _Up& __y)
1216    {
1217        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
1218    }
1219};
1220
1221template <>
1222struct __tuple_equal<0>
1223{
1224    template <class _Tp, class _Up>
1225    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1226    bool operator()(const _Tp&, const _Up&)
1227    {
1228        return true;
1229    }
1230};
1231
1232template <class ..._Tp, class ..._Up>
1233inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1234bool
1235operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1236{
1237    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
1238    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
1239}
1240
1241template <class ..._Tp, class ..._Up>
1242inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1243bool
1244operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1245{
1246    return !(__x == __y);
1247}
1248
1249template <size_t _Ip>
1250struct __tuple_less
1251{
1252    template <class _Tp, class _Up>
1253    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1254    bool operator()(const _Tp& __x, const _Up& __y)
1255    {
1256        const size_t __idx = tuple_size<_Tp>::value - _Ip;
1257        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
1258            return true;
1259        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
1260            return false;
1261        return __tuple_less<_Ip-1>()(__x, __y);
1262    }
1263};
1264
1265template <>
1266struct __tuple_less<0>
1267{
1268    template <class _Tp, class _Up>
1269    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1270    bool operator()(const _Tp&, const _Up&)
1271    {
1272        return false;
1273    }
1274};
1275
1276template <class ..._Tp, class ..._Up>
1277inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1278bool
1279operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1280{
1281    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
1282    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
1283}
1284
1285template <class ..._Tp, class ..._Up>
1286inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1287bool
1288operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1289{
1290    return __y < __x;
1291}
1292
1293template <class ..._Tp, class ..._Up>
1294inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1295bool
1296operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1297{
1298    return !(__x < __y);
1299}
1300
1301template <class ..._Tp, class ..._Up>
1302inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1303bool
1304operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1305{
1306    return !(__y < __x);
1307}
1308
1309// tuple_cat
1310
1311template <class _Tp, class _Up> struct __tuple_cat_type;
1312
1313template <class ..._Ttypes, class ..._Utypes>
1314struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
1315{
1316    typedef _LIBCPP_NODEBUG_TYPE tuple<_Ttypes..., _Utypes...> type;
1317};
1318
1319template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
1320struct __tuple_cat_return_1
1321{
1322};
1323
1324template <class ..._Types, class _Tuple0>
1325struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
1326{
1327    typedef _LIBCPP_NODEBUG_TYPE typename __tuple_cat_type<tuple<_Types...>,
1328            typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type>::type
1329                                                                           type;
1330};
1331
1332template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
1333struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
1334    : public __tuple_cat_return_1<
1335                 typename __tuple_cat_type<
1336                     tuple<_Types...>,
1337                     typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type
1338                 >::type,
1339                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
1340                 _Tuple1, _Tuples...>
1341{
1342};
1343
1344template <class ..._Tuples> struct __tuple_cat_return;
1345
1346template <class _Tuple0, class ..._Tuples>
1347struct __tuple_cat_return<_Tuple0, _Tuples...>
1348    : public __tuple_cat_return_1<tuple<>,
1349         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
1350                                                                     _Tuples...>
1351{
1352};
1353
1354template <>
1355struct __tuple_cat_return<>
1356{
1357    typedef _LIBCPP_NODEBUG_TYPE tuple<> type;
1358};
1359
1360inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1361tuple<>
1362tuple_cat()
1363{
1364    return tuple<>();
1365}
1366
1367template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
1368struct __tuple_cat_return_ref_imp;
1369
1370template <class ..._Types, size_t ..._I0, class _Tuple0>
1371struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
1372{
1373    typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
1374    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1375                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
1376};
1377
1378template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1379struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1380                                  _Tuple0, _Tuple1, _Tuples...>
1381    : public __tuple_cat_return_ref_imp<
1382         tuple<_Types..., typename __apply_cv<_Tuple0,
1383               typename tuple_element<_I0,
1384                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
1385         typename __make_tuple_indices<tuple_size<typename
1386                                 remove_reference<_Tuple1>::type>::value>::type,
1387         _Tuple1, _Tuples...>
1388{
1389};
1390
1391template <class _Tuple0, class ..._Tuples>
1392struct __tuple_cat_return_ref
1393    : public __tuple_cat_return_ref_imp<tuple<>,
1394               typename __make_tuple_indices<
1395                        tuple_size<typename remove_reference<_Tuple0>::type>::value
1396               >::type, _Tuple0, _Tuples...>
1397{
1398};
1399
1400template <class _Types, class _I0, class _J0>
1401struct __tuple_cat;
1402
1403template <class ..._Types, size_t ..._I0, size_t ..._J0>
1404struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
1405{
1406    template <class _Tuple0>
1407    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1408    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1409    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1410    {
1411        return _VSTD::forward_as_tuple(
1412            _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1413            _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
1414    }
1415
1416    template <class _Tuple0, class _Tuple1, class ..._Tuples>
1417    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1418    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1419    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
1420    {
1421        typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
1422        typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple1>::type _T1;
1423        return __tuple_cat<
1424            tuple<_Types...,
1425                  typename __apply_cv<_Tuple0, typename tuple_element<
1426                                                   _J0, _T0>::type>::type&&...>,
1427            typename __make_tuple_indices<sizeof...(_Types) +
1428                                          tuple_size<_T0>::value>::type,
1429            typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1430            _VSTD::forward_as_tuple(
1431                _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1432                _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...),
1433            _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...);
1434    }
1435};
1436
1437template <class _Tuple0, class... _Tuples>
1438inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1439typename __tuple_cat_return<_Tuple0, _Tuples...>::type
1440tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1441{
1442    typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
1443    return __tuple_cat<tuple<>, __tuple_indices<>,
1444                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
1445                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
1446                                            _VSTD::forward<_Tuples>(__tpls)...);
1447}
1448
1449template <class ..._Tp, class _Alloc>
1450struct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
1451    : true_type {};
1452
1453template <class _T1, class _T2>
1454template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1455inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1456pair<_T1, _T2>::pair(piecewise_construct_t,
1457                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
1458                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1459    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
1460      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
1461{
1462}
1463
1464#if _LIBCPP_STD_VER > 14
1465template <class _Tp>
1466_LIBCPP_INLINE_VAR constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
1467
1468#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
1469
1470template <class _Fn, class _Tuple, size_t ..._Id>
1471inline _LIBCPP_INLINE_VISIBILITY
1472constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
1473                                            __tuple_indices<_Id...>)
1474_LIBCPP_NOEXCEPT_RETURN(
1475    _VSTD::__invoke_constexpr(
1476        _VSTD::forward<_Fn>(__f),
1477        _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
1478)
1479
1480template <class _Fn, class _Tuple>
1481inline _LIBCPP_INLINE_VISIBILITY
1482constexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
1483_LIBCPP_NOEXCEPT_RETURN(
1484    _VSTD::__apply_tuple_impl(
1485        _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
1486        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
1487)
1488
1489template <class _Tp, class _Tuple, size_t... _Idx>
1490inline _LIBCPP_INLINE_VISIBILITY
1491constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
1492_LIBCPP_NOEXCEPT_RETURN(
1493    _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
1494)
1495
1496template <class _Tp, class _Tuple>
1497inline _LIBCPP_INLINE_VISIBILITY
1498constexpr _Tp make_from_tuple(_Tuple&& __t)
1499_LIBCPP_NOEXCEPT_RETURN(
1500    _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
1501        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
1502)
1503
1504#undef _LIBCPP_NOEXCEPT_RETURN
1505
1506#endif // _LIBCPP_STD_VER > 14
1507
1508#endif // !defined(_LIBCPP_CXX03_LANG)
1509
1510_LIBCPP_END_NAMESPACE_STD
1511
1512#endif // _LIBCPP_TUPLE
1513