libstdc++
tuple
Go to the documentation of this file.
00001 // <tuple> -*- C++ -*-
00002 
00003 // Copyright (C) 2007-2017 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file include/tuple
00026  *  This is a Standard C++ Library header.
00027  */
00028 
00029 #ifndef _GLIBCXX_TUPLE
00030 #define _GLIBCXX_TUPLE 1
00031 
00032 #pragma GCC system_header
00033 
00034 #if __cplusplus < 201103L
00035 # include <bits/c++0x_warning.h>
00036 #else
00037 
00038 #include <utility>
00039 #include <array>
00040 #include <bits/uses_allocator.h>
00041 #include <bits/invoke.h>
00042 
00043 namespace std _GLIBCXX_VISIBILITY(default)
00044 {
00045 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00046 
00047   /**
00048    *  @addtogroup utilities
00049    *  @{
00050    */
00051 
00052   template<typename... _Elements>
00053     class tuple;
00054 
00055   template<typename _Tp>
00056     struct __is_empty_non_tuple : is_empty<_Tp> { };
00057 
00058   // Using EBO for elements that are tuples causes ambiguous base errors.
00059   template<typename _El0, typename... _El>
00060     struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
00061 
00062   // Use the Empty Base-class Optimization for empty, non-final types.
00063   template<typename _Tp>
00064     using __empty_not_final
00065     = typename conditional<__is_final(_Tp), false_type,
00066                            __is_empty_non_tuple<_Tp>>::type;
00067 
00068   template<std::size_t _Idx, typename _Head,
00069            bool = __empty_not_final<_Head>::value>
00070     struct _Head_base;
00071 
00072   template<std::size_t _Idx, typename _Head>
00073     struct _Head_base<_Idx, _Head, true>
00074     : public _Head
00075     {
00076       constexpr _Head_base()
00077       : _Head() { }
00078 
00079       constexpr _Head_base(const _Head& __h)
00080       : _Head(__h) { }
00081 
00082       constexpr _Head_base(const _Head_base&) = default;
00083       constexpr _Head_base(_Head_base&&) = default;
00084 
00085       template<typename _UHead>
00086         constexpr _Head_base(_UHead&& __h)
00087         : _Head(std::forward<_UHead>(__h)) { }
00088 
00089       _Head_base(allocator_arg_t, __uses_alloc0)
00090       : _Head() { }
00091 
00092       template<typename _Alloc>
00093         _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
00094         : _Head(allocator_arg, *__a._M_a) { }
00095 
00096       template<typename _Alloc>
00097         _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
00098         : _Head(*__a._M_a) { }
00099 
00100       template<typename _UHead>
00101         _Head_base(__uses_alloc0, _UHead&& __uhead)
00102         : _Head(std::forward<_UHead>(__uhead)) { }
00103 
00104       template<typename _Alloc, typename _UHead>
00105         _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
00106         : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
00107 
00108       template<typename _Alloc, typename _UHead>
00109         _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
00110         : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
00111 
00112       static constexpr _Head&
00113       _M_head(_Head_base& __b) noexcept { return __b; }
00114 
00115       static constexpr const _Head&
00116       _M_head(const _Head_base& __b) noexcept { return __b; }
00117     };
00118 
00119   template<std::size_t _Idx, typename _Head>
00120     struct _Head_base<_Idx, _Head, false>
00121     {
00122       constexpr _Head_base()
00123       : _M_head_impl() { }
00124 
00125       constexpr _Head_base(const _Head& __h)
00126       : _M_head_impl(__h) { }
00127 
00128       constexpr _Head_base(const _Head_base&) = default;
00129       constexpr _Head_base(_Head_base&&) = default;
00130 
00131       template<typename _UHead>
00132         constexpr _Head_base(_UHead&& __h)
00133         : _M_head_impl(std::forward<_UHead>(__h)) { }
00134 
00135       _Head_base(allocator_arg_t, __uses_alloc0)
00136       : _M_head_impl() { }
00137 
00138       template<typename _Alloc>
00139         _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
00140         : _M_head_impl(allocator_arg, *__a._M_a) { }
00141 
00142       template<typename _Alloc>
00143         _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
00144         : _M_head_impl(*__a._M_a) { }
00145 
00146       template<typename _UHead>
00147         _Head_base(__uses_alloc0, _UHead&& __uhead)
00148         : _M_head_impl(std::forward<_UHead>(__uhead)) { }
00149 
00150       template<typename _Alloc, typename _UHead>
00151         _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
00152         : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
00153         { }
00154 
00155       template<typename _Alloc, typename _UHead>
00156         _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
00157         : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
00158 
00159       static constexpr _Head&
00160       _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
00161 
00162       static constexpr const _Head&
00163       _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
00164 
00165       _Head _M_head_impl;
00166     };
00167 
00168   /**
00169    * Contains the actual implementation of the @c tuple template, stored
00170    * as a recursive inheritance hierarchy from the first element (most
00171    * derived class) to the last (least derived class). The @c Idx
00172    * parameter gives the 0-based index of the element stored at this
00173    * point in the hierarchy; we use it to implement a constant-time
00174    * get() operation.
00175    */
00176   template<std::size_t _Idx, typename... _Elements>
00177     struct _Tuple_impl;
00178 
00179   /**
00180    * Recursive tuple implementation. Here we store the @c Head element
00181    * and derive from a @c Tuple_impl containing the remaining elements
00182    * (which contains the @c Tail).
00183    */
00184   template<std::size_t _Idx, typename _Head, typename... _Tail>
00185     struct _Tuple_impl<_Idx, _Head, _Tail...>
00186     : public _Tuple_impl<_Idx + 1, _Tail...>,
00187       private _Head_base<_Idx, _Head>
00188     {
00189       template<std::size_t, typename...> friend class _Tuple_impl;
00190 
00191       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
00192       typedef _Head_base<_Idx, _Head> _Base;
00193 
00194       static constexpr _Head&
00195       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
00196 
00197       static constexpr const _Head&
00198       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
00199 
00200       static constexpr _Inherited&
00201       _M_tail(_Tuple_impl& __t) noexcept { return __t; }
00202 
00203       static constexpr const _Inherited&
00204       _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
00205 
00206       constexpr _Tuple_impl()
00207       : _Inherited(), _Base() { }
00208 
00209       explicit
00210       constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
00211       : _Inherited(__tail...), _Base(__head) { }
00212 
00213       template<typename _UHead, typename... _UTail, typename = typename
00214                enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
00215         explicit
00216         constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
00217         : _Inherited(std::forward<_UTail>(__tail)...),
00218           _Base(std::forward<_UHead>(__head)) { }
00219 
00220       constexpr _Tuple_impl(const _Tuple_impl&) = default;
00221 
00222       constexpr
00223       _Tuple_impl(_Tuple_impl&& __in)
00224       noexcept(__and_<is_nothrow_move_constructible<_Head>,
00225                       is_nothrow_move_constructible<_Inherited>>::value)
00226       : _Inherited(std::move(_M_tail(__in))),
00227         _Base(std::forward<_Head>(_M_head(__in))) { }
00228 
00229       template<typename... _UElements>
00230         constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
00231         : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
00232           _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
00233 
00234       template<typename _UHead, typename... _UTails>
00235         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
00236         : _Inherited(std::move
00237                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
00238           _Base(std::forward<_UHead>
00239                 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
00240 
00241       template<typename _Alloc>
00242         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
00243         : _Inherited(__tag, __a),
00244           _Base(__tag, __use_alloc<_Head>(__a)) { }
00245 
00246       template<typename _Alloc>
00247         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00248                     const _Head& __head, const _Tail&... __tail)
00249         : _Inherited(__tag, __a, __tail...),
00250           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
00251 
00252       template<typename _Alloc, typename _UHead, typename... _UTail,
00253                typename = typename enable_if<sizeof...(_Tail)
00254                                              == sizeof...(_UTail)>::type>
00255         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00256                     _UHead&& __head, _UTail&&... __tail)
00257         : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
00258           _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
00259                 std::forward<_UHead>(__head)) { }
00260 
00261       template<typename _Alloc>
00262         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00263                     const _Tuple_impl& __in)
00264         : _Inherited(__tag, __a, _M_tail(__in)),
00265           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
00266 
00267       template<typename _Alloc>
00268         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00269                     _Tuple_impl&& __in)
00270         : _Inherited(__tag, __a, std::move(_M_tail(__in))),
00271           _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
00272                 std::forward<_Head>(_M_head(__in))) { }
00273 
00274       template<typename _Alloc, typename... _UElements>
00275         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00276                     const _Tuple_impl<_Idx, _UElements...>& __in)
00277         : _Inherited(__tag, __a,
00278                      _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
00279           _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
00280                 _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
00281 
00282       template<typename _Alloc, typename _UHead, typename... _UTails>
00283         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00284                     _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
00285         : _Inherited(__tag, __a, std::move
00286                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
00287           _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
00288                 std::forward<_UHead>
00289                 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
00290 
00291       _Tuple_impl&
00292       operator=(const _Tuple_impl& __in)
00293       {
00294         _M_head(*this) = _M_head(__in);
00295         _M_tail(*this) = _M_tail(__in);
00296         return *this;
00297       }
00298 
00299       _Tuple_impl&
00300       operator=(_Tuple_impl&& __in)
00301       noexcept(__and_<is_nothrow_move_assignable<_Head>,
00302                       is_nothrow_move_assignable<_Inherited>>::value)
00303       {
00304         _M_head(*this) = std::forward<_Head>(_M_head(__in));
00305         _M_tail(*this) = std::move(_M_tail(__in));
00306         return *this;
00307       }
00308 
00309       template<typename... _UElements>
00310         _Tuple_impl&
00311         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
00312         {
00313           _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
00314           _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in);
00315           return *this;
00316         }
00317 
00318       template<typename _UHead, typename... _UTails>
00319         _Tuple_impl&
00320         operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
00321         {
00322           _M_head(*this) = std::forward<_UHead>
00323             (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
00324           _M_tail(*this) = std::move
00325             (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in));
00326           return *this;
00327         }
00328 
00329     protected:
00330       void
00331       _M_swap(_Tuple_impl& __in)
00332       noexcept(__is_nothrow_swappable<_Head>::value
00333                && noexcept(_M_tail(__in)._M_swap(_M_tail(__in))))
00334       {
00335         using std::swap;
00336         swap(_M_head(*this), _M_head(__in));
00337         _Inherited::_M_swap(_M_tail(__in));
00338       }
00339     };
00340 
00341   // Basis case of inheritance recursion.
00342   template<std::size_t _Idx, typename _Head>
00343     struct _Tuple_impl<_Idx, _Head>
00344     : private _Head_base<_Idx, _Head>
00345     {
00346       template<std::size_t, typename...> friend class _Tuple_impl;
00347 
00348       typedef _Head_base<_Idx, _Head> _Base;
00349 
00350       static constexpr _Head&
00351       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
00352 
00353       static constexpr const _Head&
00354       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
00355 
00356       constexpr _Tuple_impl()
00357       : _Base() { }
00358 
00359       explicit
00360       constexpr _Tuple_impl(const _Head& __head)
00361       : _Base(__head) { }
00362 
00363       template<typename _UHead>
00364         explicit
00365         constexpr _Tuple_impl(_UHead&& __head)
00366         : _Base(std::forward<_UHead>(__head)) { }
00367 
00368       constexpr _Tuple_impl(const _Tuple_impl&) = default;
00369 
00370       constexpr
00371       _Tuple_impl(_Tuple_impl&& __in)
00372       noexcept(is_nothrow_move_constructible<_Head>::value)
00373       : _Base(std::forward<_Head>(_M_head(__in))) { }
00374 
00375       template<typename _UHead>
00376         constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
00377         : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
00378 
00379       template<typename _UHead>
00380         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
00381         : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
00382         { }
00383 
00384       template<typename _Alloc>
00385         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
00386         : _Base(__tag, __use_alloc<_Head>(__a)) { }
00387 
00388       template<typename _Alloc>
00389         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00390                     const _Head& __head)
00391         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
00392 
00393       template<typename _Alloc, typename _UHead>
00394         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00395                     _UHead&& __head)
00396         : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
00397                 std::forward<_UHead>(__head)) { }
00398 
00399       template<typename _Alloc>
00400         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00401                     const _Tuple_impl& __in)
00402         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
00403 
00404       template<typename _Alloc>
00405         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00406                     _Tuple_impl&& __in)
00407         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
00408                 std::forward<_Head>(_M_head(__in))) { }
00409 
00410       template<typename _Alloc, typename _UHead>
00411         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00412                     const _Tuple_impl<_Idx, _UHead>& __in)
00413         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
00414                 _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
00415 
00416       template<typename _Alloc, typename _UHead>
00417         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00418                     _Tuple_impl<_Idx, _UHead>&& __in)
00419         : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
00420                 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
00421         { }
00422 
00423       _Tuple_impl&
00424       operator=(const _Tuple_impl& __in)
00425       {
00426         _M_head(*this) = _M_head(__in);
00427         return *this;
00428       }
00429 
00430       _Tuple_impl&
00431       operator=(_Tuple_impl&& __in)
00432       noexcept(is_nothrow_move_assignable<_Head>::value)
00433       {
00434         _M_head(*this) = std::forward<_Head>(_M_head(__in));
00435         return *this;
00436       }
00437 
00438       template<typename _UHead>
00439         _Tuple_impl&
00440         operator=(const _Tuple_impl<_Idx, _UHead>& __in)
00441         {
00442           _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
00443           return *this;
00444         }
00445 
00446       template<typename _UHead>
00447         _Tuple_impl&
00448         operator=(_Tuple_impl<_Idx, _UHead>&& __in)
00449         {
00450           _M_head(*this)
00451             = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
00452           return *this;
00453         }
00454 
00455     protected:
00456       void
00457       _M_swap(_Tuple_impl& __in)
00458       noexcept(__is_nothrow_swappable<_Head>::value)
00459       {
00460         using std::swap;
00461         swap(_M_head(*this), _M_head(__in));
00462       }
00463     };
00464 
00465   // Concept utility functions, reused in conditionally-explicit
00466   // constructors.
00467   template<bool, typename... _Elements>
00468   struct _TC
00469   {
00470     template<typename... _UElements>
00471     static constexpr bool _ConstructibleTuple()
00472     {
00473       return __and_<is_constructible<_Elements, const _UElements&>...>::value;
00474     }
00475 
00476     template<typename... _UElements>
00477     static constexpr bool _ImplicitlyConvertibleTuple()
00478     {
00479       return __and_<is_convertible<const _UElements&, _Elements>...>::value;
00480     }
00481 
00482     template<typename... _UElements>
00483     static constexpr bool _MoveConstructibleTuple()
00484     {
00485       return __and_<is_constructible<_Elements, _UElements&&>...>::value;
00486     }
00487 
00488     template<typename... _UElements>
00489     static constexpr bool _ImplicitlyMoveConvertibleTuple()
00490     {
00491       return __and_<is_convertible<_UElements&&, _Elements>...>::value;
00492     }
00493 
00494     template<typename _SrcTuple>
00495     static constexpr bool _NonNestedTuple()
00496     {
00497       return  __and_<__not_<is_same<tuple<_Elements...>,
00498                                    typename remove_cv<
00499                                      typename remove_reference<_SrcTuple>::type
00500                                    >::type>>,
00501                      __not_<is_convertible<_SrcTuple, _Elements...>>,
00502                      __not_<is_constructible<_Elements..., _SrcTuple>>
00503               >::value;
00504     }
00505     template<typename... _UElements>
00506     static constexpr bool _NotSameTuple()
00507     {
00508       return  __not_<is_same<tuple<_Elements...>,
00509                              typename remove_const<
00510                                typename remove_reference<_UElements...>::type
00511                                >::type>>::value;
00512     }
00513   };
00514 
00515   template<typename... _Elements>
00516   struct _TC<false, _Elements...>
00517   {
00518     template<typename... _UElements>
00519     static constexpr bool _ConstructibleTuple()
00520     {
00521       return false;
00522     }
00523 
00524     template<typename... _UElements>
00525     static constexpr bool _ImplicitlyConvertibleTuple()
00526     {
00527       return false;
00528     }
00529 
00530     template<typename... _UElements>
00531     static constexpr bool _MoveConstructibleTuple()
00532     {
00533       return false;
00534     }
00535 
00536     template<typename... _UElements>
00537     static constexpr bool _ImplicitlyMoveConvertibleTuple()
00538     {
00539       return false;
00540     }
00541 
00542     template<typename... _UElements>
00543     static constexpr bool _NonNestedTuple()
00544     {
00545       return true;
00546     }
00547     template<typename... _UElements>
00548     static constexpr bool _NotSameTuple()
00549     {
00550       return  true;
00551     }
00552   };
00553 
00554   /// Primary class template, tuple
00555   template<typename... _Elements>
00556     class tuple : public _Tuple_impl<0, _Elements...>
00557     {
00558       typedef _Tuple_impl<0, _Elements...> _Inherited;
00559 
00560       // Used for constraining the default constructor so
00561       // that it becomes dependent on the constraints.
00562       template<typename _Dummy>
00563       struct _TC2
00564       {
00565         static constexpr bool _DefaultConstructibleTuple()
00566         {
00567           return __and_<is_default_constructible<_Elements>...>::value;
00568         }
00569         static constexpr bool _ImplicitlyDefaultConstructibleTuple()
00570         {
00571           return __and_<__is_implicitly_default_constructible<_Elements>...>
00572             ::value;
00573         }
00574       };
00575 
00576     public:
00577       template<typename _Dummy = void,
00578                typename enable_if<_TC2<_Dummy>::
00579                                     _ImplicitlyDefaultConstructibleTuple(),
00580                                   bool>::type = true>
00581       constexpr tuple()
00582       : _Inherited() { }
00583 
00584       template<typename _Dummy = void,
00585                typename enable_if<_TC2<_Dummy>::
00586                                     _DefaultConstructibleTuple()
00587                                   &&
00588                                   !_TC2<_Dummy>::
00589                                     _ImplicitlyDefaultConstructibleTuple(),
00590                                   bool>::type = false>
00591       explicit constexpr tuple()
00592       : _Inherited() { }
00593 
00594       // Shortcut for the cases where constructors taking _Elements...
00595       // need to be constrained.
00596       template<typename _Dummy> using _TCC =
00597         _TC<is_same<_Dummy, void>::value,
00598             _Elements...>;
00599 
00600       template<typename _Dummy = void,
00601                typename enable_if<
00602                  _TCC<_Dummy>::template
00603                    _ConstructibleTuple<_Elements...>()
00604                  && _TCC<_Dummy>::template
00605                    _ImplicitlyConvertibleTuple<_Elements...>()
00606                  && (sizeof...(_Elements) >= 1),
00607                bool>::type=true>
00608         constexpr tuple(const _Elements&... __elements)
00609       : _Inherited(__elements...) { }
00610 
00611       template<typename _Dummy = void,
00612                typename enable_if<
00613                  _TCC<_Dummy>::template
00614                    _ConstructibleTuple<_Elements...>()
00615                  && !_TCC<_Dummy>::template
00616                    _ImplicitlyConvertibleTuple<_Elements...>()
00617                  && (sizeof...(_Elements) >= 1),
00618                bool>::type=false>
00619       explicit constexpr tuple(const _Elements&... __elements)
00620       : _Inherited(__elements...) { }
00621 
00622       // Shortcut for the cases where constructors taking _UElements...
00623       // need to be constrained.
00624       template<typename... _UElements> using _TMC =
00625                   _TC<(sizeof...(_Elements) == sizeof...(_UElements))
00626                       && (_TC<(sizeof...(_UElements)==1), _Elements...>::
00627                           template _NotSameTuple<_UElements...>()),
00628                       _Elements...>;
00629 
00630       // Shortcut for the cases where constructors taking tuple<_UElements...>
00631       // need to be constrained.
00632       template<typename... _UElements> using _TMCT =
00633                   _TC<(sizeof...(_Elements) == sizeof...(_UElements))
00634                       && !is_same<tuple<_Elements...>,
00635                                   tuple<_UElements...>>::value,
00636                       _Elements...>;
00637 
00638       template<typename... _UElements, typename
00639                enable_if<
00640                   _TMC<_UElements...>::template
00641                     _MoveConstructibleTuple<_UElements...>()
00642                   && _TMC<_UElements...>::template
00643                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
00644                   && (sizeof...(_Elements) >= 1),
00645         bool>::type=true>
00646         constexpr tuple(_UElements&&... __elements)
00647         : _Inherited(std::forward<_UElements>(__elements)...) { }
00648 
00649       template<typename... _UElements, typename
00650         enable_if<
00651                   _TMC<_UElements...>::template
00652                     _MoveConstructibleTuple<_UElements...>()
00653                   && !_TMC<_UElements...>::template
00654                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
00655                   && (sizeof...(_Elements) >= 1),
00656         bool>::type=false>
00657         explicit constexpr tuple(_UElements&&... __elements)
00658         : _Inherited(std::forward<_UElements>(__elements)...) { }
00659 
00660       constexpr tuple(const tuple&) = default;
00661 
00662       constexpr tuple(tuple&&) = default;
00663 
00664       // Shortcut for the cases where constructors taking tuples
00665       // must avoid creating temporaries.
00666       template<typename _Dummy> using _TNTC =
00667         _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1,
00668             _Elements...>;
00669 
00670       template<typename... _UElements, typename _Dummy = void, typename
00671         enable_if<_TMCT<_UElements...>::template
00672                     _ConstructibleTuple<_UElements...>()
00673                   && _TMCT<_UElements...>::template
00674                     _ImplicitlyConvertibleTuple<_UElements...>()
00675                   && _TNTC<_Dummy>::template
00676                     _NonNestedTuple<const tuple<_UElements...>&>(),
00677         bool>::type=true>
00678         constexpr tuple(const tuple<_UElements...>& __in)
00679         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
00680         { }
00681 
00682       template<typename... _UElements, typename _Dummy = void, typename
00683         enable_if<_TMCT<_UElements...>::template
00684                     _ConstructibleTuple<_UElements...>()
00685                   && !_TMCT<_UElements...>::template
00686                     _ImplicitlyConvertibleTuple<_UElements...>()
00687                   && _TNTC<_Dummy>::template
00688                     _NonNestedTuple<const tuple<_UElements...>&>(),
00689         bool>::type=false>
00690         explicit constexpr tuple(const tuple<_UElements...>& __in)
00691         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
00692         { }
00693 
00694       template<typename... _UElements, typename _Dummy = void, typename
00695         enable_if<_TMCT<_UElements...>::template
00696                     _MoveConstructibleTuple<_UElements...>()
00697                   && _TMCT<_UElements...>::template
00698                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
00699                   && _TNTC<_Dummy>::template
00700                     _NonNestedTuple<tuple<_UElements...>&&>(),
00701         bool>::type=true>
00702         constexpr tuple(tuple<_UElements...>&& __in)
00703         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
00704 
00705       template<typename... _UElements, typename _Dummy = void, typename
00706         enable_if<_TMCT<_UElements...>::template
00707                     _MoveConstructibleTuple<_UElements...>()
00708                   && !_TMCT<_UElements...>::template
00709                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
00710                   && _TNTC<_Dummy>::template
00711                     _NonNestedTuple<tuple<_UElements...>&&>(),
00712         bool>::type=false>
00713         explicit constexpr tuple(tuple<_UElements...>&& __in)
00714         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
00715 
00716       // Allocator-extended constructors.
00717 
00718       template<typename _Alloc>
00719         tuple(allocator_arg_t __tag, const _Alloc& __a)
00720         : _Inherited(__tag, __a) { }
00721 
00722       template<typename _Alloc, typename _Dummy = void,
00723                typename enable_if<
00724                  _TCC<_Dummy>::template
00725                    _ConstructibleTuple<_Elements...>()
00726                  && _TCC<_Dummy>::template
00727                    _ImplicitlyConvertibleTuple<_Elements...>(),
00728                bool>::type=true>
00729         tuple(allocator_arg_t __tag, const _Alloc& __a,
00730               const _Elements&... __elements)
00731         : _Inherited(__tag, __a, __elements...) { }
00732 
00733       template<typename _Alloc, typename _Dummy = void,
00734                typename enable_if<
00735                  _TCC<_Dummy>::template
00736                    _ConstructibleTuple<_Elements...>()
00737                  && !_TCC<_Dummy>::template
00738                    _ImplicitlyConvertibleTuple<_Elements...>(),
00739                bool>::type=false>
00740         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
00741                        const _Elements&... __elements)
00742         : _Inherited(__tag, __a, __elements...) { }
00743 
00744       template<typename _Alloc, typename... _UElements, typename
00745         enable_if<_TMC<_UElements...>::template
00746                     _MoveConstructibleTuple<_UElements...>()
00747                   && _TMC<_UElements...>::template
00748                     _ImplicitlyMoveConvertibleTuple<_UElements...>(),
00749         bool>::type=true>
00750         tuple(allocator_arg_t __tag, const _Alloc& __a,
00751               _UElements&&... __elements)
00752         : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
00753         { }
00754 
00755       template<typename _Alloc, typename... _UElements, typename
00756         enable_if<_TMC<_UElements...>::template
00757                     _MoveConstructibleTuple<_UElements...>()
00758                   && !_TMC<_UElements...>::template
00759                     _ImplicitlyMoveConvertibleTuple<_UElements...>(),
00760         bool>::type=false>
00761         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
00762               _UElements&&... __elements)
00763         : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
00764         { }
00765 
00766       template<typename _Alloc>
00767         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
00768         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
00769 
00770       template<typename _Alloc>
00771         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
00772         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
00773 
00774       template<typename _Alloc, typename _Dummy = void,
00775                typename... _UElements, typename
00776         enable_if<_TMCT<_UElements...>::template
00777                     _ConstructibleTuple<_UElements...>()
00778                   && _TMCT<_UElements...>::template
00779                     _ImplicitlyConvertibleTuple<_UElements...>()
00780                   && _TNTC<_Dummy>::template
00781                     _NonNestedTuple<tuple<_UElements...>&&>(),
00782         bool>::type=true>
00783         tuple(allocator_arg_t __tag, const _Alloc& __a,
00784               const tuple<_UElements...>& __in)
00785         : _Inherited(__tag, __a,
00786                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
00787         { }
00788 
00789       template<typename _Alloc, typename _Dummy = void,
00790                typename... _UElements, typename
00791         enable_if<_TMCT<_UElements...>::template
00792                     _ConstructibleTuple<_UElements...>()
00793                   && !_TMCT<_UElements...>::template
00794                     _ImplicitlyConvertibleTuple<_UElements...>()
00795                   && _TNTC<_Dummy>::template
00796                     _NonNestedTuple<tuple<_UElements...>&&>(),
00797         bool>::type=false>
00798         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
00799               const tuple<_UElements...>& __in)
00800         : _Inherited(__tag, __a,
00801                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
00802         { }
00803 
00804       template<typename _Alloc, typename _Dummy = void,
00805                typename... _UElements, typename
00806         enable_if<_TMCT<_UElements...>::template
00807                     _MoveConstructibleTuple<_UElements...>()
00808                   && _TMCT<_UElements...>::template
00809                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
00810                   && _TNTC<_Dummy>::template
00811                     _NonNestedTuple<tuple<_UElements...>&&>(),
00812         bool>::type=true>
00813         tuple(allocator_arg_t __tag, const _Alloc& __a,
00814               tuple<_UElements...>&& __in)
00815         : _Inherited(__tag, __a,
00816                      static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
00817         { }
00818 
00819       template<typename _Alloc, typename _Dummy = void,
00820                typename... _UElements, typename
00821         enable_if<_TMCT<_UElements...>::template
00822                     _MoveConstructibleTuple<_UElements...>()
00823                   && !_TMCT<_UElements...>::template
00824                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
00825                   && _TNTC<_Dummy>::template
00826                     _NonNestedTuple<tuple<_UElements...>&&>(),
00827         bool>::type=false>
00828         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
00829               tuple<_UElements...>&& __in)
00830         : _Inherited(__tag, __a,
00831                      static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
00832         { }
00833 
00834       tuple&
00835       operator=(const tuple& __in)
00836       {
00837         static_cast<_Inherited&>(*this) = __in;
00838         return *this;
00839       }
00840 
00841       tuple&
00842       operator=(tuple&& __in)
00843       noexcept(is_nothrow_move_assignable<_Inherited>::value)
00844       {
00845         static_cast<_Inherited&>(*this) = std::move(__in);
00846         return *this;
00847       }
00848 
00849       template<typename... _UElements>
00850         typename
00851                enable_if<sizeof...(_UElements)
00852                          == sizeof...(_Elements), tuple&>::type
00853         operator=(const tuple<_UElements...>& __in)
00854         {
00855           static_cast<_Inherited&>(*this) = __in;
00856           return *this;
00857         }
00858 
00859       template<typename... _UElements>
00860         typename
00861                enable_if<sizeof...(_UElements)
00862                          == sizeof...(_Elements), tuple&>::type
00863         operator=(tuple<_UElements...>&& __in)
00864         {
00865           static_cast<_Inherited&>(*this) = std::move(__in);
00866           return *this;
00867         }
00868 
00869       void
00870       swap(tuple& __in)
00871       noexcept(noexcept(__in._M_swap(__in)))
00872       { _Inherited::_M_swap(__in); }
00873     };
00874 
00875 #if __cpp_deduction_guides >= 201606
00876   template<typename... _UTypes>
00877     tuple(_UTypes...) -> tuple<_UTypes...>;
00878   template<typename _T1, typename _T2>
00879     tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
00880   template<typename _Alloc, typename... _UTypes>
00881     tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
00882   template<typename _Alloc, typename _T1, typename _T2>
00883     tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
00884   template<typename _Alloc, typename... _UTypes>
00885     tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
00886 #endif
00887 
00888   // Explicit specialization, zero-element tuple.
00889   template<>
00890     class tuple<>
00891     {
00892     public:
00893       void swap(tuple&) noexcept { /* no-op */ }
00894       // We need the default since we're going to define no-op
00895       // allocator constructors.
00896       tuple() = default;
00897       // No-op allocator constructors.
00898       template<typename _Alloc>
00899         tuple(allocator_arg_t, const _Alloc&) { }
00900       template<typename _Alloc>
00901         tuple(allocator_arg_t, const _Alloc&, const tuple&) { }
00902     };
00903 
00904   /// Partial specialization, 2-element tuple.
00905   /// Includes construction and assignment from a pair.
00906   template<typename _T1, typename _T2>
00907     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
00908     {
00909       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
00910 
00911     public:
00912       template <typename _U1 = _T1,
00913                 typename _U2 = _T2,
00914                 typename enable_if<__and_<
00915                                      __is_implicitly_default_constructible<_U1>,
00916                                      __is_implicitly_default_constructible<_U2>>
00917                                    ::value, bool>::type = true>
00918 
00919       constexpr tuple()
00920       : _Inherited() { }
00921 
00922       template <typename _U1 = _T1,
00923                 typename _U2 = _T2,
00924                 typename enable_if<
00925                   __and_<
00926                     is_default_constructible<_U1>,
00927                     is_default_constructible<_U2>,
00928                     __not_<
00929                       __and_<__is_implicitly_default_constructible<_U1>,
00930                              __is_implicitly_default_constructible<_U2>>>>
00931                   ::value, bool>::type = false>
00932 
00933       explicit constexpr tuple()
00934       : _Inherited() { }
00935 
00936       // Shortcut for the cases where constructors taking _T1, _T2
00937       // need to be constrained.
00938       template<typename _Dummy> using _TCC =
00939         _TC<is_same<_Dummy, void>::value, _T1, _T2>;
00940 
00941       template<typename _Dummy = void, typename
00942                enable_if<_TCC<_Dummy>::template
00943                            _ConstructibleTuple<_T1, _T2>()
00944                          && _TCC<_Dummy>::template
00945                            _ImplicitlyConvertibleTuple<_T1, _T2>(),
00946         bool>::type = true>
00947         constexpr tuple(const _T1& __a1, const _T2& __a2)
00948         : _Inherited(__a1, __a2) { }
00949 
00950       template<typename _Dummy = void, typename
00951                enable_if<_TCC<_Dummy>::template
00952                            _ConstructibleTuple<_T1, _T2>()
00953                          && !_TCC<_Dummy>::template
00954                            _ImplicitlyConvertibleTuple<_T1, _T2>(),
00955         bool>::type = false>
00956         explicit constexpr tuple(const _T1& __a1, const _T2& __a2)
00957         : _Inherited(__a1, __a2) { }
00958 
00959       // Shortcut for the cases where constructors taking _U1, _U2
00960       // need to be constrained.
00961       using _TMC = _TC<true, _T1, _T2>;
00962 
00963       template<typename _U1, typename _U2, typename
00964         enable_if<_TMC::template
00965                     _MoveConstructibleTuple<_U1, _U2>()
00966                   && _TMC::template
00967                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
00968                   && !is_same<typename decay<_U1>::type,
00969                               allocator_arg_t>::value,
00970         bool>::type = true>
00971         constexpr tuple(_U1&& __a1, _U2&& __a2)
00972         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
00973 
00974       template<typename _U1, typename _U2, typename
00975         enable_if<_TMC::template
00976                     _MoveConstructibleTuple<_U1, _U2>()
00977                   && !_TMC::template
00978                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
00979                   && !is_same<typename decay<_U1>::type,
00980                               allocator_arg_t>::value,
00981         bool>::type = false>
00982         explicit constexpr tuple(_U1&& __a1, _U2&& __a2)
00983         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
00984 
00985       constexpr tuple(const tuple&) = default;
00986 
00987       constexpr tuple(tuple&&) = default;
00988 
00989       template<typename _U1, typename _U2, typename
00990         enable_if<_TMC::template
00991                     _ConstructibleTuple<_U1, _U2>()
00992                   && _TMC::template
00993                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
00994         bool>::type = true>
00995         constexpr tuple(const tuple<_U1, _U2>& __in)
00996         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
00997 
00998       template<typename _U1, typename _U2, typename
00999         enable_if<_TMC::template
01000                     _ConstructibleTuple<_U1, _U2>()
01001                   && !_TMC::template
01002                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01003         bool>::type = false>
01004         explicit constexpr tuple(const tuple<_U1, _U2>& __in)
01005         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
01006 
01007       template<typename _U1, typename _U2, typename
01008         enable_if<_TMC::template
01009                     _MoveConstructibleTuple<_U1, _U2>()
01010                   && _TMC::template
01011                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01012         bool>::type = true>
01013         constexpr tuple(tuple<_U1, _U2>&& __in)
01014         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
01015 
01016       template<typename _U1, typename _U2, typename
01017         enable_if<_TMC::template
01018                     _MoveConstructibleTuple<_U1, _U2>()
01019                   && !_TMC::template
01020                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01021         bool>::type = false>
01022         explicit constexpr tuple(tuple<_U1, _U2>&& __in)
01023         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
01024 
01025       template<typename _U1, typename _U2, typename
01026         enable_if<_TMC::template
01027                     _ConstructibleTuple<_U1, _U2>()
01028                   && _TMC::template
01029                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01030         bool>::type = true>
01031         constexpr tuple(const pair<_U1, _U2>& __in)
01032         : _Inherited(__in.first, __in.second) { }
01033 
01034       template<typename _U1, typename _U2, typename
01035         enable_if<_TMC::template
01036                     _ConstructibleTuple<_U1, _U2>()
01037                   && !_TMC::template
01038                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01039         bool>::type = false>
01040         explicit constexpr tuple(const pair<_U1, _U2>& __in)
01041         : _Inherited(__in.first, __in.second) { }
01042 
01043       template<typename _U1, typename _U2, typename
01044         enable_if<_TMC::template
01045                     _MoveConstructibleTuple<_U1, _U2>()
01046                   && _TMC::template
01047                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01048         bool>::type = true>
01049         constexpr tuple(pair<_U1, _U2>&& __in)
01050         : _Inherited(std::forward<_U1>(__in.first),
01051                      std::forward<_U2>(__in.second)) { }
01052 
01053       template<typename _U1, typename _U2, typename
01054         enable_if<_TMC::template
01055                     _MoveConstructibleTuple<_U1, _U2>()
01056                   && !_TMC::template
01057                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01058         bool>::type = false>
01059         explicit constexpr tuple(pair<_U1, _U2>&& __in)
01060         : _Inherited(std::forward<_U1>(__in.first),
01061                      std::forward<_U2>(__in.second)) { }
01062 
01063       // Allocator-extended constructors.
01064 
01065       template<typename _Alloc>
01066         tuple(allocator_arg_t __tag, const _Alloc& __a)
01067         : _Inherited(__tag, __a) { }
01068 
01069       template<typename _Alloc, typename _Dummy = void,
01070                typename enable_if<
01071                  _TCC<_Dummy>::template
01072                    _ConstructibleTuple<_T1, _T2>()
01073                  && _TCC<_Dummy>::template
01074                    _ImplicitlyConvertibleTuple<_T1, _T2>(),
01075                bool>::type=true>
01076 
01077         tuple(allocator_arg_t __tag, const _Alloc& __a,
01078               const _T1& __a1, const _T2& __a2)
01079         : _Inherited(__tag, __a, __a1, __a2) { }
01080 
01081       template<typename _Alloc, typename _Dummy = void,
01082                typename enable_if<
01083                  _TCC<_Dummy>::template
01084                    _ConstructibleTuple<_T1, _T2>()
01085                  && !_TCC<_Dummy>::template
01086                    _ImplicitlyConvertibleTuple<_T1, _T2>(),
01087                bool>::type=false>
01088 
01089         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01090               const _T1& __a1, const _T2& __a2)
01091         : _Inherited(__tag, __a, __a1, __a2) { }
01092 
01093       template<typename _Alloc, typename _U1, typename _U2, typename
01094         enable_if<_TMC::template
01095                     _MoveConstructibleTuple<_U1, _U2>()
01096                   && _TMC::template
01097                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01098         bool>::type = true>
01099         tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
01100         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
01101                      std::forward<_U2>(__a2)) { }
01102 
01103       template<typename _Alloc, typename _U1, typename _U2, typename
01104         enable_if<_TMC::template
01105                     _MoveConstructibleTuple<_U1, _U2>()
01106                   && !_TMC::template
01107                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01108         bool>::type = false>
01109         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01110                        _U1&& __a1, _U2&& __a2)
01111         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
01112                      std::forward<_U2>(__a2)) { }
01113 
01114       template<typename _Alloc>
01115         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
01116         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
01117 
01118       template<typename _Alloc>
01119         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
01120         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
01121 
01122       template<typename _Alloc, typename _U1, typename _U2, typename
01123         enable_if<_TMC::template
01124                     _ConstructibleTuple<_U1, _U2>()
01125                   && _TMC::template
01126                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01127         bool>::type = true>
01128         tuple(allocator_arg_t __tag, const _Alloc& __a,
01129               const tuple<_U1, _U2>& __in)
01130         : _Inherited(__tag, __a,
01131                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
01132         { }
01133 
01134       template<typename _Alloc, typename _U1, typename _U2, typename
01135         enable_if<_TMC::template
01136                     _ConstructibleTuple<_U1, _U2>()
01137                   && !_TMC::template
01138                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01139         bool>::type = false>
01140         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01141               const tuple<_U1, _U2>& __in)
01142         : _Inherited(__tag, __a,
01143                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
01144         { }
01145 
01146       template<typename _Alloc, typename _U1, typename _U2, typename
01147         enable_if<_TMC::template
01148                     _MoveConstructibleTuple<_U1, _U2>()
01149                   && _TMC::template
01150                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01151         bool>::type = true>
01152         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
01153         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
01154         { }
01155 
01156       template<typename _Alloc, typename _U1, typename _U2, typename
01157         enable_if<_TMC::template
01158                     _MoveConstructibleTuple<_U1, _U2>()
01159                   && !_TMC::template
01160                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01161         bool>::type = false>
01162         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01163                        tuple<_U1, _U2>&& __in)
01164         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
01165         { }
01166 
01167       template<typename _Alloc, typename _U1, typename _U2, typename
01168         enable_if<_TMC::template
01169                     _ConstructibleTuple<_U1, _U2>()
01170                   && _TMC::template
01171                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01172         bool>::type = true>
01173         tuple(allocator_arg_t __tag, const _Alloc& __a,
01174               const pair<_U1, _U2>& __in)
01175         : _Inherited(__tag, __a, __in.first, __in.second) { }
01176 
01177       template<typename _Alloc, typename _U1, typename _U2, typename
01178         enable_if<_TMC::template
01179                     _ConstructibleTuple<_U1, _U2>()
01180                   && !_TMC::template
01181                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01182         bool>::type = false>
01183         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01184               const pair<_U1, _U2>& __in)
01185         : _Inherited(__tag, __a, __in.first, __in.second) { }
01186 
01187       template<typename _Alloc, typename _U1, typename _U2, typename
01188         enable_if<_TMC::template
01189                     _MoveConstructibleTuple<_U1, _U2>()
01190                   && _TMC::template
01191                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01192         bool>::type = true>
01193         tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
01194         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
01195                      std::forward<_U2>(__in.second)) { }
01196 
01197       template<typename _Alloc, typename _U1, typename _U2, typename
01198         enable_if<_TMC::template
01199                     _MoveConstructibleTuple<_U1, _U2>()
01200                   && !_TMC::template
01201                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01202         bool>::type = false>
01203         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01204                        pair<_U1, _U2>&& __in)
01205         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
01206                      std::forward<_U2>(__in.second)) { }
01207 
01208       tuple&
01209       operator=(const tuple& __in)
01210       {
01211         static_cast<_Inherited&>(*this) = __in;
01212         return *this;
01213       }
01214 
01215       tuple&
01216       operator=(tuple&& __in)
01217       noexcept(is_nothrow_move_assignable<_Inherited>::value)
01218       {
01219         static_cast<_Inherited&>(*this) = std::move(__in);
01220         return *this;
01221       }
01222 
01223       template<typename _U1, typename _U2>
01224         tuple&
01225         operator=(const tuple<_U1, _U2>& __in)
01226         {
01227           static_cast<_Inherited&>(*this) = __in;
01228           return *this;
01229         }
01230 
01231       template<typename _U1, typename _U2>
01232         tuple&
01233         operator=(tuple<_U1, _U2>&& __in)
01234         {
01235           static_cast<_Inherited&>(*this) = std::move(__in);
01236           return *this;
01237         }
01238 
01239       template<typename _U1, typename _U2>
01240         tuple&
01241         operator=(const pair<_U1, _U2>& __in)
01242         {
01243           this->_M_head(*this) = __in.first;
01244           this->_M_tail(*this)._M_head(*this) = __in.second;
01245           return *this;
01246         }
01247 
01248       template<typename _U1, typename _U2>
01249         tuple&
01250         operator=(pair<_U1, _U2>&& __in)
01251         {
01252           this->_M_head(*this) = std::forward<_U1>(__in.first);
01253           this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
01254           return *this;
01255         }
01256 
01257       void
01258       swap(tuple& __in)
01259       noexcept(noexcept(__in._M_swap(__in)))
01260       { _Inherited::_M_swap(__in); }
01261     };
01262 
01263 
01264   /// class tuple_size
01265   template<typename... _Elements>
01266     struct tuple_size<tuple<_Elements...>>
01267     : public integral_constant<std::size_t, sizeof...(_Elements)> { };
01268 
01269 #if __cplusplus > 201402L
01270   template <typename _Tp>
01271     inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
01272 #endif
01273 
01274   /**
01275    * Recursive case for tuple_element: strip off the first element in
01276    * the tuple and retrieve the (i-1)th element of the remaining tuple.
01277    */
01278   template<std::size_t __i, typename _Head, typename... _Tail>
01279     struct tuple_element<__i, tuple<_Head, _Tail...> >
01280     : tuple_element<__i - 1, tuple<_Tail...> > { };
01281 
01282   /**
01283    * Basis case for tuple_element: The first element is the one we're seeking.
01284    */
01285   template<typename _Head, typename... _Tail>
01286     struct tuple_element<0, tuple<_Head, _Tail...> >
01287     {
01288       typedef _Head type;
01289     };
01290 
01291   /**
01292    * Error case for tuple_element: invalid index.
01293    */
01294   template<size_t __i>
01295     struct tuple_element<__i, tuple<>>
01296     {
01297       static_assert(__i < tuple_size<tuple<>>::value,
01298           "tuple index is in range");
01299     };
01300 
01301   template<std::size_t __i, typename _Head, typename... _Tail>
01302     constexpr _Head&
01303     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
01304     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
01305 
01306   template<std::size_t __i, typename _Head, typename... _Tail>
01307     constexpr const _Head&
01308     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
01309     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
01310 
01311   /// Return a reference to the ith element of a tuple.
01312   template<std::size_t __i, typename... _Elements>
01313     constexpr __tuple_element_t<__i, tuple<_Elements...>>&
01314     get(tuple<_Elements...>& __t) noexcept
01315     { return std::__get_helper<__i>(__t); }
01316 
01317   /// Return a const reference to the ith element of a const tuple.
01318   template<std::size_t __i, typename... _Elements>
01319     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
01320     get(const tuple<_Elements...>& __t) noexcept
01321     { return std::__get_helper<__i>(__t); }
01322 
01323   /// Return an rvalue reference to the ith element of a tuple rvalue.
01324   template<std::size_t __i, typename... _Elements>
01325     constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
01326     get(tuple<_Elements...>&& __t) noexcept
01327     {
01328       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
01329       return std::forward<__element_type&&>(std::get<__i>(__t));
01330     }
01331 
01332 #if __cplusplus > 201103L
01333 
01334 #define __cpp_lib_tuples_by_type 201304
01335 
01336   template<typename _Head, size_t __i, typename... _Tail>
01337     constexpr _Head&
01338     __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
01339     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
01340 
01341   template<typename _Head, size_t __i, typename... _Tail>
01342     constexpr const _Head&
01343     __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
01344     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
01345 
01346   /// Return a reference to the unique element of type _Tp of a tuple.
01347   template <typename _Tp, typename... _Types>
01348     constexpr _Tp&
01349     get(tuple<_Types...>& __t) noexcept
01350     { return std::__get_helper2<_Tp>(__t); }
01351 
01352   /// Return a reference to the unique element of type _Tp of a tuple rvalue.
01353   template <typename _Tp, typename... _Types>
01354     constexpr _Tp&&
01355     get(tuple<_Types...>&& __t) noexcept
01356     { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
01357 
01358   /// Return a const reference to the unique element of type _Tp of a tuple.
01359   template <typename _Tp, typename... _Types>
01360     constexpr const _Tp&
01361     get(const tuple<_Types...>& __t) noexcept
01362     { return std::__get_helper2<_Tp>(__t); }
01363 #endif
01364 
01365   // This class performs the comparison operations on tuples
01366   template<typename _Tp, typename _Up, size_t __i, size_t __size>
01367     struct __tuple_compare
01368     {
01369       static constexpr bool
01370       __eq(const _Tp& __t, const _Up& __u)
01371       {
01372         return bool(std::get<__i>(__t) == std::get<__i>(__u))
01373           && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
01374       }
01375 
01376       static constexpr bool
01377       __less(const _Tp& __t, const _Up& __u)
01378       {
01379         return bool(std::get<__i>(__t) < std::get<__i>(__u))
01380           || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
01381               && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
01382       }
01383     };
01384 
01385   template<typename _Tp, typename _Up, size_t __size>
01386     struct __tuple_compare<_Tp, _Up, __size, __size>
01387     {
01388       static constexpr bool
01389       __eq(const _Tp&, const _Up&) { return true; }
01390 
01391       static constexpr bool
01392       __less(const _Tp&, const _Up&) { return false; }
01393     };
01394 
01395   template<typename... _TElements, typename... _UElements>
01396     constexpr bool
01397     operator==(const tuple<_TElements...>& __t,
01398                const tuple<_UElements...>& __u)
01399     {
01400       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
01401           "tuple objects can only be compared if they have equal sizes.");
01402       using __compare = __tuple_compare<tuple<_TElements...>,
01403                                         tuple<_UElements...>,
01404                                         0, sizeof...(_TElements)>;
01405       return __compare::__eq(__t, __u);
01406     }
01407 
01408   template<typename... _TElements, typename... _UElements>
01409     constexpr bool
01410     operator<(const tuple<_TElements...>& __t,
01411               const tuple<_UElements...>& __u)
01412     {
01413       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
01414           "tuple objects can only be compared if they have equal sizes.");
01415       using __compare = __tuple_compare<tuple<_TElements...>,
01416                                         tuple<_UElements...>,
01417                                         0, sizeof...(_TElements)>;
01418       return __compare::__less(__t, __u);
01419     }
01420 
01421   template<typename... _TElements, typename... _UElements>
01422     constexpr bool
01423     operator!=(const tuple<_TElements...>& __t,
01424                const tuple<_UElements...>& __u)
01425     { return !(__t == __u); }
01426 
01427   template<typename... _TElements, typename... _UElements>
01428     constexpr bool
01429     operator>(const tuple<_TElements...>& __t,
01430               const tuple<_UElements...>& __u)
01431     { return __u < __t; }
01432 
01433   template<typename... _TElements, typename... _UElements>
01434     constexpr bool
01435     operator<=(const tuple<_TElements...>& __t,
01436                const tuple<_UElements...>& __u)
01437     { return !(__u < __t); }
01438 
01439   template<typename... _TElements, typename... _UElements>
01440     constexpr bool
01441     operator>=(const tuple<_TElements...>& __t,
01442                const tuple<_UElements...>& __u)
01443     { return !(__t < __u); }
01444 
01445   // NB: DR 705.
01446   template<typename... _Elements>
01447     constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
01448     make_tuple(_Elements&&... __args)
01449     {
01450       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
01451         __result_type;
01452       return __result_type(std::forward<_Elements>(__args)...);
01453     }
01454 
01455   // _GLIBCXX_RESOLVE_LIB_DEFECTS
01456   // 2275. Why is forward_as_tuple not constexpr?
01457   template<typename... _Elements>
01458     constexpr tuple<_Elements&&...>
01459     forward_as_tuple(_Elements&&... __args) noexcept
01460     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
01461 
01462   template<size_t, typename, typename, size_t>
01463     struct __make_tuple_impl;
01464 
01465   template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
01466     struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
01467     : __make_tuple_impl<_Idx + 1,
01468                         tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
01469                         _Tuple, _Nm>
01470     { };
01471 
01472   template<std::size_t _Nm, typename _Tuple, typename... _Tp>
01473     struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
01474     {
01475       typedef tuple<_Tp...> __type;
01476     };
01477 
01478   template<typename _Tuple>
01479     struct __do_make_tuple
01480     : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
01481     { };
01482 
01483   // Returns the std::tuple equivalent of a tuple-like type.
01484   template<typename _Tuple>
01485     struct __make_tuple
01486     : public __do_make_tuple<typename std::remove_cv
01487             <typename std::remove_reference<_Tuple>::type>::type>
01488     { };
01489 
01490   // Combines several std::tuple's into a single one.
01491   template<typename...>
01492     struct __combine_tuples;
01493 
01494   template<>
01495     struct __combine_tuples<>
01496     {
01497       typedef tuple<> __type;
01498     };
01499 
01500   template<typename... _Ts>
01501     struct __combine_tuples<tuple<_Ts...>>
01502     {
01503       typedef tuple<_Ts...> __type;
01504     };
01505 
01506   template<typename... _T1s, typename... _T2s, typename... _Rem>
01507     struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
01508     {
01509       typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
01510                                         _Rem...>::__type __type;
01511     };
01512 
01513   // Computes the result type of tuple_cat given a set of tuple-like types.
01514   template<typename... _Tpls>
01515     struct __tuple_cat_result
01516     {
01517       typedef typename __combine_tuples
01518         <typename __make_tuple<_Tpls>::__type...>::__type __type;
01519     };
01520 
01521   // Helper to determine the index set for the first tuple-like
01522   // type of a given set.
01523   template<typename...>
01524     struct __make_1st_indices;
01525 
01526   template<>
01527     struct __make_1st_indices<>
01528     {
01529       typedef std::_Index_tuple<> __type;
01530     };
01531 
01532   template<typename _Tp, typename... _Tpls>
01533     struct __make_1st_indices<_Tp, _Tpls...>
01534     {
01535       typedef typename std::_Build_index_tuple<std::tuple_size<
01536         typename std::remove_reference<_Tp>::type>::value>::__type __type;
01537     };
01538 
01539   // Performs the actual concatenation by step-wise expanding tuple-like
01540   // objects into the elements,  which are finally forwarded into the
01541   // result tuple.
01542   template<typename _Ret, typename _Indices, typename... _Tpls>
01543     struct __tuple_concater;
01544 
01545   template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
01546     struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
01547     {
01548       template<typename... _Us>
01549         static constexpr _Ret
01550         _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
01551         {
01552           typedef typename __make_1st_indices<_Tpls...>::__type __idx;
01553           typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
01554           return __next::_S_do(std::forward<_Tpls>(__tps)...,
01555                                std::forward<_Us>(__us)...,
01556                                std::get<_Is>(std::forward<_Tp>(__tp))...);
01557         }
01558     };
01559 
01560   template<typename _Ret>
01561     struct __tuple_concater<_Ret, std::_Index_tuple<>>
01562     {
01563       template<typename... _Us>
01564         static constexpr _Ret
01565         _S_do(_Us&&... __us)
01566         {
01567           return _Ret(std::forward<_Us>(__us)...);
01568         }
01569     };
01570 
01571   /// tuple_cat
01572   template<typename... _Tpls, typename = typename
01573            enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
01574     constexpr auto
01575     tuple_cat(_Tpls&&... __tpls)
01576     -> typename __tuple_cat_result<_Tpls...>::__type
01577     {
01578       typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
01579       typedef typename __make_1st_indices<_Tpls...>::__type __idx;
01580       typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
01581       return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
01582     }
01583 
01584   // _GLIBCXX_RESOLVE_LIB_DEFECTS
01585   // 2301. Why is tie not constexpr?
01586   /// tie
01587   template<typename... _Elements>
01588     constexpr tuple<_Elements&...>
01589     tie(_Elements&... __args) noexcept
01590     { return tuple<_Elements&...>(__args...); }
01591 
01592   /// swap
01593   template<typename... _Elements>
01594     inline
01595 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
01596     // Constrained free swap overload, see p0185r1
01597     typename enable_if<__and_<__is_swappable<_Elements>...>::value
01598       >::type
01599 #else
01600     void
01601 #endif
01602     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
01603     noexcept(noexcept(__x.swap(__y)))
01604     { __x.swap(__y); }
01605 
01606 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
01607   template<typename... _Elements>
01608     typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
01609     swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
01610 #endif
01611 
01612   // A class (and instance) which can be used in 'tie' when an element
01613   // of a tuple is not required.
01614   // _GLIBCXX14_CONSTEXPR
01615   // 2933. PR for LWG 2773 could be clearer
01616   struct _Swallow_assign
01617   {
01618     template<class _Tp>
01619       _GLIBCXX14_CONSTEXPR const _Swallow_assign&
01620       operator=(const _Tp&) const
01621       { return *this; }
01622   };
01623 
01624   // _GLIBCXX_RESOLVE_LIB_DEFECTS
01625   // 2773. Making std::ignore constexpr
01626   _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
01627 
01628   /// Partial specialization for tuples
01629   template<typename... _Types, typename _Alloc>
01630     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
01631 
01632   // See stl_pair.h...
01633   template<class _T1, class _T2>
01634     template<typename... _Args1, typename... _Args2>
01635       inline
01636       pair<_T1, _T2>::
01637       pair(piecewise_construct_t,
01638            tuple<_Args1...> __first, tuple<_Args2...> __second)
01639       : pair(__first, __second,
01640              typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
01641              typename _Build_index_tuple<sizeof...(_Args2)>::__type())
01642       { }
01643 
01644   template<class _T1, class _T2>
01645     template<typename... _Args1, std::size_t... _Indexes1,
01646              typename... _Args2, std::size_t... _Indexes2>
01647       inline
01648       pair<_T1, _T2>::
01649       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
01650            _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
01651       : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
01652         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
01653       { }
01654 
01655 #if __cplusplus > 201402L
01656 # define __cpp_lib_apply 201603
01657 
01658   template <typename _Fn, typename _Tuple, size_t... _Idx>
01659     constexpr decltype(auto)
01660     __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
01661     {
01662       return std::__invoke(std::forward<_Fn>(__f),
01663                            std::get<_Idx>(std::forward<_Tuple>(__t))...);
01664     }
01665 
01666   template <typename _Fn, typename _Tuple>
01667     constexpr decltype(auto)
01668     apply(_Fn&& __f, _Tuple&& __t)
01669     {
01670       using _Indices = make_index_sequence<tuple_size_v<decay_t<_Tuple>>>;
01671       return std::__apply_impl(std::forward<_Fn>(__f),
01672                                std::forward<_Tuple>(__t),
01673                                _Indices{});
01674     }
01675 
01676 #define __cpp_lib_make_from_tuple  201606
01677 
01678   template <typename _Tp, typename _Tuple, size_t... _Idx>
01679     constexpr _Tp
01680     __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
01681     { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
01682 
01683   template <typename _Tp, typename _Tuple>
01684     constexpr _Tp
01685     make_from_tuple(_Tuple&& __t)
01686     {
01687       return __make_from_tuple_impl<_Tp>(
01688         std::forward<_Tuple>(__t),
01689         make_index_sequence<tuple_size_v<decay_t<_Tuple>>>{});
01690     }
01691 #endif // C++17
01692 
01693   /// @}
01694 
01695 _GLIBCXX_END_NAMESPACE_VERSION
01696 } // namespace std
01697 
01698 #endif // C++11
01699 
01700 #endif // _GLIBCXX_TUPLE