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 const 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 // 20.4.1.4, tuple helper classes:
     81 template <class T> class tuple_size; // undefined
     82 template <class... T> class tuple_size<tuple<T...>>;
     83 template <intsize_t I, class T> class tuple_element; // undefined
     84 template <intsize_t I, class... T> class tuple_element<I, tuple<T...>>;
     85 template <size_t _Ip, class ..._Tp>
     86   using tuple_element_t = typename tuple_element <_Ip, _Tp...>::type; // C++14
     87 
     88 // 20.4.1.5, element access:
     89 template <intsize_t I, class... T>
     90     typename tuple_element<I, tuple<T...>>::type&
     91     get(tuple<T...>&) noexcept; // constexpr in C++14
     92 template <intsize_t I, class... T>
     93     typename const tuple_element<I, tuple<T...>>::type &
     94     get(const tuple<T...>&) noexcept; // constexpr in C++14
     95 template <intsize_t I, class... T>
     96     typename tuple_element<I, tuple<T...>>::type&&
     97     get(tuple<T...>&&) noexcept; // constexpr in C++14
     98 
     99 template <class T1, class... T>
    100     constexpr T1& get(tuple<T...>&) noexcept;  // C++14
    101 template <class T1, class... T>
    102     constexpr T1 const& get(const tuple<T...>&) noexcept;   // C++14
    103 template <class T1, class... T>
    104     constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
    105 
    106 // 20.4.1.6, relational operators:
    107 template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
    108 template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
    109 template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
    110 template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
    111 template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
    112 template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
    113 
    114 template <class... Types, class Alloc>
    115   struct uses_allocator<tuple<Types...>, Alloc>;
    116 
    117 template <class... Types>
    118   void
    119   swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
    120 
    121 }  // std
    122 
    123 */
    124 
    125 #include <__config>
    126 #include <__tuple>
    127 #include <cstddef>
    128 #include <type_traits>
    129 #include <__functional_base>
    130 #include <utility>
    131 
    132 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
    133 #pragma GCC system_header
    134 #endif
    135 
    136 _LIBCPP_BEGIN_NAMESPACE_STD
    137 
    138 #ifndef _LIBCPP_HAS_NO_VARIADICS
    139 
    140 // tuple_size
    141 
    142 template <class ..._Tp>
    143 class _LIBCPP_TYPE_VIS_ONLY tuple_size<tuple<_Tp...> >
    144     : public integral_constant<size_t, sizeof...(_Tp)>
    145 {
    146 };
    147 
    148 // tuple_element
    149 
    150 template <size_t _Ip, class ..._Tp>
    151 class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, tuple<_Tp...> >
    152 {
    153 public:
    154     typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
    155 };
    156 
    157 #if _LIBCPP_STD_VER > 11
    158 template <size_t _Ip, class ..._Tp>
    159 using tuple_element_t = typename tuple_element <_Ip, _Tp...>::type;
    160 #endif
    161 
    162 // __tuple_leaf
    163 
    164 template <size_t _Ip, class _Hp,
    165           bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
    166          >
    167 class __tuple_leaf;
    168 
    169 template <size_t _Ip, class _Hp, bool _Ep>
    170 inline _LIBCPP_INLINE_VISIBILITY
    171 void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
    172     _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
    173 {
    174     swap(__x.get(), __y.get());
    175 }
    176 
    177 template <size_t _Ip, class _Hp, bool>
    178 class __tuple_leaf
    179 {
    180     _Hp value;
    181 
    182     __tuple_leaf& operator=(const __tuple_leaf&);
    183 public:
    184     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
    185              _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : value()
    186        {static_assert(!is_reference<_Hp>::value,
    187               "Attempted to default construct a reference element in a tuple");}
    188 
    189     template <class _Alloc>
    190         _LIBCPP_INLINE_VISIBILITY
    191         __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
    192             : value()
    193         {static_assert(!is_reference<_Hp>::value,
    194               "Attempted to default construct a reference element in a tuple");}
    195 
    196     template <class _Alloc>
    197         _LIBCPP_INLINE_VISIBILITY
    198         __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
    199             : value(allocator_arg_t(), __a)
    200         {static_assert(!is_reference<_Hp>::value,
    201               "Attempted to default construct a reference element in a tuple");}
    202 
    203     template <class _Alloc>
    204         _LIBCPP_INLINE_VISIBILITY
    205         __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
    206             : value(__a)
    207         {static_assert(!is_reference<_Hp>::value,
    208               "Attempted to default construct a reference element in a tuple");}
    209 
    210     template <class _Tp,
    211               class = typename enable_if<
    212                   __lazy_and<
    213                       __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>
    214                     , is_constructible<_Hp, _Tp>
    215                     >::value
    216                 >::type
    217             >
    218         _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    219         explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
    220             : value(_VSTD::forward<_Tp>(__t))
    221         {static_assert(!is_reference<_Hp>::value ||
    222                        (is_lvalue_reference<_Hp>::value &&
    223                         (is_lvalue_reference<_Tp>::value ||
    224                          is_same<typename remove_reference<_Tp>::type,
    225                                  reference_wrapper<
    226                                     typename remove_reference<_Hp>::type
    227                                  >
    228                                 >::value)) ||
    229                         (is_rvalue_reference<_Hp>::value &&
    230                          !is_lvalue_reference<_Tp>::value),
    231        "Attempted to construct a reference element in a tuple with an rvalue");}
    232 
    233     template <class _Tp, class _Alloc>
    234         _LIBCPP_INLINE_VISIBILITY
    235         explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
    236             : value(_VSTD::forward<_Tp>(__t))
    237         {static_assert(!is_lvalue_reference<_Hp>::value ||
    238                        (is_lvalue_reference<_Hp>::value &&
    239                         (is_lvalue_reference<_Tp>::value ||
    240                          is_same<typename remove_reference<_Tp>::type,
    241                                  reference_wrapper<
    242                                     typename remove_reference<_Hp>::type
    243                                  >
    244                                 >::value)),
    245        "Attempted to construct a reference element in a tuple with an rvalue");}
    246 
    247     template <class _Tp, class _Alloc>
    248         _LIBCPP_INLINE_VISIBILITY
    249         explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
    250             : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
    251         {static_assert(!is_lvalue_reference<_Hp>::value ||
    252                        (is_lvalue_reference<_Hp>::value &&
    253                         (is_lvalue_reference<_Tp>::value ||
    254                          is_same<typename remove_reference<_Tp>::type,
    255                                  reference_wrapper<
    256                                     typename remove_reference<_Hp>::type
    257                                  >
    258                                 >::value)),
    259        "Attempted to construct a reference element in a tuple with an rvalue");}
    260 
    261     template <class _Tp, class _Alloc>
    262         _LIBCPP_INLINE_VISIBILITY
    263         explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
    264             : value(_VSTD::forward<_Tp>(__t), __a)
    265         {static_assert(!is_lvalue_reference<_Hp>::value ||
    266                        (is_lvalue_reference<_Hp>::value &&
    267                         (is_lvalue_reference<_Tp>::value ||
    268                          is_same<typename remove_reference<_Tp>::type,
    269                                  reference_wrapper<
    270                                     typename remove_reference<_Hp>::type
    271                                  >
    272                                 >::value)),
    273        "Attempted to construct a reference element in a tuple with an rvalue");}
    274 
    275     __tuple_leaf(const __tuple_leaf& __t) = default;
    276     __tuple_leaf(__tuple_leaf&& __t) = default;
    277 
    278     template <class _Tp>
    279         _LIBCPP_INLINE_VISIBILITY
    280         __tuple_leaf&
    281         operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
    282         {
    283             value = _VSTD::forward<_Tp>(__t);
    284             return *this;
    285         }
    286 
    287     _LIBCPP_INLINE_VISIBILITY
    288     int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
    289     {
    290         _VSTD::swap(*this, __t);
    291         return 0;
    292     }
    293 
    294     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return value;}
    295     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return value;}
    296 };
    297 
    298 template <size_t _Ip, class _Hp>
    299 class __tuple_leaf<_Ip, _Hp, true>
    300     : private _Hp
    301 {
    302 
    303     __tuple_leaf& operator=(const __tuple_leaf&);
    304 public:
    305     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
    306              _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
    307 
    308     template <class _Alloc>
    309         _LIBCPP_INLINE_VISIBILITY
    310         __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
    311 
    312     template <class _Alloc>
    313         _LIBCPP_INLINE_VISIBILITY
    314         __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
    315             : _Hp(allocator_arg_t(), __a) {}
    316 
    317     template <class _Alloc>
    318         _LIBCPP_INLINE_VISIBILITY
    319         __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
    320             : _Hp(__a) {}
    321 
    322     template <class _Tp,
    323               class = typename enable_if<
    324                   __lazy_and<
    325                         __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>
    326                       , is_constructible<_Hp, _Tp>
    327                     >::value
    328                 >::type
    329             >
    330         _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    331         explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
    332             : _Hp(_VSTD::forward<_Tp>(__t)) {}
    333 
    334     template <class _Tp, class _Alloc>
    335         _LIBCPP_INLINE_VISIBILITY
    336         explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
    337             : _Hp(_VSTD::forward<_Tp>(__t)) {}
    338 
    339     template <class _Tp, class _Alloc>
    340         _LIBCPP_INLINE_VISIBILITY
    341         explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
    342             : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
    343 
    344     template <class _Tp, class _Alloc>
    345         _LIBCPP_INLINE_VISIBILITY
    346         explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
    347             : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
    348 
    349     __tuple_leaf(__tuple_leaf const &) = default;
    350     __tuple_leaf(__tuple_leaf &&) = default;
    351 
    352     template <class _Tp>
    353         _LIBCPP_INLINE_VISIBILITY
    354         __tuple_leaf&
    355         operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
    356         {
    357             _Hp::operator=(_VSTD::forward<_Tp>(__t));
    358             return *this;
    359         }
    360 
    361     _LIBCPP_INLINE_VISIBILITY
    362     int
    363     swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
    364     {
    365         _VSTD::swap(*this, __t);
    366         return 0;
    367     }
    368 
    369     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
    370     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
    371 };
    372 
    373 template <class ..._Tp>
    374 _LIBCPP_INLINE_VISIBILITY
    375 void __swallow(_Tp&&...) _NOEXCEPT {}
    376 
    377 template <bool ..._Pred>
    378 struct __all
    379     : is_same<__all<_Pred...>, __all<(_Pred, true)...>>
    380 { };
    381 
    382 template <class _Tp>
    383 struct __all_default_constructible;
    384 
    385 template <class ..._Tp>
    386 struct __all_default_constructible<__tuple_types<_Tp...>>
    387     : __all<is_default_constructible<_Tp>::value...>
    388 { };
    389 
    390 // __tuple_impl
    391 
    392 template<class _Indx, class ..._Tp> struct __tuple_impl;
    393 
    394 template<size_t ..._Indx, class ..._Tp>
    395 struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
    396     : public __tuple_leaf<_Indx, _Tp>...
    397 {
    398     _LIBCPP_INLINE_VISIBILITY
    399     _LIBCPP_CONSTEXPR __tuple_impl()
    400         _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
    401 
    402     template <size_t ..._Uf, class ..._Tf,
    403               size_t ..._Ul, class ..._Tl, class ..._Up>
    404         _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    405         explicit
    406         __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
    407                      __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
    408                      _Up&&... __u)
    409                      _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
    410                                  __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
    411             __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
    412             __tuple_leaf<_Ul, _Tl>()...
    413             {}
    414 
    415     template <class _Alloc, size_t ..._Uf, class ..._Tf,
    416               size_t ..._Ul, class ..._Tl, class ..._Up>
    417         _LIBCPP_INLINE_VISIBILITY
    418         explicit
    419         __tuple_impl(allocator_arg_t, const _Alloc& __a,
    420                      __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
    421                      __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
    422                      _Up&&... __u) :
    423             __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
    424             _VSTD::forward<_Up>(__u))...,
    425             __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
    426             {}
    427 
    428     template <class _Tuple,
    429               class = typename enable_if
    430                       <
    431                          __tuple_constructible<_Tuple, tuple<_Tp...> >::value
    432                       >::type
    433              >
    434         _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    435         __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
    436                                        typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
    437             : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
    438                                        typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
    439             {}
    440 
    441     template <class _Alloc, class _Tuple,
    442               class = typename enable_if
    443                       <
    444                          __tuple_convertible<_Tuple, tuple<_Tp...> >::value
    445                       >::type
    446              >
    447         _LIBCPP_INLINE_VISIBILITY
    448         __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
    449             : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
    450                                        typename __make_tuple_types<_Tuple>::type>::type>(), __a,
    451                                        _VSTD::forward<typename tuple_element<_Indx,
    452                                        typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
    453             {}
    454 
    455     template <class _Tuple>
    456         _LIBCPP_INLINE_VISIBILITY
    457         typename enable_if
    458         <
    459             __tuple_assignable<_Tuple, tuple<_Tp...> >::value,
    460             __tuple_impl&
    461         >::type
    462         operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx,
    463                                        typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
    464         {
    465             __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx,
    466                                        typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...);
    467             return *this;
    468         }
    469 
    470     __tuple_impl(const __tuple_impl&) = default;
    471     __tuple_impl(__tuple_impl&&) = default;
    472 
    473     _LIBCPP_INLINE_VISIBILITY
    474     __tuple_impl&
    475     operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
    476     {
    477         __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
    478         return *this;
    479     }
    480 
    481     _LIBCPP_INLINE_VISIBILITY
    482     __tuple_impl&
    483     operator=(__tuple_impl&& __t) _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
    484     {
    485         __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...);
    486         return *this;
    487     }
    488 
    489     _LIBCPP_INLINE_VISIBILITY
    490     void swap(__tuple_impl& __t)
    491         _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
    492     {
    493         __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
    494     }
    495 };
    496 
    497 template <class ..._Tp>
    498 class _LIBCPP_TYPE_VIS_ONLY tuple
    499 {
    500     typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
    501 
    502     base base_;
    503 
    504     template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
    505         typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
    506     template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
    507         const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
    508     template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
    509         typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
    510 public:
    511 
    512     template <bool _Dummy = true, class = typename enable_if<
    513         __all<__dependent_type<is_default_constructible<_Tp>, _Dummy>::value...>::value
    514     >::type>
    515     _LIBCPP_INLINE_VISIBILITY
    516     _LIBCPP_CONSTEXPR tuple()
    517         _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
    518 
    519     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    520     explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) 
    521         : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
    522                 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
    523                 typename __make_tuple_indices<0>::type(),
    524                 typename __make_tuple_types<tuple, 0>::type(),
    525                 __t...
    526                ) {}
    527 
    528     template <class _Alloc>
    529       _LIBCPP_INLINE_VISIBILITY
    530       tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
    531         : base_(allocator_arg_t(), __a,
    532                 typename __make_tuple_indices<sizeof...(_Tp)>::type(),
    533                 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
    534                 typename __make_tuple_indices<0>::type(),
    535                 typename __make_tuple_types<tuple, 0>::type(),
    536                 __t...
    537                ) {}
    538 
    539     template <class ..._Up,
    540               typename enable_if
    541                       <
    542                          sizeof...(_Up) <= sizeof...(_Tp) &&
    543                          __tuple_convertible
    544                          <
    545                             tuple<_Up...>,
    546                             typename __make_tuple_types<tuple,
    547                                      sizeof...(_Up) < sizeof...(_Tp) ?
    548                                         sizeof...(_Up) :
    549                                         sizeof...(_Tp)>::type
    550                          >::value &&
    551                          __all_default_constructible<
    552                             typename __make_tuple_types<tuple, sizeof...(_Tp),
    553                                 sizeof...(_Up) < sizeof...(_Tp) ?
    554                                     sizeof...(_Up) :
    555                                     sizeof...(_Tp)>::type
    556                          >::value,
    557                          bool
    558                       >::type = false
    559              >
    560         _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    561         tuple(_Up&&... __u)
    562             _NOEXCEPT_((
    563                 is_nothrow_constructible<base,
    564                     typename __make_tuple_indices<sizeof...(_Up)>::type,
    565                     typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
    566                     typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
    567                     typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
    568                     _Up...
    569                 >::value
    570             ))
    571             : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
    572                     typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
    573                     typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
    574                     typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
    575                     _VSTD::forward<_Up>(__u)...) {}
    576 
    577     template <class ..._Up,
    578               typename enable_if
    579                       <
    580                          sizeof...(_Up) <= sizeof...(_Tp) &&
    581                          __tuple_constructible
    582                          <
    583                             tuple<_Up...>,
    584                             typename __make_tuple_types<tuple,
    585                                      sizeof...(_Up) < sizeof...(_Tp) ?
    586                                         sizeof...(_Up) :
    587                                         sizeof...(_Tp)>::type
    588                          >::value &&
    589                          !__tuple_convertible
    590                          <
    591                             tuple<_Up...>,
    592                             typename __make_tuple_types<tuple,
    593                                      sizeof...(_Up) < sizeof...(_Tp) ?
    594                                         sizeof...(_Up) :
    595                                         sizeof...(_Tp)>::type
    596                          >::value &&
    597                          __all_default_constructible<
    598                             typename __make_tuple_types<tuple, sizeof...(_Tp),
    599                                 sizeof...(_Up) < sizeof...(_Tp) ?
    600                                     sizeof...(_Up) :
    601                                     sizeof...(_Tp)>::type
    602                          >::value,
    603                          bool
    604                       >::type =false
    605              >
    606         _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    607         explicit
    608         tuple(_Up&&... __u)
    609             _NOEXCEPT_((
    610                 is_nothrow_constructible<base,
    611                     typename __make_tuple_indices<sizeof...(_Up)>::type,
    612                     typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
    613                     typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
    614                     typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
    615                     _Up...
    616                 >::value
    617             ))
    618             : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
    619                     typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
    620                     typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
    621                     typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
    622                     _VSTD::forward<_Up>(__u)...) {}
    623 
    624     template <class _Alloc, class ..._Up,
    625               class = typename enable_if
    626                       <
    627                          sizeof...(_Up) <= sizeof...(_Tp) &&
    628                          __tuple_convertible
    629                          <
    630                             tuple<_Up...>,
    631                             typename __make_tuple_types<tuple,
    632                                      sizeof...(_Up) < sizeof...(_Tp) ?
    633                                         sizeof...(_Up) :
    634                                         sizeof...(_Tp)>::type
    635                          >::value &&
    636                          __all_default_constructible<
    637                             typename __make_tuple_types<tuple, sizeof...(_Tp),
    638                                 sizeof...(_Up) < sizeof...(_Tp) ?
    639                                     sizeof...(_Up) :
    640                                     sizeof...(_Tp)>::type
    641                          >::value
    642                       >::type
    643              >
    644         _LIBCPP_INLINE_VISIBILITY
    645         tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
    646             : base_(allocator_arg_t(), __a,
    647                     typename __make_tuple_indices<sizeof...(_Up)>::type(),
    648                     typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
    649                     typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
    650                     typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
    651                     _VSTD::forward<_Up>(__u)...) {}
    652 
    653     template <class _Tuple,
    654               typename enable_if
    655                       <
    656                          __tuple_convertible<_Tuple, tuple>::value,
    657                          bool
    658                       >::type = false
    659              >
    660         _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    661         tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
    662             : base_(_VSTD::forward<_Tuple>(__t)) {}
    663 
    664     template <class _Tuple,
    665               typename enable_if
    666                       <
    667                          __tuple_constructible<_Tuple, tuple>::value &&
    668                          !__tuple_convertible<_Tuple, tuple>::value,
    669                          bool
    670                       >::type = false
    671              >
    672         _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    673         explicit
    674         tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
    675             : base_(_VSTD::forward<_Tuple>(__t)) {}
    676 
    677     template <class _Alloc, class _Tuple,
    678               class = typename enable_if
    679                       <
    680                          __tuple_convertible<_Tuple, tuple>::value
    681                       >::type
    682              >
    683         _LIBCPP_INLINE_VISIBILITY
    684         tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
    685             : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
    686 
    687     template <class _Tuple,
    688               class = typename enable_if
    689                       <
    690                          __tuple_assignable<_Tuple, tuple>::value
    691                       >::type
    692              >
    693         _LIBCPP_INLINE_VISIBILITY
    694         tuple&
    695         operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<base&, _Tuple>::value))
    696         {
    697             base_.operator=(_VSTD::forward<_Tuple>(__t));
    698             return *this;
    699         }
    700 
    701     _LIBCPP_INLINE_VISIBILITY
    702     void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
    703         {base_.swap(__t.base_);}
    704 };
    705 
    706 template <>
    707 class _LIBCPP_TYPE_VIS_ONLY tuple<>
    708 {
    709 public:
    710     _LIBCPP_INLINE_VISIBILITY
    711     _LIBCPP_CONSTEXPR tuple() _NOEXCEPT {}
    712     template <class _Alloc>
    713     _LIBCPP_INLINE_VISIBILITY
    714         tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
    715     template <class _Alloc>
    716     _LIBCPP_INLINE_VISIBILITY
    717         tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
    718     template <class _Up>
    719     _LIBCPP_INLINE_VISIBILITY
    720         tuple(array<_Up, 0>) _NOEXCEPT {}
    721     template <class _Alloc, class _Up>
    722     _LIBCPP_INLINE_VISIBILITY
    723         tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
    724     _LIBCPP_INLINE_VISIBILITY
    725     void swap(tuple&) _NOEXCEPT {}
    726 };
    727 
    728 template <class ..._Tp>
    729 inline _LIBCPP_INLINE_VISIBILITY
    730 typename enable_if
    731 <
    732     __all<__is_swappable<_Tp>::value...>::value,
    733     void
    734 >::type
    735 swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
    736                  _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
    737     {__t.swap(__u);}
    738 
    739 // get
    740 
    741 template <size_t _Ip, class ..._Tp>
    742 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    743 typename tuple_element<_Ip, tuple<_Tp...> >::type&
    744 get(tuple<_Tp...>& __t) _NOEXCEPT
    745 {
    746     typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
    747     return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get();
    748 }
    749 
    750 template <size_t _Ip, class ..._Tp>
    751 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    752 const typename tuple_element<_Ip, tuple<_Tp...> >::type&
    753 get(const tuple<_Tp...>& __t) _NOEXCEPT
    754 {
    755     typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
    756     return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get();
    757 }
    758 
    759 template <size_t _Ip, class ..._Tp>
    760 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    761 typename tuple_element<_Ip, tuple<_Tp...> >::type&&
    762 get(tuple<_Tp...>&& __t) _NOEXCEPT
    763 {
    764     typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
    765     return static_cast<type&&>(
    766              static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get());
    767 }
    768 
    769 #if _LIBCPP_STD_VER > 11
    770 // get by type
    771 template <typename _T1, size_t _Idx, typename... _Args>
    772 struct __find_exactly_one_t_helper;
    773 
    774 // -- find exactly one
    775 template <typename _T1, size_t _Idx, typename... _Args>
    776 struct __find_exactly_one_t_checker {
    777     static constexpr size_t value = _Idx;
    778 //  Check the rest of the list to make sure there's only one
    779     static_assert ( __find_exactly_one_t_helper<_T1, 0, _Args...>::value == -1, "type can only occur once in type list" );
    780     };
    781 
    782 
    783 template <typename _T1, size_t _Idx>
    784 struct __find_exactly_one_t_helper <_T1, _Idx> {
    785     static constexpr size_t value = -1;
    786     };
    787 
    788 template <typename _T1, size_t _Idx, typename _Head, typename... _Args>
    789 struct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> {
    790     static constexpr size_t value =
    791         std::conditional<
    792             std::is_same<_T1, _Head>::value,
    793             __find_exactly_one_t_checker<_T1, _Idx,   _Args...>,
    794             __find_exactly_one_t_helper <_T1, _Idx+1, _Args...>
    795         >::type::value;
    796     };
    797 
    798 template <typename _T1, typename... _Args>
    799 struct __find_exactly_one_t {
    800     static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value;
    801     static_assert ( value != -1, "type not found in type list" );
    802     };
    803 
    804 template <class _T1, class... _Args>
    805 inline _LIBCPP_INLINE_VISIBILITY
    806 constexpr _T1& get(tuple<_Args...>& __tup) noexcept
    807 {
    808     return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
    809 }
    810 
    811 template <class _T1, class... _Args>
    812 inline _LIBCPP_INLINE_VISIBILITY
    813 constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
    814 {
    815     return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
    816 }
    817 
    818 template <class _T1, class... _Args>
    819 inline _LIBCPP_INLINE_VISIBILITY
    820 constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
    821 {
    822     return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
    823 }
    824 
    825 #endif
    826 
    827 // tie
    828 
    829 template <class ..._Tp>
    830 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    831 tuple<_Tp&...>
    832 tie(_Tp&... __t) _NOEXCEPT
    833 {
    834     return tuple<_Tp&...>(__t...);
    835 }
    836 
    837 template <class _Up>
    838 struct __ignore_t
    839 {
    840     template <class _Tp>
    841         _LIBCPP_INLINE_VISIBILITY
    842         const __ignore_t& operator=(_Tp&&) const {return *this;}
    843 };
    844 
    845 namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
    846 
    847 template <class _Tp>
    848 struct __make_tuple_return_impl
    849 {
    850     typedef _Tp type;
    851 };
    852 
    853 template <class _Tp>
    854 struct __make_tuple_return_impl<reference_wrapper<_Tp> >
    855 {
    856     typedef _Tp& type;
    857 };
    858 
    859 template <class _Tp>
    860 struct __make_tuple_return
    861 {
    862     typedef typename __make_tuple_return_impl<typename decay<_Tp>::type>::type type;
    863 };
    864 
    865 template <class... _Tp>
    866 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    867 tuple<typename __make_tuple_return<_Tp>::type...>
    868 make_tuple(_Tp&&... __t)
    869 {
    870     return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
    871 }
    872 
    873 template <class... _Tp>
    874 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    875 tuple<_Tp&&...>
    876 forward_as_tuple(_Tp&&... __t) _NOEXCEPT
    877 {
    878     return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
    879 }
    880 
    881 template <size_t _Ip>
    882 struct __tuple_equal
    883 {
    884     template <class _Tp, class _Up>
    885     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    886     bool operator()(const _Tp& __x, const _Up& __y)
    887     {
    888         return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
    889     }
    890 };
    891 
    892 template <>
    893 struct __tuple_equal<0>
    894 {
    895     template <class _Tp, class _Up>
    896     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    897     bool operator()(const _Tp&, const _Up&)
    898     {
    899         return true;
    900     }
    901 };
    902 
    903 template <class ..._Tp, class ..._Up>
    904 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    905 bool
    906 operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
    907 {
    908     return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
    909 }
    910 
    911 template <class ..._Tp, class ..._Up>
    912 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    913 bool
    914 operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
    915 {
    916     return !(__x == __y);
    917 }
    918 
    919 template <size_t _Ip>
    920 struct __tuple_less
    921 {
    922     template <class _Tp, class _Up>
    923     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    924     bool operator()(const _Tp& __x, const _Up& __y)
    925     {
    926         const size_t __idx = tuple_size<_Tp>::value - _Ip;
    927         if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
    928             return true;
    929         if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
    930             return false;
    931         return __tuple_less<_Ip-1>()(__x, __y);
    932     }
    933 };
    934 
    935 template <>
    936 struct __tuple_less<0>
    937 {
    938     template <class _Tp, class _Up>
    939     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    940     bool operator()(const _Tp&, const _Up&)
    941     {
    942         return false;
    943     }
    944 };
    945 
    946 template <class ..._Tp, class ..._Up>
    947 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    948 bool
    949 operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
    950 {
    951     return __tuple_less<sizeof...(_Tp)>()(__x, __y);
    952 }
    953 
    954 template <class ..._Tp, class ..._Up>
    955 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    956 bool
    957 operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
    958 {
    959     return __y < __x;
    960 }
    961 
    962 template <class ..._Tp, class ..._Up>
    963 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    964 bool
    965 operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
    966 {
    967     return !(__x < __y);
    968 }
    969 
    970 template <class ..._Tp, class ..._Up>
    971 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    972 bool
    973 operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
    974 {
    975     return !(__y < __x);
    976 }
    977 
    978 // tuple_cat
    979 
    980 template <class _Tp, class _Up> struct __tuple_cat_type;
    981 
    982 template <class ..._Ttypes, class ..._Utypes>
    983 struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
    984 {
    985     typedef tuple<_Ttypes..., _Utypes...> type;
    986 };
    987 
    988 template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
    989 struct __tuple_cat_return_1
    990 {
    991 };
    992 
    993 template <class ..._Types, class _Tuple0>
    994 struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
    995 {
    996     typedef typename __tuple_cat_type<tuple<_Types...>,
    997             typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type>::type
    998                                                                            type;
    999 };
   1000 
   1001 template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
   1002 struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
   1003     : public __tuple_cat_return_1<
   1004                  typename __tuple_cat_type<
   1005                      tuple<_Types...>,
   1006                      typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type
   1007                  >::type,
   1008                  __tuple_like<typename remove_reference<_Tuple1>::type>::value,
   1009                  _Tuple1, _Tuples...>
   1010 {
   1011 };
   1012 
   1013 template <class ..._Tuples> struct __tuple_cat_return;
   1014 
   1015 template <class _Tuple0, class ..._Tuples>
   1016 struct __tuple_cat_return<_Tuple0, _Tuples...>
   1017     : public __tuple_cat_return_1<tuple<>,
   1018          __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
   1019                                                                      _Tuples...>
   1020 {
   1021 };
   1022 
   1023 template <>
   1024 struct __tuple_cat_return<>
   1025 {
   1026     typedef tuple<> type;
   1027 };
   1028 
   1029 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
   1030 tuple<>
   1031 tuple_cat()
   1032 {
   1033     return tuple<>();
   1034 }
   1035 
   1036 template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
   1037 struct __tuple_cat_return_ref_imp;
   1038 
   1039 template <class ..._Types, size_t ..._I0, class _Tuple0>
   1040 struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
   1041 {
   1042     typedef typename remove_reference<_Tuple0>::type _T0;
   1043     typedef tuple<_Types..., typename __apply_cv<_Tuple0,
   1044                           typename tuple_element<_I0, _T0>::type>::type&&...> type;
   1045 };
   1046 
   1047 template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
   1048 struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
   1049                                   _Tuple0, _Tuple1, _Tuples...>
   1050     : public __tuple_cat_return_ref_imp<
   1051          tuple<_Types..., typename __apply_cv<_Tuple0,
   1052                typename tuple_element<_I0,
   1053                   typename remove_reference<_Tuple0>::type>::type>::type&&...>,
   1054          typename __make_tuple_indices<tuple_size<typename
   1055                                  remove_reference<_Tuple1>::type>::value>::type,
   1056          _Tuple1, _Tuples...>
   1057 {
   1058 };
   1059 
   1060 template <class _Tuple0, class ..._Tuples>
   1061 struct __tuple_cat_return_ref
   1062     : public __tuple_cat_return_ref_imp<tuple<>,
   1063                typename __make_tuple_indices<
   1064                         tuple_size<typename remove_reference<_Tuple0>::type>::value
   1065                >::type, _Tuple0, _Tuples...>
   1066 {
   1067 };
   1068 
   1069 template <class _Types, class _I0, class _J0>
   1070 struct __tuple_cat;
   1071 
   1072 template <class ..._Types, size_t ..._I0, size_t ..._J0>
   1073 struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
   1074 {
   1075     template <class _Tuple0>
   1076     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
   1077     typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
   1078     operator()(tuple<_Types...> __t, _Tuple0&& __t0)
   1079     {
   1080         return forward_as_tuple(_VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
   1081                                       _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
   1082     }
   1083 
   1084     template <class _Tuple0, class _Tuple1, class ..._Tuples>
   1085     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
   1086     typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
   1087     operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
   1088     {
   1089         typedef typename remove_reference<_Tuple0>::type _T0;
   1090         typedef typename remove_reference<_Tuple1>::type _T1;
   1091         return __tuple_cat<
   1092            tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>,
   1093            typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type,
   1094            typename __make_tuple_indices<tuple_size<_T1>::value>::type>()
   1095                            (forward_as_tuple(
   1096                               _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
   1097                               _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...
   1098                             ),
   1099                             _VSTD::forward<_Tuple1>(__t1),
   1100                             _VSTD::forward<_Tuples>(__tpls)...);
   1101     }
   1102 };
   1103 
   1104 template <class _Tuple0, class... _Tuples>
   1105 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
   1106 typename __tuple_cat_return<_Tuple0, _Tuples...>::type
   1107 tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
   1108 {
   1109     typedef typename remove_reference<_Tuple0>::type _T0;
   1110     return __tuple_cat<tuple<>, __tuple_indices<>,
   1111                   typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
   1112                   (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
   1113                                             _VSTD::forward<_Tuples>(__tpls)...);
   1114 }
   1115 
   1116 template <class ..._Tp, class _Alloc>
   1117 struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<tuple<_Tp...>, _Alloc>
   1118     : true_type {};
   1119 
   1120 template <class _T1, class _T2>
   1121 template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
   1122 inline _LIBCPP_INLINE_VISIBILITY
   1123 pair<_T1, _T2>::pair(piecewise_construct_t,
   1124                      tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
   1125                      __tuple_indices<_I1...>, __tuple_indices<_I2...>)
   1126     :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
   1127       second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
   1128 {
   1129 }
   1130 
   1131 #endif  // _LIBCPP_HAS_NO_VARIADICS
   1132 
   1133 _LIBCPP_END_NAMESPACE_STD
   1134 
   1135 #endif  // _LIBCPP_TUPLE
   1136