Home | History | Annotate | Line # | Download | only in std
tuple revision 1.1.1.14
      1 // <tuple> -*- C++ -*-
      2 
      3 // Copyright (C) 2007-2020 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file include/tuple
     26  *  This is a Standard C++ Library header.
     27  */
     28 
     29 #ifndef _GLIBCXX_TUPLE
     30 #define _GLIBCXX_TUPLE 1
     31 
     32 #pragma GCC system_header
     33 
     34 #if __cplusplus < 201103L
     35 # include <bits/c++0x_warning.h>
     36 #else
     37 
     38 #include <utility>
     39 #include <array>
     40 #include <bits/uses_allocator.h>
     41 #include <bits/invoke.h>
     42 #if __cplusplus > 201703L
     43 # include <compare>
     44 # define __cpp_lib_constexpr_tuple 201811L
     45 #endif
     46 
     47 namespace std _GLIBCXX_VISIBILITY(default)
     48 {
     49 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     50 
     51   /**
     52    *  @addtogroup utilities
     53    *  @{
     54    */
     55 
     56   template<typename... _Elements>
     57     class tuple;
     58 
     59   template<typename _Tp>
     60     struct __is_empty_non_tuple : is_empty<_Tp> { };
     61 
     62   // Using EBO for elements that are tuples causes ambiguous base errors.
     63   template<typename _El0, typename... _El>
     64     struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
     65 
     66   // Use the Empty Base-class Optimization for empty, non-final types.
     67   template<typename _Tp>
     68     using __empty_not_final
     69     = typename conditional<__is_final(_Tp), false_type,
     70 			   __is_empty_non_tuple<_Tp>>::type;
     71 
     72   template<std::size_t _Idx, typename _Head,
     73 	   bool = __empty_not_final<_Head>::value>
     74     struct _Head_base;
     75 
     76   template<std::size_t _Idx, typename _Head>
     77     struct _Head_base<_Idx, _Head, true>
     78     : public _Head
     79     {
     80       constexpr _Head_base()
     81       : _Head() { }
     82 
     83       constexpr _Head_base(const _Head& __h)
     84       : _Head(__h) { }
     85 
     86       constexpr _Head_base(const _Head_base&) = default;
     87       constexpr _Head_base(_Head_base&&) = default;
     88 
     89       template<typename _UHead>
     90         constexpr _Head_base(_UHead&& __h)
     91 	: _Head(std::forward<_UHead>(__h)) { }
     92 
     93       _GLIBCXX20_CONSTEXPR
     94       _Head_base(allocator_arg_t, __uses_alloc0)
     95       : _Head() { }
     96 
     97       template<typename _Alloc>
     98 	_GLIBCXX20_CONSTEXPR
     99 	_Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
    100 	: _Head(allocator_arg, *__a._M_a) { }
    101 
    102       template<typename _Alloc>
    103 	_GLIBCXX20_CONSTEXPR
    104 	_Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
    105 	: _Head(*__a._M_a) { }
    106 
    107       template<typename _UHead>
    108 	_GLIBCXX20_CONSTEXPR
    109 	_Head_base(__uses_alloc0, _UHead&& __uhead)
    110 	: _Head(std::forward<_UHead>(__uhead)) { }
    111 
    112       template<typename _Alloc, typename _UHead>
    113 	_GLIBCXX20_CONSTEXPR
    114 	_Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
    115 	: _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
    116 
    117       template<typename _Alloc, typename _UHead>
    118 	_GLIBCXX20_CONSTEXPR
    119 	_Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
    120 	: _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
    121 
    122       static constexpr _Head&
    123       _M_head(_Head_base& __b) noexcept { return __b; }
    124 
    125       static constexpr const _Head&
    126       _M_head(const _Head_base& __b) noexcept { return __b; }
    127     };
    128 
    129   template<std::size_t _Idx, typename _Head>
    130     struct _Head_base<_Idx, _Head, false>
    131     {
    132       constexpr _Head_base()
    133       : _M_head_impl() { }
    134 
    135       constexpr _Head_base(const _Head& __h)
    136       : _M_head_impl(__h) { }
    137 
    138       constexpr _Head_base(const _Head_base&) = default;
    139       constexpr _Head_base(_Head_base&&) = default;
    140 
    141       template<typename _UHead>
    142         constexpr _Head_base(_UHead&& __h)
    143 	: _M_head_impl(std::forward<_UHead>(__h)) { }
    144 
    145       _GLIBCXX20_CONSTEXPR
    146       _Head_base(allocator_arg_t, __uses_alloc0)
    147       : _M_head_impl() { }
    148 
    149       template<typename _Alloc>
    150 	_GLIBCXX20_CONSTEXPR
    151 	_Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
    152 	: _M_head_impl(allocator_arg, *__a._M_a) { }
    153 
    154       template<typename _Alloc>
    155 	_GLIBCXX20_CONSTEXPR
    156 	_Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
    157 	: _M_head_impl(*__a._M_a) { }
    158 
    159       template<typename _UHead>
    160 	_GLIBCXX20_CONSTEXPR
    161 	_Head_base(__uses_alloc0, _UHead&& __uhead)
    162 	: _M_head_impl(std::forward<_UHead>(__uhead)) { }
    163 
    164       template<typename _Alloc, typename _UHead>
    165 	_GLIBCXX20_CONSTEXPR
    166 	_Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
    167 	: _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
    168 	{ }
    169 
    170       template<typename _Alloc, typename _UHead>
    171 	_GLIBCXX20_CONSTEXPR
    172 	_Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
    173 	: _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
    174 
    175       static constexpr _Head&
    176       _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
    177 
    178       static constexpr const _Head&
    179       _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
    180 
    181       _Head _M_head_impl;
    182     };
    183 
    184   /**
    185    * Contains the actual implementation of the @c tuple template, stored
    186    * as a recursive inheritance hierarchy from the first element (most
    187    * derived class) to the last (least derived class). The @c Idx
    188    * parameter gives the 0-based index of the element stored at this
    189    * point in the hierarchy; we use it to implement a constant-time
    190    * get() operation.
    191    */
    192   template<std::size_t _Idx, typename... _Elements>
    193     struct _Tuple_impl;
    194 
    195   /**
    196    * Recursive tuple implementation. Here we store the @c Head element
    197    * and derive from a @c Tuple_impl containing the remaining elements
    198    * (which contains the @c Tail).
    199    */
    200   template<std::size_t _Idx, typename _Head, typename... _Tail>
    201     struct _Tuple_impl<_Idx, _Head, _Tail...>
    202     : public _Tuple_impl<_Idx + 1, _Tail...>,
    203       private _Head_base<_Idx, _Head>
    204     {
    205       template<std::size_t, typename...> friend class _Tuple_impl;
    206 
    207       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
    208       typedef _Head_base<_Idx, _Head> _Base;
    209 
    210       static constexpr _Head&
    211       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
    212 
    213       static constexpr const _Head&
    214       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
    215 
    216       static constexpr _Inherited&
    217       _M_tail(_Tuple_impl& __t) noexcept { return __t; }
    218 
    219       static constexpr const _Inherited&
    220       _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
    221 
    222       constexpr _Tuple_impl()
    223       : _Inherited(), _Base() { }
    224 
    225       explicit
    226       constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
    227       : _Inherited(__tail...), _Base(__head) { }
    228 
    229       template<typename _UHead, typename... _UTail, typename = typename
    230                enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
    231         explicit
    232         constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
    233 	: _Inherited(std::forward<_UTail>(__tail)...),
    234 	  _Base(std::forward<_UHead>(__head)) { }
    235 
    236       constexpr _Tuple_impl(const _Tuple_impl&) = default;
    237 
    238       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    239       // 2729. Missing SFINAE on std::pair::operator=
    240       _Tuple_impl& operator=(const _Tuple_impl&) = delete;
    241 
    242       constexpr
    243       _Tuple_impl(_Tuple_impl&& __in)
    244       noexcept(__and_<is_nothrow_move_constructible<_Head>,
    245 	              is_nothrow_move_constructible<_Inherited>>::value)
    246       : _Inherited(std::move(_M_tail(__in))),
    247 	_Base(std::forward<_Head>(_M_head(__in))) { }
    248 
    249       template<typename... _UElements>
    250         constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
    251 	: _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
    252 	  _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
    253 
    254       template<typename _UHead, typename... _UTails>
    255         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
    256 	: _Inherited(std::move
    257 		     (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
    258 	  _Base(std::forward<_UHead>
    259 		(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
    260 
    261       template<typename _Alloc>
    262 	_GLIBCXX20_CONSTEXPR
    263 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
    264 	: _Inherited(__tag, __a),
    265           _Base(__tag, __use_alloc<_Head>(__a)) { }
    266 
    267       template<typename _Alloc>
    268 	_GLIBCXX20_CONSTEXPR
    269 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    270 		    const _Head& __head, const _Tail&... __tail)
    271 	: _Inherited(__tag, __a, __tail...),
    272           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
    273 
    274       template<typename _Alloc, typename _UHead, typename... _UTail,
    275                typename = typename enable_if<sizeof...(_Tail)
    276 					     == sizeof...(_UTail)>::type>
    277 	_GLIBCXX20_CONSTEXPR
    278 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    279 	            _UHead&& __head, _UTail&&... __tail)
    280 	: _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
    281           _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
    282 	        std::forward<_UHead>(__head)) { }
    283 
    284       template<typename _Alloc>
    285 	_GLIBCXX20_CONSTEXPR
    286         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    287 	            const _Tuple_impl& __in)
    288 	: _Inherited(__tag, __a, _M_tail(__in)),
    289           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
    290 
    291       template<typename _Alloc>
    292 	_GLIBCXX20_CONSTEXPR
    293 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    294 	            _Tuple_impl&& __in)
    295 	: _Inherited(__tag, __a, std::move(_M_tail(__in))),
    296 	  _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
    297 	        std::forward<_Head>(_M_head(__in))) { }
    298 
    299       template<typename _Alloc, typename _UHead, typename... _UTails>
    300 	_GLIBCXX20_CONSTEXPR
    301 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    302 		    const _Tuple_impl<_Idx, _UHead, _UTails...>& __in)
    303 	: _Inherited(__tag, __a,
    304 		     _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),
    305 	  _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
    306 		_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)) { }
    307 
    308       template<typename _Alloc, typename _UHead, typename... _UTails>
    309 	_GLIBCXX20_CONSTEXPR
    310 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    311 	            _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
    312 	: _Inherited(__tag, __a, std::move
    313 		     (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
    314 	  _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
    315                 std::forward<_UHead>
    316 		(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
    317 
    318       template<typename... _UElements>
    319 	_GLIBCXX20_CONSTEXPR
    320         void
    321         _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in)
    322         {
    323 	  _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
    324 	  _M_tail(*this)._M_assign(
    325 	      _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
    326 	}
    327 
    328       template<typename _UHead, typename... _UTails>
    329 	_GLIBCXX20_CONSTEXPR
    330         void
    331         _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
    332         {
    333 	  _M_head(*this) = std::forward<_UHead>
    334 	    (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
    335 	  _M_tail(*this)._M_assign(
    336 	      std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
    337 	}
    338 
    339     protected:
    340       _GLIBCXX20_CONSTEXPR
    341       void
    342       _M_swap(_Tuple_impl& __in)
    343       {
    344 	using std::swap;
    345 	swap(_M_head(*this), _M_head(__in));
    346 	_Inherited::_M_swap(_M_tail(__in));
    347       }
    348     };
    349 
    350   // Basis case of inheritance recursion.
    351   template<std::size_t _Idx, typename _Head>
    352     struct _Tuple_impl<_Idx, _Head>
    353     : private _Head_base<_Idx, _Head>
    354     {
    355       template<std::size_t, typename...> friend class _Tuple_impl;
    356 
    357       typedef _Head_base<_Idx, _Head> _Base;
    358 
    359       static constexpr _Head&
    360       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
    361 
    362       static constexpr const _Head&
    363       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
    364 
    365       constexpr _Tuple_impl()
    366       : _Base() { }
    367 
    368       explicit
    369       constexpr _Tuple_impl(const _Head& __head)
    370       : _Base(__head) { }
    371 
    372       template<typename _UHead>
    373         explicit
    374         constexpr _Tuple_impl(_UHead&& __head)
    375 	: _Base(std::forward<_UHead>(__head)) { }
    376 
    377       constexpr _Tuple_impl(const _Tuple_impl&) = default;
    378 
    379       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    380       // 2729. Missing SFINAE on std::pair::operator=
    381       _Tuple_impl& operator=(const _Tuple_impl&) = delete;
    382 
    383       constexpr
    384       _Tuple_impl(_Tuple_impl&& __in)
    385       noexcept(is_nothrow_move_constructible<_Head>::value)
    386       : _Base(std::forward<_Head>(_M_head(__in))) { }
    387 
    388       template<typename _UHead>
    389         constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
    390 	: _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
    391 
    392       template<typename _UHead>
    393         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
    394 	: _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
    395 	{ }
    396 
    397       template<typename _Alloc>
    398 	_GLIBCXX20_CONSTEXPR
    399 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
    400 	: _Base(__tag, __use_alloc<_Head>(__a)) { }
    401 
    402       template<typename _Alloc>
    403 	_GLIBCXX20_CONSTEXPR
    404 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    405 		    const _Head& __head)
    406 	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
    407 
    408       template<typename _Alloc, typename _UHead>
    409 	_GLIBCXX20_CONSTEXPR
    410 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    411 	            _UHead&& __head)
    412 	: _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
    413 	        std::forward<_UHead>(__head)) { }
    414 
    415       template<typename _Alloc>
    416 	_GLIBCXX20_CONSTEXPR
    417         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    418 	            const _Tuple_impl& __in)
    419 	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
    420 
    421       template<typename _Alloc>
    422 	_GLIBCXX20_CONSTEXPR
    423 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    424 	            _Tuple_impl&& __in)
    425 	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
    426 	        std::forward<_Head>(_M_head(__in))) { }
    427 
    428       template<typename _Alloc, typename _UHead>
    429 	_GLIBCXX20_CONSTEXPR
    430 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    431 	            const _Tuple_impl<_Idx, _UHead>& __in)
    432 	: _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
    433 		_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
    434 
    435       template<typename _Alloc, typename _UHead>
    436 	_GLIBCXX20_CONSTEXPR
    437 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    438 	            _Tuple_impl<_Idx, _UHead>&& __in)
    439 	: _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
    440                 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
    441 	{ }
    442 
    443       template<typename _UHead>
    444 	_GLIBCXX20_CONSTEXPR
    445         void
    446         _M_assign(const _Tuple_impl<_Idx, _UHead>& __in)
    447         {
    448 	  _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
    449 	}
    450 
    451       template<typename _UHead>
    452 	_GLIBCXX20_CONSTEXPR
    453         void
    454         _M_assign(_Tuple_impl<_Idx, _UHead>&& __in)
    455         {
    456 	  _M_head(*this)
    457 	    = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
    458 	}
    459 
    460     protected:
    461       _GLIBCXX20_CONSTEXPR
    462       void
    463       _M_swap(_Tuple_impl& __in)
    464       {
    465 	using std::swap;
    466 	swap(_M_head(*this), _M_head(__in));
    467       }
    468     };
    469 
    470   // Concept utility functions, reused in conditionally-explicit
    471   // constructors.
    472   template<bool, typename... _Types>
    473     struct _TupleConstraints
    474     {
    475       template<typename _Tp, typename _Up> // Workaround for PR 96592
    476 	using is_constructible
    477 	  = __bool_constant<__is_constructible(_Tp, _Up)>;
    478 
    479       // Constraint for a non-explicit constructor.
    480       // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
    481       // and every Ui is implicitly convertible to Ti.
    482       template<typename... _UTypes>
    483 	static constexpr bool __is_implicitly_constructible()
    484 	{
    485 	  return __and_<is_constructible<_Types, _UTypes>...,
    486 			is_convertible<_UTypes, _Types>...
    487 			>::value;
    488 	}
    489 
    490       // Constraint for a non-explicit constructor.
    491       // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
    492       // but not every Ui is implicitly convertible to Ti.
    493       template<typename... _UTypes>
    494 	static constexpr bool __is_explicitly_constructible()
    495 	{
    496 	  return __and_<is_constructible<_Types, _UTypes>...,
    497 			__not_<__and_<is_convertible<_UTypes, _Types>...>>
    498 			>::value;
    499 	}
    500 
    501       static constexpr bool __is_implicitly_default_constructible()
    502       {
    503 	return __and_<std::__is_implicitly_default_constructible<_Types>...
    504 		      >::value;
    505       }
    506 
    507       static constexpr bool __is_explicitly_default_constructible()
    508       {
    509 	return __and_<is_default_constructible<_Types>...,
    510 		      __not_<__and_<
    511 			std::__is_implicitly_default_constructible<_Types>...>
    512 		      >>::value;
    513       }
    514     };
    515 
    516   // Partial specialization used when a required precondition isn't met,
    517   // e.g. when sizeof...(_Types) != sizeof...(_UTypes).
    518   template<typename... _Types>
    519     struct _TupleConstraints<false, _Types...>
    520     {
    521       template<typename... _UTypes>
    522 	static constexpr bool __is_implicitly_constructible()
    523 	{ return false; }
    524 
    525       template<typename... _UTypes>
    526 	static constexpr bool __is_explicitly_constructible()
    527 	{ return false; }
    528     };
    529 
    530   /// Primary class template, tuple
    531   template<typename... _Elements>
    532     class tuple : public _Tuple_impl<0, _Elements...>
    533     {
    534       typedef _Tuple_impl<0, _Elements...> _Inherited;
    535 
    536       template<bool _Cond>
    537 	using _TCC = _TupleConstraints<_Cond, _Elements...>;
    538 
    539       // Constraint for non-explicit default constructor
    540       template<bool _Dummy>
    541 	using _ImplicitDefaultCtor = __enable_if_t<
    542 	  _TCC<_Dummy>::__is_implicitly_default_constructible(),
    543 	  bool>;
    544 
    545       // Constraint for explicit default constructor
    546       template<bool _Dummy>
    547 	using _ExplicitDefaultCtor = __enable_if_t<
    548 	  _TCC<_Dummy>::__is_explicitly_default_constructible(),
    549 	  bool>;
    550 
    551       // Constraint for non-explicit constructors
    552       template<bool _Cond, typename... _Args>
    553 	using _ImplicitCtor = __enable_if_t<
    554 	  _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
    555 	  bool>;
    556 
    557       // Constraint for non-explicit constructors
    558       template<bool _Cond, typename... _Args>
    559 	using _ExplicitCtor = __enable_if_t<
    560 	  _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(),
    561 	  bool>;
    562 
    563       template<typename... _UElements>
    564 	static constexpr
    565 	__enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool>
    566 	__assignable()
    567 	{ return __and_<is_assignable<_Elements&, _UElements>...>::value; }
    568 
    569       // Condition for noexcept-specifier of an assignment operator.
    570       template<typename... _UElements>
    571 	static constexpr bool __nothrow_assignable()
    572 	{
    573 	  return
    574 	    __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value;
    575 	}
    576 
    577       // Condition for noexcept-specifier of a constructor.
    578       template<typename... _UElements>
    579 	static constexpr bool __nothrow_constructible()
    580 	{
    581 	  return
    582 	    __and_<is_nothrow_constructible<_Elements, _UElements>...>::value;
    583 	}
    584 
    585       // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) == 1.
    586       template<typename _Up>
    587 	static constexpr bool __valid_args()
    588 	{
    589 	  return sizeof...(_Elements) == 1
    590 	    && !is_same<tuple, __remove_cvref_t<_Up>>::value;
    591 	}
    592 
    593       // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) > 1.
    594       template<typename, typename, typename... _Tail>
    595 	static constexpr bool __valid_args()
    596 	{ return (sizeof...(_Tail) + 2) == sizeof...(_Elements); }
    597 
    598       /* Constraint for constructors with a tuple<UTypes...> parameter ensures
    599        * that the constructor is only viable when it would not interfere with
    600        * tuple(UTypes&&...) or tuple(const tuple&) or tuple(tuple&&).
    601        * Such constructors are only viable if:
    602        * either sizeof...(Types) != 1,
    603        * or (when Types... expands to T and UTypes... expands to U)
    604        * is_convertible_v<TUPLE, T>, is_constructible_v<T, TUPLE>,
    605        * and is_same_v<T, U> are all false.
    606        */
    607       template<typename _Tuple, typename = tuple,
    608 	       typename = __remove_cvref_t<_Tuple>>
    609 	struct _UseOtherCtor
    610 	: false_type
    611 	{ };
    612       // If TUPLE is convertible to the single element in *this,
    613       // then TUPLE should match tuple(UTypes&&...) instead.
    614       template<typename _Tuple, typename _Tp, typename _Up>
    615 	struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>>
    616 	: __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>>
    617 	{ };
    618       // If TUPLE and *this each have a single element of the same type,
    619       // then TUPLE should match a copy/move constructor instead.
    620       template<typename _Tuple, typename _Tp>
    621 	struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>>
    622 	: true_type
    623 	{ };
    624 
    625       // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1
    626       // and the single element in Types can be initialized from TUPLE,
    627       // or is the same type as tuple_element_t<0, TUPLE>.
    628       template<typename _Tuple>
    629 	static constexpr bool __use_other_ctor()
    630 	{ return _UseOtherCtor<_Tuple>::value; }
    631 
    632     public:
    633       template<typename _Dummy = void,
    634 	       _ImplicitDefaultCtor<is_void<_Dummy>::value> = true>
    635 	constexpr
    636 	tuple()
    637 	noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
    638 	: _Inherited() { }
    639 
    640       template<typename _Dummy = void,
    641 	       _ExplicitDefaultCtor<is_void<_Dummy>::value> = false>
    642 	explicit constexpr
    643 	tuple()
    644 	noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
    645 	: _Inherited() { }
    646 
    647       template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
    648 	       _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
    649 	constexpr
    650 	tuple(const _Elements&... __elements)
    651 	noexcept(__nothrow_constructible<const _Elements&...>())
    652 	: _Inherited(__elements...) { }
    653 
    654       template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
    655 	       _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
    656 	explicit constexpr
    657 	tuple(const _Elements&... __elements)
    658 	noexcept(__nothrow_constructible<const _Elements&...>())
    659 	: _Inherited(__elements...) { }
    660 
    661       template<typename... _UElements,
    662 	       bool _Valid = __valid_args<_UElements...>(),
    663 	       _ImplicitCtor<_Valid, _UElements...> = true>
    664 	constexpr
    665 	tuple(_UElements&&... __elements)
    666 	noexcept(__nothrow_constructible<_UElements...>())
    667 	: _Inherited(std::forward<_UElements>(__elements)...) { }
    668 
    669       template<typename... _UElements,
    670 	       bool _Valid = __valid_args<_UElements...>(),
    671 	       _ExplicitCtor<_Valid, _UElements...> = false>
    672 	explicit constexpr
    673 	tuple(_UElements&&... __elements)
    674 	noexcept(__nothrow_constructible<_UElements...>())
    675 	: _Inherited(std::forward<_UElements>(__elements)...) {	}
    676 
    677       constexpr tuple(const tuple&) = default;
    678 
    679       constexpr tuple(tuple&&) = default;
    680 
    681       template<typename... _UElements,
    682 	       bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    683 			   && !__use_other_ctor<const tuple<_UElements...>&>(),
    684 	       _ImplicitCtor<_Valid, const _UElements&...> = true>
    685 	constexpr
    686 	tuple(const tuple<_UElements...>& __in)
    687 	noexcept(__nothrow_constructible<const _UElements&...>())
    688 	: _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    689 	{ }
    690 
    691       template<typename... _UElements,
    692 	       bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    693 			   && !__use_other_ctor<const tuple<_UElements...>&>(),
    694 	       _ExplicitCtor<_Valid, const _UElements&...> = false>
    695 	explicit constexpr
    696 	tuple(const tuple<_UElements...>& __in)
    697 	noexcept(__nothrow_constructible<const _UElements&...>())
    698 	: _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    699 	{ }
    700 
    701       template<typename... _UElements,
    702 	       bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    703 			     && !__use_other_ctor<tuple<_UElements...>&&>(),
    704 	       _ImplicitCtor<_Valid, _UElements...> = true>
    705 	constexpr
    706 	tuple(tuple<_UElements...>&& __in)
    707 	noexcept(__nothrow_constructible<_UElements...>())
    708 	: _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
    709 
    710       template<typename... _UElements,
    711 	       bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    712 			     && !__use_other_ctor<tuple<_UElements...>&&>(),
    713 	       _ExplicitCtor<_Valid, _UElements...> = false>
    714 	explicit constexpr
    715 	tuple(tuple<_UElements...>&& __in)
    716 	noexcept(__nothrow_constructible<_UElements...>())
    717 	: _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
    718 
    719       // Allocator-extended constructors.
    720 
    721       template<typename _Alloc,
    722 	       _ImplicitDefaultCtor<is_object<_Alloc>::value> = true>
    723 	_GLIBCXX20_CONSTEXPR
    724 	tuple(allocator_arg_t __tag, const _Alloc& __a)
    725 	: _Inherited(__tag, __a) { }
    726 
    727       template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
    728 	       _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
    729 	_GLIBCXX20_CONSTEXPR
    730 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    731 	      const _Elements&... __elements)
    732 	: _Inherited(__tag, __a, __elements...) { }
    733 
    734       template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
    735 	       _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
    736 	_GLIBCXX20_CONSTEXPR
    737 	explicit
    738 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    739 	      const _Elements&... __elements)
    740 	: _Inherited(__tag, __a, __elements...) { }
    741 
    742       template<typename _Alloc, typename... _UElements,
    743 	       bool _Valid = __valid_args<_UElements...>(),
    744 	       _ImplicitCtor<_Valid, _UElements...> = true>
    745 	_GLIBCXX20_CONSTEXPR
    746 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    747 	      _UElements&&... __elements)
    748 	: _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
    749 	{ }
    750 
    751       template<typename _Alloc, typename... _UElements,
    752 		 bool _Valid = __valid_args<_UElements...>(),
    753 	       _ExplicitCtor<_Valid, _UElements...> = false>
    754 	_GLIBCXX20_CONSTEXPR
    755 	explicit
    756 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    757 	      _UElements&&... __elements)
    758 	: _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
    759 	{ }
    760 
    761       template<typename _Alloc>
    762 	_GLIBCXX20_CONSTEXPR
    763 	tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
    764 	: _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
    765 
    766       template<typename _Alloc>
    767 	_GLIBCXX20_CONSTEXPR
    768 	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
    769 	: _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
    770 
    771       template<typename _Alloc, typename... _UElements,
    772 	       bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    773 			     && !__use_other_ctor<const tuple<_UElements...>&>(),
    774 	       _ImplicitCtor<_Valid, const _UElements&...> = true>
    775 	_GLIBCXX20_CONSTEXPR
    776 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    777 	      const tuple<_UElements...>& __in)
    778 	: _Inherited(__tag, __a,
    779 	             static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    780 	{ }
    781 
    782       template<typename _Alloc, typename... _UElements,
    783 	       bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    784 			     && !__use_other_ctor<const tuple<_UElements...>&>(),
    785 	       _ExplicitCtor<_Valid, const _UElements&...> = false>
    786 	_GLIBCXX20_CONSTEXPR
    787 	explicit
    788 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    789 	      const tuple<_UElements...>& __in)
    790 	: _Inherited(__tag, __a,
    791 	             static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    792 	{ }
    793 
    794       template<typename _Alloc, typename... _UElements,
    795 	       bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    796 			     && !__use_other_ctor<tuple<_UElements...>&&>(),
    797 	       _ImplicitCtor<_Valid, _UElements...> = true>
    798 	_GLIBCXX20_CONSTEXPR
    799 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    800 	      tuple<_UElements...>&& __in)
    801 	: _Inherited(__tag, __a,
    802 	             static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
    803 	{ }
    804 
    805       template<typename _Alloc, typename... _UElements,
    806 	       bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    807 			     && !__use_other_ctor<tuple<_UElements...>&&>(),
    808 	       _ExplicitCtor<_Valid, _UElements...> = false>
    809 	_GLIBCXX20_CONSTEXPR
    810 	explicit
    811 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    812 	      tuple<_UElements...>&& __in)
    813 	: _Inherited(__tag, __a,
    814 	             static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
    815 	{ }
    816 
    817       // tuple assignment
    818 
    819       _GLIBCXX20_CONSTEXPR
    820       tuple&
    821       operator=(typename conditional<__assignable<const _Elements&...>(),
    822 				     const tuple&,
    823 				     const __nonesuch&>::type __in)
    824       noexcept(__nothrow_assignable<const _Elements&...>())
    825       {
    826 	this->_M_assign(__in);
    827 	return *this;
    828       }
    829 
    830       _GLIBCXX20_CONSTEXPR
    831       tuple&
    832       operator=(typename conditional<__assignable<_Elements...>(),
    833 				     tuple&&,
    834 				     __nonesuch&&>::type __in)
    835       noexcept(__nothrow_assignable<_Elements...>())
    836       {
    837 	this->_M_assign(std::move(__in));
    838 	return *this;
    839       }
    840 
    841       template<typename... _UElements>
    842 	_GLIBCXX20_CONSTEXPR
    843 	__enable_if_t<__assignable<const _UElements&...>(), tuple&>
    844 	operator=(const tuple<_UElements...>& __in)
    845 	noexcept(__nothrow_assignable<const _UElements&...>())
    846 	{
    847 	  this->_M_assign(__in);
    848 	  return *this;
    849 	}
    850 
    851       template<typename... _UElements>
    852 	_GLIBCXX20_CONSTEXPR
    853 	__enable_if_t<__assignable<_UElements...>(), tuple&>
    854 	operator=(tuple<_UElements...>&& __in)
    855 	noexcept(__nothrow_assignable<_UElements...>())
    856 	{
    857 	  this->_M_assign(std::move(__in));
    858 	  return *this;
    859 	}
    860 
    861       // tuple swap
    862       _GLIBCXX20_CONSTEXPR
    863       void
    864       swap(tuple& __in)
    865       noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
    866       { _Inherited::_M_swap(__in); }
    867     };
    868 
    869 #if __cpp_deduction_guides >= 201606
    870   template<typename... _UTypes>
    871     tuple(_UTypes...) -> tuple<_UTypes...>;
    872   template<typename _T1, typename _T2>
    873     tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
    874   template<typename _Alloc, typename... _UTypes>
    875     tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
    876   template<typename _Alloc, typename _T1, typename _T2>
    877     tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
    878   template<typename _Alloc, typename... _UTypes>
    879     tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
    880 #endif
    881 
    882   // Explicit specialization, zero-element tuple.
    883   template<>
    884     class tuple<>
    885     {
    886     public:
    887       _GLIBCXX20_CONSTEXPR
    888       void swap(tuple&) noexcept { /* no-op */ }
    889       // We need the default since we're going to define no-op
    890       // allocator constructors.
    891       tuple() = default;
    892       // No-op allocator constructors.
    893       template<typename _Alloc>
    894 	_GLIBCXX20_CONSTEXPR
    895 	tuple(allocator_arg_t, const _Alloc&) noexcept { }
    896       template<typename _Alloc>
    897 	_GLIBCXX20_CONSTEXPR
    898 	tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { }
    899     };
    900 
    901   /// Partial specialization, 2-element tuple.
    902   /// Includes construction and assignment from a pair.
    903   template<typename _T1, typename _T2>
    904     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
    905     {
    906       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
    907 
    908       // Constraint for non-explicit default constructor
    909       template<bool _Dummy, typename _U1, typename _U2>
    910 	using _ImplicitDefaultCtor = __enable_if_t<
    911 	  _TupleConstraints<_Dummy, _U1, _U2>::
    912 	    __is_implicitly_default_constructible(),
    913 	  bool>;
    914 
    915       // Constraint for explicit default constructor
    916       template<bool _Dummy, typename _U1, typename _U2>
    917 	using _ExplicitDefaultCtor = __enable_if_t<
    918 	  _TupleConstraints<_Dummy, _U1, _U2>::
    919 	    __is_explicitly_default_constructible(),
    920 	  bool>;
    921 
    922       template<bool _Dummy>
    923 	using _TCC = _TupleConstraints<_Dummy, _T1, _T2>;
    924 
    925       // Constraint for non-explicit constructors
    926       template<bool _Cond, typename _U1, typename _U2>
    927 	using _ImplicitCtor = __enable_if_t<
    928 	  _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(),
    929 	  bool>;
    930 
    931       // Constraint for non-explicit constructors
    932       template<bool _Cond, typename _U1, typename _U2>
    933 	using _ExplicitCtor = __enable_if_t<
    934 	  _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(),
    935 	  bool>;
    936 
    937       template<typename _U1, typename _U2>
    938 	static constexpr bool __assignable()
    939 	{
    940 	  return __and_<is_assignable<_T1&, _U1>,
    941 			is_assignable<_T2&, _U2>>::value;
    942 	}
    943 
    944       template<typename _U1, typename _U2>
    945 	static constexpr bool __nothrow_assignable()
    946 	{
    947 	  return __and_<is_nothrow_assignable<_T1&, _U1>,
    948 			is_nothrow_assignable<_T2&, _U2>>::value;
    949 	}
    950 
    951       template<typename _U1, typename _U2>
    952 	static constexpr bool __nothrow_constructible()
    953 	{
    954 	  return __and_<is_nothrow_constructible<_T1, _U1>,
    955 			    is_nothrow_constructible<_T2, _U2>>::value;
    956 	}
    957 
    958       static constexpr bool __nothrow_default_constructible()
    959       {
    960 	return __and_<is_nothrow_default_constructible<_T1>,
    961 		      is_nothrow_default_constructible<_T2>>::value;
    962       }
    963 
    964       template<typename _U1>
    965 	static constexpr bool __is_alloc_arg()
    966 	{ return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; }
    967 
    968     public:
    969       template<bool _Dummy = true,
    970 	       _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true>
    971 	constexpr
    972 	tuple()
    973 	noexcept(__nothrow_default_constructible())
    974 	: _Inherited() { }
    975 
    976       template<bool _Dummy = true,
    977 	       _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false>
    978 	explicit constexpr
    979 	tuple()
    980 	noexcept(__nothrow_default_constructible())
    981 	: _Inherited() { }
    982 
    983       template<bool _Dummy = true,
    984 	       _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
    985 	constexpr
    986 	tuple(const _T1& __a1, const _T2& __a2)
    987 	noexcept(__nothrow_constructible<const _T1&, const _T2&>())
    988 	: _Inherited(__a1, __a2) { }
    989 
    990       template<bool _Dummy = true,
    991 	       _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
    992 	explicit constexpr
    993 	tuple(const _T1& __a1, const _T2& __a2)
    994 	noexcept(__nothrow_constructible<const _T1&, const _T2&>())
    995 	: _Inherited(__a1, __a2) { }
    996 
    997       template<typename _U1, typename _U2,
    998 	       _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true>
    999 	constexpr
   1000 	tuple(_U1&& __a1, _U2&& __a2)
   1001 	noexcept(__nothrow_constructible<_U1, _U2>())
   1002 	: _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
   1003 
   1004       template<typename _U1, typename _U2,
   1005 	       _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false>
   1006 	explicit constexpr
   1007 	tuple(_U1&& __a1, _U2&& __a2)
   1008 	noexcept(__nothrow_constructible<_U1, _U2>())
   1009 	: _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
   1010 
   1011       constexpr tuple(const tuple&) = default;
   1012 
   1013       constexpr tuple(tuple&&) = default;
   1014 
   1015       template<typename _U1, typename _U2,
   1016 	       _ImplicitCtor<true, const _U1&, const _U2&> = true>
   1017 	constexpr
   1018 	tuple(const tuple<_U1, _U2>& __in)
   1019 	noexcept(__nothrow_constructible<const _U1&, const _U2&>())
   1020 	: _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
   1021 
   1022       template<typename _U1, typename _U2,
   1023 	       _ExplicitCtor<true, const _U1&, const _U2&> = false>
   1024 	explicit constexpr
   1025 	tuple(const tuple<_U1, _U2>& __in)
   1026 	noexcept(__nothrow_constructible<const _U1&, const _U2&>())
   1027 	: _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
   1028 
   1029       template<typename _U1, typename _U2,
   1030 	       _ImplicitCtor<true, _U1, _U2> = true>
   1031 	constexpr
   1032 	tuple(tuple<_U1, _U2>&& __in)
   1033 	noexcept(__nothrow_constructible<_U1, _U2>())
   1034 	: _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
   1035 
   1036       template<typename _U1, typename _U2,
   1037 	       _ExplicitCtor<true, _U1, _U2> = false>
   1038 	explicit constexpr
   1039 	tuple(tuple<_U1, _U2>&& __in)
   1040 	noexcept(__nothrow_constructible<_U1, _U2>())
   1041 	: _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
   1042 
   1043       template<typename _U1, typename _U2,
   1044 	       _ImplicitCtor<true, const _U1&, const _U2&> = true>
   1045 	constexpr
   1046 	tuple(const pair<_U1, _U2>& __in)
   1047 	noexcept(__nothrow_constructible<const _U1&, const _U2&>())
   1048 	: _Inherited(__in.first, __in.second) { }
   1049 
   1050       template<typename _U1, typename _U2,
   1051 	       _ExplicitCtor<true, const _U1&, const _U2&> = false>
   1052 	explicit constexpr
   1053 	tuple(const pair<_U1, _U2>& __in)
   1054 	noexcept(__nothrow_constructible<const _U1&, const _U2&>())
   1055 	: _Inherited(__in.first, __in.second) { }
   1056 
   1057       template<typename _U1, typename _U2,
   1058 	       _ImplicitCtor<true, _U1, _U2> = true>
   1059 	constexpr
   1060 	tuple(pair<_U1, _U2>&& __in)
   1061 	noexcept(__nothrow_constructible<_U1, _U2>())
   1062 	: _Inherited(std::forward<_U1>(__in.first),
   1063 		     std::forward<_U2>(__in.second)) { }
   1064 
   1065       template<typename _U1, typename _U2,
   1066 	       _ExplicitCtor<true, _U1, _U2> = false>
   1067 	explicit constexpr
   1068 	tuple(pair<_U1, _U2>&& __in)
   1069 	noexcept(__nothrow_constructible<_U1, _U2>())
   1070 	: _Inherited(std::forward<_U1>(__in.first),
   1071 		     std::forward<_U2>(__in.second)) { }
   1072 
   1073       // Allocator-extended constructors.
   1074 
   1075       template<typename _Alloc,
   1076 	       _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true>
   1077 	_GLIBCXX20_CONSTEXPR
   1078 	tuple(allocator_arg_t __tag, const _Alloc& __a)
   1079 	: _Inherited(__tag, __a) { }
   1080 
   1081       template<typename _Alloc, bool _Dummy = true,
   1082 	       _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
   1083 	_GLIBCXX20_CONSTEXPR
   1084 	tuple(allocator_arg_t __tag, const _Alloc& __a,
   1085 	      const _T1& __a1, const _T2& __a2)
   1086 	: _Inherited(__tag, __a, __a1, __a2) { }
   1087 
   1088       template<typename _Alloc, bool _Dummy = true,
   1089 	       _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
   1090 	explicit
   1091 	_GLIBCXX20_CONSTEXPR
   1092 	tuple(allocator_arg_t __tag, const _Alloc& __a,
   1093 	      const _T1& __a1, const _T2& __a2)
   1094 	: _Inherited(__tag, __a, __a1, __a2) { }
   1095 
   1096       template<typename _Alloc, typename _U1, typename _U2,
   1097 	       _ImplicitCtor<true, _U1, _U2> = true>
   1098 	_GLIBCXX20_CONSTEXPR
   1099 	tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
   1100 	: _Inherited(__tag, __a, std::forward<_U1>(__a1),
   1101 	             std::forward<_U2>(__a2)) { }
   1102 
   1103       template<typename _Alloc, typename _U1, typename _U2,
   1104 	       _ExplicitCtor<true, _U1, _U2> = false>
   1105 	explicit
   1106 	_GLIBCXX20_CONSTEXPR
   1107 	tuple(allocator_arg_t __tag, const _Alloc& __a,
   1108 	      _U1&& __a1, _U2&& __a2)
   1109 	: _Inherited(__tag, __a, std::forward<_U1>(__a1),
   1110 	             std::forward<_U2>(__a2)) { }
   1111 
   1112       template<typename _Alloc>
   1113 	_GLIBCXX20_CONSTEXPR
   1114 	tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
   1115 	: _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
   1116 
   1117       template<typename _Alloc>
   1118 	_GLIBCXX20_CONSTEXPR
   1119 	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
   1120 	: _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
   1121 
   1122       template<typename _Alloc, typename _U1, typename _U2,
   1123 	       _ImplicitCtor<true, const _U1&, const _U2&> = true>
   1124 	_GLIBCXX20_CONSTEXPR
   1125 	tuple(allocator_arg_t __tag, const _Alloc& __a,
   1126 	      const tuple<_U1, _U2>& __in)
   1127 	: _Inherited(__tag, __a,
   1128 	             static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
   1129 	{ }
   1130 
   1131       template<typename _Alloc, typename _U1, typename _U2,
   1132 	       _ExplicitCtor<true, const _U1&, const _U2&> = false>
   1133 	explicit
   1134 	_GLIBCXX20_CONSTEXPR
   1135 	tuple(allocator_arg_t __tag, const _Alloc& __a,
   1136 	      const tuple<_U1, _U2>& __in)
   1137 	: _Inherited(__tag, __a,
   1138 	             static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
   1139 	{ }
   1140 
   1141       template<typename _Alloc, typename _U1, typename _U2,
   1142 	       _ImplicitCtor<true, _U1, _U2> = true>
   1143 	_GLIBCXX20_CONSTEXPR
   1144 	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
   1145 	: _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
   1146 	{ }
   1147 
   1148       template<typename _Alloc, typename _U1, typename _U2,
   1149 	       _ExplicitCtor<true, _U1, _U2> = false>
   1150 	explicit
   1151 	_GLIBCXX20_CONSTEXPR
   1152 	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
   1153 	: _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
   1154 	{ }
   1155 
   1156       template<typename _Alloc, typename _U1, typename _U2,
   1157 	       _ImplicitCtor<true, const _U1&, const _U2&> = true>
   1158 	_GLIBCXX20_CONSTEXPR
   1159 	tuple(allocator_arg_t __tag, const _Alloc& __a,
   1160 	      const pair<_U1, _U2>& __in)
   1161 	: _Inherited(__tag, __a, __in.first, __in.second) { }
   1162 
   1163       template<typename _Alloc, typename _U1, typename _U2,
   1164 	       _ExplicitCtor<true, const _U1&, const _U2&> = false>
   1165 	explicit
   1166 	_GLIBCXX20_CONSTEXPR
   1167 	tuple(allocator_arg_t __tag, const _Alloc& __a,
   1168 	      const pair<_U1, _U2>& __in)
   1169 	: _Inherited(__tag, __a, __in.first, __in.second) { }
   1170 
   1171       template<typename _Alloc, typename _U1, typename _U2,
   1172 	       _ImplicitCtor<true, _U1, _U2> = true>
   1173 	_GLIBCXX20_CONSTEXPR
   1174 	tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
   1175 	: _Inherited(__tag, __a, std::forward<_U1>(__in.first),
   1176 		     std::forward<_U2>(__in.second)) { }
   1177 
   1178       template<typename _Alloc, typename _U1, typename _U2,
   1179 	       _ExplicitCtor<true, _U1, _U2> = false>
   1180 	explicit
   1181 	_GLIBCXX20_CONSTEXPR
   1182 	tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
   1183 	: _Inherited(__tag, __a, std::forward<_U1>(__in.first),
   1184 		     std::forward<_U2>(__in.second)) { }
   1185 
   1186       // Tuple assignment.
   1187 
   1188       _GLIBCXX20_CONSTEXPR
   1189       tuple&
   1190       operator=(typename conditional<__assignable<const _T1&, const _T2&>(),
   1191 				     const tuple&,
   1192 				     const __nonesuch&>::type __in)
   1193       noexcept(__nothrow_assignable<const _T1&, const _T2&>())
   1194       {
   1195 	this->_M_assign(__in);
   1196 	return *this;
   1197       }
   1198 
   1199       _GLIBCXX20_CONSTEXPR
   1200       tuple&
   1201       operator=(typename conditional<__assignable<_T1, _T2>(),
   1202 				     tuple&&,
   1203 				     __nonesuch&&>::type __in)
   1204       noexcept(__nothrow_assignable<_T1, _T2>())
   1205       {
   1206 	this->_M_assign(std::move(__in));
   1207 	return *this;
   1208       }
   1209 
   1210       template<typename _U1, typename _U2>
   1211 	_GLIBCXX20_CONSTEXPR
   1212 	__enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
   1213 	operator=(const tuple<_U1, _U2>& __in)
   1214 	noexcept(__nothrow_assignable<const _U1&, const _U2&>())
   1215 	{
   1216 	  this->_M_assign(__in);
   1217 	  return *this;
   1218 	}
   1219 
   1220       template<typename _U1, typename _U2>
   1221 	_GLIBCXX20_CONSTEXPR
   1222 	__enable_if_t<__assignable<_U1, _U2>(), tuple&>
   1223 	operator=(tuple<_U1, _U2>&& __in)
   1224 	noexcept(__nothrow_assignable<_U1, _U2>())
   1225 	{
   1226 	  this->_M_assign(std::move(__in));
   1227 	  return *this;
   1228 	}
   1229 
   1230       template<typename _U1, typename _U2>
   1231 	_GLIBCXX20_CONSTEXPR
   1232 	__enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
   1233 	operator=(const pair<_U1, _U2>& __in)
   1234 	noexcept(__nothrow_assignable<const _U1&, const _U2&>())
   1235 	{
   1236 	  this->_M_head(*this) = __in.first;
   1237 	  this->_M_tail(*this)._M_head(*this) = __in.second;
   1238 	  return *this;
   1239 	}
   1240 
   1241       template<typename _U1, typename _U2>
   1242 	_GLIBCXX20_CONSTEXPR
   1243 	__enable_if_t<__assignable<_U1, _U2>(), tuple&>
   1244 	operator=(pair<_U1, _U2>&& __in)
   1245 	noexcept(__nothrow_assignable<_U1, _U2>())
   1246 	{
   1247 	  this->_M_head(*this) = std::forward<_U1>(__in.first);
   1248 	  this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
   1249 	  return *this;
   1250 	}
   1251 
   1252       _GLIBCXX20_CONSTEXPR
   1253       void
   1254       swap(tuple& __in)
   1255       noexcept(__and_<__is_nothrow_swappable<_T1>,
   1256 		      __is_nothrow_swappable<_T2>>::value)
   1257       { _Inherited::_M_swap(__in); }
   1258     };
   1259 
   1260 
   1261   /// class tuple_size
   1262   template<typename... _Elements>
   1263     struct tuple_size<tuple<_Elements...>>
   1264     : public integral_constant<std::size_t, sizeof...(_Elements)> { };
   1265 
   1266 #if __cplusplus > 201402L
   1267   template <typename _Tp>
   1268     inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
   1269 #endif
   1270 
   1271   /**
   1272    * Recursive case for tuple_element: strip off the first element in
   1273    * the tuple and retrieve the (i-1)th element of the remaining tuple.
   1274    */
   1275   template<std::size_t __i, typename _Head, typename... _Tail>
   1276     struct tuple_element<__i, tuple<_Head, _Tail...> >
   1277     : tuple_element<__i - 1, tuple<_Tail...> > { };
   1278 
   1279   /**
   1280    * Basis case for tuple_element: The first element is the one we're seeking.
   1281    */
   1282   template<typename _Head, typename... _Tail>
   1283     struct tuple_element<0, tuple<_Head, _Tail...> >
   1284     {
   1285       typedef _Head type;
   1286     };
   1287 
   1288   /**
   1289    * Error case for tuple_element: invalid index.
   1290    */
   1291   template<size_t __i>
   1292     struct tuple_element<__i, tuple<>>
   1293     {
   1294       static_assert(__i < tuple_size<tuple<>>::value,
   1295 	  "tuple index is in range");
   1296     };
   1297 
   1298   template<std::size_t __i, typename _Head, typename... _Tail>
   1299     constexpr _Head&
   1300     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
   1301     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
   1302 
   1303   template<std::size_t __i, typename _Head, typename... _Tail>
   1304     constexpr const _Head&
   1305     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
   1306     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
   1307 
   1308   /// Return a reference to the ith element of a tuple.
   1309   template<std::size_t __i, typename... _Elements>
   1310     constexpr __tuple_element_t<__i, tuple<_Elements...>>&
   1311     get(tuple<_Elements...>& __t) noexcept
   1312     { return std::__get_helper<__i>(__t); }
   1313 
   1314   /// Return a const reference to the ith element of a const tuple.
   1315   template<std::size_t __i, typename... _Elements>
   1316     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
   1317     get(const tuple<_Elements...>& __t) noexcept
   1318     { return std::__get_helper<__i>(__t); }
   1319 
   1320   /// Return an rvalue reference to the ith element of a tuple rvalue.
   1321   template<std::size_t __i, typename... _Elements>
   1322     constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
   1323     get(tuple<_Elements...>&& __t) noexcept
   1324     {
   1325       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
   1326       return std::forward<__element_type&&>(std::get<__i>(__t));
   1327     }
   1328 
   1329   /// Return a const rvalue reference to the ith element of a const tuple rvalue.
   1330   template<std::size_t __i, typename... _Elements>
   1331     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
   1332     get(const tuple<_Elements...>&& __t) noexcept
   1333     {
   1334       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
   1335       return std::forward<const __element_type&&>(std::get<__i>(__t));
   1336     }
   1337 
   1338 #if __cplusplus >= 201402L
   1339 
   1340 #define __cpp_lib_tuples_by_type 201304
   1341 
   1342   template<typename _Head, size_t __i, typename... _Tail>
   1343     constexpr _Head&
   1344     __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
   1345     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
   1346 
   1347   template<typename _Head, size_t __i, typename... _Tail>
   1348     constexpr const _Head&
   1349     __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
   1350     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
   1351 
   1352   /// Return a reference to the unique element of type _Tp of a tuple.
   1353   template <typename _Tp, typename... _Types>
   1354     constexpr _Tp&
   1355     get(tuple<_Types...>& __t) noexcept
   1356     { return std::__get_helper2<_Tp>(__t); }
   1357 
   1358   /// Return a reference to the unique element of type _Tp of a tuple rvalue.
   1359   template <typename _Tp, typename... _Types>
   1360     constexpr _Tp&&
   1361     get(tuple<_Types...>&& __t) noexcept
   1362     { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
   1363 
   1364   /// Return a const reference to the unique element of type _Tp of a tuple.
   1365   template <typename _Tp, typename... _Types>
   1366     constexpr const _Tp&
   1367     get(const tuple<_Types...>& __t) noexcept
   1368     { return std::__get_helper2<_Tp>(__t); }
   1369 
   1370   /// Return a const reference to the unique element of type _Tp of
   1371   /// a const tuple rvalue.
   1372   template <typename _Tp, typename... _Types>
   1373     constexpr const _Tp&&
   1374     get(const tuple<_Types...>&& __t) noexcept
   1375     { return std::forward<const _Tp&&>(std::__get_helper2<_Tp>(__t)); }
   1376 #endif
   1377 
   1378   // This class performs the comparison operations on tuples
   1379   template<typename _Tp, typename _Up, size_t __i, size_t __size>
   1380     struct __tuple_compare
   1381     {
   1382       static constexpr bool
   1383       __eq(const _Tp& __t, const _Up& __u)
   1384       {
   1385 	return bool(std::get<__i>(__t) == std::get<__i>(__u))
   1386 	  && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
   1387       }
   1388 
   1389       static constexpr bool
   1390       __less(const _Tp& __t, const _Up& __u)
   1391       {
   1392 	return bool(std::get<__i>(__t) < std::get<__i>(__u))
   1393 	  || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
   1394 	      && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
   1395       }
   1396     };
   1397 
   1398   template<typename _Tp, typename _Up, size_t __size>
   1399     struct __tuple_compare<_Tp, _Up, __size, __size>
   1400     {
   1401       static constexpr bool
   1402       __eq(const _Tp&, const _Up&) { return true; }
   1403 
   1404       static constexpr bool
   1405       __less(const _Tp&, const _Up&) { return false; }
   1406     };
   1407 
   1408   template<typename... _TElements, typename... _UElements>
   1409     constexpr bool
   1410     operator==(const tuple<_TElements...>& __t,
   1411 	       const tuple<_UElements...>& __u)
   1412     {
   1413       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
   1414 	  "tuple objects can only be compared if they have equal sizes.");
   1415       using __compare = __tuple_compare<tuple<_TElements...>,
   1416 					tuple<_UElements...>,
   1417 					0, sizeof...(_TElements)>;
   1418       return __compare::__eq(__t, __u);
   1419     }
   1420 
   1421 #if __cpp_lib_three_way_comparison
   1422   template<typename _Cat, typename _Tp, typename _Up>
   1423     constexpr _Cat
   1424     __tuple_cmp(const _Tp&, const _Up&, index_sequence<>)
   1425     { return _Cat::equivalent; }
   1426 
   1427   template<typename _Cat, typename _Tp, typename _Up,
   1428 	   size_t _Idx0, size_t... _Idxs>
   1429     constexpr _Cat
   1430     __tuple_cmp(const _Tp& __t, const _Up& __u,
   1431 		index_sequence<_Idx0, _Idxs...>)
   1432     {
   1433       auto __c
   1434 	= __detail::__synth3way(std::get<_Idx0>(__t), std::get<_Idx0>(__u));
   1435       if (__c != 0)
   1436 	return __c;
   1437       return std::__tuple_cmp<_Cat>(__t, __u, index_sequence<_Idxs...>());
   1438     }
   1439 
   1440   template<typename... _Tps, typename... _Ups>
   1441     constexpr
   1442     common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>
   1443     operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u)
   1444     {
   1445       using _Cat
   1446 	= common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>;
   1447       return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>());
   1448     }
   1449 #else
   1450   template<typename... _TElements, typename... _UElements>
   1451     constexpr bool
   1452     operator<(const tuple<_TElements...>& __t,
   1453 	      const tuple<_UElements...>& __u)
   1454     {
   1455       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
   1456 	  "tuple objects can only be compared if they have equal sizes.");
   1457       using __compare = __tuple_compare<tuple<_TElements...>,
   1458 					tuple<_UElements...>,
   1459 					0, sizeof...(_TElements)>;
   1460       return __compare::__less(__t, __u);
   1461     }
   1462 
   1463   template<typename... _TElements, typename... _UElements>
   1464     constexpr bool
   1465     operator!=(const tuple<_TElements...>& __t,
   1466 	       const tuple<_UElements...>& __u)
   1467     { return !(__t == __u); }
   1468 
   1469   template<typename... _TElements, typename... _UElements>
   1470     constexpr bool
   1471     operator>(const tuple<_TElements...>& __t,
   1472 	      const tuple<_UElements...>& __u)
   1473     { return __u < __t; }
   1474 
   1475   template<typename... _TElements, typename... _UElements>
   1476     constexpr bool
   1477     operator<=(const tuple<_TElements...>& __t,
   1478 	       const tuple<_UElements...>& __u)
   1479     { return !(__u < __t); }
   1480 
   1481   template<typename... _TElements, typename... _UElements>
   1482     constexpr bool
   1483     operator>=(const tuple<_TElements...>& __t,
   1484 	       const tuple<_UElements...>& __u)
   1485     { return !(__t < __u); }
   1486 #endif // three_way_comparison
   1487 
   1488   // NB: DR 705.
   1489   template<typename... _Elements>
   1490     constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
   1491     make_tuple(_Elements&&... __args)
   1492     {
   1493       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
   1494 	__result_type;
   1495       return __result_type(std::forward<_Elements>(__args)...);
   1496     }
   1497 
   1498   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   1499   // 2275. Why is forward_as_tuple not constexpr?
   1500   /// std::forward_as_tuple
   1501   template<typename... _Elements>
   1502     constexpr tuple<_Elements&&...>
   1503     forward_as_tuple(_Elements&&... __args) noexcept
   1504     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
   1505 
   1506   template<size_t, typename, typename, size_t>
   1507     struct __make_tuple_impl;
   1508 
   1509   template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
   1510     struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
   1511     : __make_tuple_impl<_Idx + 1,
   1512 			tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
   1513 			_Tuple, _Nm>
   1514     { };
   1515 
   1516   template<std::size_t _Nm, typename _Tuple, typename... _Tp>
   1517     struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
   1518     {
   1519       typedef tuple<_Tp...> __type;
   1520     };
   1521 
   1522   template<typename _Tuple>
   1523     struct __do_make_tuple
   1524     : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
   1525     { };
   1526 
   1527   // Returns the std::tuple equivalent of a tuple-like type.
   1528   template<typename _Tuple>
   1529     struct __make_tuple
   1530     : public __do_make_tuple<__remove_cvref_t<_Tuple>>
   1531     { };
   1532 
   1533   // Combines several std::tuple's into a single one.
   1534   template<typename...>
   1535     struct __combine_tuples;
   1536 
   1537   template<>
   1538     struct __combine_tuples<>
   1539     {
   1540       typedef tuple<> __type;
   1541     };
   1542 
   1543   template<typename... _Ts>
   1544     struct __combine_tuples<tuple<_Ts...>>
   1545     {
   1546       typedef tuple<_Ts...> __type;
   1547     };
   1548 
   1549   template<typename... _T1s, typename... _T2s, typename... _Rem>
   1550     struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
   1551     {
   1552       typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
   1553 					_Rem...>::__type __type;
   1554     };
   1555 
   1556   // Computes the result type of tuple_cat given a set of tuple-like types.
   1557   template<typename... _Tpls>
   1558     struct __tuple_cat_result
   1559     {
   1560       typedef typename __combine_tuples
   1561         <typename __make_tuple<_Tpls>::__type...>::__type __type;
   1562     };
   1563 
   1564   // Helper to determine the index set for the first tuple-like
   1565   // type of a given set.
   1566   template<typename...>
   1567     struct __make_1st_indices;
   1568 
   1569   template<>
   1570     struct __make_1st_indices<>
   1571     {
   1572       typedef std::_Index_tuple<> __type;
   1573     };
   1574 
   1575   template<typename _Tp, typename... _Tpls>
   1576     struct __make_1st_indices<_Tp, _Tpls...>
   1577     {
   1578       typedef typename std::_Build_index_tuple<std::tuple_size<
   1579 	typename std::remove_reference<_Tp>::type>::value>::__type __type;
   1580     };
   1581 
   1582   // Performs the actual concatenation by step-wise expanding tuple-like
   1583   // objects into the elements,  which are finally forwarded into the
   1584   // result tuple.
   1585   template<typename _Ret, typename _Indices, typename... _Tpls>
   1586     struct __tuple_concater;
   1587 
   1588   template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
   1589     struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
   1590     {
   1591       template<typename... _Us>
   1592         static constexpr _Ret
   1593         _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
   1594         {
   1595 	  typedef typename __make_1st_indices<_Tpls...>::__type __idx;
   1596 	  typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
   1597 	  return __next::_S_do(std::forward<_Tpls>(__tps)...,
   1598 			       std::forward<_Us>(__us)...,
   1599 			       std::get<_Is>(std::forward<_Tp>(__tp))...);
   1600 	}
   1601     };
   1602 
   1603   template<typename _Ret>
   1604     struct __tuple_concater<_Ret, std::_Index_tuple<>>
   1605     {
   1606       template<typename... _Us>
   1607 	static constexpr _Ret
   1608 	_S_do(_Us&&... __us)
   1609         {
   1610 	  return _Ret(std::forward<_Us>(__us)...);
   1611 	}
   1612     };
   1613 
   1614   /// tuple_cat
   1615   template<typename... _Tpls, typename = typename
   1616            enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
   1617     constexpr auto
   1618     tuple_cat(_Tpls&&... __tpls)
   1619     -> typename __tuple_cat_result<_Tpls...>::__type
   1620     {
   1621       typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
   1622       typedef typename __make_1st_indices<_Tpls...>::__type __idx;
   1623       typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
   1624       return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
   1625     }
   1626 
   1627   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   1628   // 2301. Why is tie not constexpr?
   1629   /// tie
   1630   template<typename... _Elements>
   1631     constexpr tuple<_Elements&...>
   1632     tie(_Elements&... __args) noexcept
   1633     { return tuple<_Elements&...>(__args...); }
   1634 
   1635   /// swap
   1636   template<typename... _Elements>
   1637     _GLIBCXX20_CONSTEXPR
   1638     inline
   1639 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
   1640     // Constrained free swap overload, see p0185r1
   1641     typename enable_if<__and_<__is_swappable<_Elements>...>::value
   1642       >::type
   1643 #else
   1644     void
   1645 #endif
   1646     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
   1647     noexcept(noexcept(__x.swap(__y)))
   1648     { __x.swap(__y); }
   1649 
   1650 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
   1651   template<typename... _Elements>
   1652     _GLIBCXX20_CONSTEXPR
   1653     typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
   1654     swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
   1655 #endif
   1656 
   1657   // A class (and instance) which can be used in 'tie' when an element
   1658   // of a tuple is not required.
   1659   // _GLIBCXX14_CONSTEXPR
   1660   // 2933. PR for LWG 2773 could be clearer
   1661   struct _Swallow_assign
   1662   {
   1663     template<class _Tp>
   1664       _GLIBCXX14_CONSTEXPR const _Swallow_assign&
   1665       operator=(const _Tp&) const
   1666       { return *this; }
   1667   };
   1668 
   1669   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   1670   // 2773. Making std::ignore constexpr
   1671   _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
   1672 
   1673   /// Partial specialization for tuples
   1674   template<typename... _Types, typename _Alloc>
   1675     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
   1676 
   1677   // See stl_pair.h...
   1678   /** "piecewise construction" using a tuple of arguments for each member.
   1679    *
   1680    * @param __first Arguments for the first member of the pair.
   1681    * @param __second Arguments for the second member of the pair.
   1682    *
   1683    * The elements of each tuple will be used as the constructor arguments
   1684    * for the data members of the pair.
   1685   */
   1686   template<class _T1, class _T2>
   1687     template<typename... _Args1, typename... _Args2>
   1688       _GLIBCXX20_CONSTEXPR
   1689       inline
   1690       pair<_T1, _T2>::
   1691       pair(piecewise_construct_t,
   1692 	   tuple<_Args1...> __first, tuple<_Args2...> __second)
   1693       : pair(__first, __second,
   1694 	     typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
   1695 	     typename _Build_index_tuple<sizeof...(_Args2)>::__type())
   1696       { }
   1697 
   1698   template<class _T1, class _T2>
   1699     template<typename... _Args1, std::size_t... _Indexes1,
   1700              typename... _Args2, std::size_t... _Indexes2>
   1701       _GLIBCXX20_CONSTEXPR inline
   1702       pair<_T1, _T2>::
   1703       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
   1704 	   _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
   1705       : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
   1706         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
   1707       { }
   1708 
   1709 #if __cplusplus >= 201703L
   1710 
   1711   // Unpack a std::tuple into a type trait and use its value.
   1712   // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value.
   1713   // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value.
   1714   // Otherwise the result is false (because we don't know if std::get throws).
   1715   template<template<typename...> class _Trait, typename _Tp, typename _Tuple>
   1716     inline constexpr bool __unpack_std_tuple = false;
   1717 
   1718   template<template<typename...> class _Trait, typename _Tp, typename... _Up>
   1719     inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>>
   1720       = _Trait<_Tp, _Up...>::value;
   1721 
   1722   template<template<typename...> class _Trait, typename _Tp, typename... _Up>
   1723     inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&>
   1724       = _Trait<_Tp, _Up&...>::value;
   1725 
   1726   template<template<typename...> class _Trait, typename _Tp, typename... _Up>
   1727     inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>>
   1728       = _Trait<_Tp, const _Up...>::value;
   1729 
   1730   template<template<typename...> class _Trait, typename _Tp, typename... _Up>
   1731     inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&>
   1732       = _Trait<_Tp, const _Up&...>::value;
   1733 
   1734 # define __cpp_lib_apply 201603
   1735 
   1736   template <typename _Fn, typename _Tuple, size_t... _Idx>
   1737     constexpr decltype(auto)
   1738     __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
   1739     {
   1740       return std::__invoke(std::forward<_Fn>(__f),
   1741 			   std::get<_Idx>(std::forward<_Tuple>(__t))...);
   1742     }
   1743 
   1744   template <typename _Fn, typename _Tuple>
   1745     constexpr decltype(auto)
   1746     apply(_Fn&& __f, _Tuple&& __t)
   1747     noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>)
   1748     {
   1749       using _Indices
   1750 	= make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>;
   1751       return std::__apply_impl(std::forward<_Fn>(__f),
   1752 			       std::forward<_Tuple>(__t),
   1753 			       _Indices{});
   1754     }
   1755 
   1756 #define __cpp_lib_make_from_tuple  201606
   1757 
   1758   template <typename _Tp, typename _Tuple, size_t... _Idx>
   1759     constexpr _Tp
   1760     __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
   1761     { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
   1762 
   1763   template <typename _Tp, typename _Tuple>
   1764     constexpr _Tp
   1765     make_from_tuple(_Tuple&& __t)
   1766     noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)
   1767     {
   1768       return __make_from_tuple_impl<_Tp>(
   1769         std::forward<_Tuple>(__t),
   1770 	make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>{});
   1771     }
   1772 #endif // C++17
   1773 
   1774   /// @}
   1775 
   1776 _GLIBCXX_END_NAMESPACE_VERSION
   1777 } // namespace std
   1778 
   1779 #endif // C++11
   1780 
   1781 #endif // _GLIBCXX_TUPLE
   1782