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