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