LCOV - code coverage report
Current view: top level - /usr/include/c++/14 - tuple (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 28 28
Test Date: 2026-02-27 05:14:50 Functions: 75.8 % 95 72
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // <tuple> -*- C++ -*-
       2              : 
       3              : // Copyright (C) 2007-2024 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              : #endif
      46              : 
      47              : #define __glibcxx_want_constexpr_tuple
      48              : #define __glibcxx_want_tuple_element_t
      49              : #define __glibcxx_want_tuples_by_type
      50              : #define __glibcxx_want_apply
      51              : #define __glibcxx_want_make_from_tuple
      52              : #define __glibcxx_want_ranges_zip
      53              : #define __glibcxx_want_tuple_like
      54              : #include <bits/version.h>
      55              : 
      56              : namespace std _GLIBCXX_VISIBILITY(default)
      57              : {
      58              : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      59              : 
      60              :   /**
      61              :    *  @addtogroup utilities
      62              :    *  @{
      63              :    */
      64              : 
      65              :   template<typename... _Elements>
      66              :     class tuple;
      67              : 
      68              :   /// @cond undocumented
      69              :   template<typename _Tp>
      70              :     struct __is_empty_non_tuple : is_empty<_Tp> { };
      71              : 
      72              :   // Using EBO for elements that are tuples causes ambiguous base errors.
      73              :   template<typename _El0, typename... _El>
      74              :     struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
      75              : 
      76              :   // Use the Empty Base-class Optimization for empty, non-final types.
      77              :   template<typename _Tp>
      78              :     using __empty_not_final
      79              :     = __conditional_t<__is_final(_Tp), false_type,
      80              :               __is_empty_non_tuple<_Tp>>;
      81              : 
      82              :   template<size_t _Idx, typename _Head,
      83              :        bool = __empty_not_final<_Head>::value>
      84              :     struct _Head_base;
      85              : 
      86              : #if __has_cpp_attribute(__no_unique_address__)
      87              :   template<size_t _Idx, typename _Head>
      88              :     struct _Head_base<_Idx, _Head, true>
      89              :     {
      90         1213 :       constexpr _Head_base()
      91         1213 :       : _M_head_impl() { }
      92              : 
      93              :       constexpr _Head_base(const _Head& __h)
      94              :       : _M_head_impl(__h) { }
      95              : 
      96              :       constexpr _Head_base(const _Head_base&) = default;
      97              :       constexpr _Head_base(_Head_base&&) = default;
      98              : 
      99              :       template<typename _UHead>
     100              :     constexpr _Head_base(_UHead&& __h)
     101              :     : _M_head_impl(std::forward<_UHead>(__h)) { }
     102              : 
     103              :       _GLIBCXX20_CONSTEXPR
     104              :       _Head_base(allocator_arg_t, __uses_alloc0)
     105              :       : _M_head_impl() { }
     106              : 
     107              :       template<typename _Alloc>
     108              :     _GLIBCXX20_CONSTEXPR
     109              :     _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
     110              :     : _M_head_impl(allocator_arg, *__a._M_a) { }
     111              : 
     112              :       template<typename _Alloc>
     113              :     _GLIBCXX20_CONSTEXPR
     114              :     _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
     115              :     : _M_head_impl(*__a._M_a) { }
     116              : 
     117              :       template<typename _UHead>
     118              :     _GLIBCXX20_CONSTEXPR
     119              :     _Head_base(__uses_alloc0, _UHead&& __uhead)
     120              :     : _M_head_impl(std::forward<_UHead>(__uhead)) { }
     121              : 
     122              :       template<typename _Alloc, typename _UHead>
     123              :     _GLIBCXX20_CONSTEXPR
     124              :     _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
     125              :     : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
     126              :     { }
     127              : 
     128              :       template<typename _Alloc, typename _UHead>
     129              :     _GLIBCXX20_CONSTEXPR
     130              :     _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
     131              :     : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
     132              : 
     133              :       static constexpr _Head&
     134          243 :       _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
     135              : 
     136              :       static constexpr const _Head&
     137              :       _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
     138              : 
     139              :       [[__no_unique_address__]] _Head _M_head_impl;
     140              :     };
     141              : #else
     142              :   template<size_t _Idx, typename _Head>
     143              :     struct _Head_base<_Idx, _Head, true>
     144              :     : public _Head
     145              :     {
     146              :       constexpr _Head_base()
     147              :       : _Head() { }
     148              : 
     149              :       constexpr _Head_base(const _Head& __h)
     150              :       : _Head(__h) { }
     151              : 
     152              :       constexpr _Head_base(const _Head_base&) = default;
     153              :       constexpr _Head_base(_Head_base&&) = default;
     154              : 
     155              :       template<typename _UHead>
     156              :         constexpr _Head_base(_UHead&& __h)
     157              :     : _Head(std::forward<_UHead>(__h)) { }
     158              : 
     159              :       _GLIBCXX20_CONSTEXPR
     160              :       _Head_base(allocator_arg_t, __uses_alloc0)
     161              :       : _Head() { }
     162              : 
     163              :       template<typename _Alloc>
     164              :     _GLIBCXX20_CONSTEXPR
     165              :     _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
     166              :     : _Head(allocator_arg, *__a._M_a) { }
     167              : 
     168              :       template<typename _Alloc>
     169              :     _GLIBCXX20_CONSTEXPR
     170              :     _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
     171              :     : _Head(*__a._M_a) { }
     172              : 
     173              :       template<typename _UHead>
     174              :     _GLIBCXX20_CONSTEXPR
     175              :     _Head_base(__uses_alloc0, _UHead&& __uhead)
     176              :     : _Head(std::forward<_UHead>(__uhead)) { }
     177              : 
     178              :       template<typename _Alloc, typename _UHead>
     179              :     _GLIBCXX20_CONSTEXPR
     180              :     _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
     181              :     : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
     182              : 
     183              :       template<typename _Alloc, typename _UHead>
     184              :     _GLIBCXX20_CONSTEXPR
     185              :     _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
     186              :     : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
     187              : 
     188              :       static constexpr _Head&
     189              :       _M_head(_Head_base& __b) noexcept { return __b; }
     190              : 
     191              :       static constexpr const _Head&
     192              :       _M_head(const _Head_base& __b) noexcept { return __b; }
     193              :     };
     194              : #endif
     195              : 
     196              :   template<size_t _Idx, typename _Head>
     197              :     struct _Head_base<_Idx, _Head, false>
     198              :     {
     199         1213 :       constexpr _Head_base()
     200         1213 :       : _M_head_impl() { }
     201              : 
     202              :       constexpr _Head_base(const _Head& __h)
     203              :       : _M_head_impl(__h) { }
     204              : 
     205              :       constexpr _Head_base(const _Head_base&) = default;
     206              :       constexpr _Head_base(_Head_base&&) = default;
     207              : 
     208              :       template<typename _UHead>
     209              :         constexpr _Head_base(_UHead&& __h)
     210              :     : _M_head_impl(std::forward<_UHead>(__h)) { }
     211              : 
     212              :       _GLIBCXX20_CONSTEXPR
     213              :       _Head_base(allocator_arg_t, __uses_alloc0)
     214              :       : _M_head_impl() { }
     215              : 
     216              :       template<typename _Alloc>
     217              :     _GLIBCXX20_CONSTEXPR
     218              :     _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
     219              :     : _M_head_impl(allocator_arg, *__a._M_a) { }
     220              : 
     221              :       template<typename _Alloc>
     222              :     _GLIBCXX20_CONSTEXPR
     223              :     _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
     224              :     : _M_head_impl(*__a._M_a) { }
     225              : 
     226              :       template<typename _UHead>
     227              :     _GLIBCXX20_CONSTEXPR
     228              :     _Head_base(__uses_alloc0, _UHead&& __uhead)
     229              :     : _M_head_impl(std::forward<_UHead>(__uhead)) { }
     230              : 
     231              :       template<typename _Alloc, typename _UHead>
     232              :     _GLIBCXX20_CONSTEXPR
     233              :     _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
     234              :     : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
     235              :     { }
     236              : 
     237              :       template<typename _Alloc, typename _UHead>
     238              :     _GLIBCXX20_CONSTEXPR
     239              :     _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
     240              :     : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
     241              : 
     242              :       static constexpr _Head&
     243        11117 :       _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
     244              : 
     245              :       static constexpr const _Head&
     246        10965 :       _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
     247              : 
     248              :       _Head _M_head_impl;
     249              :     };
     250              : 
     251              : #if __cpp_lib_tuple_like // >= C++23
     252              :   struct __tuple_like_tag_t { explicit __tuple_like_tag_t() = default; };
     253              : 
     254              :   // These forward declarations are used by the operator<=> overload for
     255              :   // tuple-like types.
     256              :   template<typename _Cat, typename _Tp, typename _Up>
     257              :     constexpr _Cat
     258              :     __tuple_cmp(const _Tp&, const _Up&, index_sequence<>);
     259              : 
     260              :   template<typename _Cat, typename _Tp, typename _Up,
     261              :        size_t _Idx0, size_t... _Idxs>
     262              :     constexpr _Cat
     263              :     __tuple_cmp(const _Tp& __t, const _Up& __u,
     264              :         index_sequence<_Idx0, _Idxs...>);
     265              : #endif // C++23
     266              : 
     267              :   /**
     268              :    * Contains the actual implementation of the @c tuple template, stored
     269              :    * as a recursive inheritance hierarchy from the first element (most
     270              :    * derived class) to the last (least derived class). The @c Idx
     271              :    * parameter gives the 0-based index of the element stored at this
     272              :    * point in the hierarchy; we use it to implement a constant-time
     273              :    * get() operation.
     274              :    */
     275              :   template<size_t _Idx, typename... _Elements>
     276              :     struct _Tuple_impl;
     277              : 
     278              :   /**
     279              :    * Recursive tuple implementation. Here we store the @c Head element
     280              :    * and derive from a @c Tuple_impl containing the remaining elements
     281              :    * (which contains the @c Tail).
     282              :    */
     283              :   template<size_t _Idx, typename _Head, typename... _Tail>
     284              :     struct _Tuple_impl<_Idx, _Head, _Tail...>
     285              :     : public _Tuple_impl<_Idx + 1, _Tail...>,
     286              :       private _Head_base<_Idx, _Head>
     287              :     {
     288              :       template<size_t, typename...> friend struct _Tuple_impl;
     289              : 
     290              :       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
     291              :       typedef _Head_base<_Idx, _Head> _Base;
     292              : 
     293              :       static constexpr _Head&
     294        11117 :       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     295              : 
     296              :       static constexpr const _Head&
     297        10965 :       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     298              : 
     299              :       static constexpr _Inherited&
     300              :       _M_tail(_Tuple_impl& __t) noexcept { return __t; }
     301              : 
     302              :       static constexpr const _Inherited&
     303              :       _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
     304              : 
     305         1213 :       constexpr _Tuple_impl()
     306         1213 :       : _Inherited(), _Base() { }
     307              : 
     308              :       explicit constexpr
     309              :       _Tuple_impl(const _Head& __head, const _Tail&... __tail)
     310              :       : _Inherited(__tail...), _Base(__head)
     311              :       { }
     312              : 
     313              :       template<typename _UHead, typename... _UTail,
     314              :            typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>>
     315              :     explicit constexpr
     316              :     _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
     317              :     : _Inherited(std::forward<_UTail>(__tail)...),
     318              :       _Base(std::forward<_UHead>(__head))
     319              :     { }
     320              : 
     321              :       constexpr _Tuple_impl(const _Tuple_impl&) = default;
     322              : 
     323              :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
     324              :       // 2729. Missing SFINAE on std::pair::operator=
     325              :       _Tuple_impl& operator=(const _Tuple_impl&) = delete;
     326              : 
     327         4283 :       _Tuple_impl(_Tuple_impl&&) = default;
     328              : 
     329              :       template<typename... _UElements>
     330              :     constexpr
     331              :     _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
     332              :     : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
     333              :       _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in))
     334              :     { }
     335              : 
     336              :       template<typename _UHead, typename... _UTails>
     337              :     constexpr
     338              :     _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     339              :     : _Inherited(std::move
     340              :              (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
     341              :       _Base(std::forward<_UHead>
     342              :         (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
     343              :     { }
     344              : 
     345              : #if __cpp_lib_ranges_zip // >= C++23
     346              :       template<typename... _UElements>
     347              :     constexpr
     348              :     _Tuple_impl(_Tuple_impl<_Idx, _UElements...>& __in)
     349              :     : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
     350              :       _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in))
     351              :     { }
     352              : 
     353              :       template<typename _UHead, typename... _UTails>
     354              :     constexpr
     355              :     _Tuple_impl(const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     356              :     : _Inherited(std::move
     357              :              (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
     358              :       _Base(std::forward<const _UHead>
     359              :         (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
     360              :     { }
     361              : #endif // C++23
     362              : 
     363              : #if __cpp_lib_tuple_like // >= C++23
     364              :       template<typename _UTuple, size_t... _Is>
     365              :     constexpr
     366              :     _Tuple_impl(__tuple_like_tag_t, _UTuple&& __u, index_sequence<_Is...>)
     367              :     : _Tuple_impl(std::get<_Is>(std::forward<_UTuple>(__u))...)
     368              :     { }
     369              : #endif // C++23
     370              : 
     371              :       template<typename _Alloc>
     372              :     _GLIBCXX20_CONSTEXPR
     373              :     _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
     374              :     : _Inherited(__tag, __a),
     375              :       _Base(__tag, __use_alloc<_Head>(__a))
     376              :     { }
     377              : 
     378              :       template<typename _Alloc>
     379              :     _GLIBCXX20_CONSTEXPR
     380              :     _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     381              :             const _Head& __head, const _Tail&... __tail)
     382              :     : _Inherited(__tag, __a, __tail...),
     383              :       _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head)
     384              :     { }
     385              : 
     386              :       template<typename _Alloc, typename _UHead, typename... _UTail,
     387              :            typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>>
     388              :     _GLIBCXX20_CONSTEXPR
     389              :     _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     390              :             _UHead&& __head, _UTail&&... __tail)
     391              :     : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
     392              :       _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
     393              :         std::forward<_UHead>(__head))
     394              :     { }
     395              : 
     396              :       template<typename _Alloc>
     397              :     _GLIBCXX20_CONSTEXPR
     398              :     _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     399              :             const _Tuple_impl& __in)
     400              :     : _Inherited(__tag, __a, _M_tail(__in)),
     401              :       _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in))
     402              :     { }
     403              : 
     404              :       template<typename _Alloc>
     405              :     _GLIBCXX20_CONSTEXPR
     406              :     _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     407              :             _Tuple_impl&& __in)
     408              :     : _Inherited(__tag, __a, std::move(_M_tail(__in))),
     409              :       _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
     410              :         std::forward<_Head>(_M_head(__in)))
     411              :     { }
     412              : 
     413              :       template<typename _Alloc, typename _UHead, typename... _UTails>
     414              :     _GLIBCXX20_CONSTEXPR
     415              :     _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     416              :             const _Tuple_impl<_Idx, _UHead, _UTails...>& __in)
     417              :     : _Inherited(__tag, __a,
     418              :              _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),
     419              :       _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
     420              :         _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))
     421              :     { }
     422              : 
     423              :       template<typename _Alloc, typename _UHead, typename... _UTails>
     424              :     _GLIBCXX20_CONSTEXPR
     425              :     _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     426              :             _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     427              :     : _Inherited(__tag, __a, std::move
     428              :              (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
     429              :       _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
     430              :         std::forward<_UHead>
     431              :         (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
     432              :     { }
     433              : 
     434              : #if __cpp_lib_ranges_zip // >= C++23
     435              :       template<typename _Alloc, typename _UHead, typename... _UTails>
     436              :     constexpr
     437              :     _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     438              :             _Tuple_impl<_Idx, _UHead, _UTails...>& __in)
     439              :     : _Inherited(__tag, __a,
     440              :              _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),
     441              :       _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a),
     442              :         _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))
     443              :     { }
     444              : 
     445              :       template<typename _Alloc, typename _UHead, typename... _UTails>
     446              :     constexpr
     447              :     _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     448              :             const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     449              :     : _Inherited(__tag, __a, std::move
     450              :              (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
     451              :       _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a),
     452              :         std::forward<const _UHead>
     453              :         (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
     454              :     { }
     455              : #endif // C++23
     456              : 
     457              : #if __cpp_lib_tuple_like // >= C++23
     458              :       template<typename _Alloc, typename _UTuple, size_t... _Is>
     459              :     constexpr
     460              :     _Tuple_impl(__tuple_like_tag_t, allocator_arg_t __tag, const _Alloc& __a,
     461              :             _UTuple&& __u, index_sequence<_Is...>)
     462              :     : _Tuple_impl(__tag, __a, std::get<_Is>(std::forward<_UTuple>(__u))...)
     463              :     { }
     464              : #endif // C++23
     465              : 
     466              :       template<typename... _UElements>
     467              :     _GLIBCXX20_CONSTEXPR
     468              :     void
     469              :     _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in)
     470              :     {
     471              :       _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
     472              :       _M_tail(*this)._M_assign(
     473              :           _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
     474              :     }
     475              : 
     476              :       template<typename _UHead, typename... _UTails>
     477              :     _GLIBCXX20_CONSTEXPR
     478              :     void
     479              :     _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     480              :     {
     481              :       _M_head(*this) = std::forward<_UHead>
     482              :         (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
     483              :       _M_tail(*this)._M_assign(
     484              :           std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
     485              :     }
     486              : 
     487              : #if __cpp_lib_ranges_zip // >= C++23
     488              :       template<typename... _UElements>
     489              :     constexpr void
     490              :     _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in) const
     491              :     {
     492              :       _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
     493              :       _M_tail(*this)._M_assign(
     494              :           _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
     495              :     }
     496              : 
     497              :       template<typename _UHead, typename... _UTails>
     498              :     constexpr void
     499              :     _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) const
     500              :     {
     501              :       _M_head(*this) = std::forward<_UHead>
     502              :         (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
     503              :       _M_tail(*this)._M_assign(
     504              :           std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
     505              :     }
     506              : #endif // C++23
     507              : 
     508              : #if __cpp_lib_tuple_like // >= C++23
     509              :       template<typename _UTuple>
     510              :     constexpr void
     511              :     _M_assign(__tuple_like_tag_t __tag, _UTuple&& __u)
     512              :     {
     513              :       _M_head(*this) = std::get<_Idx>(std::forward<_UTuple>(__u));
     514              :       _M_tail(*this)._M_assign(__tag, std::forward<_UTuple>(__u));
     515              :     }
     516              : 
     517              :       template<typename _UTuple>
     518              :     constexpr void
     519              :     _M_assign(__tuple_like_tag_t __tag, _UTuple&& __u) const
     520              :     {
     521              :       _M_head(*this) = std::get<_Idx>(std::forward<_UTuple>(__u));
     522              :       _M_tail(*this)._M_assign(__tag, std::forward<_UTuple>(__u));
     523              :     }
     524              : #endif // C++23
     525              : 
     526              :     protected:
     527              :       _GLIBCXX20_CONSTEXPR
     528              :       void
     529              :       _M_swap(_Tuple_impl& __in)
     530              :       {
     531              :     using std::swap;
     532              :     swap(_M_head(*this), _M_head(__in));
     533              :     _Inherited::_M_swap(_M_tail(__in));
     534              :       }
     535              : 
     536              : #if __cpp_lib_ranges_zip // >= C++23
     537              :       constexpr void
     538              :       _M_swap(const _Tuple_impl& __in) const
     539              :       {
     540              :     using std::swap;
     541              :     swap(_M_head(*this), _M_head(__in));
     542              :     _Inherited::_M_swap(_M_tail(__in));
     543              :       }
     544              : #endif // C++23
     545              :     };
     546              : 
     547              :   // Basis case of inheritance recursion.
     548              :   template<size_t _Idx, typename _Head>
     549              :     struct _Tuple_impl<_Idx, _Head>
     550              :     : private _Head_base<_Idx, _Head>
     551              :     {
     552              :       template<size_t, typename...> friend struct _Tuple_impl;
     553              : 
     554              :       typedef _Head_base<_Idx, _Head> _Base;
     555              : 
     556              :       static constexpr _Head&
     557          243 :       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     558              : 
     559              :       static constexpr const _Head&
     560              :       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     561              : 
     562              :       constexpr
     563         1213 :       _Tuple_impl()
     564         1213 :       : _Base() { }
     565              : 
     566              :       explicit constexpr
     567              :       _Tuple_impl(const _Head& __head)
     568              :       : _Base(__head)
     569              :       { }
     570              : 
     571              :       template<typename _UHead>
     572              :     explicit constexpr
     573              :     _Tuple_impl(_UHead&& __head)
     574              :     : _Base(std::forward<_UHead>(__head))
     575              :     { }
     576              : 
     577              :       constexpr _Tuple_impl(const _Tuple_impl&) = default;
     578              : 
     579              :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
     580              :       // 2729. Missing SFINAE on std::pair::operator=
     581              :       _Tuple_impl& operator=(const _Tuple_impl&) = delete;
     582              : 
     583              : #if _GLIBCXX_INLINE_VERSION
     584              :       _Tuple_impl(_Tuple_impl&&) = default;
     585              : #else
     586              :       constexpr
     587         4283 :       _Tuple_impl(_Tuple_impl&& __in)
     588              :       noexcept(is_nothrow_move_constructible<_Head>::value)
     589              :       : _Base(static_cast<_Base&&>(__in))
     590         4283 :       { }
     591              : #endif
     592              : 
     593              :       template<typename _UHead>
     594              :     constexpr
     595              :     _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
     596              :     : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in))
     597              :     { }
     598              : 
     599              :       template<typename _UHead>
     600              :     constexpr
     601              :     _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
     602              :     : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
     603              :     { }
     604              : 
     605              : #if __cpp_lib_ranges_zip // >= C++23
     606              :       template<typename _UHead>
     607              :     constexpr
     608              :     _Tuple_impl(_Tuple_impl<_Idx, _UHead>& __in)
     609              :     : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in))
     610              :     { }
     611              : 
     612              :       template<typename _UHead>
     613              :     constexpr
     614              :     _Tuple_impl(const _Tuple_impl<_Idx, _UHead>&& __in)
     615              :     : _Base(std::forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
     616              :     { }
     617              : #endif // C++23
     618              : 
     619              : #if __cpp_lib_tuple_like // >= C++23
     620              :       template<typename _UTuple>
     621              :     constexpr
     622              :     _Tuple_impl(__tuple_like_tag_t, _UTuple&& __u, index_sequence<0>)
     623              :     : _Tuple_impl(std::get<0>(std::forward<_UTuple>(__u)))
     624              :     { }
     625              : #endif // C++23
     626              : 
     627              :       template<typename _Alloc>
     628              :     _GLIBCXX20_CONSTEXPR
     629              :     _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
     630              :     : _Base(__tag, __use_alloc<_Head>(__a))
     631              :     { }
     632              : 
     633              :       template<typename _Alloc>
     634              :     _GLIBCXX20_CONSTEXPR
     635              :     _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     636              :             const _Head& __head)
     637              :     : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), __head)
     638              :     { }
     639              : 
     640              :       template<typename _Alloc, typename _UHead>
     641              :     _GLIBCXX20_CONSTEXPR
     642              :     _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     643              :             _UHead&& __head)
     644              :     : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
     645              :         std::forward<_UHead>(__head))
     646              :     { }
     647              : 
     648              :       template<typename _Alloc>
     649              :     _GLIBCXX20_CONSTEXPR
     650              :     _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     651              :             const _Tuple_impl& __in)
     652              :     : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), _M_head(__in))
     653              :     { }
     654              : 
     655              :       template<typename _Alloc>
     656              :     _GLIBCXX20_CONSTEXPR
     657              :     _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     658              :             _Tuple_impl&& __in)
     659              :     : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
     660              :         std::forward<_Head>(_M_head(__in)))
     661              :     { }
     662              : 
     663              :       template<typename _Alloc, typename _UHead>
     664              :     _GLIBCXX20_CONSTEXPR
     665              :     _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     666              :             const _Tuple_impl<_Idx, _UHead>& __in)
     667              :     : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
     668              :         _Tuple_impl<_Idx, _UHead>::_M_head(__in))
     669              :     { }
     670              : 
     671              :       template<typename _Alloc, typename _UHead>
     672              :     _GLIBCXX20_CONSTEXPR
     673              :     _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     674              :             _Tuple_impl<_Idx, _UHead>&& __in)
     675              :     : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
     676              :         std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
     677              :     { }
     678              : 
     679              : #if __cpp_lib_ranges_zip // >= C++23
     680              :       template<typename _Alloc, typename _UHead>
     681              :     constexpr
     682              :     _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     683              :             _Tuple_impl<_Idx, _UHead>& __in)
     684              :     : _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a),
     685              :         _Tuple_impl<_Idx, _UHead>::_M_head(__in))
     686              :     { }
     687              : 
     688              :       template<typename _Alloc, typename _UHead>
     689              :     constexpr
     690              :     _Tuple_impl(allocator_arg_t, const _Alloc& __a,
     691              :             const _Tuple_impl<_Idx, _UHead>&& __in)
     692              :     : _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a),
     693              :         std::forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
     694              :     { }
     695              : #endif // C++23
     696              : 
     697              : #if __cpp_lib_tuple_like // >= C++23
     698              :       template<typename _Alloc, typename _UTuple>
     699              :     constexpr
     700              :     _Tuple_impl(__tuple_like_tag_t, allocator_arg_t __tag, const _Alloc& __a,
     701              :             _UTuple&& __u, index_sequence<0>)
     702              :     : _Tuple_impl(__tag, __a, std::get<0>(std::forward<_UTuple>(__u)))
     703              :     { }
     704              : #endif // C++23
     705              : 
     706              :       template<typename _UHead>
     707              :     _GLIBCXX20_CONSTEXPR
     708              :     void
     709              :     _M_assign(const _Tuple_impl<_Idx, _UHead>& __in)
     710              :     {
     711              :       _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
     712              :     }
     713              : 
     714              :       template<typename _UHead>
     715              :     _GLIBCXX20_CONSTEXPR
     716              :     void
     717              :     _M_assign(_Tuple_impl<_Idx, _UHead>&& __in)
     718              :     {
     719              :       _M_head(*this)
     720              :         = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
     721              :     }
     722              : 
     723              : #if __cpp_lib_ranges_zip // >= C++23
     724              :       template<typename _UHead>
     725              :     constexpr void
     726              :     _M_assign(const _Tuple_impl<_Idx, _UHead>& __in) const
     727              :     {
     728              :       _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
     729              :     }
     730              : 
     731              :       template<typename _UHead>
     732              :     constexpr void
     733              :     _M_assign(_Tuple_impl<_Idx, _UHead>&& __in) const
     734              :     {
     735              :       _M_head(*this)
     736              :         = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
     737              :     }
     738              : #endif // C++23
     739              : 
     740              : #if __cpp_lib_tuple_like // >= C++23
     741              :     template<typename _UTuple>
     742              :       constexpr void
     743              :       _M_assign(__tuple_like_tag_t, _UTuple&& __u)
     744              :       { _M_head(*this) = std::get<_Idx>(std::forward<_UTuple>(__u)); }
     745              : 
     746              :     template<typename _UTuple>
     747              :       constexpr void
     748              :       _M_assign(__tuple_like_tag_t, _UTuple&& __u) const
     749              :       { _M_head(*this) = std::get<_Idx>(std::forward<_UTuple>(__u)); }
     750              : #endif // C++23
     751              : 
     752              :     protected:
     753              :       _GLIBCXX20_CONSTEXPR
     754              :       void
     755              :       _M_swap(_Tuple_impl& __in)
     756              :       {
     757              :     using std::swap;
     758              :     swap(_M_head(*this), _M_head(__in));
     759              :       }
     760              : 
     761              : #if __cpp_lib_ranges_zip // >= C++23
     762              :       constexpr void
     763              :       _M_swap(const _Tuple_impl& __in) const
     764              :       {
     765              :     using std::swap;
     766              :     swap(_M_head(*this), _M_head(__in));
     767              :       }
     768              : #endif // C++23
     769              :     };
     770              : 
     771              :   // Concept utility functions, reused in conditionally-explicit
     772              :   // constructors.
     773              :   template<bool, typename... _Types>
     774              :     struct _TupleConstraints
     775              :     {
     776              :       template<typename... _UTypes>
     777              :     using __constructible = __and_<is_constructible<_Types, _UTypes>...>;
     778              : 
     779              :       template<typename... _UTypes>
     780              :     using __convertible = __and_<is_convertible<_UTypes, _Types>...>;
     781              : 
     782              :       // Constraint for a non-explicit constructor.
     783              :       // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
     784              :       // and every Ui is implicitly convertible to Ti.
     785              :       template<typename... _UTypes>
     786              :     static constexpr bool __is_implicitly_constructible()
     787              :     {
     788              :       return __and_<__constructible<_UTypes...>,
     789              :             __convertible<_UTypes...>
     790              :             >::value;
     791              :     }
     792              : 
     793              :       // Constraint for a non-explicit constructor.
     794              :       // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
     795              :       // but not every Ui is implicitly convertible to Ti.
     796              :       template<typename... _UTypes>
     797              :     static constexpr bool __is_explicitly_constructible()
     798              :     {
     799              :       return __and_<__constructible<_UTypes...>,
     800              :             __not_<__convertible<_UTypes...>>
     801              :             >::value;
     802              :     }
     803              : 
     804              :       static constexpr bool __is_implicitly_default_constructible()
     805              :       {
     806              :     return __and_<std::__is_implicitly_default_constructible<_Types>...
     807              :               >::value;
     808              :       }
     809              : 
     810              :       static constexpr bool __is_explicitly_default_constructible()
     811              :       {
     812              :     return __and_<is_default_constructible<_Types>...,
     813              :               __not_<__and_<
     814              :             std::__is_implicitly_default_constructible<_Types>...>
     815              :               >>::value;
     816              :       }
     817              :     };
     818              : 
     819              :   // Partial specialization used when a required precondition isn't met,
     820              :   // e.g. when sizeof...(_Types) != sizeof...(_UTypes).
     821              :   template<typename... _Types>
     822              :     struct _TupleConstraints<false, _Types...>
     823              :     {
     824              :       template<typename... _UTypes>
     825              :     static constexpr bool __is_implicitly_constructible()
     826              :     { return false; }
     827              : 
     828              :       template<typename... _UTypes>
     829              :     static constexpr bool __is_explicitly_constructible()
     830              :     { return false; }
     831              :     };
     832              :   /// @endcond
     833              : 
     834              :   /// Primary class template, tuple
     835              :   template<typename... _Elements>
     836              :     class tuple : public _Tuple_impl<0, _Elements...>
     837              :     {
     838              :       using _Inherited = _Tuple_impl<0, _Elements...>;
     839              : 
     840              : #if __cpp_concepts && __cpp_consteval && __cpp_conditional_explicit // >= C++20
     841              :       template<typename... _UTypes>
     842              :     static consteval bool
     843              :     __constructible()
     844              :     {
     845              :       if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))
     846              :         return __and_v<is_constructible<_Elements, _UTypes>...>;
     847              :       else
     848              :         return false;
     849              :     }
     850              : 
     851              :       template<typename... _UTypes>
     852              :     static consteval bool
     853              :     __nothrow_constructible()
     854              :     {
     855              :       if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))
     856              :         return __and_v<is_nothrow_constructible<_Elements, _UTypes>...>;
     857              :       else
     858              :         return false;
     859              :     }
     860              : 
     861              :       template<typename... _UTypes>
     862              :     static consteval bool
     863              :     __convertible()
     864              :     {
     865              :       if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))
     866              :         return __and_v<is_convertible<_UTypes, _Elements>...>;
     867              :       else
     868              :         return false;
     869              :     }
     870              : 
     871              :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
     872              :       // 3121. tuple constructor constraints for UTypes&&... overloads
     873              :       template<typename... _UTypes>
     874              :     static consteval bool
     875              :     __disambiguating_constraint()
     876              :     {
     877              :       if constexpr (sizeof...(_Elements) != sizeof...(_UTypes))
     878              :         return false;
     879              :       else if constexpr (sizeof...(_Elements) == 1)
     880              :         {
     881              :           using _U0 = typename _Nth_type<0, _UTypes...>::type;
     882              :           return !is_same_v<remove_cvref_t<_U0>, tuple>;
     883              :         }
     884              :       else if constexpr (sizeof...(_Elements) < 4)
     885              :         {
     886              :           using _U0 = typename _Nth_type<0, _UTypes...>::type;
     887              :           if constexpr (!is_same_v<remove_cvref_t<_U0>, allocator_arg_t>)
     888              :         return true;
     889              :           else
     890              :         {
     891              :           using _T0 = typename _Nth_type<0, _Elements...>::type;
     892              :           return is_same_v<remove_cvref_t<_T0>, allocator_arg_t>;
     893              :         }
     894              :         }
     895              :       return true;
     896              :     }
     897              : 
     898              :       // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1
     899              :       // and the single element in Types can be initialized from TUPLE,
     900              :       // or is the same type as tuple_element_t<0, TUPLE>.
     901              :       template<typename _Tuple>
     902              :     static consteval bool
     903              :     __use_other_ctor()
     904              :     {
     905              :       if constexpr (sizeof...(_Elements) != 1)
     906              :         return false;
     907              :       else if constexpr (is_same_v<remove_cvref_t<_Tuple>, tuple>)
     908              :         return true; // Should use a copy/move constructor instead.
     909              :       else
     910              :         {
     911              :           using _Tp = typename _Nth_type<0, _Elements...>::type;
     912              :           if constexpr (is_convertible_v<_Tuple, _Tp>)
     913              :         return true;
     914              :           else if constexpr (is_constructible_v<_Tp, _Tuple>)
     915              :         return true;
     916              :         }
     917              :       return false;
     918              :     }
     919              : 
     920              :       template<typename... _Up>
     921              :     static consteval bool
     922              :     __dangles()
     923              :     {
     924              : #if __has_builtin(__reference_constructs_from_temporary)
     925              :       return (__reference_constructs_from_temporary(_Elements, _Up&&)
     926              :             || ...);
     927              : #else
     928              :       return false;
     929              : #endif
     930              :     }
     931              : 
     932              : #if __cpp_lib_tuple_like // >= C++23
     933              :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
     934              :       // 4045. tuple can create dangling references from tuple-like
     935              :       template<typename _UTuple>
     936              :     static consteval bool
     937              :     __dangles_from_tuple_like()
     938              :     {
     939              :       return []<size_t... _Is>(index_sequence<_Is...>) {
     940              :         return __dangles<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
     941              :       }(index_sequence_for<_Elements...>{});
     942              :     }
     943              : 
     944              :       template<typename _UTuple>
     945              :     static consteval bool
     946              :     __constructible_from_tuple_like()
     947              :     {
     948              :       return []<size_t... _Is>(index_sequence<_Is...>) {
     949              :         return __constructible<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
     950              :       }(index_sequence_for<_Elements...>{});
     951              :     }
     952              : 
     953              :       template<typename _UTuple>
     954              :     static consteval bool
     955              :     __convertible_from_tuple_like()
     956              :     {
     957              :       return []<size_t... _Is>(index_sequence<_Is...>) {
     958              :         return __convertible<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
     959              :       }(index_sequence_for<_Elements...>{});
     960              :     }
     961              : #endif // C++23
     962              : 
     963              :     public:
     964              :       constexpr
     965              :       explicit(!(__is_implicitly_default_constructible_v<_Elements> && ...))
     966              :       tuple()
     967              :       noexcept((is_nothrow_default_constructible_v<_Elements> && ...))
     968              :       requires (is_default_constructible_v<_Elements> && ...)
     969              :       : _Inherited()
     970              :       { }
     971              : 
     972              :       constexpr explicit(!__convertible<const _Elements&...>())
     973              :       tuple(const _Elements&... __elements)
     974              :       noexcept(__nothrow_constructible<const _Elements&...>())
     975              :       requires (__constructible<const _Elements&...>())
     976              :       : _Inherited(__elements...)
     977              :       { }
     978              : 
     979              :       template<typename... _UTypes>
     980              :     requires (__disambiguating_constraint<_UTypes...>())
     981              :       && (__constructible<_UTypes...>())
     982              :       && (!__dangles<_UTypes...>())
     983              :     constexpr explicit(!__convertible<_UTypes...>())
     984              :     tuple(_UTypes&&... __u)
     985              :     noexcept(__nothrow_constructible<_UTypes...>())
     986              :     : _Inherited(std::forward<_UTypes>(__u)...)
     987              :     { }
     988              : 
     989              :       template<typename... _UTypes>
     990              :     requires (__disambiguating_constraint<_UTypes...>())
     991              :       && (__constructible<_UTypes...>())
     992              :       && (__dangles<_UTypes...>())
     993              :     tuple(_UTypes&&...) = delete;
     994              : 
     995              :       constexpr tuple(const tuple&) = default;
     996              : 
     997              :       constexpr tuple(tuple&&) = default;
     998              : 
     999              :       template<typename... _UTypes>
    1000              :     requires (__constructible<const _UTypes&...>())
    1001              :       && (!__use_other_ctor<const tuple<_UTypes...>&>())
    1002              :       && (!__dangles<const _UTypes&...>())
    1003              :     constexpr explicit(!__convertible<const _UTypes&...>())
    1004              :     tuple(const tuple<_UTypes...>& __u)
    1005              :     noexcept(__nothrow_constructible<const _UTypes&...>())
    1006              :     : _Inherited(static_cast<const _Tuple_impl<0, _UTypes...>&>(__u))
    1007              :     { }
    1008              : 
    1009              :       template<typename... _UTypes>
    1010              :     requires (__constructible<const _UTypes&...>())
    1011              :       && (!__use_other_ctor<const tuple<_UTypes...>&>())
    1012              :       && (__dangles<const _UTypes&...>())
    1013              :     tuple(const tuple<_UTypes...>&) = delete;
    1014              : 
    1015              :       template<typename... _UTypes>
    1016              :     requires (__constructible<_UTypes...>())
    1017              :       && (!__use_other_ctor<tuple<_UTypes...>>())
    1018              :       && (!__dangles<_UTypes...>())
    1019              :     constexpr explicit(!__convertible<_UTypes...>())
    1020              :     tuple(tuple<_UTypes...>&& __u)
    1021              :     noexcept(__nothrow_constructible<_UTypes...>())
    1022              :     : _Inherited(static_cast<_Tuple_impl<0, _UTypes...>&&>(__u))
    1023              :     { }
    1024              : 
    1025              :       template<typename... _UTypes>
    1026              :     requires (__constructible<_UTypes...>())
    1027              :       && (!__use_other_ctor<tuple<_UTypes...>>())
    1028              :       && (__dangles<_UTypes...>())
    1029              :     tuple(tuple<_UTypes...>&&) = delete;
    1030              : 
    1031              : #if __cpp_lib_ranges_zip // >= C++23
    1032              :       template<typename... _UTypes>
    1033              :     requires (__constructible<_UTypes&...>())
    1034              :       && (!__use_other_ctor<tuple<_UTypes...>&>())
    1035              :       && (!__dangles<_UTypes&...>())
    1036              :     constexpr explicit(!__convertible<_UTypes&...>())
    1037              :     tuple(tuple<_UTypes...>& __u)
    1038              :     noexcept(__nothrow_constructible<_UTypes&...>())
    1039              :     : _Inherited(static_cast<_Tuple_impl<0, _UTypes...>&>(__u))
    1040              :     { }
    1041              : 
    1042              :       template<typename... _UTypes>
    1043              :     requires (__constructible<_UTypes&...>())
    1044              :       && (!__use_other_ctor<tuple<_UTypes...>&>())
    1045              :       && (__dangles<_UTypes&...>())
    1046              :     tuple(tuple<_UTypes...>&) = delete;
    1047              : 
    1048              :       template<typename... _UTypes>
    1049              :     requires (__constructible<const _UTypes...>())
    1050              :       && (!__use_other_ctor<const tuple<_UTypes...>>())
    1051              :       && (!__dangles<const _UTypes...>())
    1052              :     constexpr explicit(!__convertible<const _UTypes...>())
    1053              :     tuple(const tuple<_UTypes...>&& __u)
    1054              :     noexcept(__nothrow_constructible<const _UTypes...>())
    1055              :     : _Inherited(static_cast<const _Tuple_impl<0, _UTypes...>&&>(__u))
    1056              :     { }
    1057              : 
    1058              :       template<typename... _UTypes>
    1059              :     requires (__constructible<const _UTypes...>())
    1060              :       && (!__use_other_ctor<const tuple<_UTypes...>>())
    1061              :       && (__dangles<const _UTypes...>())
    1062              :     tuple(const tuple<_UTypes...>&&) = delete;
    1063              : #endif // C++23
    1064              : 
    1065              :       template<typename _U1, typename _U2>
    1066              :     requires (sizeof...(_Elements) == 2)
    1067              :       && (__constructible<const _U1&, const _U2&>())
    1068              :       && (!__dangles<const _U1&, const _U2&>())
    1069              :     constexpr explicit(!__convertible<const _U1&, const _U2&>())
    1070              :     tuple(const pair<_U1, _U2>& __u)
    1071              :     noexcept(__nothrow_constructible<const _U1&, const _U2&>())
    1072              :     : _Inherited(__u.first, __u.second)
    1073              :     { }
    1074              : 
    1075              :       template<typename _U1, typename _U2>
    1076              :     requires (sizeof...(_Elements) == 2)
    1077              :       && (__constructible<const _U1&, const _U2&>())
    1078              :       && (__dangles<const _U1&, const _U2&>())
    1079              :     tuple(const pair<_U1, _U2>&) = delete;
    1080              : 
    1081              :       template<typename _U1, typename _U2>
    1082              :     requires (sizeof...(_Elements) == 2)
    1083              :       && (__constructible<_U1, _U2>())
    1084              :       && (!__dangles<_U1, _U2>())
    1085              :     constexpr explicit(!__convertible<_U1, _U2>())
    1086              :     tuple(pair<_U1, _U2>&& __u)
    1087              :     noexcept(__nothrow_constructible<_U1, _U2>())
    1088              :     : _Inherited(std::forward<_U1>(__u.first),
    1089              :              std::forward<_U2>(__u.second))
    1090              :     { }
    1091              : 
    1092              :       template<typename _U1, typename _U2>
    1093              :     requires (sizeof...(_Elements) == 2)
    1094              :       && (__constructible<_U1, _U2>())
    1095              :       && (__dangles<_U1, _U2>())
    1096              :     tuple(pair<_U1, _U2>&&) = delete;
    1097              : 
    1098              : #if __cpp_lib_ranges_zip // >= C++23
    1099              :       template<typename _U1, typename _U2>
    1100              :     requires (sizeof...(_Elements) == 2)
    1101              :       && (__constructible<_U1&, _U2&>())
    1102              :       && (!__dangles<_U1&, _U2&>())
    1103              :     constexpr explicit(!__convertible<_U1&, _U2&>())
    1104              :     tuple(pair<_U1, _U2>& __u)
    1105              :     noexcept(__nothrow_constructible<_U1&, _U2&>())
    1106              :     : _Inherited(__u.first, __u.second)
    1107              :     { }
    1108              : 
    1109              :       template<typename _U1, typename _U2>
    1110              :     requires (sizeof...(_Elements) == 2)
    1111              :       && (__constructible<_U1&, _U2&>())
    1112              :       && (__dangles<_U1&, _U2&>())
    1113              :     tuple(pair<_U1, _U2>&) = delete;
    1114              : 
    1115              :       template<typename _U1, typename _U2>
    1116              :     requires (sizeof...(_Elements) == 2)
    1117              :       && (__constructible<const _U1, const _U2>())
    1118              :       && (!__dangles<const _U1, const _U2>())
    1119              :     constexpr explicit(!__convertible<const _U1, const _U2>())
    1120              :     tuple(const pair<_U1, _U2>&& __u)
    1121              :     noexcept(__nothrow_constructible<const _U1, const _U2>())
    1122              :     : _Inherited(std::forward<const _U1>(__u.first),
    1123              :              std::forward<const _U2>(__u.second))
    1124              :     { }
    1125              : 
    1126              :       template<typename _U1, typename _U2>
    1127              :     requires (sizeof...(_Elements) == 2)
    1128              :       && (__constructible<const _U1, const _U2>())
    1129              :       && (__dangles<const _U1, const _U2>())
    1130              :     tuple(const pair<_U1, _U2>&&) = delete;
    1131              : #endif // C++23
    1132              : 
    1133              : #if __cpp_lib_tuple_like // >= C++23
    1134              :       template<__eligible_tuple_like<tuple> _UTuple>
    1135              :     requires (__constructible_from_tuple_like<_UTuple>())
    1136              :       && (!__use_other_ctor<_UTuple>())
    1137              :       && (!__dangles_from_tuple_like<_UTuple>())
    1138              :     constexpr explicit(!__convertible_from_tuple_like<_UTuple>())
    1139              :     tuple(_UTuple&& __u)
    1140              :     : _Inherited(__tuple_like_tag_t{},
    1141              :              std::forward<_UTuple>(__u),
    1142              :              index_sequence_for<_Elements...>{})
    1143              :     { }
    1144              : 
    1145              :       template<__eligible_tuple_like<tuple> _UTuple>
    1146              :     requires (__constructible_from_tuple_like<_UTuple>())
    1147              :       && (!__use_other_ctor<_UTuple>())
    1148              :       && (__dangles_from_tuple_like<_UTuple>())
    1149              :     tuple(_UTuple&&) = delete;
    1150              : #endif // C++23
    1151              : 
    1152              :       // Allocator-extended constructors.
    1153              : 
    1154              :       template<typename _Alloc>
    1155              :     constexpr
    1156              :     explicit(!(__is_implicitly_default_constructible_v<_Elements> && ...))
    1157              :     tuple(allocator_arg_t __tag, const _Alloc& __a)
    1158              :     requires (is_default_constructible_v<_Elements> && ...)
    1159              :     : _Inherited(__tag, __a)
    1160              :     { }
    1161              : 
    1162              :       template<typename _Alloc>
    1163              :     constexpr explicit(!__convertible<const _Elements&...>())
    1164              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    1165              :           const _Elements&... __elements)
    1166              :     requires (__constructible<const _Elements&...>())
    1167              :     : _Inherited(__tag, __a, __elements...)
    1168              :     { }
    1169              : 
    1170              :       template<typename _Alloc, typename... _UTypes>
    1171              :     requires (__disambiguating_constraint<_UTypes...>())
    1172              :       && (__constructible<_UTypes...>())
    1173              :       && (!__dangles<_UTypes...>())
    1174              :     constexpr explicit(!__convertible<_UTypes...>())
    1175              :     tuple(allocator_arg_t __tag, const _Alloc& __a, _UTypes&&... __u)
    1176              :     : _Inherited(__tag, __a, std::forward<_UTypes>(__u)...)
    1177              :     { }
    1178              : 
    1179              :       template<typename _Alloc, typename... _UTypes>
    1180              :     requires (__disambiguating_constraint<_UTypes...>())
    1181              :       && (__constructible<_UTypes...>())
    1182              :       && (__dangles<_UTypes...>())
    1183              :     tuple(allocator_arg_t, const _Alloc&, _UTypes&&...) = delete;
    1184              : 
    1185              :       template<typename _Alloc>
    1186              :     constexpr
    1187              :     tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __u)
    1188              :     : _Inherited(__tag, __a, static_cast<const _Inherited&>(__u))
    1189              :     { }
    1190              : 
    1191              :       template<typename _Alloc>
    1192              :     requires (__constructible<_Elements...>())
    1193              :     constexpr
    1194              :     tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __u)
    1195              :     : _Inherited(__tag, __a, static_cast<_Inherited&&>(__u))
    1196              :     { }
    1197              : 
    1198              :       template<typename _Alloc, typename... _UTypes>
    1199              :     requires (__constructible<const _UTypes&...>())
    1200              :       && (!__use_other_ctor<const tuple<_UTypes...>&>())
    1201              :       && (!__dangles<const _UTypes&...>())
    1202              :     constexpr explicit(!__convertible<const _UTypes&...>())
    1203              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    1204              :           const tuple<_UTypes...>& __u)
    1205              :     : _Inherited(__tag, __a,
    1206              :              static_cast<const _Tuple_impl<0, _UTypes...>&>(__u))
    1207              :     { }
    1208              : 
    1209              :       template<typename _Alloc, typename... _UTypes>
    1210              :     requires (__constructible<const _UTypes&...>())
    1211              :       && (!__use_other_ctor<const tuple<_UTypes...>&>())
    1212              :       && (__dangles<const _UTypes&...>())
    1213              :     tuple(allocator_arg_t, const _Alloc&, const tuple<_UTypes...>&) = delete;
    1214              : 
    1215              :       template<typename _Alloc, typename... _UTypes>
    1216              :     requires (__constructible<_UTypes...>())
    1217              :       && (!__use_other_ctor<tuple<_UTypes...>>())
    1218              :       && (!__dangles<_UTypes...>())
    1219              :     constexpr explicit(!__use_other_ctor<tuple<_UTypes...>>())
    1220              :     tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UTypes...>&& __u)
    1221              :     : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UTypes...>&&>(__u))
    1222              :     { }
    1223              : 
    1224              :       template<typename _Alloc, typename... _UTypes>
    1225              :     requires (__constructible<_UTypes...>())
    1226              :       && (!__use_other_ctor<tuple<_UTypes...>>())
    1227              :       && (__dangles<_UTypes...>())
    1228              :     tuple(allocator_arg_t, const _Alloc&, tuple<_UTypes...>&&) = delete;
    1229              : 
    1230              : #if __cpp_lib_ranges_zip // >= C++23
    1231              :       template<typename _Alloc, typename... _UTypes>
    1232              :     requires (__constructible<_UTypes&...>())
    1233              :       && (!__use_other_ctor<tuple<_UTypes...>&>())
    1234              :       && (!__dangles<_UTypes&...>())
    1235              :     constexpr explicit(!__convertible<_UTypes&...>())
    1236              :     tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UTypes...>& __u)
    1237              :     : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UTypes...>&>(__u))
    1238              :     { }
    1239              : 
    1240              :       template<typename _Alloc, typename... _UTypes>
    1241              :     requires (__constructible<_UTypes&...>())
    1242              :       && (!__use_other_ctor<tuple<_UTypes...>&>())
    1243              :       && (__dangles<_UTypes&...>())
    1244              :     tuple(allocator_arg_t, const _Alloc&, tuple<_UTypes...>&) = delete;
    1245              : 
    1246              :       template<typename _Alloc, typename... _UTypes>
    1247              :     requires (__constructible<const _UTypes...>())
    1248              :       && (!__use_other_ctor<const tuple<_UTypes...>>())
    1249              :       && (!__dangles<const _UTypes...>())
    1250              :     constexpr explicit(!__convertible<const _UTypes...>())
    1251              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    1252              :           const tuple<_UTypes...>&& __u)
    1253              :     : _Inherited(__tag, __a,
    1254              :              static_cast<const _Tuple_impl<0, _UTypes...>&&>(__u))
    1255              :     { }
    1256              : 
    1257              :       template<typename _Alloc, typename... _UTypes>
    1258              :     requires (__constructible<const _UTypes...>())
    1259              :       && (!__use_other_ctor<const tuple<_UTypes...>>())
    1260              :       && (__dangles<const _UTypes...>())
    1261              :     tuple(allocator_arg_t, const _Alloc&, const tuple<_UTypes...>&&) = delete;
    1262              : #endif // C++23
    1263              : 
    1264              :       template<typename _Alloc, typename _U1, typename _U2>
    1265              :     requires (sizeof...(_Elements) == 2)
    1266              :       && (__constructible<const _U1&, const _U2&>())
    1267              :       && (!__dangles<const _U1&, const _U2&>())
    1268              :     constexpr explicit(!__convertible<const _U1&, const _U2&>())
    1269              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    1270              :           const pair<_U1, _U2>& __u)
    1271              :     noexcept(__nothrow_constructible<const _U1&, const _U2&>())
    1272              :     : _Inherited(__tag, __a, __u.first, __u.second)
    1273              :     { }
    1274              : 
    1275              :       template<typename _Alloc, typename _U1, typename _U2>
    1276              :     requires (sizeof...(_Elements) == 2)
    1277              :       && (__constructible<const _U1&, const _U2&>())
    1278              :       && (__dangles<const _U1&, const _U2&>())
    1279              :     tuple(allocator_arg_t, const _Alloc&, const pair<_U1, _U2>&) = delete;
    1280              : 
    1281              :       template<typename _Alloc, typename _U1, typename _U2>
    1282              :     requires (sizeof...(_Elements) == 2)
    1283              :       && (__constructible<_U1, _U2>())
    1284              :       && (!__dangles<_U1, _U2>())
    1285              :     constexpr explicit(!__convertible<_U1, _U2>())
    1286              :     tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __u)
    1287              :     noexcept(__nothrow_constructible<_U1, _U2>())
    1288              :     : _Inherited(__tag, __a, std::move(__u.first), std::move(__u.second))
    1289              :     { }
    1290              : 
    1291              :       template<typename _Alloc, typename _U1, typename _U2>
    1292              :     requires (sizeof...(_Elements) == 2)
    1293              :       && (__constructible<_U1, _U2>())
    1294              :       && (__dangles<_U1, _U2>())
    1295              :     tuple(allocator_arg_t, const _Alloc&, pair<_U1, _U2>&&) = delete;
    1296              : 
    1297              : #if __cpp_lib_ranges_zip // >= C++23
    1298              :       template<typename _Alloc, typename _U1, typename _U2>
    1299              :     requires (sizeof...(_Elements) == 2)
    1300              :       && (__constructible<_U1&, _U2&>())
    1301              :       && (!__dangles<_U1&, _U2&>())
    1302              :     constexpr explicit(!__convertible<_U1&, _U2&>())
    1303              :     tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>& __u)
    1304              :     noexcept(__nothrow_constructible<_U1&, _U2&>())
    1305              :     : _Inherited(__tag, __a, __u.first, __u.second)
    1306              :     { }
    1307              : 
    1308              :       template<typename _Alloc, typename _U1, typename _U2>
    1309              :     requires (sizeof...(_Elements) == 2)
    1310              :       && (__constructible<_U1&, _U2&>())
    1311              :       && (__dangles<_U1&, _U2&>())
    1312              :     tuple(allocator_arg_t, const _Alloc&, pair<_U1, _U2>&) = delete;
    1313              : 
    1314              :       template<typename _Alloc, typename _U1, typename _U2>
    1315              :     requires (sizeof...(_Elements) == 2)
    1316              :       && (__constructible<const _U1, const _U2>())
    1317              :       && (!__dangles<const _U1, const _U2>())
    1318              :     constexpr explicit(!__convertible<const _U1, const _U2>())
    1319              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    1320              :     const pair<_U1, _U2>&& __u)
    1321              :     noexcept(__nothrow_constructible<const _U1, const _U2>())
    1322              :     : _Inherited(__tag, __a, std::move(__u.first), std::move(__u.second))
    1323              :     { }
    1324              : 
    1325              :       template<typename _Alloc, typename _U1, typename _U2>
    1326              :     requires (sizeof...(_Elements) == 2)
    1327              :       && (__constructible<const _U1, const _U2>())
    1328              :       && (__dangles<const _U1, const _U2>())
    1329              :     tuple(allocator_arg_t, const _Alloc&, const pair<_U1, _U2>&&) = delete;
    1330              : #endif // C++23
    1331              : 
    1332              : #if __cpp_lib_tuple_like // >= C++23
    1333              :       template<typename _Alloc, __eligible_tuple_like<tuple> _UTuple>
    1334              :     requires (__constructible_from_tuple_like<_UTuple>())
    1335              :       && (!__use_other_ctor<_UTuple>())
    1336              :       && (!__dangles_from_tuple_like<_UTuple>())
    1337              :     constexpr explicit(!__convertible_from_tuple_like<_UTuple>())
    1338              :     tuple(allocator_arg_t __tag, const _Alloc& __a, _UTuple&& __u)
    1339              :     : _Inherited(__tuple_like_tag_t{},
    1340              :              __tag, __a, std::forward<_UTuple>(__u),
    1341              :              index_sequence_for<_Elements...>{})
    1342              :     { }
    1343              : 
    1344              :       template<typename _Alloc, __eligible_tuple_like<tuple> _UTuple>
    1345              :     requires (__constructible_from_tuple_like<_UTuple>())
    1346              :       && (!__use_other_ctor<_UTuple>())
    1347              :       && (__dangles_from_tuple_like<_UTuple>())
    1348              :     tuple(allocator_arg_t, const _Alloc&, _UTuple&&) = delete;
    1349              : #endif // C++23
    1350              : 
    1351              : #else // !(concepts && conditional_explicit)
    1352              : 
    1353              :       template<bool _Cond>
    1354              :     using _TCC = _TupleConstraints<_Cond, _Elements...>;
    1355              : 
    1356              :       // Constraint for non-explicit default constructor
    1357              :       template<bool _Dummy>
    1358              :     using _ImplicitDefaultCtor = __enable_if_t<
    1359              :       _TCC<_Dummy>::__is_implicitly_default_constructible(),
    1360              :       bool>;
    1361              : 
    1362              :       // Constraint for explicit default constructor
    1363              :       template<bool _Dummy>
    1364              :     using _ExplicitDefaultCtor = __enable_if_t<
    1365              :       _TCC<_Dummy>::__is_explicitly_default_constructible(),
    1366              :       bool>;
    1367              : 
    1368              :       // Constraint for non-explicit constructors
    1369              :       template<bool _Cond, typename... _Args>
    1370              :     using _ImplicitCtor = __enable_if_t<
    1371              :       _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
    1372              :       bool>;
    1373              : 
    1374              :       // Constraint for non-explicit constructors
    1375              :       template<bool _Cond, typename... _Args>
    1376              :     using _ExplicitCtor = __enable_if_t<
    1377              :       _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(),
    1378              :       bool>;
    1379              : 
    1380              :       // Condition for noexcept-specifier of a constructor.
    1381              :       template<typename... _UElements>
    1382              :     static constexpr bool __nothrow_constructible()
    1383              :     {
    1384              :       return
    1385              :         __and_<is_nothrow_constructible<_Elements, _UElements>...>::value;
    1386              :     }
    1387              : 
    1388              :       // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) == 1.
    1389              :       template<typename _Up>
    1390              :     static constexpr bool __valid_args()
    1391              :     {
    1392              :       return sizeof...(_Elements) == 1
    1393              :         && !is_same<tuple, __remove_cvref_t<_Up>>::value;
    1394              :     }
    1395              : 
    1396              :       // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) > 1.
    1397              :       template<typename, typename, typename... _Tail>
    1398              :     static constexpr bool __valid_args()
    1399              :     { return (sizeof...(_Tail) + 2) == sizeof...(_Elements); }
    1400              : 
    1401              :       /* Constraint for constructors with a tuple<UTypes...> parameter ensures
    1402              :        * that the constructor is only viable when it would not interfere with
    1403              :        * tuple(UTypes&&...) or tuple(const tuple&) or tuple(tuple&&).
    1404              :        * Such constructors are only viable if:
    1405              :        * either sizeof...(Types) != 1,
    1406              :        * or (when Types... expands to T and UTypes... expands to U)
    1407              :        * is_convertible_v<TUPLE, T>, is_constructible_v<T, TUPLE>,
    1408              :        * and is_same_v<T, U> are all false.
    1409              :        */
    1410              :       template<typename _Tuple, typename = tuple,
    1411              :            typename = __remove_cvref_t<_Tuple>>
    1412              :     struct _UseOtherCtor
    1413              :     : false_type
    1414              :     { };
    1415              :       // If TUPLE is convertible to the single element in *this,
    1416              :       // then TUPLE should match tuple(UTypes&&...) instead.
    1417              :       template<typename _Tuple, typename _Tp, typename _Up>
    1418              :     struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>>
    1419              :     : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>>::type
    1420              :     { };
    1421              :       // If TUPLE and *this each have a single element of the same type,
    1422              :       // then TUPLE should match a copy/move constructor instead.
    1423              :       template<typename _Tuple, typename _Tp>
    1424              :     struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>>
    1425              :     : true_type
    1426              :     { };
    1427              : 
    1428              :       // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1
    1429              :       // and the single element in Types can be initialized from TUPLE,
    1430              :       // or is the same type as tuple_element_t<0, TUPLE>.
    1431              :       template<typename _Tuple>
    1432              :     static constexpr bool __use_other_ctor()
    1433              :     { return _UseOtherCtor<_Tuple>::value; }
    1434              : 
    1435              :       /// @cond undocumented
    1436              : #undef __glibcxx_no_dangling_refs
    1437              : #if __has_builtin(__reference_constructs_from_temporary) \
    1438              :       && defined _GLIBCXX_DEBUG
    1439              :       // Error if construction from U... would create a dangling ref.
    1440              : # if __cpp_fold_expressions
    1441              : #  define __glibcxx_dangling_refs(U) \
    1442              :   (__reference_constructs_from_temporary(_Elements, U) || ...)
    1443              : # else
    1444              : #  define __glibcxx_dangling_refs(U) \
    1445              :   __or_<__bool_constant<__reference_constructs_from_temporary(_Elements, U) \
    1446              :        >...>::value
    1447              : # endif
    1448              : # define __glibcxx_no_dangling_refs(U) \
    1449              :   static_assert(!__glibcxx_dangling_refs(U), \
    1450              :         "std::tuple constructor creates a dangling reference")
    1451              : #else
    1452              : # define __glibcxx_no_dangling_refs(U)
    1453              : #endif
    1454              :       /// @endcond
    1455              : 
    1456              :     public:
    1457              :       template<typename _Dummy = void,
    1458              :            _ImplicitDefaultCtor<is_void<_Dummy>::value> = true>
    1459              :     constexpr
    1460              :     tuple()
    1461              :     noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
    1462              :     : _Inherited() { }
    1463              : 
    1464              :       template<typename _Dummy = void,
    1465              :            _ExplicitDefaultCtor<is_void<_Dummy>::value> = false>
    1466              :     explicit constexpr
    1467              :     tuple()
    1468              :     noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
    1469              :     : _Inherited() { }
    1470              : 
    1471              :       template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
    1472              :            _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
    1473              :     constexpr
    1474              :     tuple(const _Elements&... __elements)
    1475              :     noexcept(__nothrow_constructible<const _Elements&...>())
    1476              :     : _Inherited(__elements...) { }
    1477              : 
    1478              :       template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
    1479              :            _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
    1480              :     explicit constexpr
    1481              :     tuple(const _Elements&... __elements)
    1482              :     noexcept(__nothrow_constructible<const _Elements&...>())
    1483              :     : _Inherited(__elements...) { }
    1484              : 
    1485              :       template<typename... _UElements,
    1486              :            bool _Valid = __valid_args<_UElements...>(),
    1487              :            _ImplicitCtor<_Valid, _UElements...> = true>
    1488              :     constexpr
    1489              :     tuple(_UElements&&... __elements)
    1490              :     noexcept(__nothrow_constructible<_UElements...>())
    1491              :     : _Inherited(std::forward<_UElements>(__elements)...)
    1492              :     { __glibcxx_no_dangling_refs(_UElements&&); }
    1493              : 
    1494              :       template<typename... _UElements,
    1495              :            bool _Valid = __valid_args<_UElements...>(),
    1496              :            _ExplicitCtor<_Valid, _UElements...> = false>
    1497              :     explicit constexpr
    1498              :     tuple(_UElements&&... __elements)
    1499              :     noexcept(__nothrow_constructible<_UElements...>())
    1500              :     : _Inherited(std::forward<_UElements>(__elements)...)
    1501              :     { __glibcxx_no_dangling_refs(_UElements&&); }
    1502              : 
    1503              :       constexpr tuple(const tuple&) = default;
    1504              : 
    1505              :       constexpr tuple(tuple&&) = default;
    1506              : 
    1507              :       template<typename... _UElements,
    1508              :            bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    1509              :                && !__use_other_ctor<const tuple<_UElements...>&>(),
    1510              :            _ImplicitCtor<_Valid, const _UElements&...> = true>
    1511              :     constexpr
    1512              :     tuple(const tuple<_UElements...>& __in)
    1513              :     noexcept(__nothrow_constructible<const _UElements&...>())
    1514              :     : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    1515              :     { __glibcxx_no_dangling_refs(const _UElements&); }
    1516              : 
    1517              :       template<typename... _UElements,
    1518              :            bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    1519              :                && !__use_other_ctor<const tuple<_UElements...>&>(),
    1520              :            _ExplicitCtor<_Valid, const _UElements&...> = false>
    1521              :     explicit constexpr
    1522              :     tuple(const tuple<_UElements...>& __in)
    1523              :     noexcept(__nothrow_constructible<const _UElements&...>())
    1524              :     : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    1525              :     { __glibcxx_no_dangling_refs(const _UElements&); }
    1526              : 
    1527              :       template<typename... _UElements,
    1528              :            bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    1529              :                  && !__use_other_ctor<tuple<_UElements...>&&>(),
    1530              :            _ImplicitCtor<_Valid, _UElements...> = true>
    1531              :     constexpr
    1532              :     tuple(tuple<_UElements...>&& __in)
    1533              :     noexcept(__nothrow_constructible<_UElements...>())
    1534              :     : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
    1535              :     { __glibcxx_no_dangling_refs(_UElements&&); }
    1536              : 
    1537              :       template<typename... _UElements,
    1538              :            bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    1539              :                  && !__use_other_ctor<tuple<_UElements...>&&>(),
    1540              :            _ExplicitCtor<_Valid, _UElements...> = false>
    1541              :     explicit constexpr
    1542              :     tuple(tuple<_UElements...>&& __in)
    1543              :     noexcept(__nothrow_constructible<_UElements...>())
    1544              :     : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
    1545              :     { __glibcxx_no_dangling_refs(_UElements&&); }
    1546              : 
    1547              :       // Allocator-extended constructors.
    1548              : 
    1549              :       template<typename _Alloc,
    1550              :            _ImplicitDefaultCtor<is_object<_Alloc>::value> = true>
    1551              :     _GLIBCXX20_CONSTEXPR
    1552              :     tuple(allocator_arg_t __tag, const _Alloc& __a)
    1553              :     : _Inherited(__tag, __a) { }
    1554              : 
    1555              :       template<typename _Alloc,
    1556              :            _ExplicitDefaultCtor<is_object<_Alloc>::value> = false>
    1557              :     _GLIBCXX20_CONSTEXPR
    1558              :     explicit
    1559              :     tuple(allocator_arg_t __tag, const _Alloc& __a)
    1560              :     : _Inherited(__tag, __a) { }
    1561              : 
    1562              :       template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
    1563              :            _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
    1564              :     _GLIBCXX20_CONSTEXPR
    1565              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    1566              :           const _Elements&... __elements)
    1567              :     : _Inherited(__tag, __a, __elements...) { }
    1568              : 
    1569              :       template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
    1570              :            _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
    1571              :     _GLIBCXX20_CONSTEXPR
    1572              :     explicit
    1573              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    1574              :           const _Elements&... __elements)
    1575              :     : _Inherited(__tag, __a, __elements...) { }
    1576              : 
    1577              :       template<typename _Alloc, typename... _UElements,
    1578              :            bool _Valid = __valid_args<_UElements...>(),
    1579              :            _ImplicitCtor<_Valid, _UElements...> = true>
    1580              :     _GLIBCXX20_CONSTEXPR
    1581              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    1582              :           _UElements&&... __elements)
    1583              :     : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
    1584              :     { __glibcxx_no_dangling_refs(_UElements&&); }
    1585              : 
    1586              :       template<typename _Alloc, typename... _UElements,
    1587              :          bool _Valid = __valid_args<_UElements...>(),
    1588              :            _ExplicitCtor<_Valid, _UElements...> = false>
    1589              :     _GLIBCXX20_CONSTEXPR
    1590              :     explicit
    1591              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    1592              :           _UElements&&... __elements)
    1593              :     : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
    1594              :     { __glibcxx_no_dangling_refs(_UElements&&); }
    1595              : 
    1596              :       template<typename _Alloc>
    1597              :     _GLIBCXX20_CONSTEXPR
    1598              :     tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
    1599              :     : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
    1600              : 
    1601              :       template<typename _Alloc>
    1602              :     _GLIBCXX20_CONSTEXPR
    1603              :     tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
    1604              :     : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
    1605              : 
    1606              :       template<typename _Alloc, typename... _UElements,
    1607              :            bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    1608              :                  && !__use_other_ctor<const tuple<_UElements...>&>(),
    1609              :            _ImplicitCtor<_Valid, const _UElements&...> = true>
    1610              :     _GLIBCXX20_CONSTEXPR
    1611              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    1612              :           const tuple<_UElements...>& __in)
    1613              :     : _Inherited(__tag, __a,
    1614              :              static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    1615              :     { __glibcxx_no_dangling_refs(const _UElements&); }
    1616              : 
    1617              :       template<typename _Alloc, typename... _UElements,
    1618              :            bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    1619              :                  && !__use_other_ctor<const tuple<_UElements...>&>(),
    1620              :            _ExplicitCtor<_Valid, const _UElements&...> = false>
    1621              :     _GLIBCXX20_CONSTEXPR
    1622              :     explicit
    1623              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    1624              :           const tuple<_UElements...>& __in)
    1625              :     : _Inherited(__tag, __a,
    1626              :              static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    1627              :     { __glibcxx_no_dangling_refs(const _UElements&); }
    1628              : 
    1629              :       template<typename _Alloc, typename... _UElements,
    1630              :            bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    1631              :                  && !__use_other_ctor<tuple<_UElements...>&&>(),
    1632              :            _ImplicitCtor<_Valid, _UElements...> = true>
    1633              :     _GLIBCXX20_CONSTEXPR
    1634              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    1635              :           tuple<_UElements...>&& __in)
    1636              :     : _Inherited(__tag, __a,
    1637              :              static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
    1638              :     { __glibcxx_no_dangling_refs(_UElements&&); }
    1639              : 
    1640              :       template<typename _Alloc, typename... _UElements,
    1641              :            bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
    1642              :                  && !__use_other_ctor<tuple<_UElements...>&&>(),
    1643              :            _ExplicitCtor<_Valid, _UElements...> = false>
    1644              :     _GLIBCXX20_CONSTEXPR
    1645              :     explicit
    1646              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    1647              :           tuple<_UElements...>&& __in)
    1648              :     : _Inherited(__tag, __a,
    1649              :              static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
    1650              :     { __glibcxx_no_dangling_refs(_UElements&&); }
    1651              : #endif // concepts && conditional_explicit
    1652              : 
    1653              :       // tuple assignment
    1654              : 
    1655              : #if __cpp_concepts && __cpp_consteval // >= C++20
    1656              :     private:
    1657              :       template<typename... _UTypes>
    1658              :     static consteval bool
    1659              :     __assignable()
    1660              :     {
    1661              :       if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))
    1662              :         return __and_v<is_assignable<_Elements&, _UTypes>...>;
    1663              :       else
    1664              :         return false;
    1665              :     }
    1666              : 
    1667              :       template<typename... _UTypes>
    1668              :     static consteval bool
    1669              :     __nothrow_assignable()
    1670              :     {
    1671              :       if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))
    1672              :         return __and_v<is_nothrow_assignable<_Elements&, _UTypes>...>;
    1673              :       else
    1674              :         return false;
    1675              :     }
    1676              : 
    1677              : #if __cpp_lib_ranges_zip // >= C++23
    1678              :       template<typename... _UTypes>
    1679              :     static consteval bool
    1680              :     __const_assignable()
    1681              :     {
    1682              :       if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))
    1683              :         return __and_v<is_assignable<const _Elements&, _UTypes>...>;
    1684              :       else
    1685              :         return false;
    1686              :     }
    1687              : #endif // C++23
    1688              : 
    1689              : #if __cpp_lib_tuple_like // >= C++23
    1690              :       template<typename _UTuple>
    1691              :     static consteval bool
    1692              :     __assignable_from_tuple_like()
    1693              :     {
    1694              :       return []<size_t... _Is>(index_sequence<_Is...>) {
    1695              :         return __assignable<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
    1696              :       }(index_sequence_for<_Elements...>{});
    1697              :     }
    1698              : 
    1699              :       template<typename _UTuple>
    1700              :     static consteval bool
    1701              :     __const_assignable_from_tuple_like()
    1702              :     {
    1703              :       return []<size_t... _Is>(index_sequence<_Is...>) {
    1704              :         return __const_assignable<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
    1705              :       }(index_sequence_for<_Elements...>{});
    1706              :     }
    1707              : #endif // C++23
    1708              : 
    1709              :     public:
    1710              : 
    1711              :       tuple& operator=(const tuple& __u) = delete;
    1712              : 
    1713              :       constexpr tuple&
    1714              :       operator=(const tuple& __u)
    1715              :       noexcept(__nothrow_assignable<const _Elements&...>())
    1716              :       requires (__assignable<const _Elements&...>())
    1717              :       {
    1718              :     this->_M_assign(__u);
    1719              :     return *this;
    1720              :       }
    1721              : 
    1722              :       constexpr tuple&
    1723              :       operator=(tuple&& __u)
    1724              :       noexcept(__nothrow_assignable<_Elements...>())
    1725              :       requires (__assignable<_Elements...>())
    1726              :       {
    1727              :     this->_M_assign(std::move(__u));
    1728              :     return *this;
    1729              :       }
    1730              : 
    1731              :       template<typename... _UTypes>
    1732              :     requires (__assignable<const _UTypes&...>())
    1733              :     constexpr tuple&
    1734              :     operator=(const tuple<_UTypes...>& __u)
    1735              :     noexcept(__nothrow_assignable<const _UTypes&...>())
    1736              :     {
    1737              :       this->_M_assign(__u);
    1738              :       return *this;
    1739              :     }
    1740              : 
    1741              :       template<typename... _UTypes>
    1742              :     requires (__assignable<_UTypes...>())
    1743              :     constexpr tuple&
    1744              :     operator=(tuple<_UTypes...>&& __u)
    1745              :     noexcept(__nothrow_assignable<_UTypes...>())
    1746              :     {
    1747              :       this->_M_assign(std::move(__u));
    1748              :       return *this;
    1749              :     }
    1750              : 
    1751              : #if __cpp_lib_ranges_zip // >= C++23
    1752              :       constexpr const tuple&
    1753              :       operator=(const tuple& __u) const
    1754              :       requires (__const_assignable<const _Elements&...>())
    1755              :       {
    1756              :     this->_M_assign(__u);
    1757              :     return *this;
    1758              :       }
    1759              : 
    1760              :       constexpr const tuple&
    1761              :       operator=(tuple&& __u) const
    1762              :       requires (__const_assignable<_Elements...>())
    1763              :       {
    1764              :     this->_M_assign(std::move(__u));
    1765              :     return *this;
    1766              :       }
    1767              : 
    1768              :       template<typename... _UTypes>
    1769              :     constexpr const tuple&
    1770              :     operator=(const tuple<_UTypes...>& __u) const
    1771              :     requires (__const_assignable<const _UTypes&...>())
    1772              :     {
    1773              :       this->_M_assign(__u);
    1774              :       return *this;
    1775              :     }
    1776              : 
    1777              :       template<typename... _UTypes>
    1778              :     constexpr const tuple&
    1779              :     operator=(tuple<_UTypes...>&& __u) const
    1780              :     requires (__const_assignable<_UTypes...>())
    1781              :     {
    1782              :       this->_M_assign(std::move(__u));
    1783              :       return *this;
    1784              :     }
    1785              : #endif // C++23
    1786              : 
    1787              :       template<typename _U1, typename _U2>
    1788              :     requires (__assignable<const _U1&, const _U2&>())
    1789              :     constexpr tuple&
    1790              :     operator=(const pair<_U1, _U2>& __u)
    1791              :     noexcept(__nothrow_assignable<const _U1&, const _U2&>())
    1792              :     {
    1793              :       this->_M_head(*this) = __u.first;
    1794              :       this->_M_tail(*this)._M_head(*this) = __u.second;
    1795              :       return *this;
    1796              :     }
    1797              : 
    1798              :       template<typename _U1, typename _U2>
    1799              :     requires (__assignable<_U1, _U2>())
    1800              :     constexpr tuple&
    1801              :     operator=(pair<_U1, _U2>&& __u)
    1802              :     noexcept(__nothrow_assignable<_U1, _U2>())
    1803              :     {
    1804              :       this->_M_head(*this) = std::forward<_U1>(__u.first);
    1805              :       this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__u.second);
    1806              :       return *this;
    1807              :     }
    1808              : 
    1809              : #if __cpp_lib_ranges_zip // >= C++23
    1810              :       template<typename _U1, typename _U2>
    1811              :     requires (__const_assignable<const _U1&, const _U2>())
    1812              :     constexpr const tuple&
    1813              :     operator=(const pair<_U1, _U2>& __u) const
    1814              :     {
    1815              :       this->_M_head(*this) = __u.first;
    1816              :       this->_M_tail(*this)._M_head(*this) = __u.second;
    1817              :       return *this;
    1818              :     }
    1819              : 
    1820              :       template<typename _U1, typename _U2>
    1821              :     requires (__const_assignable<_U1, _U2>())
    1822              :     constexpr const tuple&
    1823              :     operator=(pair<_U1, _U2>&& __u) const
    1824              :     {
    1825              :       this->_M_head(*this) = std::forward<_U1>(__u.first);
    1826              :       this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__u.second);
    1827              :       return *this;
    1828              :     }
    1829              : #endif // C++23
    1830              : 
    1831              : #if __cpp_lib_tuple_like // >= C++23
    1832              :       template<__eligible_tuple_like<tuple> _UTuple>
    1833              :     requires (__assignable_from_tuple_like<_UTuple>())
    1834              :     constexpr tuple&
    1835              :     operator=(_UTuple&& __u)
    1836              :     {
    1837              :       this->_M_assign(__tuple_like_tag_t{}, std::forward<_UTuple>(__u));
    1838              :       return *this;
    1839              :     }
    1840              : 
    1841              :       template<__eligible_tuple_like<tuple> _UTuple>
    1842              :     requires (__const_assignable_from_tuple_like<_UTuple>())
    1843              :     constexpr const tuple&
    1844              :     operator=(_UTuple&& __u) const
    1845              :     {
    1846              :       this->_M_assign(__tuple_like_tag_t{}, std::forward<_UTuple>(__u));
    1847              :       return *this;
    1848              :     }
    1849              : 
    1850              :       template<__tuple_like _UTuple>
    1851              :     requires (!__is_tuple_v<_UTuple>)
    1852              :     friend constexpr bool
    1853              :     operator==(const tuple& __t, const _UTuple& __u)
    1854              :     {
    1855              :       static_assert(sizeof...(_Elements) == tuple_size_v<_UTuple>,
    1856              :           "tuple objects can only be compared if they have equal sizes.");
    1857              :       return [&]<size_t... _Is>(index_sequence<_Is...>) {
    1858              :         return (bool(std::get<_Is>(__t) == std::get<_Is>(__u))
    1859              :             && ...);
    1860              :       }(index_sequence_for<_Elements...>{});
    1861              :     }
    1862              : 
    1863              :       template<__tuple_like _UTuple,
    1864              :            typename = make_index_sequence<tuple_size_v<_UTuple>>>
    1865              :     struct __tuple_like_common_comparison_category;
    1866              : 
    1867              :       template<__tuple_like _UTuple, size_t... _Is>
    1868              :     requires requires
    1869              :       { typename void_t<__detail::__synth3way_t<_Elements, tuple_element_t<_Is, _UTuple>>...>; }
    1870              :     struct __tuple_like_common_comparison_category<_UTuple, index_sequence<_Is...>>
    1871              :     {
    1872              :       using type = common_comparison_category_t
    1873              :         <__detail::__synth3way_t<_Elements, tuple_element_t<_Is, _UTuple>>...>;
    1874              :     };
    1875              : 
    1876              :       template<__tuple_like _UTuple>
    1877              :     requires (!__is_tuple_v<_UTuple>)
    1878              :     friend constexpr typename __tuple_like_common_comparison_category<_UTuple>::type
    1879              :     operator<=>(const tuple& __t, const _UTuple& __u)
    1880              :     {
    1881              :       using _Cat = typename __tuple_like_common_comparison_category<_UTuple>::type;
    1882              :       return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Elements...>());
    1883              :     }
    1884              : #endif // C++23
    1885              : 
    1886              : #else // ! (concepts && consteval)
    1887              : 
    1888              :     private:
    1889              :       template<typename... _UElements>
    1890              :     static constexpr
    1891              :     __enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool>
    1892              :     __assignable()
    1893              :     { return __and_<is_assignable<_Elements&, _UElements>...>::value; }
    1894              : 
    1895              :       // Condition for noexcept-specifier of an assignment operator.
    1896              :       template<typename... _UElements>
    1897              :     static constexpr bool __nothrow_assignable()
    1898              :     {
    1899              :       return
    1900              :         __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value;
    1901              :     }
    1902              : 
    1903              :     public:
    1904              : 
    1905              :       _GLIBCXX20_CONSTEXPR
    1906              :       tuple&
    1907              :       operator=(__conditional_t<__assignable<const _Elements&...>(),
    1908              :                 const tuple&,
    1909              :                 const __nonesuch&> __in)
    1910              :       noexcept(__nothrow_assignable<const _Elements&...>())
    1911              :       {
    1912              :     this->_M_assign(__in);
    1913              :     return *this;
    1914              :       }
    1915              : 
    1916              :       _GLIBCXX20_CONSTEXPR
    1917              :       tuple&
    1918              :       operator=(__conditional_t<__assignable<_Elements...>(),
    1919              :                 tuple&&,
    1920              :                 __nonesuch&&> __in)
    1921              :       noexcept(__nothrow_assignable<_Elements...>())
    1922              :       {
    1923              :     this->_M_assign(std::move(__in));
    1924              :     return *this;
    1925              :       }
    1926              : 
    1927              :       template<typename... _UElements>
    1928              :     _GLIBCXX20_CONSTEXPR
    1929              :     __enable_if_t<__assignable<const _UElements&...>(), tuple&>
    1930              :     operator=(const tuple<_UElements...>& __in)
    1931              :     noexcept(__nothrow_assignable<const _UElements&...>())
    1932              :     {
    1933              :       this->_M_assign(__in);
    1934              :       return *this;
    1935              :     }
    1936              : 
    1937              :       template<typename... _UElements>
    1938              :     _GLIBCXX20_CONSTEXPR
    1939              :     __enable_if_t<__assignable<_UElements...>(), tuple&>
    1940              :     operator=(tuple<_UElements...>&& __in)
    1941              :     noexcept(__nothrow_assignable<_UElements...>())
    1942              :     {
    1943              :       this->_M_assign(std::move(__in));
    1944              :       return *this;
    1945              :     }
    1946              : #endif // concepts && consteval
    1947              : 
    1948              :       // tuple swap
    1949              :       _GLIBCXX20_CONSTEXPR
    1950              :       void
    1951              :       swap(tuple& __in)
    1952              :       noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
    1953              :       { _Inherited::_M_swap(__in); }
    1954              : 
    1955              : #if __cpp_lib_ranges_zip // >= C++23
    1956              :       // As an extension, we constrain the const swap member function in order
    1957              :       // to continue accepting explicit instantiation of tuples whose elements
    1958              :       // are not all const swappable.  Without this constraint, such an
    1959              :       // explicit instantiation would also instantiate the ill-formed body of
    1960              :       // this function and yield a hard error.  This constraint shouldn't
    1961              :       // affect the behavior of valid programs.
    1962              :       constexpr void
    1963              :       swap(const tuple& __in) const
    1964              :       noexcept(__and_v<__is_nothrow_swappable<const _Elements>...>)
    1965              :       requires (is_swappable_v<const _Elements> && ...)
    1966              :       { _Inherited::_M_swap(__in); }
    1967              : #endif // C++23
    1968              :     };
    1969              : 
    1970              : #if __cpp_deduction_guides >= 201606
    1971              :   template<typename... _UTypes>
    1972              :     tuple(_UTypes...) -> tuple<_UTypes...>;
    1973              :   template<typename _T1, typename _T2>
    1974              :     tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
    1975              :   template<typename _Alloc, typename... _UTypes>
    1976              :     tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
    1977              :   template<typename _Alloc, typename _T1, typename _T2>
    1978              :     tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
    1979              :   template<typename _Alloc, typename... _UTypes>
    1980              :     tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
    1981              : #endif
    1982              : 
    1983              :   // Explicit specialization, zero-element tuple.
    1984              :   template<>
    1985              :     class tuple<>
    1986              :     {
    1987              :     public:
    1988              :       _GLIBCXX20_CONSTEXPR
    1989              :       void swap(tuple&) noexcept { /* no-op */ }
    1990              : #if __cpp_lib_ranges_zip // >= C++23
    1991              :       constexpr void swap(const tuple&) const noexcept { /* no-op */ }
    1992              : #endif
    1993              :       // We need the default since we're going to define no-op
    1994              :       // allocator constructors.
    1995              :       tuple() = default;
    1996              :       // No-op allocator constructors.
    1997              :       template<typename _Alloc>
    1998              :     _GLIBCXX20_CONSTEXPR
    1999              :     tuple(allocator_arg_t, const _Alloc&) noexcept { }
    2000              :       template<typename _Alloc>
    2001              :     _GLIBCXX20_CONSTEXPR
    2002              :     tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { }
    2003              :     };
    2004              : 
    2005              : #if !(__cpp_concepts && __cpp_consteval && __cpp_conditional_explicit) // !C++20
    2006              :   /// Partial specialization, 2-element tuple.
    2007              :   /// Includes construction and assignment from a pair.
    2008              :   template<typename _T1, typename _T2>
    2009              :     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
    2010              :     {
    2011              :       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
    2012              : 
    2013              :       // Constraint for non-explicit default constructor
    2014              :       template<bool _Dummy, typename _U1, typename _U2>
    2015              :     using _ImplicitDefaultCtor = __enable_if_t<
    2016              :       _TupleConstraints<_Dummy, _U1, _U2>::
    2017              :         __is_implicitly_default_constructible(),
    2018              :       bool>;
    2019              : 
    2020              :       // Constraint for explicit default constructor
    2021              :       template<bool _Dummy, typename _U1, typename _U2>
    2022              :     using _ExplicitDefaultCtor = __enable_if_t<
    2023              :       _TupleConstraints<_Dummy, _U1, _U2>::
    2024              :         __is_explicitly_default_constructible(),
    2025              :       bool>;
    2026              : 
    2027              :       template<bool _Dummy>
    2028              :     using _TCC = _TupleConstraints<_Dummy, _T1, _T2>;
    2029              : 
    2030              :       // Constraint for non-explicit constructors
    2031              :       template<bool _Cond, typename _U1, typename _U2>
    2032              :     using _ImplicitCtor = __enable_if_t<
    2033              :       _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(),
    2034              :       bool>;
    2035              : 
    2036              :       // Constraint for non-explicit constructors
    2037              :       template<bool _Cond, typename _U1, typename _U2>
    2038              :     using _ExplicitCtor = __enable_if_t<
    2039              :       _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(),
    2040              :       bool>;
    2041              : 
    2042              :       template<typename _U1, typename _U2>
    2043              :     static constexpr bool __assignable()
    2044              :     {
    2045              :       return __and_<is_assignable<_T1&, _U1>,
    2046              :             is_assignable<_T2&, _U2>>::value;
    2047              :     }
    2048              : 
    2049              :       template<typename _U1, typename _U2>
    2050              :     static constexpr bool __nothrow_assignable()
    2051              :     {
    2052              :       return __and_<is_nothrow_assignable<_T1&, _U1>,
    2053              :             is_nothrow_assignable<_T2&, _U2>>::value;
    2054              :     }
    2055              : 
    2056              :       template<typename _U1, typename _U2>
    2057              :     static constexpr bool __nothrow_constructible()
    2058              :     {
    2059              :       return __and_<is_nothrow_constructible<_T1, _U1>,
    2060              :                 is_nothrow_constructible<_T2, _U2>>::value;
    2061              :     }
    2062              : 
    2063              :       static constexpr bool __nothrow_default_constructible()
    2064              :       {
    2065              :     return __and_<is_nothrow_default_constructible<_T1>,
    2066              :               is_nothrow_default_constructible<_T2>>::value;
    2067              :       }
    2068              : 
    2069              :       template<typename _U1>
    2070              :     static constexpr bool __is_alloc_arg()
    2071              :     { return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; }
    2072              : 
    2073              :       /// @cond undocumented
    2074              : #undef __glibcxx_no_dangling_refs
    2075              :       // Error if construction from _U1 and _U2 would create a dangling ref.
    2076              : #if __has_builtin(__reference_constructs_from_temporary) \
    2077              :       && defined _GLIBCXX_DEBUG
    2078              : # define __glibcxx_no_dangling_refs(_U1, _U2) \
    2079              :   static_assert(!__reference_constructs_from_temporary(_T1, _U1) \
    2080              :            && !__reference_constructs_from_temporary(_T2, _U2), \
    2081              :         "std::tuple constructor creates a dangling reference")
    2082              : #else
    2083              : # define __glibcxx_no_dangling_refs(_U1, _U2)
    2084              : #endif
    2085              :       /// @endcond
    2086              : 
    2087              :     public:
    2088              :       template<bool _Dummy = true,
    2089              :            _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true>
    2090              :     constexpr
    2091         1213 :     tuple()
    2092              :     noexcept(__nothrow_default_constructible())
    2093         1213 :     : _Inherited() { }
    2094              : 
    2095              :       template<bool _Dummy = true,
    2096              :            _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false>
    2097              :     explicit constexpr
    2098              :     tuple()
    2099              :     noexcept(__nothrow_default_constructible())
    2100              :     : _Inherited() { }
    2101              : 
    2102              :       template<bool _Dummy = true,
    2103              :            _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
    2104              :     constexpr
    2105              :     tuple(const _T1& __a1, const _T2& __a2)
    2106              :     noexcept(__nothrow_constructible<const _T1&, const _T2&>())
    2107              :     : _Inherited(__a1, __a2) { }
    2108              : 
    2109              :       template<bool _Dummy = true,
    2110              :            _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
    2111              :     explicit constexpr
    2112              :     tuple(const _T1& __a1, const _T2& __a2)
    2113              :     noexcept(__nothrow_constructible<const _T1&, const _T2&>())
    2114              :     : _Inherited(__a1, __a2) { }
    2115              : 
    2116              :       template<typename _U1, typename _U2,
    2117              :            _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true>
    2118              :     constexpr
    2119              :     tuple(_U1&& __a1, _U2&& __a2)
    2120              :     noexcept(__nothrow_constructible<_U1, _U2>())
    2121              :     : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2))
    2122              :     { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
    2123              : 
    2124              :       template<typename _U1, typename _U2,
    2125              :            _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false>
    2126              :     explicit constexpr
    2127              :     tuple(_U1&& __a1, _U2&& __a2)
    2128              :     noexcept(__nothrow_constructible<_U1, _U2>())
    2129              :     : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2))
    2130              :     { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
    2131              : 
    2132              :       constexpr tuple(const tuple&) = default;
    2133              : 
    2134         4283 :       constexpr tuple(tuple&&) = default;
    2135              : 
    2136              :       template<typename _U1, typename _U2,
    2137              :            _ImplicitCtor<true, const _U1&, const _U2&> = true>
    2138              :     constexpr
    2139              :     tuple(const tuple<_U1, _U2>& __in)
    2140              :     noexcept(__nothrow_constructible<const _U1&, const _U2&>())
    2141              :     : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
    2142              :     { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
    2143              : 
    2144              :       template<typename _U1, typename _U2,
    2145              :            _ExplicitCtor<true, const _U1&, const _U2&> = false>
    2146              :     explicit constexpr
    2147              :     tuple(const tuple<_U1, _U2>& __in)
    2148              :     noexcept(__nothrow_constructible<const _U1&, const _U2&>())
    2149              :     : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
    2150              :     { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
    2151              : 
    2152              :       template<typename _U1, typename _U2,
    2153              :            _ImplicitCtor<true, _U1, _U2> = true>
    2154              :     constexpr
    2155              :     tuple(tuple<_U1, _U2>&& __in)
    2156              :     noexcept(__nothrow_constructible<_U1, _U2>())
    2157              :     : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
    2158              :     { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
    2159              : 
    2160              :       template<typename _U1, typename _U2,
    2161              :            _ExplicitCtor<true, _U1, _U2> = false>
    2162              :     explicit constexpr
    2163              :     tuple(tuple<_U1, _U2>&& __in)
    2164              :     noexcept(__nothrow_constructible<_U1, _U2>())
    2165              :     : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
    2166              :     { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
    2167              : 
    2168              :       template<typename _U1, typename _U2,
    2169              :            _ImplicitCtor<true, const _U1&, const _U2&> = true>
    2170              :     constexpr
    2171              :     tuple(const pair<_U1, _U2>& __in)
    2172              :     noexcept(__nothrow_constructible<const _U1&, const _U2&>())
    2173              :     : _Inherited(__in.first, __in.second)
    2174              :     { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
    2175              : 
    2176              :       template<typename _U1, typename _U2,
    2177              :            _ExplicitCtor<true, const _U1&, const _U2&> = false>
    2178              :     explicit constexpr
    2179              :     tuple(const pair<_U1, _U2>& __in)
    2180              :     noexcept(__nothrow_constructible<const _U1&, const _U2&>())
    2181              :     : _Inherited(__in.first, __in.second)
    2182              :     { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
    2183              : 
    2184              :       template<typename _U1, typename _U2,
    2185              :            _ImplicitCtor<true, _U1, _U2> = true>
    2186              :     constexpr
    2187              :     tuple(pair<_U1, _U2>&& __in)
    2188              :     noexcept(__nothrow_constructible<_U1, _U2>())
    2189              :     : _Inherited(std::forward<_U1>(__in.first),
    2190              :              std::forward<_U2>(__in.second))
    2191              :     { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
    2192              : 
    2193              :       template<typename _U1, typename _U2,
    2194              :            _ExplicitCtor<true, _U1, _U2> = false>
    2195              :     explicit constexpr
    2196              :     tuple(pair<_U1, _U2>&& __in)
    2197              :     noexcept(__nothrow_constructible<_U1, _U2>())
    2198              :     : _Inherited(std::forward<_U1>(__in.first),
    2199              :              std::forward<_U2>(__in.second))
    2200              :     { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
    2201              : 
    2202              :       // Allocator-extended constructors.
    2203              : 
    2204              :       template<typename _Alloc,
    2205              :            _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true>
    2206              :     _GLIBCXX20_CONSTEXPR
    2207              :     tuple(allocator_arg_t __tag, const _Alloc& __a)
    2208              :     : _Inherited(__tag, __a) { }
    2209              : 
    2210              :       template<typename _Alloc,
    2211              :            _ExplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = false>
    2212              :     _GLIBCXX20_CONSTEXPR
    2213              :     explicit
    2214              :     tuple(allocator_arg_t __tag, const _Alloc& __a)
    2215              :     : _Inherited(__tag, __a) { }
    2216              : 
    2217              :       template<typename _Alloc, bool _Dummy = true,
    2218              :            _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
    2219              :     _GLIBCXX20_CONSTEXPR
    2220              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    2221              :           const _T1& __a1, const _T2& __a2)
    2222              :     : _Inherited(__tag, __a, __a1, __a2) { }
    2223              : 
    2224              :       template<typename _Alloc, bool _Dummy = true,
    2225              :            _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
    2226              :     explicit
    2227              :     _GLIBCXX20_CONSTEXPR
    2228              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    2229              :           const _T1& __a1, const _T2& __a2)
    2230              :     : _Inherited(__tag, __a, __a1, __a2) { }
    2231              : 
    2232              :       template<typename _Alloc, typename _U1, typename _U2,
    2233              :            _ImplicitCtor<true, _U1, _U2> = true>
    2234              :     _GLIBCXX20_CONSTEXPR
    2235              :     tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
    2236              :     : _Inherited(__tag, __a, std::forward<_U1>(__a1),
    2237              :              std::forward<_U2>(__a2))
    2238              :     { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
    2239              : 
    2240              :       template<typename _Alloc, typename _U1, typename _U2,
    2241              :            _ExplicitCtor<true, _U1, _U2> = false>
    2242              :     explicit
    2243              :     _GLIBCXX20_CONSTEXPR
    2244              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    2245              :           _U1&& __a1, _U2&& __a2)
    2246              :     : _Inherited(__tag, __a, std::forward<_U1>(__a1),
    2247              :              std::forward<_U2>(__a2))
    2248              :     { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
    2249              : 
    2250              :       template<typename _Alloc>
    2251              :     _GLIBCXX20_CONSTEXPR
    2252              :     tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
    2253              :     : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
    2254              : 
    2255              :       template<typename _Alloc>
    2256              :     _GLIBCXX20_CONSTEXPR
    2257              :     tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
    2258              :     : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
    2259              : 
    2260              :       template<typename _Alloc, typename _U1, typename _U2,
    2261              :            _ImplicitCtor<true, const _U1&, const _U2&> = true>
    2262              :     _GLIBCXX20_CONSTEXPR
    2263              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    2264              :           const tuple<_U1, _U2>& __in)
    2265              :     : _Inherited(__tag, __a,
    2266              :              static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
    2267              :     { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
    2268              : 
    2269              :       template<typename _Alloc, typename _U1, typename _U2,
    2270              :            _ExplicitCtor<true, const _U1&, const _U2&> = false>
    2271              :     explicit
    2272              :     _GLIBCXX20_CONSTEXPR
    2273              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    2274              :           const tuple<_U1, _U2>& __in)
    2275              :     : _Inherited(__tag, __a,
    2276              :              static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
    2277              :     { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
    2278              : 
    2279              :       template<typename _Alloc, typename _U1, typename _U2,
    2280              :            _ImplicitCtor<true, _U1, _U2> = true>
    2281              :     _GLIBCXX20_CONSTEXPR
    2282              :     tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
    2283              :     : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
    2284              :     { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
    2285              : 
    2286              :       template<typename _Alloc, typename _U1, typename _U2,
    2287              :            _ExplicitCtor<true, _U1, _U2> = false>
    2288              :     explicit
    2289              :     _GLIBCXX20_CONSTEXPR
    2290              :     tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
    2291              :     : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
    2292              :     { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
    2293              : 
    2294              :       template<typename _Alloc, typename _U1, typename _U2,
    2295              :            _ImplicitCtor<true, const _U1&, const _U2&> = true>
    2296              :     _GLIBCXX20_CONSTEXPR
    2297              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    2298              :           const pair<_U1, _U2>& __in)
    2299              :     : _Inherited(__tag, __a, __in.first, __in.second)
    2300              :     { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
    2301              : 
    2302              :       template<typename _Alloc, typename _U1, typename _U2,
    2303              :            _ExplicitCtor<true, const _U1&, const _U2&> = false>
    2304              :     explicit
    2305              :     _GLIBCXX20_CONSTEXPR
    2306              :     tuple(allocator_arg_t __tag, const _Alloc& __a,
    2307              :           const pair<_U1, _U2>& __in)
    2308              :     : _Inherited(__tag, __a, __in.first, __in.second)
    2309              :     { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
    2310              : 
    2311              :       template<typename _Alloc, typename _U1, typename _U2,
    2312              :            _ImplicitCtor<true, _U1, _U2> = true>
    2313              :     _GLIBCXX20_CONSTEXPR
    2314              :     tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
    2315              :     : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
    2316              :              std::forward<_U2>(__in.second))
    2317              :     { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
    2318              : 
    2319              :       template<typename _Alloc, typename _U1, typename _U2,
    2320              :            _ExplicitCtor<true, _U1, _U2> = false>
    2321              :     explicit
    2322              :     _GLIBCXX20_CONSTEXPR
    2323              :     tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
    2324              :     : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
    2325              :              std::forward<_U2>(__in.second))
    2326              :     { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
    2327              : 
    2328              :       // Tuple assignment.
    2329              : 
    2330              :       _GLIBCXX20_CONSTEXPR
    2331              :       tuple&
    2332              :       operator=(__conditional_t<__assignable<const _T1&, const _T2&>(),
    2333              :                 const tuple&,
    2334              :                 const __nonesuch&> __in)
    2335              :       noexcept(__nothrow_assignable<const _T1&, const _T2&>())
    2336              :       {
    2337              :     this->_M_assign(__in);
    2338              :     return *this;
    2339              :       }
    2340              : 
    2341              :       _GLIBCXX20_CONSTEXPR
    2342              :       tuple&
    2343              :       operator=(__conditional_t<__assignable<_T1, _T2>(),
    2344              :                 tuple&&,
    2345              :                 __nonesuch&&> __in)
    2346              :       noexcept(__nothrow_assignable<_T1, _T2>())
    2347              :       {
    2348              :     this->_M_assign(std::move(__in));
    2349              :     return *this;
    2350              :       }
    2351              : 
    2352              :       template<typename _U1, typename _U2>
    2353              :     _GLIBCXX20_CONSTEXPR
    2354              :     __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
    2355              :     operator=(const tuple<_U1, _U2>& __in)
    2356              :     noexcept(__nothrow_assignable<const _U1&, const _U2&>())
    2357              :     {
    2358              :       this->_M_assign(__in);
    2359              :       return *this;
    2360              :     }
    2361              : 
    2362              :       template<typename _U1, typename _U2>
    2363              :     _GLIBCXX20_CONSTEXPR
    2364              :     __enable_if_t<__assignable<_U1, _U2>(), tuple&>
    2365              :     operator=(tuple<_U1, _U2>&& __in)
    2366              :     noexcept(__nothrow_assignable<_U1, _U2>())
    2367              :     {
    2368              :       this->_M_assign(std::move(__in));
    2369              :       return *this;
    2370              :     }
    2371              : 
    2372              :       template<typename _U1, typename _U2>
    2373              :     _GLIBCXX20_CONSTEXPR
    2374              :     __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
    2375              :     operator=(const pair<_U1, _U2>& __in)
    2376              :     noexcept(__nothrow_assignable<const _U1&, const _U2&>())
    2377              :     {
    2378              :       this->_M_head(*this) = __in.first;
    2379              :       this->_M_tail(*this)._M_head(*this) = __in.second;
    2380              :       return *this;
    2381              :     }
    2382              : 
    2383              :       template<typename _U1, typename _U2>
    2384              :     _GLIBCXX20_CONSTEXPR
    2385              :     __enable_if_t<__assignable<_U1, _U2>(), tuple&>
    2386              :     operator=(pair<_U1, _U2>&& __in)
    2387              :     noexcept(__nothrow_assignable<_U1, _U2>())
    2388              :     {
    2389              :       this->_M_head(*this) = std::forward<_U1>(__in.first);
    2390              :       this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
    2391              :       return *this;
    2392              :     }
    2393              : 
    2394              :       _GLIBCXX20_CONSTEXPR
    2395              :       void
    2396              :       swap(tuple& __in)
    2397              :       noexcept(__and_<__is_nothrow_swappable<_T1>,
    2398              :               __is_nothrow_swappable<_T2>>::value)
    2399              :       { _Inherited::_M_swap(__in); }
    2400              :     };
    2401              : #endif // concepts && conditional_explicit
    2402              : 
    2403              :   /// class tuple_size
    2404              :   template<typename... _Elements>
    2405              :     struct tuple_size<tuple<_Elements...>>
    2406              :     : public integral_constant<size_t, sizeof...(_Elements)> { };
    2407              : 
    2408              : #if __cplusplus >= 201703L
    2409              :   template<typename... _Types>
    2410              :     inline constexpr size_t tuple_size_v<tuple<_Types...>>
    2411              :       = sizeof...(_Types);
    2412              : 
    2413              :   template<typename... _Types>
    2414              :     inline constexpr size_t tuple_size_v<const tuple<_Types...>>
    2415              :       = sizeof...(_Types);
    2416              : #endif
    2417              : 
    2418              :   /// Trait to get the Ith element type from a tuple.
    2419              :   template<size_t __i, typename... _Types>
    2420              :     struct tuple_element<__i, tuple<_Types...>>
    2421              :     {
    2422              :       static_assert(__i < sizeof...(_Types), "tuple index must be in range");
    2423              : 
    2424              :       using type = typename _Nth_type<__i, _Types...>::type;
    2425              :     };
    2426              : 
    2427              :   template<size_t __i, typename _Head, typename... _Tail>
    2428              :     constexpr _Head&
    2429        11360 :     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
    2430        11360 :     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
    2431              : 
    2432              :   template<size_t __i, typename _Head, typename... _Tail>
    2433              :     constexpr const _Head&
    2434        10965 :     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
    2435        10965 :     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
    2436              : 
    2437              :   // Deleted overload to improve diagnostics for invalid indices
    2438              :   template<size_t __i, typename... _Types>
    2439              :     __enable_if_t<(__i >= sizeof...(_Types))>
    2440              :     __get_helper(const tuple<_Types...>&) = delete;
    2441              : 
    2442              :   /// Return a reference to the ith element of a tuple.
    2443              :   template<size_t __i, typename... _Elements>
    2444              :     constexpr __tuple_element_t<__i, tuple<_Elements...>>&
    2445        11360 :     get(tuple<_Elements...>& __t) noexcept
    2446        11360 :     { return std::__get_helper<__i>(__t); }
    2447              : 
    2448              :   /// Return a const reference to the ith element of a const tuple.
    2449              :   template<size_t __i, typename... _Elements>
    2450              :     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
    2451        10965 :     get(const tuple<_Elements...>& __t) noexcept
    2452        10965 :     { return std::__get_helper<__i>(__t); }
    2453              : 
    2454              :   /// Return an rvalue reference to the ith element of a tuple rvalue.
    2455              :   template<size_t __i, typename... _Elements>
    2456              :     constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
    2457              :     get(tuple<_Elements...>&& __t) noexcept
    2458              :     {
    2459              :       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
    2460              :       return std::forward<__element_type>(std::__get_helper<__i>(__t));
    2461              :     }
    2462              : 
    2463              :   /// Return a const rvalue reference to the ith element of a const tuple rvalue.
    2464              :   template<size_t __i, typename... _Elements>
    2465              :     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
    2466              :     get(const tuple<_Elements...>&& __t) noexcept
    2467              :     {
    2468              :       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
    2469              :       return std::forward<const __element_type>(std::__get_helper<__i>(__t));
    2470              :     }
    2471              : 
    2472              :   /// @cond undocumented
    2473              :   // Deleted overload chosen for invalid indices.
    2474              :   template<size_t __i, typename... _Elements>
    2475              :     constexpr __enable_if_t<(__i >= sizeof...(_Elements))>
    2476              :     get(const tuple<_Elements...>&) = delete;
    2477              :   /// @endcond
    2478              : 
    2479              : #ifdef __cpp_lib_tuples_by_type // C++ >= 14
    2480              :   /// Return a reference to the unique element of type _Tp of a tuple.
    2481              :   template <typename _Tp, typename... _Types>
    2482              :     constexpr _Tp&
    2483              :     get(tuple<_Types...>& __t) noexcept
    2484              :     {
    2485              :       constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
    2486              :       static_assert(__idx < sizeof...(_Types),
    2487              :       "the type T in std::get<T> must occur exactly once in the tuple");
    2488              :       return std::__get_helper<__idx>(__t);
    2489              :     }
    2490              : 
    2491              :   /// Return a reference to the unique element of type _Tp of a tuple rvalue.
    2492              :   template <typename _Tp, typename... _Types>
    2493              :     constexpr _Tp&&
    2494              :     get(tuple<_Types...>&& __t) noexcept
    2495              :     {
    2496              :       constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
    2497              :       static_assert(__idx < sizeof...(_Types),
    2498              :       "the type T in std::get<T> must occur exactly once in the tuple");
    2499              :       return std::forward<_Tp>(std::__get_helper<__idx>(__t));
    2500              :     }
    2501              : 
    2502              :   /// Return a const reference to the unique element of type _Tp of a tuple.
    2503              :   template <typename _Tp, typename... _Types>
    2504              :     constexpr const _Tp&
    2505              :     get(const tuple<_Types...>& __t) noexcept
    2506              :     {
    2507              :       constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
    2508              :       static_assert(__idx < sizeof...(_Types),
    2509              :       "the type T in std::get<T> must occur exactly once in the tuple");
    2510              :       return std::__get_helper<__idx>(__t);
    2511              :     }
    2512              : 
    2513              :   /// Return a const reference to the unique element of type _Tp of
    2514              :   /// a const tuple rvalue.
    2515              :   template <typename _Tp, typename... _Types>
    2516              :     constexpr const _Tp&&
    2517              :     get(const tuple<_Types...>&& __t) noexcept
    2518              :     {
    2519              :       constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
    2520              :       static_assert(__idx < sizeof...(_Types),
    2521              :       "the type T in std::get<T> must occur exactly once in the tuple");
    2522              :       return std::forward<const _Tp>(std::__get_helper<__idx>(__t));
    2523              :     }
    2524              : #endif
    2525              : 
    2526              :   // This class performs the comparison operations on tuples
    2527              :   template<typename _Tp, typename _Up, size_t __i, size_t __size>
    2528              :     struct __tuple_compare
    2529              :     {
    2530              :       static constexpr bool
    2531              :       __eq(const _Tp& __t, const _Up& __u)
    2532              :       {
    2533              :     return bool(std::get<__i>(__t) == std::get<__i>(__u))
    2534              :       && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
    2535              :       }
    2536              : 
    2537              :       static constexpr bool
    2538              :       __less(const _Tp& __t, const _Up& __u)
    2539              :       {
    2540              :     return bool(std::get<__i>(__t) < std::get<__i>(__u))
    2541              :       || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
    2542              :           && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
    2543              :       }
    2544              :     };
    2545              : 
    2546              :   template<typename _Tp, typename _Up, size_t __size>
    2547              :     struct __tuple_compare<_Tp, _Up, __size, __size>
    2548              :     {
    2549              :       static constexpr bool
    2550              :       __eq(const _Tp&, const _Up&) { return true; }
    2551              : 
    2552              :       static constexpr bool
    2553              :       __less(const _Tp&, const _Up&) { return false; }
    2554              :     };
    2555              : 
    2556              :   template<typename... _TElements, typename... _UElements>
    2557              :     constexpr bool
    2558              :     operator==(const tuple<_TElements...>& __t,
    2559              :            const tuple<_UElements...>& __u)
    2560              :     {
    2561              :       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
    2562              :       "tuple objects can only be compared if they have equal sizes.");
    2563              :       using __compare = __tuple_compare<tuple<_TElements...>,
    2564              :                     tuple<_UElements...>,
    2565              :                     0, sizeof...(_TElements)>;
    2566              :       return __compare::__eq(__t, __u);
    2567              :     }
    2568              : 
    2569              : #if __cpp_lib_three_way_comparison
    2570              :   template<typename _Cat, typename _Tp, typename _Up>
    2571              :     constexpr _Cat
    2572              :     __tuple_cmp(const _Tp&, const _Up&, index_sequence<>)
    2573              :     { return _Cat::equivalent; }
    2574              : 
    2575              :   template<typename _Cat, typename _Tp, typename _Up,
    2576              :        size_t _Idx0, size_t... _Idxs>
    2577              :     constexpr _Cat
    2578              :     __tuple_cmp(const _Tp& __t, const _Up& __u,
    2579              :         index_sequence<_Idx0, _Idxs...>)
    2580              :     {
    2581              :       auto __c
    2582              :     = __detail::__synth3way(std::get<_Idx0>(__t), std::get<_Idx0>(__u));
    2583              :       if (__c != 0)
    2584              :     return __c;
    2585              :       return std::__tuple_cmp<_Cat>(__t, __u, index_sequence<_Idxs...>());
    2586              :     }
    2587              : 
    2588              :   template<typename... _Tps, typename... _Ups>
    2589              :     constexpr
    2590              :     common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>
    2591              :     operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u)
    2592              :     {
    2593              :       using _Cat
    2594              :     = common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>;
    2595              :       return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>());
    2596              :     }
    2597              : #else
    2598              :   template<typename... _TElements, typename... _UElements>
    2599              :     constexpr bool
    2600              :     operator<(const tuple<_TElements...>& __t,
    2601              :           const tuple<_UElements...>& __u)
    2602              :     {
    2603              :       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
    2604              :       "tuple objects can only be compared if they have equal sizes.");
    2605              :       using __compare = __tuple_compare<tuple<_TElements...>,
    2606              :                     tuple<_UElements...>,
    2607              :                     0, sizeof...(_TElements)>;
    2608              :       return __compare::__less(__t, __u);
    2609              :     }
    2610              : 
    2611              :   template<typename... _TElements, typename... _UElements>
    2612              :     constexpr bool
    2613              :     operator!=(const tuple<_TElements...>& __t,
    2614              :            const tuple<_UElements...>& __u)
    2615              :     { return !(__t == __u); }
    2616              : 
    2617              :   template<typename... _TElements, typename... _UElements>
    2618              :     constexpr bool
    2619              :     operator>(const tuple<_TElements...>& __t,
    2620              :           const tuple<_UElements...>& __u)
    2621              :     { return __u < __t; }
    2622              : 
    2623              :   template<typename... _TElements, typename... _UElements>
    2624              :     constexpr bool
    2625              :     operator<=(const tuple<_TElements...>& __t,
    2626              :            const tuple<_UElements...>& __u)
    2627              :     { return !(__u < __t); }
    2628              : 
    2629              :   template<typename... _TElements, typename... _UElements>
    2630              :     constexpr bool
    2631              :     operator>=(const tuple<_TElements...>& __t,
    2632              :            const tuple<_UElements...>& __u)
    2633              :     { return !(__t < __u); }
    2634              : #endif // three_way_comparison
    2635              : 
    2636              :   // NB: DR 705.
    2637              :   /// Create a tuple containing copies of the arguments
    2638              :   template<typename... _Elements>
    2639              :     constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
    2640              :     make_tuple(_Elements&&... __args)
    2641              :     {
    2642              :       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
    2643              :     __result_type;
    2644              :       return __result_type(std::forward<_Elements>(__args)...);
    2645              :     }
    2646              : 
    2647              :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
    2648              :   // 2275. Why is forward_as_tuple not constexpr?
    2649              :   /// Create a tuple of lvalue or rvalue references to the arguments
    2650              :   template<typename... _Elements>
    2651              :     constexpr tuple<_Elements&&...>
    2652              :     forward_as_tuple(_Elements&&... __args) noexcept
    2653              :     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
    2654              : 
    2655              :   /// @cond undocumented
    2656              :   template<size_t, typename, typename, size_t>
    2657              :     struct __make_tuple_impl;
    2658              : 
    2659              :   template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
    2660              :     struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
    2661              :     : __make_tuple_impl<_Idx + 1,
    2662              :             tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
    2663              :             _Tuple, _Nm>
    2664              :     { };
    2665              : 
    2666              :   template<size_t _Nm, typename _Tuple, typename... _Tp>
    2667              :     struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
    2668              :     {
    2669              :       typedef tuple<_Tp...> __type;
    2670              :     };
    2671              : 
    2672              :   template<typename _Tuple>
    2673              :     struct __do_make_tuple
    2674              :     : __make_tuple_impl<0, tuple<>, _Tuple, tuple_size<_Tuple>::value>
    2675              :     { };
    2676              : 
    2677              :   // Returns the std::tuple equivalent of a tuple-like type.
    2678              :   template<typename _Tuple>
    2679              :     struct __make_tuple
    2680              :     : public __do_make_tuple<__remove_cvref_t<_Tuple>>
    2681              :     { };
    2682              : 
    2683              :   // Combines several std::tuple's into a single one.
    2684              :   template<typename...>
    2685              :     struct __combine_tuples;
    2686              : 
    2687              :   template<>
    2688              :     struct __combine_tuples<>
    2689              :     {
    2690              :       typedef tuple<> __type;
    2691              :     };
    2692              : 
    2693              :   template<typename... _Ts>
    2694              :     struct __combine_tuples<tuple<_Ts...>>
    2695              :     {
    2696              :       typedef tuple<_Ts...> __type;
    2697              :     };
    2698              : 
    2699              :   template<typename... _T1s, typename... _T2s, typename... _Rem>
    2700              :     struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
    2701              :     {
    2702              :       typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
    2703              :                     _Rem...>::__type __type;
    2704              :     };
    2705              : 
    2706              :   // Computes the result type of tuple_cat given a set of tuple-like types.
    2707              :   template<typename... _Tpls>
    2708              :     struct __tuple_cat_result
    2709              :     {
    2710              :       typedef typename __combine_tuples
    2711              :         <typename __make_tuple<_Tpls>::__type...>::__type __type;
    2712              :     };
    2713              : 
    2714              :   // Helper to determine the index set for the first tuple-like
    2715              :   // type of a given set.
    2716              :   template<typename...>
    2717              :     struct __make_1st_indices;
    2718              : 
    2719              :   template<>
    2720              :     struct __make_1st_indices<>
    2721              :     {
    2722              :       typedef _Index_tuple<> __type;
    2723              :     };
    2724              : 
    2725              :   template<typename _Tp, typename... _Tpls>
    2726              :     struct __make_1st_indices<_Tp, _Tpls...>
    2727              :     {
    2728              :       typedef typename _Build_index_tuple<tuple_size<
    2729              :     typename remove_reference<_Tp>::type>::value>::__type __type;
    2730              :     };
    2731              : 
    2732              :   // Performs the actual concatenation by step-wise expanding tuple-like
    2733              :   // objects into the elements,  which are finally forwarded into the
    2734              :   // result tuple.
    2735              :   template<typename _Ret, typename _Indices, typename... _Tpls>
    2736              :     struct __tuple_concater;
    2737              : 
    2738              :   template<typename _Ret, size_t... _Is, typename _Tp, typename... _Tpls>
    2739              :     struct __tuple_concater<_Ret, _Index_tuple<_Is...>, _Tp, _Tpls...>
    2740              :     {
    2741              :       template<typename... _Us>
    2742              :         static constexpr _Ret
    2743              :         _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
    2744              :         {
    2745              :       typedef typename __make_1st_indices<_Tpls...>::__type __idx;
    2746              :       typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
    2747              :       return __next::_S_do(std::forward<_Tpls>(__tps)...,
    2748              :                    std::forward<_Us>(__us)...,
    2749              :                    std::get<_Is>(std::forward<_Tp>(__tp))...);
    2750              :     }
    2751              :     };
    2752              : 
    2753              :   template<typename _Ret>
    2754              :     struct __tuple_concater<_Ret, _Index_tuple<>>
    2755              :     {
    2756              :       template<typename... _Us>
    2757              :     static constexpr _Ret
    2758              :     _S_do(_Us&&... __us)
    2759              :         {
    2760              :       return _Ret(std::forward<_Us>(__us)...);
    2761              :     }
    2762              :     };
    2763              : 
    2764              :   template<typename... _Tps>
    2765              :     struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
    2766              :     { };
    2767              :   /// @endcond
    2768              : 
    2769              :   /// Create a `tuple` containing all elements from multiple tuple-like objects
    2770              : #if __cpp_lib_tuple_like // >= C++23
    2771              :   template<__tuple_like... _Tpls>
    2772              : #else
    2773              :   template<typename... _Tpls, typename = typename
    2774              :            enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
    2775              : #endif
    2776              :     constexpr auto
    2777              :     tuple_cat(_Tpls&&... __tpls)
    2778              :     -> typename __tuple_cat_result<_Tpls...>::__type
    2779              :     {
    2780              :       typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
    2781              :       typedef typename __make_1st_indices<_Tpls...>::__type __idx;
    2782              :       typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
    2783              :       return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
    2784              :     }
    2785              : 
    2786              :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
    2787              :   // 2301. Why is tie not constexpr?
    2788              :   /// Return a tuple of lvalue references bound to the arguments
    2789              :   template<typename... _Elements>
    2790              :     constexpr tuple<_Elements&...>
    2791              :     tie(_Elements&... __args) noexcept
    2792              :     { return tuple<_Elements&...>(__args...); }
    2793              : 
    2794              :   /// Exchange the values of two tuples
    2795              :   template<typename... _Elements>
    2796              :     _GLIBCXX20_CONSTEXPR
    2797              :     inline
    2798              : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
    2799              :     // Constrained free swap overload, see p0185r1
    2800              :     typename enable_if<__and_<__is_swappable<_Elements>...>::value
    2801              :       >::type
    2802              : #else
    2803              :     void
    2804              : #endif
    2805              :     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
    2806              :     noexcept(noexcept(__x.swap(__y)))
    2807              :     { __x.swap(__y); }
    2808              : 
    2809              : #if __cpp_lib_ranges_zip // >= C++23
    2810              :   template<typename... _Elements>
    2811              :     requires (is_swappable_v<const _Elements> && ...)
    2812              :     constexpr void
    2813              :     swap(const tuple<_Elements...>& __x, const tuple<_Elements...>& __y)
    2814              :     noexcept(noexcept(__x.swap(__y)))
    2815              :     { __x.swap(__y); }
    2816              : #endif // C++23
    2817              : 
    2818              : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
    2819              :   /// Exchange the values of two const tuples (if const elements can be swapped)
    2820              :   template<typename... _Elements>
    2821              :     _GLIBCXX20_CONSTEXPR
    2822              :     typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
    2823              :     swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
    2824              : #endif
    2825              : 
    2826              :   // A class (and instance) which can be used in 'tie' when an element
    2827              :   // of a tuple is not required.
    2828              :   // _GLIBCXX14_CONSTEXPR
    2829              :   // 2933. PR for LWG 2773 could be clearer
    2830              :   struct _Swallow_assign
    2831              :   {
    2832              :     template<class _Tp>
    2833              :       _GLIBCXX14_CONSTEXPR const _Swallow_assign&
    2834              :       operator=(const _Tp&) const
    2835              :       { return *this; }
    2836              :   };
    2837              : 
    2838              :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
    2839              :   // 2773. Making std::ignore constexpr
    2840              :   /** Used with `std::tie` to ignore an element of a tuple
    2841              :    *
    2842              :    * When using `std::tie` to assign the elements of a tuple to variables,
    2843              :    * unwanted elements can be ignored by using `std::ignore`. For example:
    2844              :    *
    2845              :    * ```
    2846              :    * int x, y;
    2847              :    * std::tie(x, std::ignore, y) = std::make_tuple(1, 2, 3);
    2848              :    * ```
    2849              :    *
    2850              :    * This assignment will perform `x=1; std::ignore=2; y=3;` which results
    2851              :    * in the second element being ignored.
    2852              :    *
    2853              :    * @since C++11
    2854              :    */
    2855              :   _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
    2856              : 
    2857              :   /// Partial specialization for tuples
    2858              :   template<typename... _Types, typename _Alloc>
    2859              :     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
    2860              : 
    2861              :   // See stl_pair.h...
    2862              :   /** "piecewise construction" using a tuple of arguments for each member.
    2863              :    *
    2864              :    * @param __first Arguments for the first member of the pair.
    2865              :    * @param __second Arguments for the second member of the pair.
    2866              :    *
    2867              :    * The elements of each tuple will be used as the constructor arguments
    2868              :    * for the data members of the pair.
    2869              :   */
    2870              :   template<class _T1, class _T2>
    2871              :     template<typename... _Args1, typename... _Args2>
    2872              :       _GLIBCXX20_CONSTEXPR
    2873              :       inline
    2874              :       pair<_T1, _T2>::
    2875              :       pair(piecewise_construct_t,
    2876              :        tuple<_Args1...> __first, tuple<_Args2...> __second)
    2877              :       : pair(__first, __second,
    2878              :          typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
    2879              :          typename _Build_index_tuple<sizeof...(_Args2)>::__type())
    2880              :       { }
    2881              : 
    2882              :   template<class _T1, class _T2>
    2883              :     template<typename... _Args1, size_t... _Indexes1,
    2884              :          typename... _Args2, size_t... _Indexes2>
    2885              :       _GLIBCXX20_CONSTEXPR inline
    2886              :       pair<_T1, _T2>::
    2887              :       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
    2888              :        _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
    2889              :       : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
    2890              :     second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
    2891              :       { }
    2892              : 
    2893              : #if defined(__cpp_lib_apply) || defined(__cpp_lib_make_from_tuple) // C++ >= 17
    2894              :   // Unpack a std::tuple into a type trait and use its value.
    2895              :   // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value.
    2896              :   // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value.
    2897              :   // Otherwise the result is false (because we don't know if std::get throws).
    2898              :   template<template<typename...> class _Trait, typename _Tp, typename _Tuple>
    2899              :     inline constexpr bool __unpack_std_tuple = false;
    2900              : 
    2901              :   template<template<typename...> class _Trait, typename _Tp, typename... _Up>
    2902              :     inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>>
    2903              :       = _Trait<_Tp, _Up...>::value;
    2904              : 
    2905              :   template<template<typename...> class _Trait, typename _Tp, typename... _Up>
    2906              :     inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&>
    2907              :       = _Trait<_Tp, _Up&...>::value;
    2908              : 
    2909              :   template<template<typename...> class _Trait, typename _Tp, typename... _Up>
    2910              :     inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>>
    2911              :       = _Trait<_Tp, const _Up...>::value;
    2912              : 
    2913              :   template<template<typename...> class _Trait, typename _Tp, typename... _Up>
    2914              :     inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&>
    2915              :       = _Trait<_Tp, const _Up&...>::value;
    2916              : #endif
    2917              : 
    2918              : #ifdef __cpp_lib_apply // C++ >= 17
    2919              :   template <typename _Fn, typename _Tuple, size_t... _Idx>
    2920              :     constexpr decltype(auto)
    2921              :     __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
    2922              :     {
    2923              :       return std::__invoke(std::forward<_Fn>(__f),
    2924              :                std::get<_Idx>(std::forward<_Tuple>(__t))...);
    2925              :     }
    2926              : 
    2927              : #if __cpp_lib_tuple_like // >= C++23
    2928              :   template <typename _Fn, __tuple_like _Tuple>
    2929              : #else
    2930              :   template <typename _Fn, typename _Tuple>
    2931              : #endif
    2932              :     constexpr decltype(auto)
    2933              :     apply(_Fn&& __f, _Tuple&& __t)
    2934              :     noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>)
    2935              :     {
    2936              :       using _Indices
    2937              :     = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>;
    2938              :       return std::__apply_impl(std::forward<_Fn>(__f),
    2939              :                    std::forward<_Tuple>(__t),
    2940              :                    _Indices{});
    2941              :     }
    2942              : #endif
    2943              : 
    2944              : #ifdef __cpp_lib_make_from_tuple // C++ >= 17
    2945              :   template <typename _Tp, typename _Tuple, size_t... _Idx>
    2946              :     constexpr _Tp
    2947              :     __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
    2948              :     { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
    2949              : 
    2950              : #if __cpp_lib_tuple_like // >= C++23
    2951              :   template <typename _Tp, __tuple_like _Tuple>
    2952              : #else
    2953              :   template <typename _Tp, typename _Tuple>
    2954              : #endif
    2955              :     constexpr _Tp
    2956              :     make_from_tuple(_Tuple&& __t)
    2957              :     noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)
    2958              :     {
    2959              :       constexpr size_t __n = tuple_size_v<remove_reference_t<_Tuple>>;
    2960              : #if __has_builtin(__reference_constructs_from_temporary)
    2961              :       if constexpr (__n == 1)
    2962              :     {
    2963              :       using _Elt = decltype(std::get<0>(std::declval<_Tuple>()));
    2964              :       static_assert(!__reference_constructs_from_temporary(_Tp, _Elt));
    2965              :     }
    2966              : #endif
    2967              :       return __make_from_tuple_impl<_Tp>(std::forward<_Tuple>(__t),
    2968              :                      make_index_sequence<__n>{});
    2969              :     }
    2970              : #endif
    2971              : 
    2972              : #if __cpp_lib_tuple_like // >= C++23
    2973              :   template<__tuple_like _TTuple, __tuple_like _UTuple,
    2974              :        template<typename> class _TQual, template<typename> class _UQual,
    2975              :        typename = make_index_sequence<tuple_size_v<_TTuple>>>
    2976              :   struct __tuple_like_common_reference;
    2977              : 
    2978              :   template<__tuple_like _TTuple, __tuple_like _UTuple,
    2979              :        template<typename> class _TQual, template<typename> class _UQual,
    2980              :        size_t... _Is>
    2981              :     requires requires
    2982              :       { typename tuple<common_reference_t<_TQual<tuple_element_t<_Is, _TTuple>>,
    2983              :                       _UQual<tuple_element_t<_Is, _UTuple>>>...>; }
    2984              :   struct __tuple_like_common_reference<_TTuple, _UTuple, _TQual, _UQual, index_sequence<_Is...>>
    2985              :   {
    2986              :     using type = tuple<common_reference_t<_TQual<tuple_element_t<_Is, _TTuple>>,
    2987              :                       _UQual<tuple_element_t<_Is, _UTuple>>>...>;
    2988              :   };
    2989              : 
    2990              :   template<__tuple_like _TTuple, __tuple_like _UTuple,
    2991              :        template<typename> class _TQual, template<typename> class _UQual>
    2992              :     requires (__is_tuple_v<_TTuple> || __is_tuple_v<_UTuple>)
    2993              :       && is_same_v<_TTuple, decay_t<_TTuple>>
    2994              :       && is_same_v<_UTuple, decay_t<_UTuple>>
    2995              :       && (tuple_size_v<_TTuple> == tuple_size_v<_UTuple>)
    2996              :       && requires { typename __tuple_like_common_reference<_TTuple, _UTuple, _TQual, _UQual>::type; }
    2997              :   struct basic_common_reference<_TTuple, _UTuple, _TQual, _UQual>
    2998              :   {
    2999              :     using type = typename __tuple_like_common_reference<_TTuple, _UTuple, _TQual, _UQual>::type;
    3000              :   };
    3001              : 
    3002              :   template<__tuple_like _TTuple, __tuple_like _UTuple,
    3003              :        typename = make_index_sequence<tuple_size_v<_TTuple>>>
    3004              :   struct __tuple_like_common_type;
    3005              : 
    3006              :   template<__tuple_like _TTuple, __tuple_like _UTuple, size_t... _Is>
    3007              :     requires requires
    3008              :       { typename tuple<common_type_t<tuple_element_t<_Is, _TTuple>,
    3009              :                    tuple_element_t<_Is, _UTuple>>...>; }
    3010              :   struct __tuple_like_common_type<_TTuple, _UTuple, index_sequence<_Is...>>
    3011              :   {
    3012              :     using type = tuple<common_type_t<tuple_element_t<_Is, _TTuple>,
    3013              :                      tuple_element_t<_Is, _UTuple>>...>;
    3014              :   };
    3015              : 
    3016              :   template<__tuple_like _TTuple, __tuple_like _UTuple>
    3017              :     requires (__is_tuple_v<_TTuple> || __is_tuple_v<_UTuple>)
    3018              :       && is_same_v<_TTuple, decay_t<_TTuple>>
    3019              :       && is_same_v<_UTuple, decay_t<_UTuple>>
    3020              :       && (tuple_size_v<_TTuple> == tuple_size_v<_UTuple>)
    3021              :       && requires { typename __tuple_like_common_type<_TTuple, _UTuple>::type; }
    3022              :   struct common_type<_TTuple, _UTuple>
    3023              :   {
    3024              :     using type = typename __tuple_like_common_type<_TTuple, _UTuple>::type;
    3025              :   };
    3026              : #endif // C++23
    3027              : 
    3028              :   /// @}
    3029              : 
    3030              : #undef __glibcxx_no_dangling_refs
    3031              : 
    3032              : _GLIBCXX_END_NAMESPACE_VERSION
    3033              : } // namespace std
    3034              : 
    3035              : #endif // C++11
    3036              : 
    3037              : #endif // _GLIBCXX_TUPLE
        

Generated by: LCOV version 2.0-1