Home | History | Annotate | Line # | Download | only in std
tuple revision 1.1.1.5.8.1
      1 // <tuple> -*- C++ -*-
      2 
      3 // Copyright (C) 2007-2015 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(noexcept(swap(std::declval<_Head&>(),
    328 			     std::declval<_Head&>()))
    329 	       && noexcept(_M_tail(__in)._M_swap(_M_tail(__in))))
    330       {
    331 	using std::swap;
    332 	swap(_M_head(*this), _M_head(__in));
    333 	_Inherited::_M_swap(_M_tail(__in));
    334       }
    335     };
    336 
    337   // Basis case of inheritance recursion.
    338   template<std::size_t _Idx, typename _Head>
    339     struct _Tuple_impl<_Idx, _Head>
    340     : private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value>
    341     {
    342       template<std::size_t, typename...> friend class _Tuple_impl;
    343 
    344       typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base;
    345 
    346       static constexpr _Head&
    347       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
    348 
    349       static constexpr const _Head&
    350       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
    351 
    352       constexpr _Tuple_impl()
    353       : _Base() { }
    354 
    355       explicit
    356       constexpr _Tuple_impl(const _Head& __head)
    357       : _Base(__head) { }
    358 
    359       template<typename _UHead>
    360         explicit
    361         constexpr _Tuple_impl(_UHead&& __head)
    362 	: _Base(std::forward<_UHead>(__head)) { }
    363 
    364       constexpr _Tuple_impl(const _Tuple_impl&) = default;
    365 
    366       constexpr
    367       _Tuple_impl(_Tuple_impl&& __in)
    368       noexcept(is_nothrow_move_constructible<_Head>::value)
    369       : _Base(std::forward<_Head>(_M_head(__in))) { }
    370 
    371       template<typename _UHead>
    372         constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
    373 	: _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
    374 
    375       template<typename _UHead>
    376         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
    377 	: _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
    378 	{ }
    379 
    380       template<typename _Alloc>
    381 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
    382 	: _Base(__tag, __use_alloc<_Head>(__a)) { }
    383 
    384       template<typename _Alloc>
    385 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    386 		    const _Head& __head)
    387 	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
    388 
    389       template<typename _Alloc, typename _UHead>
    390 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    391 	            _UHead&& __head)
    392 	: _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
    393 	        std::forward<_UHead>(__head)) { }
    394 
    395       template<typename _Alloc>
    396         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    397 	            const _Tuple_impl& __in)
    398 	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
    399 
    400       template<typename _Alloc>
    401 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    402 	            _Tuple_impl&& __in)
    403 	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
    404 	        std::forward<_Head>(_M_head(__in))) { }
    405 
    406       template<typename _Alloc, typename _UHead>
    407 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    408 	            const _Tuple_impl<_Idx, _UHead>& __in)
    409 	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
    410 		_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
    411 
    412       template<typename _Alloc, typename _UHead>
    413 	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
    414 	            _Tuple_impl<_Idx, _UHead>&& __in)
    415 	: _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
    416                 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
    417 	{ }
    418 
    419       _Tuple_impl&
    420       operator=(const _Tuple_impl& __in)
    421       {
    422 	_M_head(*this) = _M_head(__in);
    423 	return *this;
    424       }
    425 
    426       _Tuple_impl&
    427       operator=(_Tuple_impl&& __in)
    428       noexcept(is_nothrow_move_assignable<_Head>::value)
    429       {
    430 	_M_head(*this) = std::forward<_Head>(_M_head(__in));
    431 	return *this;
    432       }
    433 
    434       template<typename _UHead>
    435         _Tuple_impl&
    436         operator=(const _Tuple_impl<_Idx, _UHead>& __in)
    437         {
    438 	  _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
    439 	  return *this;
    440 	}
    441 
    442       template<typename _UHead>
    443         _Tuple_impl&
    444         operator=(_Tuple_impl<_Idx, _UHead>&& __in)
    445         {
    446 	  _M_head(*this)
    447 	    = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
    448 	  return *this;
    449 	}
    450 
    451     protected:
    452       void
    453       _M_swap(_Tuple_impl& __in)
    454       noexcept(noexcept(swap(std::declval<_Head&>(), std::declval<_Head&>())))
    455       {
    456 	using std::swap;
    457 	swap(_M_head(*this), _M_head(__in));
    458       }
    459     };
    460 
    461   /// Primary class template, tuple
    462   template<typename... _Elements> 
    463     class tuple : public _Tuple_impl<0, _Elements...>
    464     {
    465       typedef _Tuple_impl<0, _Elements...> _Inherited;
    466 
    467     public:
    468       constexpr tuple()
    469       : _Inherited() { }
    470 
    471       explicit
    472       constexpr tuple(const _Elements&... __elements)
    473       : _Inherited(__elements...) { }
    474 
    475       template<typename... _UElements, typename = typename
    476         enable_if<__and_<is_convertible<_UElements,
    477 					_Elements>...>::value>::type>
    478 	explicit
    479         constexpr tuple(_UElements&&... __elements)
    480 	: _Inherited(std::forward<_UElements>(__elements)...) {	}
    481 
    482       constexpr tuple(const tuple&) = default;
    483 
    484       constexpr tuple(tuple&&) = default; 
    485 
    486       template<typename... _UElements, typename = typename
    487         enable_if<__and_<is_convertible<const _UElements&,
    488 					_Elements>...>::value>::type>
    489         constexpr tuple(const tuple<_UElements...>& __in)
    490         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    491         { }
    492 
    493       template<typename... _UElements, typename = typename
    494         enable_if<__and_<is_convertible<_UElements,
    495 					_Elements>...>::value>::type>
    496         constexpr tuple(tuple<_UElements...>&& __in)
    497         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
    498 
    499       // Allocator-extended constructors.
    500 
    501       template<typename _Alloc>
    502 	tuple(allocator_arg_t __tag, const _Alloc& __a)
    503 	: _Inherited(__tag, __a) { }
    504 
    505       template<typename _Alloc>
    506 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    507 	      const _Elements&... __elements)
    508 	: _Inherited(__tag, __a, __elements...) { }
    509 
    510       template<typename _Alloc, typename... _UElements, typename = typename
    511 	       enable_if<sizeof...(_UElements)
    512 			 == sizeof...(_Elements)>::type>
    513 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    514 	      _UElements&&... __elements)
    515 	: _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
    516        	{ }
    517 
    518       template<typename _Alloc>
    519 	tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
    520 	: _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
    521 
    522       template<typename _Alloc>
    523 	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
    524 	: _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
    525 
    526       template<typename _Alloc, typename... _UElements, typename = typename
    527 	       enable_if<sizeof...(_UElements)
    528 			 == sizeof...(_Elements)>::type>
    529 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    530 	      const tuple<_UElements...>& __in)
    531 	: _Inherited(__tag, __a,
    532 	             static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    533 	{ }
    534 
    535       template<typename _Alloc, typename... _UElements, typename = typename
    536 	       enable_if<sizeof...(_UElements)
    537 			 == sizeof...(_Elements)>::type>
    538 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    539 	      tuple<_UElements...>&& __in)
    540 	: _Inherited(__tag, __a,
    541 	             static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
    542 	{ }
    543 
    544       tuple&
    545       operator=(const tuple& __in)
    546       {
    547 	static_cast<_Inherited&>(*this) = __in;
    548 	return *this;
    549       }
    550 
    551       tuple&
    552       operator=(tuple&& __in)
    553       noexcept(is_nothrow_move_assignable<_Inherited>::value)
    554       {
    555 	static_cast<_Inherited&>(*this) = std::move(__in);
    556 	return *this;
    557       }
    558 
    559       template<typename... _UElements, typename = typename
    560 	       enable_if<sizeof...(_UElements)
    561 			 == sizeof...(_Elements)>::type>
    562         tuple&
    563         operator=(const tuple<_UElements...>& __in)
    564         {
    565 	  static_cast<_Inherited&>(*this) = __in;
    566 	  return *this;
    567 	}
    568 
    569       template<typename... _UElements, typename = typename
    570 	       enable_if<sizeof...(_UElements)
    571 			 == sizeof...(_Elements)>::type>
    572         tuple&
    573         operator=(tuple<_UElements...>&& __in)
    574         {
    575 	  static_cast<_Inherited&>(*this) = std::move(__in);
    576 	  return *this;
    577 	}
    578 
    579       void
    580       swap(tuple& __in)
    581       noexcept(noexcept(__in._M_swap(__in)))
    582       { _Inherited::_M_swap(__in); }
    583     };
    584 
    585   // Explicit specialization, zero-element tuple.
    586   template<>  
    587     class tuple<>
    588     {
    589     public:
    590       void swap(tuple&) noexcept { /* no-op */ }
    591     };
    592 
    593   /// Partial specialization, 2-element tuple.
    594   /// Includes construction and assignment from a pair.
    595   template<typename _T1, typename _T2>
    596     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
    597     {
    598       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
    599 
    600     public:
    601       constexpr tuple()
    602       : _Inherited() { }
    603 
    604       explicit
    605       constexpr tuple(const _T1& __a1, const _T2& __a2)
    606       : _Inherited(__a1, __a2) { }
    607 
    608       template<typename _U1, typename _U2, typename = typename
    609 	       enable_if<__and_<is_convertible<_U1, _T1>,
    610 				is_convertible<_U2, _T2>,
    611 				__not_<is_same<typename decay<_U1>::type,
    612 					       allocator_arg_t>>>
    613 			 ::value>::type>
    614         explicit
    615         constexpr tuple(_U1&& __a1, _U2&& __a2)
    616 	: _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
    617 
    618       constexpr tuple(const tuple&) = default;
    619 
    620       constexpr tuple(tuple&&) = default;
    621 
    622       template<typename _U1, typename _U2, typename = typename
    623 	enable_if<__and_<is_convertible<const _U1&, _T1>,
    624 			 is_convertible<const _U2&, _T2>>::value>::type>
    625         constexpr tuple(const tuple<_U1, _U2>& __in)
    626 	: _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
    627 
    628       template<typename _U1, typename _U2, typename = typename
    629 	       enable_if<__and_<is_convertible<_U1, _T1>,
    630 				is_convertible<_U2, _T2>>::value>::type>
    631         constexpr tuple(tuple<_U1, _U2>&& __in)
    632 	: _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
    633 
    634       template<typename _U1, typename _U2, typename = typename
    635 	enable_if<__and_<is_convertible<const _U1&, _T1>,
    636 			 is_convertible<const _U2&, _T2>>::value>::type>
    637         constexpr tuple(const pair<_U1, _U2>& __in)
    638 	: _Inherited(__in.first, __in.second) { }
    639 
    640       template<typename _U1, typename _U2, typename = typename
    641 	       enable_if<__and_<is_convertible<_U1, _T1>,
    642 				is_convertible<_U2, _T2>>::value>::type>
    643         constexpr tuple(pair<_U1, _U2>&& __in)
    644 	: _Inherited(std::forward<_U1>(__in.first),
    645 		     std::forward<_U2>(__in.second)) { }
    646 
    647       // Allocator-extended constructors.
    648 
    649       template<typename _Alloc>
    650 	tuple(allocator_arg_t __tag, const _Alloc& __a)
    651 	: _Inherited(__tag, __a) { }
    652 
    653       template<typename _Alloc>
    654 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    655 	      const _T1& __a1, const _T2& __a2)
    656 	: _Inherited(__tag, __a, __a1, __a2) { }
    657 
    658       template<typename _Alloc, typename _U1, typename _U2>
    659 	tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
    660 	: _Inherited(__tag, __a, std::forward<_U1>(__a1),
    661 	             std::forward<_U2>(__a2)) { }
    662 
    663       template<typename _Alloc>
    664 	tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
    665 	: _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
    666 
    667       template<typename _Alloc>
    668 	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
    669 	: _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
    670 
    671       template<typename _Alloc, typename _U1, typename _U2>
    672 	tuple(allocator_arg_t __tag, const _Alloc& __a,
    673 	      const tuple<_U1, _U2>& __in)
    674 	: _Inherited(__tag, __a,
    675 	             static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
    676 	{ }
    677 
    678       template<typename _Alloc, typename _U1, typename _U2>
    679 	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
    680 	: _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
    681 	{ }
    682 
    683       template<typename _Alloc, typename _U1, typename _U2>
    684         tuple(allocator_arg_t __tag, const _Alloc& __a,
    685 	      const pair<_U1, _U2>& __in)
    686 	: _Inherited(__tag, __a, __in.first, __in.second) { }
    687 
    688       template<typename _Alloc, typename _U1, typename _U2>
    689         tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
    690 	: _Inherited(__tag, __a, std::forward<_U1>(__in.first),
    691 		     std::forward<_U2>(__in.second)) { }
    692 
    693       tuple&
    694       operator=(const tuple& __in)
    695       {
    696 	static_cast<_Inherited&>(*this) = __in;
    697 	return *this;
    698       }
    699 
    700       tuple&
    701       operator=(tuple&& __in)
    702       noexcept(is_nothrow_move_assignable<_Inherited>::value)
    703       {
    704 	static_cast<_Inherited&>(*this) = std::move(__in);
    705 	return *this;
    706       }
    707 
    708       template<typename _U1, typename _U2>
    709         tuple&
    710         operator=(const tuple<_U1, _U2>& __in)
    711         {
    712 	  static_cast<_Inherited&>(*this) = __in;
    713 	  return *this;
    714 	}
    715 
    716       template<typename _U1, typename _U2>
    717         tuple&
    718         operator=(tuple<_U1, _U2>&& __in)
    719         {
    720 	  static_cast<_Inherited&>(*this) = std::move(__in);
    721 	  return *this;
    722 	}
    723 
    724       template<typename _U1, typename _U2>
    725         tuple&
    726         operator=(const pair<_U1, _U2>& __in)
    727         {
    728 	  this->_M_head(*this) = __in.first;
    729 	  this->_M_tail(*this)._M_head(*this) = __in.second;
    730 	  return *this;
    731 	}
    732 
    733       template<typename _U1, typename _U2>
    734         tuple&
    735         operator=(pair<_U1, _U2>&& __in)
    736         {
    737 	  this->_M_head(*this) = std::forward<_U1>(__in.first);
    738 	  this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
    739 	  return *this;
    740 	}
    741 
    742       void
    743       swap(tuple& __in)
    744       noexcept(noexcept(__in._M_swap(__in)))
    745       { _Inherited::_M_swap(__in); }
    746     };
    747 
    748 
    749   /// Gives the type of the ith element of a given tuple type.
    750   template<std::size_t __i, typename _Tp>
    751     struct tuple_element;
    752 
    753   /**
    754    * Recursive case for tuple_element: strip off the first element in
    755    * the tuple and retrieve the (i-1)th element of the remaining tuple.
    756    */
    757   template<std::size_t __i, typename _Head, typename... _Tail>
    758     struct tuple_element<__i, tuple<_Head, _Tail...> >
    759     : tuple_element<__i - 1, tuple<_Tail...> > { };
    760 
    761   /**
    762    * Basis case for tuple_element: The first element is the one we're seeking.
    763    */
    764   template<typename _Head, typename... _Tail>
    765     struct tuple_element<0, tuple<_Head, _Tail...> >
    766     {
    767       typedef _Head type;
    768     };
    769 
    770   // Duplicate of C++14's tuple_element_t for internal use in C++11 mode
    771   template<std::size_t __i, typename _Tp>
    772     using __tuple_element_t = typename tuple_element<__i, _Tp>::type;
    773 
    774   template<std::size_t __i, typename _Tp>
    775     struct tuple_element<__i, const _Tp>
    776     {
    777       typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type;
    778     };
    779 
    780   template<std::size_t __i, typename _Tp>
    781     struct tuple_element<__i, volatile _Tp>
    782     {
    783       typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type;
    784     };
    785 
    786   template<std::size_t __i, typename _Tp>
    787     struct tuple_element<__i, const volatile _Tp>
    788     {
    789       typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type;
    790     };
    791 
    792 #if __cplusplus > 201103L
    793 #define __cpp_lib_tuple_element_t 201402
    794 
    795   template<std::size_t __i, typename _Tp>
    796     using tuple_element_t = typename tuple_element<__i, _Tp>::type;
    797 #endif
    798 
    799   /// Finds the size of a given tuple type.
    800   template<typename _Tp>
    801     struct tuple_size;
    802 
    803   // _GLIBCXX_RESOLVE_LIB_DEFECTS
    804   // 2313. tuple_size should always derive from integral_constant<size_t, N>
    805   template<typename _Tp>
    806     struct tuple_size<const _Tp>
    807     : integral_constant<size_t, tuple_size<_Tp>::value> { };
    808 
    809   template<typename _Tp>
    810     struct tuple_size<volatile _Tp>
    811     : integral_constant<size_t, tuple_size<_Tp>::value> { };
    812 
    813   template<typename _Tp>
    814     struct tuple_size<const volatile _Tp>
    815     : integral_constant<size_t, tuple_size<_Tp>::value> { };
    816 
    817   /// class tuple_size
    818   template<typename... _Elements>
    819     struct tuple_size<tuple<_Elements...>>
    820     : public integral_constant<std::size_t, sizeof...(_Elements)> { };
    821 
    822   template<std::size_t __i, typename _Head, typename... _Tail>
    823     constexpr _Head&
    824     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
    825     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
    826 
    827   template<std::size_t __i, typename _Head, typename... _Tail>
    828     constexpr const _Head&
    829     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
    830     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
    831 
    832   /// Return a reference to the ith element of a tuple.
    833   template<std::size_t __i, typename... _Elements>
    834     constexpr __tuple_element_t<__i, tuple<_Elements...>>&
    835     get(tuple<_Elements...>& __t) noexcept
    836     { return std::__get_helper<__i>(__t); }
    837 
    838   /// Return a const reference to the ith element of a const tuple.
    839   template<std::size_t __i, typename... _Elements>
    840     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
    841     get(const tuple<_Elements...>& __t) noexcept
    842     { return std::__get_helper<__i>(__t); }
    843 
    844   /// Return an rvalue reference to the ith element of a tuple rvalue.
    845   template<std::size_t __i, typename... _Elements>
    846     constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
    847     get(tuple<_Elements...>&& __t) noexcept
    848     {
    849       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
    850       return std::forward<__element_type&&>(std::get<__i>(__t));
    851     }
    852 
    853 #if __cplusplus > 201103L
    854 
    855 #define __cpp_lib_tuples_by_type 201304
    856 
    857   template<typename _Head, size_t __i, typename... _Tail>
    858     constexpr _Head&
    859     __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
    860     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
    861 
    862   template<typename _Head, size_t __i, typename... _Tail>
    863     constexpr const _Head&
    864     __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
    865     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
    866 
    867   /// Return a reference to the unique element of type _Tp of a tuple.
    868   template <typename _Tp, typename... _Types>
    869     constexpr _Tp&
    870     get(tuple<_Types...>& __t) noexcept
    871     { return std::__get_helper2<_Tp>(__t); }
    872 
    873   /// Return a reference to the unique element of type _Tp of a tuple rvalue.
    874   template <typename _Tp, typename... _Types>
    875     constexpr _Tp&&
    876     get(tuple<_Types...>&& __t) noexcept
    877     { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
    878 
    879   /// Return a const reference to the unique element of type _Tp of a tuple.
    880   template <typename _Tp, typename... _Types>
    881     constexpr const _Tp&
    882     get(const tuple<_Types...>& __t) noexcept
    883     { return std::__get_helper2<_Tp>(__t); }
    884 #endif
    885 
    886   // This class performs the comparison operations on tuples
    887   template<typename _Tp, typename _Up, size_t __i, size_t __size>
    888     struct __tuple_compare
    889     {
    890       static constexpr bool
    891       __eq(const _Tp& __t, const _Up& __u)
    892       {
    893 	return bool(std::get<__i>(__t) == std::get<__i>(__u))
    894 	  && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
    895       }
    896    
    897       static constexpr bool
    898       __less(const _Tp& __t, const _Up& __u)
    899       {
    900 	return bool(std::get<__i>(__t) < std::get<__i>(__u))
    901 	  || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
    902 	      && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
    903       }
    904     };
    905 
    906   template<typename _Tp, typename _Up, size_t __size>
    907     struct __tuple_compare<_Tp, _Up, __size, __size>
    908     {
    909       static constexpr bool
    910       __eq(const _Tp&, const _Up&) { return true; }
    911    
    912       static constexpr bool
    913       __less(const _Tp&, const _Up&) { return false; }
    914     };
    915 
    916   template<typename... _TElements, typename... _UElements>
    917     constexpr bool
    918     operator==(const tuple<_TElements...>& __t,
    919 	       const tuple<_UElements...>& __u)
    920     {
    921       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
    922 	  "tuple objects can only be compared if they have equal sizes.");
    923       using __compare = __tuple_compare<tuple<_TElements...>,
    924 					tuple<_UElements...>,
    925 					0, sizeof...(_TElements)>;
    926       return __compare::__eq(__t, __u);
    927     }
    928 
    929   template<typename... _TElements, typename... _UElements>
    930     constexpr bool
    931     operator<(const tuple<_TElements...>& __t,
    932 	      const tuple<_UElements...>& __u)
    933     {
    934       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
    935 	  "tuple objects can only be compared if they have equal sizes.");
    936       using __compare = __tuple_compare<tuple<_TElements...>,
    937 					tuple<_UElements...>,
    938 					0, sizeof...(_TElements)>;
    939       return __compare::__less(__t, __u);
    940     }
    941 
    942   template<typename... _TElements, typename... _UElements>
    943     constexpr bool
    944     operator!=(const tuple<_TElements...>& __t,
    945 	       const tuple<_UElements...>& __u)
    946     { return !(__t == __u); }
    947 
    948   template<typename... _TElements, typename... _UElements>
    949     constexpr bool
    950     operator>(const tuple<_TElements...>& __t,
    951 	      const tuple<_UElements...>& __u)
    952     { return __u < __t; }
    953 
    954   template<typename... _TElements, typename... _UElements>
    955     constexpr bool
    956     operator<=(const tuple<_TElements...>& __t,
    957 	       const tuple<_UElements...>& __u)
    958     { return !(__u < __t); }
    959 
    960   template<typename... _TElements, typename... _UElements>
    961     constexpr bool
    962     operator>=(const tuple<_TElements...>& __t,
    963 	       const tuple<_UElements...>& __u)
    964     { return !(__t < __u); }
    965 
    966   // NB: DR 705.
    967   template<typename... _Elements>
    968     constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
    969     make_tuple(_Elements&&... __args)
    970     {
    971       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
    972 	__result_type;
    973       return __result_type(std::forward<_Elements>(__args)...);
    974     }
    975 
    976   template<typename... _Elements>
    977     tuple<_Elements&&...>
    978     forward_as_tuple(_Elements&&... __args) noexcept
    979     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
    980 
    981   template<typename>
    982     struct __is_tuple_like_impl : false_type
    983     { };
    984 
    985   template<typename... _Tps>
    986     struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
    987     { };
    988 
    989   template<typename _T1, typename _T2>
    990     struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
    991     { };
    992 
    993   template<typename _Tp, std::size_t _Nm>
    994     struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
    995     { };
    996 
    997   // Internal type trait that allows us to sfinae-protect tuple_cat.
    998   template<typename _Tp>
    999     struct __is_tuple_like
   1000     : public __is_tuple_like_impl<typename std::remove_cv
   1001             <typename std::remove_reference<_Tp>::type>::type>::type
   1002     { };
   1003 
   1004   template<size_t, typename, typename, size_t>
   1005     struct __make_tuple_impl;
   1006 
   1007   template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
   1008     struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
   1009     : __make_tuple_impl<_Idx + 1,
   1010 			tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
   1011 			_Tuple, _Nm>
   1012     { };
   1013 
   1014   template<std::size_t _Nm, typename _Tuple, typename... _Tp>
   1015     struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
   1016     {
   1017       typedef tuple<_Tp...> __type;
   1018     };
   1019 
   1020   template<typename _Tuple>
   1021     struct __do_make_tuple
   1022     : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
   1023     { };
   1024 
   1025   // Returns the std::tuple equivalent of a tuple-like type.
   1026   template<typename _Tuple>
   1027     struct __make_tuple
   1028     : public __do_make_tuple<typename std::remove_cv
   1029             <typename std::remove_reference<_Tuple>::type>::type>
   1030     { };
   1031 
   1032   // Combines several std::tuple's into a single one.
   1033   template<typename...>
   1034     struct __combine_tuples;
   1035 
   1036   template<>
   1037     struct __combine_tuples<>
   1038     {
   1039       typedef tuple<> __type;
   1040     };
   1041 
   1042   template<typename... _Ts>
   1043     struct __combine_tuples<tuple<_Ts...>>
   1044     {
   1045       typedef tuple<_Ts...> __type;
   1046     };
   1047 
   1048   template<typename... _T1s, typename... _T2s, typename... _Rem>
   1049     struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
   1050     {
   1051       typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
   1052 					_Rem...>::__type __type;
   1053     };
   1054 
   1055   // Computes the result type of tuple_cat given a set of tuple-like types.
   1056   template<typename... _Tpls>
   1057     struct __tuple_cat_result
   1058     {
   1059       typedef typename __combine_tuples
   1060         <typename __make_tuple<_Tpls>::__type...>::__type __type;
   1061     };
   1062 
   1063   // Helper to determine the index set for the first tuple-like
   1064   // type of a given set.
   1065   template<typename...>
   1066     struct __make_1st_indices;
   1067 
   1068   template<>
   1069     struct __make_1st_indices<>
   1070     {
   1071       typedef std::_Index_tuple<> __type;
   1072     };
   1073 
   1074   template<typename _Tp, typename... _Tpls>
   1075     struct __make_1st_indices<_Tp, _Tpls...>
   1076     {
   1077       typedef typename std::_Build_index_tuple<std::tuple_size<
   1078 	typename std::remove_reference<_Tp>::type>::value>::__type __type;
   1079     };
   1080 
   1081   // Performs the actual concatenation by step-wise expanding tuple-like
   1082   // objects into the elements,  which are finally forwarded into the
   1083   // result tuple.
   1084   template<typename _Ret, typename _Indices, typename... _Tpls>
   1085     struct __tuple_concater;
   1086 
   1087   template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
   1088     struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
   1089     {
   1090       template<typename... _Us>
   1091         static constexpr _Ret
   1092         _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
   1093         {
   1094 	  typedef typename __make_1st_indices<_Tpls...>::__type __idx;
   1095 	  typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
   1096 	  return __next::_S_do(std::forward<_Tpls>(__tps)...,
   1097 			       std::forward<_Us>(__us)...,
   1098 			       std::get<_Is>(std::forward<_Tp>(__tp))...);
   1099 	}
   1100     };
   1101 
   1102   template<typename _Ret>
   1103     struct __tuple_concater<_Ret, std::_Index_tuple<>>
   1104     {
   1105       template<typename... _Us>
   1106 	static constexpr _Ret
   1107 	_S_do(_Us&&... __us)
   1108         {
   1109 	  return _Ret(std::forward<_Us>(__us)...);
   1110 	}
   1111     };
   1112 
   1113   /// tuple_cat
   1114   template<typename... _Tpls, typename = typename
   1115            enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
   1116     constexpr auto
   1117     tuple_cat(_Tpls&&... __tpls)
   1118     -> typename __tuple_cat_result<_Tpls...>::__type
   1119     {
   1120       typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
   1121       typedef typename __make_1st_indices<_Tpls...>::__type __idx;
   1122       typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
   1123       return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
   1124     }
   1125 
   1126   /// tie
   1127   template<typename... _Elements>
   1128     inline tuple<_Elements&...>
   1129     tie(_Elements&... __args) noexcept
   1130     { return tuple<_Elements&...>(__args...); }
   1131 
   1132   /// swap
   1133   template<typename... _Elements>
   1134     inline void 
   1135     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
   1136     noexcept(noexcept(__x.swap(__y)))
   1137     { __x.swap(__y); }
   1138 
   1139   // A class (and instance) which can be used in 'tie' when an element
   1140   // of a tuple is not required
   1141   struct _Swallow_assign
   1142   {
   1143     template<class _Tp>
   1144       const _Swallow_assign&
   1145       operator=(const _Tp&) const
   1146       { return *this; }
   1147   };
   1148 
   1149   const _Swallow_assign ignore{};
   1150 
   1151   /// Partial specialization for tuples
   1152   template<typename... _Types, typename _Alloc>
   1153     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
   1154 
   1155   // See stl_pair.h...
   1156   template<class _T1, class _T2>
   1157     template<typename... _Args1, typename... _Args2>
   1158       inline
   1159       pair<_T1, _T2>::
   1160       pair(piecewise_construct_t,
   1161 	   tuple<_Args1...> __first, tuple<_Args2...> __second)
   1162       : pair(__first, __second,
   1163 	     typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
   1164 	     typename _Build_index_tuple<sizeof...(_Args2)>::__type())
   1165       { }
   1166 
   1167   template<class _T1, class _T2>
   1168     template<typename... _Args1, std::size_t... _Indexes1,
   1169              typename... _Args2, std::size_t... _Indexes2>
   1170       inline
   1171       pair<_T1, _T2>::
   1172       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
   1173 	   _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
   1174       : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
   1175         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
   1176       { }
   1177 
   1178   /// @}
   1179 
   1180 _GLIBCXX_END_NAMESPACE_VERSION
   1181 } // namespace std
   1182 
   1183 #endif // C++11
   1184 
   1185 #endif // _GLIBCXX_TUPLE
   1186