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