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