LCOV - code coverage report
Current view: top level - /usr/include/c++/13 - tuple (source / functions) Coverage Total Hit
Test: coverage.info Lines: 92.0 % 88 81
Test Date: 2024-04-30 13:17:26 Functions: 61.0 % 607 370

            Line data    Source code
       1              : // <tuple> -*- C++ -*-
       2              : 
       3              : // Copyright (C) 2007-2023 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::tuple_size etc.
      41              : #include <bits/invoke.h>          // for std::__invoke
      42              : #if __cplusplus > 201703L
      43              : # include <compare>
      44              : # include <bits/ranges_util.h>            // for std::ranges::subrange
      45              : # define __cpp_lib_constexpr_tuple 201811L
      46              : #endif
      47              : 
      48              : namespace std _GLIBCXX_VISIBILITY(default)
      49              : {
      50              : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      51              : 
      52              :   /**
      53              :    *  @addtogroup utilities
      54              :    *  @{
      55              :    */
      56              : 
      57              :   template<typename... _Elements>
      58              :     class tuple;
      59              : 
      60              :   template<typename _Tp>
      61              :     struct __is_empty_non_tuple : is_empty<_Tp> { };
      62              : 
      63              :   // Using EBO for elements that are tuples causes ambiguous base errors.
      64              :   template<typename _El0, typename... _El>
      65              :     struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
      66              : 
      67              :   // Use the Empty Base-class Optimization for empty, non-final types.
      68              :   template<typename _Tp>
      69              :     using __empty_not_final
      70              :     = __conditional_t<__is_final(_Tp), false_type,
      71              :                       __is_empty_non_tuple<_Tp>>;
      72              : 
      73              :   template<size_t _Idx, typename _Head,
      74              :            bool = __empty_not_final<_Head>::value>
      75              :     struct _Head_base;
      76              : 
      77              : #if __has_cpp_attribute(__no_unique_address__)
      78              :   template<size_t _Idx, typename _Head>
      79              :     struct _Head_base<_Idx, _Head, true>
      80              :     {
      81      2051824 :       constexpr _Head_base()
      82      2051824 :       : _M_head_impl() { }
      83              : 
      84              :       constexpr _Head_base(const _Head& __h)
      85              :       : _M_head_impl(__h) { }
      86              : 
      87              :       constexpr _Head_base(const _Head_base&) = default;
      88              :       constexpr _Head_base(_Head_base&&) = default;
      89              : 
      90              :       template<typename _UHead>
      91          198 :         constexpr _Head_base(_UHead&& __h)
      92          198 :         : _M_head_impl(std::forward<_UHead>(__h)) { }
      93              : 
      94              :       _GLIBCXX20_CONSTEXPR
      95              :       _Head_base(allocator_arg_t, __uses_alloc0)
      96              :       : _M_head_impl() { }
      97              : 
      98              :       template<typename _Alloc>
      99              :         _GLIBCXX20_CONSTEXPR
     100              :         _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
     101              :         : _M_head_impl(allocator_arg, *__a._M_a) { }
     102              : 
     103              :       template<typename _Alloc>
     104              :         _GLIBCXX20_CONSTEXPR
     105              :         _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
     106              :         : _M_head_impl(*__a._M_a) { }
     107              : 
     108              :       template<typename _UHead>
     109              :         _GLIBCXX20_CONSTEXPR
     110              :         _Head_base(__uses_alloc0, _UHead&& __uhead)
     111              :         : _M_head_impl(std::forward<_UHead>(__uhead)) { }
     112              : 
     113              :       template<typename _Alloc, typename _UHead>
     114              :         _GLIBCXX20_CONSTEXPR
     115              :         _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
     116              :         : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
     117              :         { }
     118              : 
     119              :       template<typename _Alloc, typename _UHead>
     120              :         _GLIBCXX20_CONSTEXPR
     121              :         _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
     122              :         : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
     123              : 
     124              :       static constexpr _Head&
     125        43464 :       _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
     126              : 
     127              :       static constexpr const _Head&
     128              :       _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
     129              : 
     130              :       [[__no_unique_address__]] _Head _M_head_impl;
     131              :     };
     132              : #else
     133              :   template<size_t _Idx, typename _Head>
     134              :     struct _Head_base<_Idx, _Head, true>
     135              :     : public _Head
     136              :     {
     137              :       constexpr _Head_base()
     138              :       : _Head() { }
     139              : 
     140              :       constexpr _Head_base(const _Head& __h)
     141              :       : _Head(__h) { }
     142              : 
     143              :       constexpr _Head_base(const _Head_base&) = default;
     144              :       constexpr _Head_base(_Head_base&&) = default;
     145              : 
     146              :       template<typename _UHead>
     147              :         constexpr _Head_base(_UHead&& __h)
     148              :         : _Head(std::forward<_UHead>(__h)) { }
     149              : 
     150              :       _GLIBCXX20_CONSTEXPR
     151              :       _Head_base(allocator_arg_t, __uses_alloc0)
     152              :       : _Head() { }
     153              : 
     154              :       template<typename _Alloc>
     155              :         _GLIBCXX20_CONSTEXPR
     156              :         _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
     157              :         : _Head(allocator_arg, *__a._M_a) { }
     158              : 
     159              :       template<typename _Alloc>
     160              :         _GLIBCXX20_CONSTEXPR
     161              :         _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
     162              :         : _Head(*__a._M_a) { }
     163              : 
     164              :       template<typename _UHead>
     165              :         _GLIBCXX20_CONSTEXPR
     166              :         _Head_base(__uses_alloc0, _UHead&& __uhead)
     167              :         : _Head(std::forward<_UHead>(__uhead)) { }
     168              : 
     169              :       template<typename _Alloc, typename _UHead>
     170              :         _GLIBCXX20_CONSTEXPR
     171              :         _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
     172              :         : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
     173              : 
     174              :       template<typename _Alloc, typename _UHead>
     175              :         _GLIBCXX20_CONSTEXPR
     176              :         _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
     177              :         : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
     178              : 
     179              :       static constexpr _Head&
     180              :       _M_head(_Head_base& __b) noexcept { return __b; }
     181              : 
     182              :       static constexpr const _Head&
     183              :       _M_head(const _Head_base& __b) noexcept { return __b; }
     184              :     };
     185              : #endif
     186              : 
     187              :   template<size_t _Idx, typename _Head>
     188              :     struct _Head_base<_Idx, _Head, false>
     189              :     {
     190      2051824 :       constexpr _Head_base()
     191      2051824 :       : _M_head_impl() { }
     192              : 
     193      8758190 :       constexpr _Head_base(const _Head& __h)
     194      8758190 :       : _M_head_impl(__h) { }
     195              : 
     196              :       constexpr _Head_base(const _Head_base&) = default;
     197              :       constexpr _Head_base(_Head_base&&) = default;
     198              : 
     199              :       template<typename _UHead>
     200      4736306 :         constexpr _Head_base(_UHead&& __h)
     201      4736306 :         : _M_head_impl(std::forward<_UHead>(__h)) { }
     202              : 
     203              :       _GLIBCXX20_CONSTEXPR
     204              :       _Head_base(allocator_arg_t, __uses_alloc0)
     205              :       : _M_head_impl() { }
     206              : 
     207              :       template<typename _Alloc>
     208              :         _GLIBCXX20_CONSTEXPR
     209              :         _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
     210              :         : _M_head_impl(allocator_arg, *__a._M_a) { }
     211              : 
     212              :       template<typename _Alloc>
     213              :         _GLIBCXX20_CONSTEXPR
     214              :         _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
     215              :         : _M_head_impl(*__a._M_a) { }
     216              : 
     217              :       template<typename _UHead>
     218              :         _GLIBCXX20_CONSTEXPR
     219              :         _Head_base(__uses_alloc0, _UHead&& __uhead)
     220              :         : _M_head_impl(std::forward<_UHead>(__uhead)) { }
     221              : 
     222              :       template<typename _Alloc, typename _UHead>
     223              :         _GLIBCXX20_CONSTEXPR
     224              :         _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
     225              :         : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
     226              :         { }
     227              : 
     228              :       template<typename _Alloc, typename _UHead>
     229              :         _GLIBCXX20_CONSTEXPR
     230              :         _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
     231              :         : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
     232              : 
     233              :       static constexpr _Head&
     234     17228284 :       _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
     235              : 
     236              :       static constexpr const _Head&
     237     31996304 :       _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
     238              : 
     239              :       _Head _M_head_impl;
     240              :     };
     241              : 
     242              :   /**
     243              :    * Contains the actual implementation of the @c tuple template, stored
     244              :    * as a recursive inheritance hierarchy from the first element (most
     245              :    * derived class) to the last (least derived class). The @c Idx
     246              :    * parameter gives the 0-based index of the element stored at this
     247              :    * point in the hierarchy; we use it to implement a constant-time
     248              :    * get() operation.
     249              :    */
     250              :   template<size_t _Idx, typename... _Elements>
     251              :     struct _Tuple_impl;
     252              : 
     253              :   /**
     254              :    * Recursive tuple implementation. Here we store the @c Head element
     255              :    * and derive from a @c Tuple_impl containing the remaining elements
     256              :    * (which contains the @c Tail).
     257              :    */
     258              :   template<size_t _Idx, typename _Head, typename... _Tail>
     259              :     struct _Tuple_impl<_Idx, _Head, _Tail...>
     260              :     : public _Tuple_impl<_Idx + 1, _Tail...>,
     261              :       private _Head_base<_Idx, _Head>
     262              :     {
     263              :       template<size_t, typename...> friend struct _Tuple_impl;
     264              : 
     265              :       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
     266              :       typedef _Head_base<_Idx, _Head> _Base;
     267              : 
     268              :       static constexpr _Head&
     269      3736022 :       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     270              : 
     271              :       static constexpr const _Head&
     272     31996304 :       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     273              : 
     274              :       static constexpr _Inherited&
     275         1144 :       _M_tail(_Tuple_impl& __t) noexcept { return __t; }
     276              : 
     277              :       static constexpr const _Inherited&
     278              :       _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
     279              : 
     280      2051824 :       constexpr _Tuple_impl()
     281      2051824 :       : _Inherited(), _Base() { }
     282              : 
     283              :       explicit constexpr
     284          572 :       _Tuple_impl(const _Head& __head, const _Tail&... __tail)
     285          572 :       : _Inherited(__tail...), _Base(__head)
     286          572 :       { }
     287              : 
     288              :       template<typename _UHead, typename... _UTail,
     289              :                typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>>
     290              :         explicit constexpr
     291         1216 :         _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
     292              :         : _Inherited(std::forward<_UTail>(__tail)...),
     293         1216 :           _Base(std::forward<_UHead>(__head))
     294         1216 :         { }
     295              : 
     296              :       constexpr _Tuple_impl(const _Tuple_impl&) = default;
     297              : 
     298              :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
     299              :       // 2729. Missing SFINAE on std::pair::operator=
     300              :       _Tuple_impl& operator=(const _Tuple_impl&) = delete;
     301              : 
     302         1210 :       _Tuple_impl(_Tuple_impl&&) = default;
     303              : 
     304              :       template<typename... _UElements>
     305              :         constexpr
     306              :         _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
     307              :         : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
     308              :           _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in))
     309              :         { }
     310              : 
     311              :       template<typename _UHead, typename... _UTails>
     312              :         constexpr
     313              :         _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     314              :         : _Inherited(std::move
     315              :                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
     316              :           _Base(std::forward<_UHead>
     317              :                 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
     318              :         { }
     319              : 
     320              : #if __cplusplus > 202002L
     321              :       template<typename... _UElements>
     322              :         constexpr
     323              :         _Tuple_impl(_Tuple_impl<_Idx, _UElements...>& __in)
     324              :         : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
     325              :           _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in))
     326              :         { }
     327              : 
     328              :       template<typename _UHead, typename... _UTails>
     329              :         constexpr
     330              :         _Tuple_impl(const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     331              :         : _Inherited(std::move
     332              :                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
     333              :           _Base(std::forward<const _UHead>
     334              :                 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
     335              :         { }
     336              : #endif // C++23
     337              : 
     338              :       template<typename _Alloc>
     339              :         _GLIBCXX20_CONSTEXPR
     340              :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
     341              :         : _Inherited(__tag, __a),
     342              :           _Base(__tag, __use_alloc<_Head>(__a))
     343              :         { }
     344              : 
     345              :       template<typename _Alloc>
     346              :         _GLIBCXX20_CONSTEXPR
     347              :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     348              :                     const _Head& __head, const _Tail&... __tail)
     349              :         : _Inherited(__tag, __a, __tail...),
     350              :           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head)
     351              :         { }
     352              : 
     353              :       template<typename _Alloc, typename _UHead, typename... _UTail,
     354              :                typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>>
     355              :         _GLIBCXX20_CONSTEXPR
     356              :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     357              :                     _UHead&& __head, _UTail&&... __tail)
     358              :         : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
     359              :           _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
     360              :                 std::forward<_UHead>(__head))
     361              :         { }
     362              : 
     363              :       template<typename _Alloc>
     364              :         _GLIBCXX20_CONSTEXPR
     365              :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     366              :                     const _Tuple_impl& __in)
     367              :         : _Inherited(__tag, __a, _M_tail(__in)),
     368              :           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in))
     369              :         { }
     370              : 
     371              :       template<typename _Alloc>
     372              :         _GLIBCXX20_CONSTEXPR
     373              :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     374              :                     _Tuple_impl&& __in)
     375              :         : _Inherited(__tag, __a, std::move(_M_tail(__in))),
     376              :           _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
     377              :                 std::forward<_Head>(_M_head(__in)))
     378              :         { }
     379              : 
     380              :       template<typename _Alloc, typename _UHead, typename... _UTails>
     381              :         _GLIBCXX20_CONSTEXPR
     382              :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     383              :                     const _Tuple_impl<_Idx, _UHead, _UTails...>& __in)
     384              :         : _Inherited(__tag, __a,
     385              :                      _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),
     386              :           _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
     387              :                 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))
     388              :         { }
     389              : 
     390              :       template<typename _Alloc, typename _UHead, typename... _UTails>
     391              :         _GLIBCXX20_CONSTEXPR
     392              :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     393              :                     _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     394              :         : _Inherited(__tag, __a, std::move
     395              :                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
     396              :           _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
     397              :                 std::forward<_UHead>
     398              :                 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
     399              :         { }
     400              : 
     401              : #if __cplusplus > 202002L
     402              :       template<typename _Alloc, typename _UHead, typename... _UTails>
     403              :         constexpr
     404              :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     405              :                     _Tuple_impl<_Idx, _UHead, _UTails...>& __in)
     406              :         : _Inherited(__tag, __a,
     407              :                      _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),
     408              :           _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a),
     409              :                 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))
     410              :         { }
     411              : 
     412              :       template<typename _Alloc, typename _UHead, typename... _UTails>
     413              :         constexpr
     414              :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     415              :                     const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     416              :         : _Inherited(__tag, __a, std::move
     417              :                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
     418              :           _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a),
     419              :                 std::forward<const _UHead>
     420              :                 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
     421              :         { }
     422              : #endif // C++23
     423              : 
     424              :       template<typename... _UElements>
     425              :         _GLIBCXX20_CONSTEXPR
     426              :         void
     427              :         _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in)
     428              :         {
     429              :           _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
     430              :           _M_tail(*this)._M_assign(
     431              :               _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
     432              :         }
     433              : 
     434              :       template<typename _UHead, typename... _UTails>
     435              :         _GLIBCXX20_CONSTEXPR
     436              :         void
     437          572 :         _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     438              :         {
     439          572 :           _M_head(*this) = std::forward<_UHead>
     440          572 :             (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
     441         1144 :           _M_tail(*this)._M_assign(
     442          572 :               std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
     443          572 :         }
     444              : 
     445              : #if __cplusplus > 202002L
     446              :       template<typename... _UElements>
     447              :         constexpr void
     448              :         _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in) const
     449              :         {
     450              :           _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
     451              :           _M_tail(*this)._M_assign(
     452              :               _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
     453              :         }
     454              : 
     455              :       template<typename _UHead, typename... _UTails>
     456              :         constexpr void
     457              :         _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) const
     458              :         {
     459              :           _M_head(*this) = std::forward<_UHead>
     460              :             (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
     461              :           _M_tail(*this)._M_assign(
     462              :               std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
     463              :         }
     464              : #endif // C++23
     465              : 
     466              :     protected:
     467              :       _GLIBCXX20_CONSTEXPR
     468              :       void
     469              :       _M_swap(_Tuple_impl& __in)
     470              :       {
     471              :         using std::swap;
     472              :         swap(_M_head(*this), _M_head(__in));
     473              :         _Inherited::_M_swap(_M_tail(__in));
     474              :       }
     475              : 
     476              : #if __cplusplus > 202002L
     477              :       constexpr void
     478              :       _M_swap(const _Tuple_impl& __in) const
     479              :       {
     480              :         using std::swap;
     481              :         swap(_M_head(*this), _M_head(__in));
     482              :         _Inherited::_M_swap(_M_tail(__in));
     483              :       }
     484              : #endif // C++23
     485              :     };
     486              : 
     487              :   // Basis case of inheritance recursion.
     488              :   template<size_t _Idx, typename _Head>
     489              :     struct _Tuple_impl<_Idx, _Head>
     490              :     : private _Head_base<_Idx, _Head>
     491              :     {
     492              :       template<size_t, typename...> friend struct _Tuple_impl;
     493              : 
     494              :       typedef _Head_base<_Idx, _Head> _Base;
     495              : 
     496              :       static constexpr _Head&
     497     13535726 :       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     498              : 
     499              :       static constexpr const _Head&
     500            0 :       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     501              : 
     502              :       constexpr
     503      2051824 :       _Tuple_impl()
     504      2051824 :       : _Base() { }
     505              : 
     506              :       explicit constexpr
     507      8757332 :       _Tuple_impl(const _Head& __head)
     508      8757332 :       : _Base(__head)
     509      8757332 :       { }
     510              : 
     511              :       template<typename _UHead>
     512              :         explicit constexpr
     513      4735574 :         _Tuple_impl(_UHead&& __head)
     514      4735574 :         : _Base(std::forward<_UHead>(__head))
     515      4735574 :         { }
     516              : 
     517              :       constexpr _Tuple_impl(const _Tuple_impl&) = default;
     518              : 
     519              :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
     520              :       // 2729. Missing SFINAE on std::pair::operator=
     521              :       _Tuple_impl& operator=(const _Tuple_impl&) = delete;
     522              : 
     523              : #if _GLIBCXX_INLINE_VERSION
     524              :       _Tuple_impl(_Tuple_impl&&) = default;
     525              : #else
     526              :       constexpr
     527     11887166 :       _Tuple_impl(_Tuple_impl&& __in)
     528              :       noexcept(is_nothrow_move_constructible<_Head>::value)
     529     11885956 :       : _Base(static_cast<_Base&&>(__in))
     530     11887166 :       { }
     531              : #endif
     532              : 
     533              :       template<typename _UHead>
     534              :         constexpr
     535              :         _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
     536              :         : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in))
     537              :         { }
     538              : 
     539              :       template<typename _UHead>
     540              :         constexpr
     541              :         _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
     542              :         : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
     543              :         { }
     544              : 
     545              : #if __cplusplus > 202002L
     546              :       template<typename _UHead>
     547              :         constexpr
     548              :         _Tuple_impl(_Tuple_impl<_Idx, _UHead>& __in)
     549              :         : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in))
     550              :         { }
     551              : 
     552              :       template<typename _UHead>
     553              :         constexpr
     554              :         _Tuple_impl(const _Tuple_impl<_Idx, _UHead>&& __in)
     555              :         : _Base(std::forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
     556              :         { }
     557              : #endif // C++23
     558              : 
     559              :       template<typename _Alloc>
     560              :         _GLIBCXX20_CONSTEXPR
     561              :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
     562              :         : _Base(__tag, __use_alloc<_Head>(__a))
     563              :         { }
     564              : 
     565              :       template<typename _Alloc>
     566              :         _GLIBCXX20_CONSTEXPR
     567              :         _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     568              :                     const _Head& __head)
     569              :         : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), __head)
     570              :         { }
     571              : 
     572              :       template<typename _Alloc, typename _UHead>
     573              :         _GLIBCXX20_CONSTEXPR
     574              :         _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     575              :                     _UHead&& __head)
     576              :         : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
     577              :                 std::forward<_UHead>(__head))
     578              :         { }
     579              : 
     580              :       template<typename _Alloc>
     581              :         _GLIBCXX20_CONSTEXPR
     582              :         _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     583              :                     const _Tuple_impl& __in)
     584              :         : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), _M_head(__in))
     585              :         { }
     586              : 
     587              :       template<typename _Alloc>
     588              :         _GLIBCXX20_CONSTEXPR
     589              :         _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     590              :                     _Tuple_impl&& __in)
     591              :         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
     592              :                 std::forward<_Head>(_M_head(__in)))
     593              :         { }
     594              : 
     595              :       template<typename _Alloc, typename _UHead>
     596              :         _GLIBCXX20_CONSTEXPR
     597              :         _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     598              :                     const _Tuple_impl<_Idx, _UHead>& __in)
     599              :         : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
     600              :                 _Tuple_impl<_Idx, _UHead>::_M_head(__in))
     601              :         { }
     602              : 
     603              :       template<typename _Alloc, typename _UHead>
     604              :         _GLIBCXX20_CONSTEXPR
     605              :         _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     606              :                     _Tuple_impl<_Idx, _UHead>&& __in)
     607              :         : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
     608              :                 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
     609              :         { }
     610              : 
     611              : #if __cplusplus > 202002L
     612              :       template<typename _Alloc, typename _UHead>
     613              :         constexpr
     614              :         _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     615              :                     _Tuple_impl<_Idx, _UHead>& __in)
     616              :         : _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a),
     617              :                 _Tuple_impl<_Idx, _UHead>::_M_head(__in))
     618              :         { }
     619              : 
     620              :       template<typename _Alloc, typename _UHead>
     621              :         constexpr
     622              :         _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     623              :                     const _Tuple_impl<_Idx, _UHead>&& __in)
     624              :         : _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a),
     625              :                 std::forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
     626              :         { }
     627              : #endif // C++23
     628              : 
     629              :       template<typename _UHead>
     630              :         _GLIBCXX20_CONSTEXPR
     631              :         void
     632              :         _M_assign(const _Tuple_impl<_Idx, _UHead>& __in)
     633              :         {
     634              :           _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
     635              :         }
     636              : 
     637              :       template<typename _UHead>
     638              :         _GLIBCXX20_CONSTEXPR
     639              :         void
     640          286 :         _M_assign(_Tuple_impl<_Idx, _UHead>&& __in)
     641              :         {
     642          286 :           _M_head(*this)
     643          286 :             = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
     644          286 :         }
     645              : 
     646              : #if __cplusplus > 202002L
     647              :       template<typename _UHead>
     648              :         constexpr void
     649              :         _M_assign(const _Tuple_impl<_Idx, _UHead>& __in) const
     650              :         {
     651              :           _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
     652              :         }
     653              : 
     654              :       template<typename _UHead>
     655              :         constexpr void
     656              :         _M_assign(_Tuple_impl<_Idx, _UHead>&& __in) const
     657              :         {
     658              :           _M_head(*this)
     659              :             = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
     660              :         }
     661              : #endif // C++23
     662              : 
     663              :     protected:
     664              :       _GLIBCXX20_CONSTEXPR
     665              :       void
     666              :       _M_swap(_Tuple_impl& __in)
     667              :       {
     668              :         using std::swap;
     669              :         swap(_M_head(*this), _M_head(__in));
     670              :       }
     671              : 
     672              : #if __cplusplus > 202002L
     673              :       constexpr void
     674              :       _M_swap(const _Tuple_impl& __in) const
     675              :       {
     676              :         using std::swap;
     677              :         swap(_M_head(*this), _M_head(__in));
     678              :       }
     679              : #endif // C++23
     680              :     };
     681              : 
     682              :   // Concept utility functions, reused in conditionally-explicit
     683              :   // constructors.
     684              :   template<bool, typename... _Types>
     685              :     struct _TupleConstraints
     686              :     {
     687              :       template<typename... _UTypes>
     688              :         using __constructible = __and_<is_constructible<_Types, _UTypes>...>;
     689              : 
     690              :       template<typename... _UTypes>
     691              :         using __convertible = __and_<is_convertible<_UTypes, _Types>...>;
     692              : 
     693              :       // Constraint for a non-explicit constructor.
     694              :       // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
     695              :       // and every Ui is implicitly convertible to Ti.
     696              :       template<typename... _UTypes>
     697              :         static constexpr bool __is_implicitly_constructible()
     698              :         {
     699              :           return __and_<__constructible<_UTypes...>,
     700              :                         __convertible<_UTypes...>
     701              :                         >::value;
     702              :         }
     703              : 
     704              :       // Constraint for a non-explicit constructor.
     705              :       // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
     706              :       // but not every Ui is implicitly convertible to Ti.
     707              :       template<typename... _UTypes>
     708              :         static constexpr bool __is_explicitly_constructible()
     709              :         {
     710              :           return __and_<__constructible<_UTypes...>,
     711              :                         __not_<__convertible<_UTypes...>>
     712              :                         >::value;
     713              :         }
     714              : 
     715              :       static constexpr bool __is_implicitly_default_constructible()
     716              :       {
     717              :         return __and_<std::__is_implicitly_default_constructible<_Types>...
     718              :                       >::value;
     719              :       }
     720              : 
     721              :       static constexpr bool __is_explicitly_default_constructible()
     722              :       {
     723              :         return __and_<is_default_constructible<_Types>...,
     724              :                       __not_<__and_<
     725              :                         std::__is_implicitly_default_constructible<_Types>...>
     726              :                       >>::value;
     727              :       }
     728              :     };
     729              : 
     730              :   // Partial specialization used when a required precondition isn't met,
     731              :   // e.g. when sizeof...(_Types) != sizeof...(_UTypes).
     732              :   template<typename... _Types>
     733              :     struct _TupleConstraints<false, _Types...>
     734              :     {
     735              :       template<typename... _UTypes>
     736              :         static constexpr bool __is_implicitly_constructible()
     737              :         { return false; }
     738              : 
     739              :       template<typename... _UTypes>
     740              :         static constexpr bool __is_explicitly_constructible()
     741              :         { return false; }
     742              :     };
     743              : 
     744              :   /// Primary class template, tuple
     745              :   template<typename... _Elements>
     746              :     class tuple : public _Tuple_impl<0, _Elements...>
     747              :     {
     748              :       typedef _Tuple_impl<0, _Elements...> _Inherited;
     749              : 
     750              :       template<bool _Cond>
     751              :         using _TCC = _TupleConstraints<_Cond, _Elements...>;
     752              : 
     753              :       // Constraint for non-explicit default constructor
     754              :       template<bool _Dummy>
     755              :         using _ImplicitDefaultCtor = __enable_if_t<
     756              :           _TCC<_Dummy>::__is_implicitly_default_constructible(),
     757              :           bool>;
     758              : 
     759              :       // Constraint for explicit default constructor
     760              :       template<bool _Dummy>
     761              :         using _ExplicitDefaultCtor = __enable_if_t<
     762              :           _TCC<_Dummy>::__is_explicitly_default_constructible(),
     763              :           bool>;
     764              : 
     765              :       // Constraint for non-explicit constructors
     766              :       template<bool _Cond, typename... _Args>
     767              :         using _ImplicitCtor = __enable_if_t<
     768              :           _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
     769              :           bool>;
     770              : 
     771              :       // Constraint for non-explicit constructors
     772              :       template<bool _Cond, typename... _Args>
     773              :         using _ExplicitCtor = __enable_if_t<
     774              :           _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(),
     775              :           bool>;
     776              : 
     777              :       template<typename... _UElements>
     778              :         static constexpr
     779              :         __enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool>
     780              :         __assignable()
     781              :         { return __and_<is_assignable<_Elements&, _UElements>...>::value; }
     782              : 
     783              :       // Condition for noexcept-specifier of an assignment operator.
     784              :       template<typename... _UElements>
     785              :         static constexpr bool __nothrow_assignable()
     786              :         {
     787              :           return
     788              :             __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value;
     789              :         }
     790              : 
     791              :       // Condition for noexcept-specifier of a constructor.
     792              :       template<typename... _UElements>
     793              :         static constexpr bool __nothrow_constructible()
     794              :         {
     795              :           return
     796              :             __and_<is_nothrow_constructible<_Elements, _UElements>...>::value;
     797              :         }
     798              : 
     799              :       // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) == 1.
     800              :       template<typename _Up>
     801              :         static constexpr bool __valid_args()
     802              :         {
     803              :           return sizeof...(_Elements) == 1
     804              :             && !is_same<tuple, __remove_cvref_t<_Up>>::value;
     805              :         }
     806              : 
     807              :       // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) > 1.
     808              :       template<typename, typename, typename... _Tail>
     809              :         static constexpr bool __valid_args()
     810              :         { return (sizeof...(_Tail) + 2) == sizeof...(_Elements); }
     811              : 
     812              :       /* Constraint for constructors with a tuple<UTypes...> parameter ensures
     813              :        * that the constructor is only viable when it would not interfere with
     814              :        * tuple(UTypes&&...) or tuple(const tuple&) or tuple(tuple&&).
     815              :        * Such constructors are only viable if:
     816              :        * either sizeof...(Types) != 1,
     817              :        * or (when Types... expands to T and UTypes... expands to U)
     818              :        * is_convertible_v<TUPLE, T>, is_constructible_v<T, TUPLE>,
     819              :        * and is_same_v<T, U> are all false.
     820              :        */
     821              :       template<typename _Tuple, typename = tuple,
     822              :                typename = __remove_cvref_t<_Tuple>>
     823              :         struct _UseOtherCtor
     824              :         : false_type
     825              :         { };
     826              :       // If TUPLE is convertible to the single element in *this,
     827              :       // then TUPLE should match tuple(UTypes&&...) instead.
     828              :       template<typename _Tuple, typename _Tp, typename _Up>
     829              :         struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>>
     830              :         : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>>::type
     831              :         { };
     832              :       // If TUPLE and *this each have a single element of the same type,
     833              :       // then TUPLE should match a copy/move constructor instead.
     834              :       template<typename _Tuple, typename _Tp>
     835              :         struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>>
     836              :         : true_type
     837              :         { };
     838              : 
     839              :       // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1
     840              :       // and the single element in Types can be initialized from TUPLE,
     841              :       // or is the same type as tuple_element_t<0, TUPLE>.
     842              :       template<typename _Tuple>
     843              :         static constexpr bool __use_other_ctor()
     844              :         { return _UseOtherCtor<_Tuple>::value; }
     845              : 
     846              : #if __cplusplus > 202002L
     847              :       template<typename... _Args>
     848              :         static constexpr bool __constructible
     849              :           = _TCC<true>::template __constructible<_Args...>::value;
     850              : 
     851              :       template<typename... _Args>
     852              :         static constexpr bool __convertible
     853              :           = _TCC<true>::template __convertible<_Args...>::value;
     854              : #endif // C++23
     855              : 
     856              :     public:
     857              :       template<typename _Dummy = void,
     858              :                _ImplicitDefaultCtor<is_void<_Dummy>::value> = true>
     859              :         constexpr
     860              :         tuple()
     861              :         noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
     862              :         : _Inherited() { }
     863              : 
     864              :       template<typename _Dummy = void,
     865              :                _ExplicitDefaultCtor<is_void<_Dummy>::value> = false>
     866              :         explicit constexpr
     867              :         tuple()
     868              :         noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
     869              :         : _Inherited() { }
     870              : 
     871              :       template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
     872              :                _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
     873              :         constexpr
     874      8756886 :         tuple(const _Elements&... __elements)
     875              :         noexcept(__nothrow_constructible<const _Elements&...>())
     876      8756886 :         : _Inherited(__elements...) { }
     877              : 
     878              :       template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
     879              :                _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
     880              :         explicit constexpr
     881              :         tuple(const _Elements&... __elements)
     882              :         noexcept(__nothrow_constructible<const _Elements&...>())
     883              :         : _Inherited(__elements...) { }
     884              : 
     885              :       template<typename... _UElements,
     886              :                bool _Valid = __valid_args<_UElements...>(),
     887              :                _ImplicitCtor<_Valid, _UElements...> = true>
     888              :         constexpr
     889      4735376 :         tuple(_UElements&&... __elements)
     890              :         noexcept(__nothrow_constructible<_UElements...>())
     891      4735376 :         : _Inherited(std::forward<_UElements>(__elements)...) { }
     892              : 
     893              :       template<typename... _UElements,
     894              :                bool _Valid = __valid_args<_UElements...>(),
     895              :                _ExplicitCtor<_Valid, _UElements...> = false>
     896              :         explicit constexpr
     897              :         tuple(_UElements&&... __elements)
     898              :         noexcept(__nothrow_constructible<_UElements...>())
     899              :         : _Inherited(std::forward<_UElements>(__elements)...) {   }
     900              : 
     901              :       constexpr tuple(const tuple&) = default;
     902              : 
     903     11885956 :       constexpr tuple(tuple&&) = default;
     904              : 
     905              :       template<typename... _UElements,
     906              :                bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
     907              :                            && !__use_other_ctor<const tuple<_UElements...>&>(),
     908              :                _ImplicitCtor<_Valid, const _UElements&...> = true>
     909              :         constexpr
     910              :         tuple(const tuple<_UElements...>& __in)
     911              :         noexcept(__nothrow_constructible<const _UElements&...>())
     912              :         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
     913              :         { }
     914              : 
     915              :       template<typename... _UElements,
     916              :                bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
     917              :                            && !__use_other_ctor<const tuple<_UElements...>&>(),
     918              :                _ExplicitCtor<_Valid, const _UElements&...> = false>
     919              :         explicit constexpr
     920              :         tuple(const tuple<_UElements...>& __in)
     921              :         noexcept(__nothrow_constructible<const _UElements&...>())
     922              :         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
     923              :         { }
     924              : 
     925              :       template<typename... _UElements,
     926              :                bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
     927              :                              && !__use_other_ctor<tuple<_UElements...>&&>(),
     928              :                _ImplicitCtor<_Valid, _UElements...> = true>
     929              :         constexpr
     930              :         tuple(tuple<_UElements...>&& __in)
     931              :         noexcept(__nothrow_constructible<_UElements...>())
     932              :         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
     933              : 
     934              :       template<typename... _UElements,
     935              :                bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
     936              :                              && !__use_other_ctor<tuple<_UElements...>&&>(),
     937              :                _ExplicitCtor<_Valid, _UElements...> = false>
     938              :         explicit constexpr
     939              :         tuple(tuple<_UElements...>&& __in)
     940              :         noexcept(__nothrow_constructible<_UElements...>())
     941              :         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
     942              : 
     943              : #if __cplusplus > 202002L
     944              :       template<typename... _UElements>
     945              :         requires (sizeof...(_Elements) == sizeof...(_UElements))
     946              :           && (!__use_other_ctor<tuple<_UElements...>&>())
     947              :           && __constructible<_UElements&...>
     948              :         explicit(!__convertible<_UElements&...>)
     949              :         constexpr
     950              :         tuple(tuple<_UElements...>& __in)
     951              :         noexcept(__nothrow_constructible<_UElements&...>())
     952              :         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&>(__in))
     953              :         { }
     954              : 
     955              :       template<typename... _UElements>
     956              :         requires (sizeof...(_Elements) == sizeof...(_UElements))
     957              :           && (!__use_other_ctor<const tuple<_UElements...>&&>())
     958              :           && __constructible<const _UElements...>
     959              :         explicit(!__convertible<const _UElements...>)
     960              :         constexpr
     961              :         tuple(const tuple<_UElements...>&& __in)
     962              :         noexcept(__nothrow_constructible<const _UElements...>())
     963              :         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&&>(__in)) { }
     964              : #endif // C++23
     965              : 
     966              :       // Allocator-extended constructors.
     967              : 
     968              :       template<typename _Alloc,
     969              :                _ImplicitDefaultCtor<is_object<_Alloc>::value> = true>
     970              :         _GLIBCXX20_CONSTEXPR
     971              :         tuple(allocator_arg_t __tag, const _Alloc& __a)
     972              :         : _Inherited(__tag, __a) { }
     973              : 
     974              :       template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
     975              :                _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
     976              :         _GLIBCXX20_CONSTEXPR
     977              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
     978              :               const _Elements&... __elements)
     979              :         : _Inherited(__tag, __a, __elements...) { }
     980              : 
     981              :       template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
     982              :                _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
     983              :         _GLIBCXX20_CONSTEXPR
     984              :         explicit
     985              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
     986              :               const _Elements&... __elements)
     987              :         : _Inherited(__tag, __a, __elements...) { }
     988              : 
     989              :       template<typename _Alloc, typename... _UElements,
     990              :                bool _Valid = __valid_args<_UElements...>(),
     991              :                _ImplicitCtor<_Valid, _UElements...> = true>
     992              :         _GLIBCXX20_CONSTEXPR
     993              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
     994              :               _UElements&&... __elements)
     995              :         : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
     996              :         { }
     997              : 
     998              :       template<typename _Alloc, typename... _UElements,
     999              :                  bool _Valid = __valid_args<_UElements...>(),
    1000              :                _ExplicitCtor<_Valid, _UElements...> = false>
    1001              :         _GLIBCXX20_CONSTEXPR
    1002              :         explicit
    1003              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1004              :               _UElements&&... __elements)
    1005              :         : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
    1006              :         { }
    1007              : 
    1008              :       template<typename _Alloc>
    1009              :         _GLIBCXX20_CONSTEXPR
    1010              :         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
    1011              :         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
    1012              : 
    1013              :       template<typename _Alloc>
    1014              :         _GLIBCXX20_CONSTEXPR
    1015              :         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
    1016              :         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
    1017              : 
    1018              :       template<typename _Alloc, typename... _UElements,
    1019              :                bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    1020              :                              && !__use_other_ctor<const tuple<_UElements...>&>(),
    1021              :                _ImplicitCtor<_Valid, const _UElements&...> = true>
    1022              :         _GLIBCXX20_CONSTEXPR
    1023              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1024              :               const tuple<_UElements...>& __in)
    1025              :         : _Inherited(__tag, __a,
    1026              :                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    1027              :         { }
    1028              : 
    1029              :       template<typename _Alloc, typename... _UElements,
    1030              :                bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    1031              :                              && !__use_other_ctor<const tuple<_UElements...>&>(),
    1032              :                _ExplicitCtor<_Valid, const _UElements&...> = false>
    1033              :         _GLIBCXX20_CONSTEXPR
    1034              :         explicit
    1035              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1036              :               const tuple<_UElements...>& __in)
    1037              :         : _Inherited(__tag, __a,
    1038              :                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    1039              :         { }
    1040              : 
    1041              :       template<typename _Alloc, typename... _UElements,
    1042              :                bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    1043              :                              && !__use_other_ctor<tuple<_UElements...>&&>(),
    1044              :                _ImplicitCtor<_Valid, _UElements...> = true>
    1045              :         _GLIBCXX20_CONSTEXPR
    1046              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1047              :               tuple<_UElements...>&& __in)
    1048              :         : _Inherited(__tag, __a,
    1049              :                      static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
    1050              :         { }
    1051              : 
    1052              :       template<typename _Alloc, typename... _UElements,
    1053              :                bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    1054              :                              && !__use_other_ctor<tuple<_UElements...>&&>(),
    1055              :                _ExplicitCtor<_Valid, _UElements...> = false>
    1056              :         _GLIBCXX20_CONSTEXPR
    1057              :         explicit
    1058              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1059              :               tuple<_UElements...>&& __in)
    1060              :         : _Inherited(__tag, __a,
    1061              :                      static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
    1062              :         { }
    1063              : 
    1064              : #if __cplusplus > 202002L
    1065              :       template<typename _Alloc, typename... _UElements>
    1066              :         requires (sizeof...(_Elements) == sizeof...(_UElements))
    1067              :           && (!__use_other_ctor<tuple<_UElements...>&>())
    1068              :           && __constructible<_UElements&...>
    1069              :         explicit(!__convertible<_UElements&...>)
    1070              :         constexpr
    1071              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1072              :               tuple<_UElements...>& __in)
    1073              :         : _Inherited(__tag, __a,
    1074              :                      static_cast<_Tuple_impl<0, _UElements...>&>(__in))
    1075              :         { }
    1076              : 
    1077              :       template<typename _Alloc, typename... _UElements>
    1078              :         requires (sizeof...(_Elements) == sizeof...(_UElements))
    1079              :           && (!__use_other_ctor<const tuple<_UElements...>>())
    1080              :           && __constructible<const _UElements...>
    1081              :         explicit(!__convertible<const _UElements...>)
    1082              :         constexpr
    1083              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1084              :               const tuple<_UElements...>&& __in)
    1085              :         : _Inherited(__tag, __a,
    1086              :                      static_cast<const _Tuple_impl<0, _UElements...>&&>(__in))
    1087              :         { }
    1088              : #endif // C++23
    1089              : 
    1090              :       // tuple assignment
    1091              : 
    1092              :       _GLIBCXX20_CONSTEXPR
    1093              :       tuple&
    1094              :       operator=(__conditional_t<__assignable<const _Elements&...>(),
    1095              :                                 const tuple&,
    1096              :                                 const __nonesuch&> __in)
    1097              :       noexcept(__nothrow_assignable<const _Elements&...>())
    1098              :       {
    1099              :         this->_M_assign(__in);
    1100              :         return *this;
    1101              :       }
    1102              : 
    1103              :       _GLIBCXX20_CONSTEXPR
    1104              :       tuple&
    1105              :       operator=(__conditional_t<__assignable<_Elements...>(),
    1106              :                                 tuple&&,
    1107              :                                 __nonesuch&&> __in)
    1108              :       noexcept(__nothrow_assignable<_Elements...>())
    1109              :       {
    1110              :         this->_M_assign(std::move(__in));
    1111              :         return *this;
    1112              :       }
    1113              : 
    1114              :       template<typename... _UElements>
    1115              :         _GLIBCXX20_CONSTEXPR
    1116              :         __enable_if_t<__assignable<const _UElements&...>(), tuple&>
    1117              :         operator=(const tuple<_UElements...>& __in)
    1118              :         noexcept(__nothrow_assignable<const _UElements&...>())
    1119              :         {
    1120              :           this->_M_assign(__in);
    1121              :           return *this;
    1122              :         }
    1123              : 
    1124              :       template<typename... _UElements>
    1125              :         _GLIBCXX20_CONSTEXPR
    1126              :         __enable_if_t<__assignable<_UElements...>(), tuple&>
    1127          286 :         operator=(tuple<_UElements...>&& __in)
    1128              :         noexcept(__nothrow_assignable<_UElements...>())
    1129              :         {
    1130          286 :           this->_M_assign(std::move(__in));
    1131          286 :           return *this;
    1132              :         }
    1133              : 
    1134              : #if __cplusplus > 202002L
    1135              :       constexpr const tuple&
    1136              :       operator=(const tuple& __in) const
    1137              :       requires (is_copy_assignable_v<const _Elements> && ...)
    1138              :       {
    1139              :         this->_M_assign(__in);
    1140              :         return *this;
    1141              :       }
    1142              : 
    1143              :       constexpr const tuple&
    1144              :       operator=(tuple&& __in) const
    1145              :       requires (is_assignable_v<const _Elements&, _Elements> && ...)
    1146              :       {
    1147              :         this->_M_assign(std::move(__in));
    1148              :         return *this;
    1149              :       }
    1150              : 
    1151              :       template<typename... _UElements>
    1152              :         constexpr const tuple&
    1153              :         operator=(const tuple<_UElements...>& __in) const
    1154              :         requires (sizeof...(_Elements) == sizeof...(_UElements))
    1155              :           && (is_assignable_v<const _Elements&, const _UElements&> && ...)
    1156              :         {
    1157              :           this->_M_assign(__in);
    1158              :           return *this;
    1159              :         }
    1160              : 
    1161              :       template<typename... _UElements>
    1162              :         constexpr const tuple&
    1163              :         operator=(tuple<_UElements...>&& __in) const
    1164              :         requires (sizeof...(_Elements) == sizeof...(_UElements))
    1165              :           && (is_assignable_v<const _Elements&, _UElements> && ...)
    1166              :         {
    1167              :           this->_M_assign(std::move(__in));
    1168              :           return *this;
    1169              :         }
    1170              : #endif // C++23
    1171              : 
    1172              :       // tuple swap
    1173              :       _GLIBCXX20_CONSTEXPR
    1174              :       void
    1175              :       swap(tuple& __in)
    1176              :       noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
    1177              :       { _Inherited::_M_swap(__in); }
    1178              : 
    1179              : #if __cplusplus > 202002L
    1180              :       // As an extension, we constrain the const swap member function in order
    1181              :       // to continue accepting explicit instantiation of tuples whose elements
    1182              :       // are not all const swappable.  Without this constraint, such an
    1183              :       // explicit instantiation would also instantiate the ill-formed body of
    1184              :       // this function and yield a hard error.  This constraint shouldn't
    1185              :       // affect the behavior of valid programs.
    1186              :       constexpr void
    1187              :       swap(const tuple& __in) const
    1188              :       noexcept(__and_v<__is_nothrow_swappable<const _Elements>...>)
    1189              :       requires (is_swappable_v<const _Elements> && ...)
    1190              :       { _Inherited::_M_swap(__in); }
    1191              : #endif // C++23
    1192              :     };
    1193              : 
    1194              : #if __cpp_deduction_guides >= 201606
    1195              :   template<typename... _UTypes>
    1196              :     tuple(_UTypes...) -> tuple<_UTypes...>;
    1197              :   template<typename _T1, typename _T2>
    1198              :     tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
    1199              :   template<typename _Alloc, typename... _UTypes>
    1200              :     tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
    1201              :   template<typename _Alloc, typename _T1, typename _T2>
    1202              :     tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
    1203              :   template<typename _Alloc, typename... _UTypes>
    1204              :     tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
    1205              : #endif
    1206              : 
    1207              :   // Explicit specialization, zero-element tuple.
    1208              :   template<>
    1209              :     class tuple<>
    1210              :     {
    1211              :     public:
    1212              :       _GLIBCXX20_CONSTEXPR
    1213              :       void swap(tuple&) noexcept { /* no-op */ }
    1214              : #if __cplusplus > 202002L
    1215              :       constexpr void swap(const tuple&) const noexcept { /* no-op */ }
    1216              : #endif
    1217              :       // We need the default since we're going to define no-op
    1218              :       // allocator constructors.
    1219              :       tuple() = default;
    1220              :       // No-op allocator constructors.
    1221              :       template<typename _Alloc>
    1222              :         _GLIBCXX20_CONSTEXPR
    1223              :         tuple(allocator_arg_t, const _Alloc&) noexcept { }
    1224              :       template<typename _Alloc>
    1225              :         _GLIBCXX20_CONSTEXPR
    1226              :         tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { }
    1227              :     };
    1228              : 
    1229              :   /// Partial specialization, 2-element tuple.
    1230              :   /// Includes construction and assignment from a pair.
    1231              :   template<typename _T1, typename _T2>
    1232              :     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
    1233              :     {
    1234              :       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
    1235              : 
    1236              :       // Constraint for non-explicit default constructor
    1237              :       template<bool _Dummy, typename _U1, typename _U2>
    1238              :         using _ImplicitDefaultCtor = __enable_if_t<
    1239              :           _TupleConstraints<_Dummy, _U1, _U2>::
    1240              :             __is_implicitly_default_constructible(),
    1241              :           bool>;
    1242              : 
    1243              :       // Constraint for explicit default constructor
    1244              :       template<bool _Dummy, typename _U1, typename _U2>
    1245              :         using _ExplicitDefaultCtor = __enable_if_t<
    1246              :           _TupleConstraints<_Dummy, _U1, _U2>::
    1247              :             __is_explicitly_default_constructible(),
    1248              :           bool>;
    1249              : 
    1250              :       template<bool _Dummy>
    1251              :         using _TCC = _TupleConstraints<_Dummy, _T1, _T2>;
    1252              : 
    1253              :       // Constraint for non-explicit constructors
    1254              :       template<bool _Cond, typename _U1, typename _U2>
    1255              :         using _ImplicitCtor = __enable_if_t<
    1256              :           _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(),
    1257              :           bool>;
    1258              : 
    1259              :       // Constraint for non-explicit constructors
    1260              :       template<bool _Cond, typename _U1, typename _U2>
    1261              :         using _ExplicitCtor = __enable_if_t<
    1262              :           _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(),
    1263              :           bool>;
    1264              : 
    1265              :       template<typename _U1, typename _U2>
    1266              :         static constexpr bool __assignable()
    1267              :         {
    1268              :           return __and_<is_assignable<_T1&, _U1>,
    1269              :                         is_assignable<_T2&, _U2>>::value;
    1270              :         }
    1271              : 
    1272              :       template<typename _U1, typename _U2>
    1273              :         static constexpr bool __nothrow_assignable()
    1274              :         {
    1275              :           return __and_<is_nothrow_assignable<_T1&, _U1>,
    1276              :                         is_nothrow_assignable<_T2&, _U2>>::value;
    1277              :         }
    1278              : 
    1279              :       template<typename _U1, typename _U2>
    1280              :         static constexpr bool __nothrow_constructible()
    1281              :         {
    1282              :           return __and_<is_nothrow_constructible<_T1, _U1>,
    1283              :                             is_nothrow_constructible<_T2, _U2>>::value;
    1284              :         }
    1285              : 
    1286              :       static constexpr bool __nothrow_default_constructible()
    1287              :       {
    1288              :         return __and_<is_nothrow_default_constructible<_T1>,
    1289              :                       is_nothrow_default_constructible<_T2>>::value;
    1290              :       }
    1291              : 
    1292              :       template<typename _U1>
    1293              :         static constexpr bool __is_alloc_arg()
    1294              :         { return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; }
    1295              : 
    1296              : #if __cplusplus > 202002L
    1297              :       template<typename _U1, typename _U2>
    1298              :         static constexpr bool __constructible
    1299              :           = _TCC<true>::template __constructible<_U1, _U2>::value;
    1300              : 
    1301              :       template<typename _U1, typename _U2>
    1302              :         static constexpr bool __convertible
    1303              :           = _TCC<true>::template __convertible<_U1, _U2>::value;
    1304              : #endif // C++23
    1305              : 
    1306              :     public:
    1307              :       template<bool _Dummy = true,
    1308              :                _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true>
    1309              :         constexpr
    1310      2051824 :         tuple()
    1311              :         noexcept(__nothrow_default_constructible())
    1312      2051824 :         : _Inherited() { }
    1313              : 
    1314              :       template<bool _Dummy = true,
    1315              :                _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false>
    1316              :         explicit constexpr
    1317              :         tuple()
    1318              :         noexcept(__nothrow_default_constructible())
    1319              :         : _Inherited() { }
    1320              : 
    1321              :       template<bool _Dummy = true,
    1322              :                _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
    1323              :         constexpr
    1324              :         tuple(const _T1& __a1, const _T2& __a2)
    1325              :         noexcept(__nothrow_constructible<const _T1&, const _T2&>())
    1326              :         : _Inherited(__a1, __a2) { }
    1327              : 
    1328              :       template<bool _Dummy = true,
    1329              :                _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
    1330              :         explicit constexpr
    1331              :         tuple(const _T1& __a1, const _T2& __a2)
    1332              :         noexcept(__nothrow_constructible<const _T1&, const _T2&>())
    1333              :         : _Inherited(__a1, __a2) { }
    1334              : 
    1335              :       template<typename _U1, typename _U2,
    1336              :                _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true>
    1337              :         constexpr
    1338          644 :         tuple(_U1&& __a1, _U2&& __a2)
    1339              :         noexcept(__nothrow_constructible<_U1, _U2>())
    1340          644 :         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
    1341              : 
    1342              :       template<typename _U1, typename _U2,
    1343              :                _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false>
    1344              :         explicit constexpr
    1345              :         tuple(_U1&& __a1, _U2&& __a2)
    1346              :         noexcept(__nothrow_constructible<_U1, _U2>())
    1347              :         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
    1348              : 
    1349              :       constexpr tuple(const tuple&) = default;
    1350              : 
    1351         1210 :       constexpr tuple(tuple&&) = default;
    1352              : 
    1353              :       template<typename _U1, typename _U2,
    1354              :                _ImplicitCtor<true, const _U1&, const _U2&> = true>
    1355              :         constexpr
    1356              :         tuple(const tuple<_U1, _U2>& __in)
    1357              :         noexcept(__nothrow_constructible<const _U1&, const _U2&>())
    1358              :         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
    1359              : 
    1360              :       template<typename _U1, typename _U2,
    1361              :                _ExplicitCtor<true, const _U1&, const _U2&> = false>
    1362              :         explicit constexpr
    1363              :         tuple(const tuple<_U1, _U2>& __in)
    1364              :         noexcept(__nothrow_constructible<const _U1&, const _U2&>())
    1365              :         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
    1366              : 
    1367              :       template<typename _U1, typename _U2,
    1368              :                _ImplicitCtor<true, _U1, _U2> = true>
    1369              :         constexpr
    1370              :         tuple(tuple<_U1, _U2>&& __in)
    1371              :         noexcept(__nothrow_constructible<_U1, _U2>())
    1372              :         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
    1373              : 
    1374              :       template<typename _U1, typename _U2,
    1375              :                _ExplicitCtor<true, _U1, _U2> = false>
    1376              :         explicit constexpr
    1377              :         tuple(tuple<_U1, _U2>&& __in)
    1378              :         noexcept(__nothrow_constructible<_U1, _U2>())
    1379              :         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
    1380              : 
    1381              : #if __cplusplus > 202002L
    1382              :       template<typename _U1, typename _U2>
    1383              :         requires __constructible<_U1&, _U2&>
    1384              :         explicit(!__convertible<_U1&, _U2&>)
    1385              :         constexpr
    1386              :         tuple(tuple<_U1, _U2>& __in)
    1387              :         noexcept(__nothrow_constructible<_U1&, _U2&>())
    1388              :         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&>(__in)) { }
    1389              : 
    1390              :       template<typename _U1, typename _U2>
    1391              :         requires __constructible<const _U1, const _U2>
    1392              :         explicit(!__convertible<const _U1, const _U2>)
    1393              :         constexpr
    1394              :         tuple(const tuple<_U1, _U2>&& __in)
    1395              :         noexcept(__nothrow_constructible<const _U1, const _U2>())
    1396              :         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&&>(__in)) { }
    1397              : #endif // C++23
    1398              : 
    1399              :       template<typename _U1, typename _U2,
    1400              :                _ImplicitCtor<true, const _U1&, const _U2&> = true>
    1401              :         constexpr
    1402              :         tuple(const pair<_U1, _U2>& __in)
    1403              :         noexcept(__nothrow_constructible<const _U1&, const _U2&>())
    1404              :         : _Inherited(__in.first, __in.second) { }
    1405              : 
    1406              :       template<typename _U1, typename _U2,
    1407              :                _ExplicitCtor<true, const _U1&, const _U2&> = false>
    1408              :         explicit constexpr
    1409              :         tuple(const pair<_U1, _U2>& __in)
    1410              :         noexcept(__nothrow_constructible<const _U1&, const _U2&>())
    1411              :         : _Inherited(__in.first, __in.second) { }
    1412              : 
    1413              :       template<typename _U1, typename _U2,
    1414              :                _ImplicitCtor<true, _U1, _U2> = true>
    1415              :         constexpr
    1416              :         tuple(pair<_U1, _U2>&& __in)
    1417              :         noexcept(__nothrow_constructible<_U1, _U2>())
    1418              :         : _Inherited(std::forward<_U1>(__in.first),
    1419              :                      std::forward<_U2>(__in.second)) { }
    1420              : 
    1421              :       template<typename _U1, typename _U2,
    1422              :                _ExplicitCtor<true, _U1, _U2> = false>
    1423              :         explicit constexpr
    1424              :         tuple(pair<_U1, _U2>&& __in)
    1425              :         noexcept(__nothrow_constructible<_U1, _U2>())
    1426              :         : _Inherited(std::forward<_U1>(__in.first),
    1427              :                      std::forward<_U2>(__in.second)) { }
    1428              : 
    1429              : #if __cplusplus > 202002L
    1430              :       template<typename _U1, typename _U2>
    1431              :         requires __constructible<_U1&, _U2&>
    1432              :         explicit(!__convertible<_U1&, _U2&>)
    1433              :         constexpr
    1434              :         tuple(pair<_U1, _U2>& __in)
    1435              :         noexcept(__nothrow_constructible<_U1&, _U2&>())
    1436              :         : _Inherited(__in.first, __in.second) { }
    1437              : 
    1438              :       template<typename _U1, typename _U2>
    1439              :         requires __constructible<const _U1, const _U2>
    1440              :         explicit(!__convertible<const _U1, const _U2>)
    1441              :         constexpr
    1442              :         tuple(const pair<_U1, _U2>&& __in)
    1443              :         noexcept(__nothrow_constructible<const _U1, const _U2>())
    1444              :         : _Inherited(std::forward<const _U1>(__in.first),
    1445              :                      std::forward<const _U2>(__in.second)) { }
    1446              : #endif // C++23
    1447              : 
    1448              :       // Allocator-extended constructors.
    1449              : 
    1450              :       template<typename _Alloc,
    1451              :                _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true>
    1452              :         _GLIBCXX20_CONSTEXPR
    1453              :         tuple(allocator_arg_t __tag, const _Alloc& __a)
    1454              :         : _Inherited(__tag, __a) { }
    1455              : 
    1456              :       template<typename _Alloc, bool _Dummy = true,
    1457              :                _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
    1458              :         _GLIBCXX20_CONSTEXPR
    1459              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1460              :               const _T1& __a1, const _T2& __a2)
    1461              :         : _Inherited(__tag, __a, __a1, __a2) { }
    1462              : 
    1463              :       template<typename _Alloc, bool _Dummy = true,
    1464              :                _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
    1465              :         explicit
    1466              :         _GLIBCXX20_CONSTEXPR
    1467              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1468              :               const _T1& __a1, const _T2& __a2)
    1469              :         : _Inherited(__tag, __a, __a1, __a2) { }
    1470              : 
    1471              :       template<typename _Alloc, typename _U1, typename _U2,
    1472              :                _ImplicitCtor<true, _U1, _U2> = true>
    1473              :         _GLIBCXX20_CONSTEXPR
    1474              :         tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
    1475              :         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
    1476              :                      std::forward<_U2>(__a2)) { }
    1477              : 
    1478              :       template<typename _Alloc, typename _U1, typename _U2,
    1479              :                _ExplicitCtor<true, _U1, _U2> = false>
    1480              :         explicit
    1481              :         _GLIBCXX20_CONSTEXPR
    1482              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1483              :               _U1&& __a1, _U2&& __a2)
    1484              :         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
    1485              :                      std::forward<_U2>(__a2)) { }
    1486              : 
    1487              :       template<typename _Alloc>
    1488              :         _GLIBCXX20_CONSTEXPR
    1489              :         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
    1490              :         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
    1491              : 
    1492              :       template<typename _Alloc>
    1493              :         _GLIBCXX20_CONSTEXPR
    1494              :         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
    1495              :         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
    1496              : 
    1497              :       template<typename _Alloc, typename _U1, typename _U2,
    1498              :                _ImplicitCtor<true, const _U1&, const _U2&> = true>
    1499              :         _GLIBCXX20_CONSTEXPR
    1500              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1501              :               const tuple<_U1, _U2>& __in)
    1502              :         : _Inherited(__tag, __a,
    1503              :                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
    1504              :         { }
    1505              : 
    1506              :       template<typename _Alloc, typename _U1, typename _U2,
    1507              :                _ExplicitCtor<true, const _U1&, const _U2&> = false>
    1508              :         explicit
    1509              :         _GLIBCXX20_CONSTEXPR
    1510              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1511              :               const tuple<_U1, _U2>& __in)
    1512              :         : _Inherited(__tag, __a,
    1513              :                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
    1514              :         { }
    1515              : 
    1516              :       template<typename _Alloc, typename _U1, typename _U2,
    1517              :                _ImplicitCtor<true, _U1, _U2> = true>
    1518              :         _GLIBCXX20_CONSTEXPR
    1519              :         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
    1520              :         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
    1521              :         { }
    1522              : 
    1523              :       template<typename _Alloc, typename _U1, typename _U2,
    1524              :                _ExplicitCtor<true, _U1, _U2> = false>
    1525              :         explicit
    1526              :         _GLIBCXX20_CONSTEXPR
    1527              :         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
    1528              :         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
    1529              :         { }
    1530              : 
    1531              : #if __cplusplus > 202002L
    1532              :       template<typename _Alloc, typename _U1, typename _U2>
    1533              :         requires __constructible<_U1&, _U2&>
    1534              :         explicit(!__convertible<_U1&, _U2&>)
    1535              :         constexpr
    1536              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1537              :               tuple<_U1, _U2>& __in)
    1538              :         : _Inherited(__tag, __a,
    1539              :                      static_cast<_Tuple_impl<0, _U1, _U2>&>(__in))
    1540              :         { }
    1541              : 
    1542              :       template<typename _Alloc, typename _U1, typename _U2>
    1543              :         requires __constructible<const _U1, const _U2>
    1544              :         explicit(!__convertible<const _U1, const _U2>)
    1545              :         constexpr
    1546              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1547              :               const tuple<_U1, _U2>&& __in)
    1548              :         : _Inherited(__tag, __a,
    1549              :                      static_cast<const _Tuple_impl<0, _U1, _U2>&&>(__in))
    1550              :         { }
    1551              : #endif // C++23
    1552              : 
    1553              :       template<typename _Alloc, typename _U1, typename _U2,
    1554              :                _ImplicitCtor<true, const _U1&, const _U2&> = true>
    1555              :         _GLIBCXX20_CONSTEXPR
    1556              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1557              :               const pair<_U1, _U2>& __in)
    1558              :         : _Inherited(__tag, __a, __in.first, __in.second) { }
    1559              : 
    1560              :       template<typename _Alloc, typename _U1, typename _U2,
    1561              :                _ExplicitCtor<true, const _U1&, const _U2&> = false>
    1562              :         explicit
    1563              :         _GLIBCXX20_CONSTEXPR
    1564              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1565              :               const pair<_U1, _U2>& __in)
    1566              :         : _Inherited(__tag, __a, __in.first, __in.second) { }
    1567              : 
    1568              :       template<typename _Alloc, typename _U1, typename _U2,
    1569              :                _ImplicitCtor<true, _U1, _U2> = true>
    1570              :         _GLIBCXX20_CONSTEXPR
    1571              :         tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
    1572              :         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
    1573              :                      std::forward<_U2>(__in.second)) { }
    1574              : 
    1575              :       template<typename _Alloc, typename _U1, typename _U2,
    1576              :                _ExplicitCtor<true, _U1, _U2> = false>
    1577              :         explicit
    1578              :         _GLIBCXX20_CONSTEXPR
    1579              :         tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
    1580              :         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
    1581              :                      std::forward<_U2>(__in.second)) { }
    1582              : 
    1583              : #if __cplusplus > 202002L
    1584              :       template<typename _Alloc, typename _U1, typename _U2>
    1585              :         requires __constructible<_U1&, _U2&>
    1586              :         explicit(!__convertible<_U1&, _U2&>)
    1587              :         constexpr
    1588              :         tuple(allocator_arg_t __tag, const _Alloc& __a,
    1589              :               pair<_U1, _U2>& __in)
    1590              :         : _Inherited(__tag, __a, __in.first, __in.second) { }
    1591              : 
    1592              :       template<typename _Alloc, typename _U1, typename _U2>
    1593              :         requires __constructible<const _U1, const _U2>
    1594              :         explicit(!__convertible<const _U1, const _U2>)
    1595              :         constexpr
    1596              :         tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>&& __in)
    1597              :         : _Inherited(__tag, __a, std::forward<const _U1>(__in.first),
    1598              :                      std::forward<const _U2>(__in.second)) { }
    1599              : #endif // C++23
    1600              : 
    1601              :       // Tuple assignment.
    1602              : 
    1603              :       _GLIBCXX20_CONSTEXPR
    1604              :       tuple&
    1605              :       operator=(__conditional_t<__assignable<const _T1&, const _T2&>(),
    1606              :                                 const tuple&,
    1607              :                                 const __nonesuch&> __in)
    1608              :       noexcept(__nothrow_assignable<const _T1&, const _T2&>())
    1609              :       {
    1610              :         this->_M_assign(__in);
    1611              :         return *this;
    1612              :       }
    1613              : 
    1614              :       _GLIBCXX20_CONSTEXPR
    1615              :       tuple&
    1616              :       operator=(__conditional_t<__assignable<_T1, _T2>(),
    1617              :                                 tuple&&,
    1618              :                                 __nonesuch&&> __in)
    1619              :       noexcept(__nothrow_assignable<_T1, _T2>())
    1620              :       {
    1621              :         this->_M_assign(std::move(__in));
    1622              :         return *this;
    1623              :       }
    1624              : 
    1625              :       template<typename _U1, typename _U2>
    1626              :         _GLIBCXX20_CONSTEXPR
    1627              :         __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
    1628              :         operator=(const tuple<_U1, _U2>& __in)
    1629              :         noexcept(__nothrow_assignable<const _U1&, const _U2&>())
    1630              :         {
    1631              :           this->_M_assign(__in);
    1632              :           return *this;
    1633              :         }
    1634              : 
    1635              :       template<typename _U1, typename _U2>
    1636              :         _GLIBCXX20_CONSTEXPR
    1637              :         __enable_if_t<__assignable<_U1, _U2>(), tuple&>
    1638              :         operator=(tuple<_U1, _U2>&& __in)
    1639              :         noexcept(__nothrow_assignable<_U1, _U2>())
    1640              :         {
    1641              :           this->_M_assign(std::move(__in));
    1642              :           return *this;
    1643              :         }
    1644              : 
    1645              : #if __cplusplus > 202002L
    1646              :       constexpr const tuple&
    1647              :       operator=(const tuple& __in) const
    1648              :       requires is_copy_assignable_v<const _T1> && is_copy_assignable_v<const _T2>
    1649              :       {
    1650              :         this->_M_assign(__in);
    1651              :         return *this;
    1652              :       }
    1653              : 
    1654              :       constexpr const tuple&
    1655              :       operator=(tuple&& __in) const
    1656              :       requires is_assignable_v<const _T1&, _T1> && is_assignable_v<const _T2, _T2>
    1657              :       {
    1658              :         this->_M_assign(std::move(__in));
    1659              :         return *this;
    1660              :       }
    1661              : 
    1662              :       template<typename _U1, typename _U2>
    1663              :         constexpr const tuple&
    1664              :         operator=(const tuple<_U1, _U2>& __in) const
    1665              :         requires is_assignable_v<const _T1&, const _U1&>
    1666              :           && is_assignable_v<const _T2&, const _U2&>
    1667              :         {
    1668              :           this->_M_assign(__in);
    1669              :           return *this;
    1670              :         }
    1671              : 
    1672              :       template<typename _U1, typename _U2>
    1673              :         constexpr const tuple&
    1674              :         operator=(tuple<_U1, _U2>&& __in) const
    1675              :         requires is_assignable_v<const _T1&, _U1>
    1676              :           && is_assignable_v<const _T2&, _U2>
    1677              :         {
    1678              :           this->_M_assign(std::move(__in));
    1679              :           return *this;
    1680              :         }
    1681              : #endif // C++23
    1682              : 
    1683              :       template<typename _U1, typename _U2>
    1684              :         _GLIBCXX20_CONSTEXPR
    1685              :         __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
    1686              :         operator=(const pair<_U1, _U2>& __in)
    1687              :         noexcept(__nothrow_assignable<const _U1&, const _U2&>())
    1688              :         {
    1689              :           this->_M_head(*this) = __in.first;
    1690              :           this->_M_tail(*this)._M_head(*this) = __in.second;
    1691              :           return *this;
    1692              :         }
    1693              : 
    1694              :       template<typename _U1, typename _U2>
    1695              :         _GLIBCXX20_CONSTEXPR
    1696              :         __enable_if_t<__assignable<_U1, _U2>(), tuple&>
    1697              :         operator=(pair<_U1, _U2>&& __in)
    1698              :         noexcept(__nothrow_assignable<_U1, _U2>())
    1699              :         {
    1700              :           this->_M_head(*this) = std::forward<_U1>(__in.first);
    1701              :           this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
    1702              :           return *this;
    1703              :         }
    1704              : 
    1705              : #if __cplusplus > 202002L
    1706              :       template<typename _U1, typename _U2>
    1707              :         constexpr const tuple&
    1708              :         operator=(const pair<_U1, _U2>& __in) const
    1709              :         requires is_assignable_v<const _T1&, const _U1&>
    1710              :           && is_assignable_v<const _T2&, const _U2&>
    1711              :         {
    1712              :           this->_M_head(*this) = __in.first;
    1713              :           this->_M_tail(*this)._M_head(*this) = __in.second;
    1714              :           return *this;
    1715              :         }
    1716              : 
    1717              :       template<typename _U1, typename _U2>
    1718              :         constexpr const tuple&
    1719              :         operator=(pair<_U1, _U2>&& __in) const
    1720              :         requires is_assignable_v<const _T1&, _U1>
    1721              :           && is_assignable_v<const _T2&, _U2>
    1722              :         {
    1723              :           this->_M_head(*this) = std::forward<_U1>(__in.first);
    1724              :           this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
    1725              :           return *this;
    1726              :         }
    1727              : #endif // C++23
    1728              : 
    1729              :       _GLIBCXX20_CONSTEXPR
    1730              :       void
    1731              :       swap(tuple& __in)
    1732              :       noexcept(__and_<__is_nothrow_swappable<_T1>,
    1733              :                       __is_nothrow_swappable<_T2>>::value)
    1734              :       { _Inherited::_M_swap(__in); }
    1735              : 
    1736              : #if __cplusplus > 202002L
    1737              :       constexpr void
    1738              :       swap(const tuple& __in) const
    1739              :       noexcept(__and_v<__is_nothrow_swappable<const _T1>,
    1740              :                        __is_nothrow_swappable<const _T2>>)
    1741              :       requires is_swappable_v<const _T1> && is_swappable_v<const _T2>
    1742              :       { _Inherited::_M_swap(__in); }
    1743              : #endif // C++23
    1744              :     };
    1745              : 
    1746              : 
    1747              :   /// class tuple_size
    1748              :   template<typename... _Elements>
    1749              :     struct tuple_size<tuple<_Elements...>>
    1750              :     : public integral_constant<size_t, sizeof...(_Elements)> { };
    1751              : 
    1752              : #if __cplusplus >= 201703L
    1753              :   template<typename... _Types>
    1754              :     inline constexpr size_t tuple_size_v<tuple<_Types...>>
    1755              :       = sizeof...(_Types);
    1756              : 
    1757              :   template<typename... _Types>
    1758              :     inline constexpr size_t tuple_size_v<const tuple<_Types...>>
    1759              :       = sizeof...(_Types);
    1760              : #endif
    1761              : 
    1762              :   /// Trait to get the Ith element type from a tuple.
    1763              :   template<size_t __i, typename... _Types>
    1764              :     struct tuple_element<__i, tuple<_Types...>>
    1765              :     {
    1766              :       static_assert(__i < sizeof...(_Types), "tuple index must be in range");
    1767              : 
    1768              :       using type = typename _Nth_type<__i, _Types...>::type;
    1769              :     };
    1770              : 
    1771              :   template<size_t __i, typename _Head, typename... _Tail>
    1772              :     constexpr _Head&
    1773     17270032 :     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
    1774     17270032 :     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
    1775              : 
    1776              :   template<size_t __i, typename _Head, typename... _Tail>
    1777              :     constexpr const _Head&
    1778     31996304 :     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
    1779     31996304 :     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
    1780              : 
    1781              :   // Deleted overload to improve diagnostics for invalid indices
    1782              :   template<size_t __i, typename... _Types>
    1783              :     __enable_if_t<(__i >= sizeof...(_Types))>
    1784              :     __get_helper(const tuple<_Types...>&) = delete;
    1785              : 
    1786              :   /// Return a reference to the ith element of a tuple.
    1787              :   template<size_t __i, typename... _Elements>
    1788              :     constexpr __tuple_element_t<__i, tuple<_Elements...>>&
    1789     15664298 :     get(tuple<_Elements...>& __t) noexcept
    1790     15664298 :     { return std::__get_helper<__i>(__t); }
    1791              : 
    1792              :   /// Return a const reference to the ith element of a const tuple.
    1793              :   template<size_t __i, typename... _Elements>
    1794              :     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
    1795     31996304 :     get(const tuple<_Elements...>& __t) noexcept
    1796     31996304 :     { return std::__get_helper<__i>(__t); }
    1797              : 
    1798              :   /// Return an rvalue reference to the ith element of a tuple rvalue.
    1799              :   template<size_t __i, typename... _Elements>
    1800              :     constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
    1801      1605734 :     get(tuple<_Elements...>&& __t) noexcept
    1802              :     {
    1803              :       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
    1804      1605734 :       return std::forward<__element_type>(std::__get_helper<__i>(__t));
    1805              :     }
    1806              : 
    1807              :   /// Return a const rvalue reference to the ith element of a const tuple rvalue.
    1808              :   template<size_t __i, typename... _Elements>
    1809              :     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
    1810              :     get(const tuple<_Elements...>&& __t) noexcept
    1811              :     {
    1812              :       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
    1813              :       return std::forward<const __element_type>(std::__get_helper<__i>(__t));
    1814              :     }
    1815              : 
    1816              :   /// @cond undocumented
    1817              :   // Deleted overload chosen for invalid indices.
    1818              :   template<size_t __i, typename... _Elements>
    1819              :     constexpr __enable_if_t<(__i >= sizeof...(_Elements))>
    1820              :     get(const tuple<_Elements...>&) = delete;
    1821              :   /// @endcond
    1822              : 
    1823              : #if __cplusplus >= 201402L
    1824              : 
    1825              : #define __cpp_lib_tuples_by_type 201304L
    1826              : 
    1827              :   /// Return a reference to the unique element of type _Tp of a tuple.
    1828              :   template <typename _Tp, typename... _Types>
    1829              :     constexpr _Tp&
    1830              :     get(tuple<_Types...>& __t) noexcept
    1831              :     {
    1832              :       constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
    1833              :       static_assert(__idx < sizeof...(_Types),
    1834              :           "the type T in std::get<T> must occur exactly once in the tuple");
    1835              :       return std::__get_helper<__idx>(__t);
    1836              :     }
    1837              : 
    1838              :   /// Return a reference to the unique element of type _Tp of a tuple rvalue.
    1839              :   template <typename _Tp, typename... _Types>
    1840              :     constexpr _Tp&&
    1841              :     get(tuple<_Types...>&& __t) noexcept
    1842              :     {
    1843              :       constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
    1844              :       static_assert(__idx < sizeof...(_Types),
    1845              :           "the type T in std::get<T> must occur exactly once in the tuple");
    1846              :       return std::forward<_Tp>(std::__get_helper<__idx>(__t));
    1847              :     }
    1848              : 
    1849              :   /// Return a const reference to the unique element of type _Tp of a tuple.
    1850              :   template <typename _Tp, typename... _Types>
    1851              :     constexpr const _Tp&
    1852              :     get(const tuple<_Types...>& __t) noexcept
    1853              :     {
    1854              :       constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
    1855              :       static_assert(__idx < sizeof...(_Types),
    1856              :           "the type T in std::get<T> must occur exactly once in the tuple");
    1857              :       return std::__get_helper<__idx>(__t);
    1858              :     }
    1859              : 
    1860              :   /// Return a const reference to the unique element of type _Tp of
    1861              :   /// a const tuple rvalue.
    1862              :   template <typename _Tp, typename... _Types>
    1863              :     constexpr const _Tp&&
    1864              :     get(const tuple<_Types...>&& __t) noexcept
    1865              :     {
    1866              :       constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
    1867              :       static_assert(__idx < sizeof...(_Types),
    1868              :           "the type T in std::get<T> must occur exactly once in the tuple");
    1869              :       return std::forward<const _Tp>(std::__get_helper<__idx>(__t));
    1870              :     }
    1871              : #endif
    1872              : 
    1873              :   // This class performs the comparison operations on tuples
    1874              :   template<typename _Tp, typename _Up, size_t __i, size_t __size>
    1875              :     struct __tuple_compare
    1876              :     {
    1877              :       static constexpr bool
    1878            0 :       __eq(const _Tp& __t, const _Up& __u)
    1879              :       {
    1880            0 :         return bool(std::get<__i>(__t) == std::get<__i>(__u))
    1881            0 :           && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
    1882              :       }
    1883              : 
    1884              :       static constexpr bool
    1885              :       __less(const _Tp& __t, const _Up& __u)
    1886              :       {
    1887              :         return bool(std::get<__i>(__t) < std::get<__i>(__u))
    1888              :           || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
    1889              :               && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
    1890              :       }
    1891              :     };
    1892              : 
    1893              :   template<typename _Tp, typename _Up, size_t __size>
    1894              :     struct __tuple_compare<_Tp, _Up, __size, __size>
    1895              :     {
    1896              :       static constexpr bool
    1897            0 :       __eq(const _Tp&, const _Up&) { return true; }
    1898              : 
    1899              :       static constexpr bool
    1900              :       __less(const _Tp&, const _Up&) { return false; }
    1901              :     };
    1902              : 
    1903              :   template<typename... _TElements, typename... _UElements>
    1904              :     constexpr bool
    1905            0 :     operator==(const tuple<_TElements...>& __t,
    1906              :                const tuple<_UElements...>& __u)
    1907              :     {
    1908              :       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
    1909              :           "tuple objects can only be compared if they have equal sizes.");
    1910              :       using __compare = __tuple_compare<tuple<_TElements...>,
    1911              :                                         tuple<_UElements...>,
    1912              :                                         0, sizeof...(_TElements)>;
    1913            0 :       return __compare::__eq(__t, __u);
    1914              :     }
    1915              : 
    1916              : #if __cpp_lib_three_way_comparison
    1917              :   template<typename _Cat, typename _Tp, typename _Up>
    1918              :     constexpr _Cat
    1919              :     __tuple_cmp(const _Tp&, const _Up&, index_sequence<>)
    1920              :     { return _Cat::equivalent; }
    1921              : 
    1922              :   template<typename _Cat, typename _Tp, typename _Up,
    1923              :            size_t _Idx0, size_t... _Idxs>
    1924              :     constexpr _Cat
    1925              :     __tuple_cmp(const _Tp& __t, const _Up& __u,
    1926              :                 index_sequence<_Idx0, _Idxs...>)
    1927              :     {
    1928              :       auto __c
    1929              :         = __detail::__synth3way(std::get<_Idx0>(__t), std::get<_Idx0>(__u));
    1930              :       if (__c != 0)
    1931              :         return __c;
    1932              :       return std::__tuple_cmp<_Cat>(__t, __u, index_sequence<_Idxs...>());
    1933              :     }
    1934              : 
    1935              :   template<typename... _Tps, typename... _Ups>
    1936              :     constexpr
    1937              :     common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>
    1938              :     operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u)
    1939              :     {
    1940              :       using _Cat
    1941              :         = common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>;
    1942              :       return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>());
    1943              :     }
    1944              : #else
    1945              :   template<typename... _TElements, typename... _UElements>
    1946              :     constexpr bool
    1947              :     operator<(const tuple<_TElements...>& __t,
    1948              :               const tuple<_UElements...>& __u)
    1949              :     {
    1950              :       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
    1951              :           "tuple objects can only be compared if they have equal sizes.");
    1952              :       using __compare = __tuple_compare<tuple<_TElements...>,
    1953              :                                         tuple<_UElements...>,
    1954              :                                         0, sizeof...(_TElements)>;
    1955              :       return __compare::__less(__t, __u);
    1956              :     }
    1957              : 
    1958              :   template<typename... _TElements, typename... _UElements>
    1959              :     constexpr bool
    1960              :     operator!=(const tuple<_TElements...>& __t,
    1961              :                const tuple<_UElements...>& __u)
    1962              :     { return !(__t == __u); }
    1963              : 
    1964              :   template<typename... _TElements, typename... _UElements>
    1965              :     constexpr bool
    1966              :     operator>(const tuple<_TElements...>& __t,
    1967              :               const tuple<_UElements...>& __u)
    1968              :     { return __u < __t; }
    1969              : 
    1970              :   template<typename... _TElements, typename... _UElements>
    1971              :     constexpr bool
    1972              :     operator<=(const tuple<_TElements...>& __t,
    1973              :                const tuple<_UElements...>& __u)
    1974              :     { return !(__u < __t); }
    1975              : 
    1976              :   template<typename... _TElements, typename... _UElements>
    1977              :     constexpr bool
    1978              :     operator>=(const tuple<_TElements...>& __t,
    1979              :                const tuple<_UElements...>& __u)
    1980              :     { return !(__t < __u); }
    1981              : #endif // three_way_comparison
    1982              : 
    1983              :   // NB: DR 705.
    1984              :   /// Create a tuple containing copies of the arguments
    1985              :   template<typename... _Elements>
    1986              :     constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
    1987              :     make_tuple(_Elements&&... __args)
    1988              :     {
    1989              :       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
    1990              :         __result_type;
    1991              :       return __result_type(std::forward<_Elements>(__args)...);
    1992              :     }
    1993              : 
    1994              :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
    1995              :   // 2275. Why is forward_as_tuple not constexpr?
    1996              :   /// Create a tuple of lvalue or rvalue references to the arguments
    1997              :   template<typename... _Elements>
    1998              :     constexpr tuple<_Elements&&...>
    1999      3129356 :     forward_as_tuple(_Elements&&... __args) noexcept
    2000      3129356 :     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
    2001              : 
    2002              :   // Declarations of std::array and its std::get overloads, so that
    2003              :   // std::tuple_cat can use them if <tuple> is included before <array>.
    2004              : 
    2005              :   template<typename _Tp, size_t _Nm> struct array;
    2006              : 
    2007              :   template<size_t _Int, typename _Tp, size_t _Nm>
    2008              :     constexpr _Tp&
    2009              :     get(array<_Tp, _Nm>&) noexcept;
    2010              : 
    2011              :   template<size_t _Int, typename _Tp, size_t _Nm>
    2012              :     constexpr _Tp&&
    2013              :     get(array<_Tp, _Nm>&&) noexcept;
    2014              : 
    2015              :   template<size_t _Int, typename _Tp, size_t _Nm>
    2016              :     constexpr const _Tp&
    2017              :     get(const array<_Tp, _Nm>&) noexcept;
    2018              : 
    2019              :   template<size_t _Int, typename _Tp, size_t _Nm>
    2020              :     constexpr const _Tp&&
    2021              :     get(const array<_Tp, _Nm>&&) noexcept;
    2022              : 
    2023              :   /// @cond undocumented
    2024              :   template<size_t, typename, typename, size_t>
    2025              :     struct __make_tuple_impl;
    2026              : 
    2027              :   template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
    2028              :     struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
    2029              :     : __make_tuple_impl<_Idx + 1,
    2030              :                         tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
    2031              :                         _Tuple, _Nm>
    2032              :     { };
    2033              : 
    2034              :   template<size_t _Nm, typename _Tuple, typename... _Tp>
    2035              :     struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
    2036              :     {
    2037              :       typedef tuple<_Tp...> __type;
    2038              :     };
    2039              : 
    2040              :   template<typename _Tuple>
    2041              :     struct __do_make_tuple
    2042              :     : __make_tuple_impl<0, tuple<>, _Tuple, tuple_size<_Tuple>::value>
    2043              :     { };
    2044              : 
    2045              :   // Returns the std::tuple equivalent of a tuple-like type.
    2046              :   template<typename _Tuple>
    2047              :     struct __make_tuple
    2048              :     : public __do_make_tuple<__remove_cvref_t<_Tuple>>
    2049              :     { };
    2050              : 
    2051              :   // Combines several std::tuple's into a single one.
    2052              :   template<typename...>
    2053              :     struct __combine_tuples;
    2054              : 
    2055              :   template<>
    2056              :     struct __combine_tuples<>
    2057              :     {
    2058              :       typedef tuple<> __type;
    2059              :     };
    2060              : 
    2061              :   template<typename... _Ts>
    2062              :     struct __combine_tuples<tuple<_Ts...>>
    2063              :     {
    2064              :       typedef tuple<_Ts...> __type;
    2065              :     };
    2066              : 
    2067              :   template<typename... _T1s, typename... _T2s, typename... _Rem>
    2068              :     struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
    2069              :     {
    2070              :       typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
    2071              :                                         _Rem...>::__type __type;
    2072              :     };
    2073              : 
    2074              :   // Computes the result type of tuple_cat given a set of tuple-like types.
    2075              :   template<typename... _Tpls>
    2076              :     struct __tuple_cat_result
    2077              :     {
    2078              :       typedef typename __combine_tuples
    2079              :         <typename __make_tuple<_Tpls>::__type...>::__type __type;
    2080              :     };
    2081              : 
    2082              :   // Helper to determine the index set for the first tuple-like
    2083              :   // type of a given set.
    2084              :   template<typename...>
    2085              :     struct __make_1st_indices;
    2086              : 
    2087              :   template<>
    2088              :     struct __make_1st_indices<>
    2089              :     {
    2090              :       typedef _Index_tuple<> __type;
    2091              :     };
    2092              : 
    2093              :   template<typename _Tp, typename... _Tpls>
    2094              :     struct __make_1st_indices<_Tp, _Tpls...>
    2095              :     {
    2096              :       typedef typename _Build_index_tuple<tuple_size<
    2097              :         typename remove_reference<_Tp>::type>::value>::__type __type;
    2098              :     };
    2099              : 
    2100              :   // Performs the actual concatenation by step-wise expanding tuple-like
    2101              :   // objects into the elements,  which are finally forwarded into the
    2102              :   // result tuple.
    2103              :   template<typename _Ret, typename _Indices, typename... _Tpls>
    2104              :     struct __tuple_concater;
    2105              : 
    2106              :   template<typename _Ret, size_t... _Is, typename _Tp, typename... _Tpls>
    2107              :     struct __tuple_concater<_Ret, _Index_tuple<_Is...>, _Tp, _Tpls...>
    2108              :     {
    2109              :       template<typename... _Us>
    2110              :         static constexpr _Ret
    2111              :         _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
    2112              :         {
    2113              :           typedef typename __make_1st_indices<_Tpls...>::__type __idx;
    2114              :           typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
    2115              :           return __next::_S_do(std::forward<_Tpls>(__tps)...,
    2116              :                                std::forward<_Us>(__us)...,
    2117              :                                std::get<_Is>(std::forward<_Tp>(__tp))...);
    2118              :         }
    2119              :     };
    2120              : 
    2121              :   template<typename _Ret>
    2122              :     struct __tuple_concater<_Ret, _Index_tuple<>>
    2123              :     {
    2124              :       template<typename... _Us>
    2125              :         static constexpr _Ret
    2126              :         _S_do(_Us&&... __us)
    2127              :         {
    2128              :           return _Ret(std::forward<_Us>(__us)...);
    2129              :         }
    2130              :     };
    2131              : 
    2132              :   template<typename... _Tps>
    2133              :     struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
    2134              :     { };
    2135              :   /// @endcond
    2136              : 
    2137              :   /// Create a `tuple` containing all elements from multiple tuple-like objects
    2138              :   template<typename... _Tpls, typename = typename
    2139              :            enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
    2140              :     constexpr auto
    2141              :     tuple_cat(_Tpls&&... __tpls)
    2142              :     -> typename __tuple_cat_result<_Tpls...>::__type
    2143              :     {
    2144              :       typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
    2145              :       typedef typename __make_1st_indices<_Tpls...>::__type __idx;
    2146              :       typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
    2147              :       return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
    2148              :     }
    2149              : 
    2150              :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
    2151              :   // 2301. Why is tie not constexpr?
    2152              :   /// Return a tuple of lvalue references bound to the arguments
    2153              :   template<typename... _Elements>
    2154              :     constexpr tuple<_Elements&...>
    2155          286 :     tie(_Elements&... __args) noexcept
    2156          286 :     { return tuple<_Elements&...>(__args...); }
    2157              : 
    2158              :   /// Exchange the values of two tuples
    2159              :   template<typename... _Elements>
    2160              :     _GLIBCXX20_CONSTEXPR
    2161              :     inline
    2162              : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
    2163              :     // Constrained free swap overload, see p0185r1
    2164              :     typename enable_if<__and_<__is_swappable<_Elements>...>::value
    2165              :       >::type
    2166              : #else
    2167              :     void
    2168              : #endif
    2169              :     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
    2170              :     noexcept(noexcept(__x.swap(__y)))
    2171              :     { __x.swap(__y); }
    2172              : 
    2173              : #if __cplusplus > 202002L
    2174              :   template<typename... _Elements>
    2175              :     requires (is_swappable_v<const _Elements> && ...)
    2176              :     constexpr void
    2177              :     swap(const tuple<_Elements...>& __x, const tuple<_Elements...>& __y)
    2178              :     noexcept(noexcept(__x.swap(__y)))
    2179              :     { __x.swap(__y); }
    2180              : #endif // C++23
    2181              : 
    2182              : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
    2183              :   /// Exchange the values of two const tuples (if const elements can be swapped)
    2184              :   template<typename... _Elements>
    2185              :     _GLIBCXX20_CONSTEXPR
    2186              :     typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
    2187              :     swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
    2188              : #endif
    2189              : 
    2190              :   // A class (and instance) which can be used in 'tie' when an element
    2191              :   // of a tuple is not required.
    2192              :   // _GLIBCXX14_CONSTEXPR
    2193              :   // 2933. PR for LWG 2773 could be clearer
    2194              :   struct _Swallow_assign
    2195              :   {
    2196              :     template<class _Tp>
    2197              :       _GLIBCXX14_CONSTEXPR const _Swallow_assign&
    2198              :       operator=(const _Tp&) const
    2199              :       { return *this; }
    2200              :   };
    2201              : 
    2202              :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
    2203              :   // 2773. Making std::ignore constexpr
    2204              :   /** Used with `std::tie` to ignore an element of a tuple
    2205              :    *
    2206              :    * When using `std::tie` to assign the elements of a tuple to variables,
    2207              :    * unwanted elements can be ignored by using `std::ignore`. For example:
    2208              :    *
    2209              :    * ```
    2210              :    * int x, y;
    2211              :    * std::tie(x, std::ignore, y) = std::make_tuple(1, 2, 3);
    2212              :    * ```
    2213              :    *
    2214              :    * This assignment will perform `x=1; std::ignore=2; y=3;` which results
    2215              :    * in the second element being ignored.
    2216              :    *
    2217              :    * @since C++11
    2218              :    */
    2219              :   _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
    2220              : 
    2221              :   /// Partial specialization for tuples
    2222              :   template<typename... _Types, typename _Alloc>
    2223              :     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
    2224              : 
    2225              :   // See stl_pair.h...
    2226              :   /** "piecewise construction" using a tuple of arguments for each member.
    2227              :    *
    2228              :    * @param __first Arguments for the first member of the pair.
    2229              :    * @param __second Arguments for the second member of the pair.
    2230              :    *
    2231              :    * The elements of each tuple will be used as the constructor arguments
    2232              :    * for the data members of the pair.
    2233              :   */
    2234              :   template<class _T1, class _T2>
    2235              :     template<typename... _Args1, typename... _Args2>
    2236              :       _GLIBCXX20_CONSTEXPR
    2237              :       inline
    2238     10538856 :       pair<_T1, _T2>::
    2239              :       pair(piecewise_construct_t,
    2240              :            tuple<_Args1...> __first, tuple<_Args2...> __second)
    2241              :       : pair(__first, __second,
    2242              :              typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
    2243     10538856 :              typename _Build_index_tuple<sizeof...(_Args2)>::__type())
    2244     10538856 :       { }
    2245              : 
    2246              :   template<class _T1, class _T2>
    2247              :     template<typename... _Args1, size_t... _Indexes1,
    2248              :              typename... _Args2, size_t... _Indexes2>
    2249              :       _GLIBCXX20_CONSTEXPR inline
    2250     10538856 :       pair<_T1, _T2>::
    2251              :       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
    2252              :            _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
    2253     10538856 :       : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
    2254     10538856 :         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
    2255     10538856 :       { }
    2256              : 
    2257              : #if __cplusplus >= 201703L
    2258              : 
    2259              :   // Unpack a std::tuple into a type trait and use its value.
    2260              :   // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value.
    2261              :   // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value.
    2262              :   // Otherwise the result is false (because we don't know if std::get throws).
    2263              :   template<template<typename...> class _Trait, typename _Tp, typename _Tuple>
    2264              :     inline constexpr bool __unpack_std_tuple = false;
    2265              : 
    2266              :   template<template<typename...> class _Trait, typename _Tp, typename... _Up>
    2267              :     inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>>
    2268              :       = _Trait<_Tp, _Up...>::value;
    2269              : 
    2270              :   template<template<typename...> class _Trait, typename _Tp, typename... _Up>
    2271              :     inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&>
    2272              :       = _Trait<_Tp, _Up&...>::value;
    2273              : 
    2274              :   template<template<typename...> class _Trait, typename _Tp, typename... _Up>
    2275              :     inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>>
    2276              :       = _Trait<_Tp, const _Up...>::value;
    2277              : 
    2278              :   template<template<typename...> class _Trait, typename _Tp, typename... _Up>
    2279              :     inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&>
    2280              :       = _Trait<_Tp, const _Up&...>::value;
    2281              : 
    2282              : # define __cpp_lib_apply 201603L
    2283              : 
    2284              :   template <typename _Fn, typename _Tuple, size_t... _Idx>
    2285              :     constexpr decltype(auto)
    2286              :     __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
    2287              :     {
    2288              :       return std::__invoke(std::forward<_Fn>(__f),
    2289              :                            std::get<_Idx>(std::forward<_Tuple>(__t))...);
    2290              :     }
    2291              : 
    2292              :   template <typename _Fn, typename _Tuple>
    2293              :     constexpr decltype(auto)
    2294              :     apply(_Fn&& __f, _Tuple&& __t)
    2295              :     noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>)
    2296              :     {
    2297              :       using _Indices
    2298              :         = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>;
    2299              :       return std::__apply_impl(std::forward<_Fn>(__f),
    2300              :                                std::forward<_Tuple>(__t),
    2301              :                                _Indices{});
    2302              :     }
    2303              : 
    2304              : #define __cpp_lib_make_from_tuple  201606L
    2305              : 
    2306              :   template <typename _Tp, typename _Tuple, size_t... _Idx>
    2307              :     constexpr _Tp
    2308              :     __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
    2309              :     { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
    2310              : 
    2311              :   template <typename _Tp, typename _Tuple>
    2312              :     constexpr _Tp
    2313              :     make_from_tuple(_Tuple&& __t)
    2314              :     noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)
    2315              :     {
    2316              :       constexpr size_t __n = tuple_size_v<remove_reference_t<_Tuple>>;
    2317              : #if __has_builtin(__reference_constructs_from_temporary)
    2318              :       if constexpr (__n == 1)
    2319              :         {
    2320              :           using _Elt = decltype(std::get<0>(std::declval<_Tuple>()));
    2321              :           static_assert(!__reference_constructs_from_temporary(_Tp, _Elt));
    2322              :         }
    2323              : #endif
    2324              :       return __make_from_tuple_impl<_Tp>(std::forward<_Tuple>(__t),
    2325              :                                          make_index_sequence<__n>{});
    2326              :     }
    2327              : #endif // C++17
    2328              : 
    2329              : #if __cplusplus > 202002L
    2330              :   template<typename... _TTypes, typename... _UTypes,
    2331              :            template<typename> class _TQual, template<typename> class _UQual>
    2332              :     requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; }
    2333              :   struct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual>
    2334              :   { using type = tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; };
    2335              : 
    2336              :   template<typename... _TTypes, typename... _UTypes>
    2337              :     requires requires { typename tuple<common_type_t<_TTypes, _UTypes>...>; }
    2338              :   struct common_type<tuple<_TTypes...>, tuple<_UTypes...>>
    2339              :   { using type = tuple<common_type_t<_TTypes, _UTypes>...>; };
    2340              : #endif // C++23
    2341              : 
    2342              :   /// @}
    2343              : 
    2344              : _GLIBCXX_END_NAMESPACE_VERSION
    2345              : } // namespace std
    2346              : 
    2347              : #endif // C++11
    2348              : 
    2349              : #endif // _GLIBCXX_TUPLE
        

Generated by: LCOV version 2.0-1