LCOV - code coverage report
Current view: top level - usr/include/c++/12 - tuple (source / functions) Hit Total Coverage
Test: gcc.info Lines: 28 28 100.0 %
Date: 2023-07-19 08:18:47 Functions: 0 0 -

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

Generated by: LCOV version 1.16