LCOV - code coverage report
Current view: top level - usr/include/c++/9 - tuple (source / functions) Hit Total Coverage
Test: ROSE Lines: 43 65 66.2 %
Date: 2022-12-08 13:48:47 Functions: 0 15 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14