Home | History | Annotate | Download | only in 4.6.x-google
      1 // <tuple> -*- C++ -*-
      2 
      3 // Copyright (C) 2007, 2008, 2009, 2010, 2011 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 #ifndef __GXX_EXPERIMENTAL_CXX0X__
     35 # include <bits/c++0x_warning.h>
     36 #else
     37 
     38 #include <utility>
     39 
     40 namespace std _GLIBCXX_VISIBILITY(default)
     41 {
     42 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     43 
     44   // Adds a const reference to a non-reference type.
     45   template<typename _Tp>
     46     struct __add_c_ref
     47     { typedef const _Tp& type; };
     48 
     49   template<typename _Tp>
     50     struct __add_c_ref<_Tp&>
     51     { typedef _Tp& type; };
     52 
     53   // Adds a reference to a non-reference type.
     54   template<typename _Tp>
     55     struct __add_ref
     56     { typedef _Tp& type; };
     57 
     58   template<typename _Tp>
     59     struct __add_ref<_Tp&>
     60     { typedef _Tp& type; };
     61 
     62   template<std::size_t _Idx, typename _Head, bool _IsEmpty>
     63     struct _Head_base;
     64 
     65   template<std::size_t _Idx, typename _Head>
     66     struct _Head_base<_Idx, _Head, true>
     67     : public _Head
     68     {
     69       constexpr _Head_base()
     70       : _Head() { }
     71 
     72       constexpr _Head_base(const _Head& __h)
     73       : _Head(__h) { }
     74 
     75       template<typename _UHead>
     76         _Head_base(_UHead&& __h)
     77 	: _Head(std::forward<_UHead>(__h)) { }
     78 
     79       _Head&       _M_head()       { return *this; }
     80       const _Head& _M_head() const { return *this; }
     81     
     82       void 
     83       _M_swap_impl(_Head& __h)
     84       {
     85 	using std::swap;
     86 	swap(__h, _M_head());
     87       }
     88     };
     89 
     90   template<std::size_t _Idx, typename _Head>
     91     struct _Head_base<_Idx, _Head, false>
     92     {
     93       constexpr _Head_base()
     94       : _M_head_impl() { }
     95 
     96       constexpr _Head_base(const _Head& __h)
     97       : _M_head_impl(__h) { }
     98 
     99       template<typename _UHead>
    100         _Head_base(_UHead&& __h)
    101 	: _M_head_impl(std::forward<_UHead>(__h)) { }
    102 
    103       _Head&       _M_head()       { return _M_head_impl; }
    104       const _Head& _M_head() const { return _M_head_impl; }        
    105 
    106       void
    107       _M_swap_impl(_Head& __h)
    108       { 
    109 	using std::swap;
    110 	swap(__h, _M_head());
    111       }
    112 
    113       _Head _M_head_impl; 
    114     };
    115 
    116   /**
    117    * Contains the actual implementation of the @c tuple template, stored
    118    * as a recursive inheritance hierarchy from the first element (most
    119    * derived class) to the last (least derived class). The @c Idx
    120    * parameter gives the 0-based index of the element stored at this
    121    * point in the hierarchy; we use it to implement a constant-time
    122    * get() operation.
    123    */
    124   template<std::size_t _Idx, typename... _Elements>
    125     struct _Tuple_impl; 
    126 
    127   /**
    128    * Zero-element tuple implementation. This is the basis case for the 
    129    * inheritance recursion.
    130    */
    131   template<std::size_t _Idx>
    132     struct _Tuple_impl<_Idx>
    133     { 
    134     protected:
    135       void _M_swap_impl(_Tuple_impl&) { /* no-op */ }
    136     };
    137 
    138   /**
    139    * Recursive tuple implementation. Here we store the @c Head element
    140    * and derive from a @c Tuple_impl containing the remaining elements
    141    * (which contains the @c Tail).
    142    */
    143   template<std::size_t _Idx, typename _Head, typename... _Tail>
    144     struct _Tuple_impl<_Idx, _Head, _Tail...>
    145     : public _Tuple_impl<_Idx + 1, _Tail...>,
    146       private _Head_base<_Idx, _Head, std::is_empty<_Head>::value>
    147     {
    148       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
    149       typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base;
    150 
    151       _Head&            _M_head()       { return _Base::_M_head(); }
    152       const _Head&      _M_head() const { return _Base::_M_head(); }
    153 
    154       _Inherited&       _M_tail()       { return *this; }
    155       const _Inherited& _M_tail() const { return *this; }
    156 
    157       constexpr _Tuple_impl()
    158       : _Inherited(), _Base() { }
    159 
    160       explicit 
    161       constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
    162       : _Inherited(__tail...), _Base(__head) { }
    163 
    164       template<typename _UHead, typename... _UTail> 
    165         explicit
    166         _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
    167 	: _Inherited(std::forward<_UTail>(__tail)...),
    168 	  _Base(std::forward<_UHead>(__head)) { }
    169 
    170       constexpr _Tuple_impl(const _Tuple_impl&) = default;
    171 
    172       _Tuple_impl(_Tuple_impl&& __in)
    173       : _Inherited(std::move(__in._M_tail())), 
    174 	_Base(std::forward<_Head>(__in._M_head())) { }
    175 
    176       template<typename... _UElements>
    177         _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
    178 	: _Inherited(__in._M_tail()), _Base(__in._M_head()) { }
    179 
    180       template<typename _UHead, typename... _UTails>
    181         _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
    182 	: _Inherited(std::move(__in._M_tail())),
    183 	  _Base(std::forward<_UHead>(__in._M_head())) { }
    184 
    185       _Tuple_impl&
    186       operator=(const _Tuple_impl& __in)
    187       {
    188 	_M_head() = __in._M_head();
    189 	_M_tail() = __in._M_tail();
    190 	return *this;
    191       }
    192 
    193       _Tuple_impl&
    194       operator=(_Tuple_impl&& __in)
    195       {
    196 	_M_head() = std::forward<_Head>(__in._M_head());
    197 	_M_tail() = std::move(__in._M_tail());
    198 	return *this;
    199       }
    200 
    201       template<typename... _UElements>
    202         _Tuple_impl&
    203         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
    204         {
    205 	  _M_head() = __in._M_head();
    206 	  _M_tail() = __in._M_tail();
    207 	  return *this;
    208 	}
    209 
    210       template<typename _UHead, typename... _UTails>
    211         _Tuple_impl&
    212         operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
    213         {
    214 	  _M_head() = std::forward<_UHead>(__in._M_head());
    215 	  _M_tail() = std::move(__in._M_tail());
    216 	  return *this;
    217 	}
    218 
    219     protected:
    220       void
    221       _M_swap_impl(_Tuple_impl& __in)
    222       {
    223 	_Base::_M_swap_impl(__in._M_head());
    224 	_Inherited::_M_swap_impl(__in._M_tail());
    225       }
    226     };
    227 
    228   /// tuple
    229   template<typename... _Elements> 
    230     class tuple : public _Tuple_impl<0, _Elements...>
    231     {
    232       typedef _Tuple_impl<0, _Elements...> _Inherited;
    233 
    234     public:
    235       constexpr tuple()
    236       : _Inherited() { }
    237 
    238       explicit
    239       constexpr tuple(const _Elements&... __elements)
    240       : _Inherited(__elements...) { }
    241 
    242       template<typename... _UElements, typename = typename
    243 	       std::enable_if<sizeof...(_UElements)
    244 			      == sizeof...(_Elements)>::type>
    245         explicit
    246         tuple(_UElements&&... __elements)
    247 	: _Inherited(std::forward<_UElements>(__elements)...) {	}
    248 
    249       constexpr tuple(const tuple&) = default;
    250 
    251       tuple(tuple&& __in)
    252       : _Inherited(static_cast<_Inherited&&>(__in)) { }
    253 
    254       template<typename... _UElements, typename = typename
    255 	       std::enable_if<sizeof...(_UElements)
    256 			      == sizeof...(_Elements)>::type>
    257         tuple(const tuple<_UElements...>& __in)
    258         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    259         { }
    260 
    261       template<typename... _UElements, typename = typename
    262 	       std::enable_if<sizeof...(_UElements)
    263 			      == sizeof...(_Elements)>::type>
    264         tuple(tuple<_UElements...>&& __in)
    265         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
    266 
    267       tuple&
    268       operator=(const tuple& __in)
    269       {
    270 	static_cast<_Inherited&>(*this) = __in;
    271 	return *this;
    272       }
    273 
    274       tuple&
    275       operator=(tuple&& __in)
    276       {
    277 	static_cast<_Inherited&>(*this) = std::move(__in);
    278 	return *this;
    279       }
    280 
    281       template<typename... _UElements, typename = typename
    282 	       std::enable_if<sizeof...(_UElements)
    283 			      == sizeof...(_Elements)>::type>
    284         tuple&
    285         operator=(const tuple<_UElements...>& __in)
    286         {
    287 	  static_cast<_Inherited&>(*this) = __in;
    288 	  return *this;
    289 	}
    290 
    291       template<typename... _UElements, typename = typename
    292 	       std::enable_if<sizeof...(_UElements)
    293 			      == sizeof...(_Elements)>::type>
    294         tuple&
    295         operator=(tuple<_UElements...>&& __in)
    296         {
    297 	  static_cast<_Inherited&>(*this) = std::move(__in);
    298 	  return *this;
    299 	}
    300 
    301       void
    302       swap(tuple& __in)
    303       { _Inherited::_M_swap_impl(__in); }
    304     };
    305 
    306   template<>  
    307     class tuple<>
    308     {
    309     public:
    310       void swap(tuple&) { /* no-op */ }
    311     };
    312 
    313   /// tuple (2-element), with construction and assignment from a pair.
    314   template<typename _T1, typename _T2>
    315     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
    316     {
    317       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
    318 
    319     public:
    320       constexpr tuple()
    321       : _Inherited() { }
    322 
    323       explicit
    324       constexpr tuple(const _T1& __a1, const _T2& __a2)
    325       : _Inherited(__a1, __a2) { }
    326 
    327       template<typename _U1, typename _U2>
    328         explicit
    329         tuple(_U1&& __a1, _U2&& __a2)
    330 	: _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
    331 
    332       constexpr tuple(const tuple&) = default;
    333 
    334       tuple(tuple&& __in)
    335       : _Inherited(static_cast<_Inherited&&>(__in)) { }
    336 
    337       template<typename _U1, typename _U2>
    338         tuple(const tuple<_U1, _U2>& __in)
    339 	: _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
    340 
    341       template<typename _U1, typename _U2>
    342         tuple(tuple<_U1, _U2>&& __in)
    343 	: _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
    344 
    345       template<typename _U1, typename _U2>
    346         tuple(const pair<_U1, _U2>& __in)
    347 	: _Inherited(__in.first, __in.second) { }
    348 
    349       template<typename _U1, typename _U2>
    350         tuple(pair<_U1, _U2>&& __in)
    351 	: _Inherited(std::forward<_U1>(__in.first),
    352 		     std::forward<_U2>(__in.second)) { }
    353 
    354       tuple&
    355       operator=(const tuple& __in)
    356       {
    357 	static_cast<_Inherited&>(*this) = __in;
    358 	return *this;
    359       }
    360 
    361       tuple&
    362       operator=(tuple&& __in)
    363       {
    364 	static_cast<_Inherited&>(*this) = std::move(__in);
    365 	return *this;
    366       }
    367 
    368       template<typename _U1, typename _U2>
    369         tuple&
    370         operator=(const tuple<_U1, _U2>& __in)
    371         {
    372 	  static_cast<_Inherited&>(*this) = __in;
    373 	  return *this;
    374 	}
    375 
    376       template<typename _U1, typename _U2>
    377         tuple&
    378         operator=(tuple<_U1, _U2>&& __in)
    379         {
    380 	  static_cast<_Inherited&>(*this) = std::move(__in);
    381 	  return *this;
    382 	}
    383 
    384       template<typename _U1, typename _U2>
    385         tuple&
    386         operator=(const pair<_U1, _U2>& __in)
    387         {
    388 	  this->_M_head() = __in.first;
    389 	  this->_M_tail()._M_head() = __in.second;
    390 	  return *this;
    391 	}
    392 
    393       template<typename _U1, typename _U2>
    394         tuple&
    395         operator=(pair<_U1, _U2>&& __in)
    396         {
    397 	  this->_M_head() = std::forward<_U1>(__in.first);
    398 	  this->_M_tail()._M_head() = std::forward<_U2>(__in.second);
    399 	  return *this;
    400 	}
    401 
    402       void
    403       swap(tuple& __in)
    404       { 
    405 	using std::swap;
    406 	swap(this->_M_head(), __in._M_head());
    407 	swap(this->_M_tail()._M_head(), __in._M_tail()._M_head());	
    408       }
    409     };
    410 
    411   /// tuple (1-element).
    412   template<typename _T1>
    413     class tuple<_T1> : public _Tuple_impl<0, _T1>
    414     {
    415       typedef _Tuple_impl<0, _T1> _Inherited;
    416 
    417     public:
    418       constexpr tuple()
    419       : _Inherited() { }
    420 
    421       explicit
    422       constexpr tuple(const _T1& __a1)
    423       : _Inherited(__a1) { }
    424 
    425       template<typename _U1, typename = typename
    426 	       std::enable_if<std::is_convertible<_U1, _T1>::value>::type>
    427         explicit
    428         tuple(_U1&& __a1)
    429 	: _Inherited(std::forward<_U1>(__a1)) { }
    430 
    431       constexpr tuple(const tuple&) = default;
    432 
    433       tuple(tuple&& __in)
    434       : _Inherited(static_cast<_Inherited&&>(__in)) { }
    435 
    436       template<typename _U1>
    437         tuple(const tuple<_U1>& __in)
    438 	: _Inherited(static_cast<const _Tuple_impl<0, _U1>&>(__in)) { }
    439 
    440       template<typename _U1>
    441         tuple(tuple<_U1>&& __in)
    442 	: _Inherited(static_cast<_Tuple_impl<0, _U1>&&>(__in)) { }
    443 
    444       tuple&
    445       operator=(const tuple& __in)
    446       {
    447 	static_cast<_Inherited&>(*this) = __in;
    448 	return *this;
    449       }
    450 
    451       tuple&
    452       operator=(tuple&& __in)
    453       {
    454 	static_cast<_Inherited&>(*this) = std::move(__in);
    455 	return *this;
    456       }
    457 
    458       template<typename _U1>
    459         tuple&
    460         operator=(const tuple<_U1>& __in)
    461         {
    462 	  static_cast<_Inherited&>(*this) = __in;
    463 	  return *this;
    464 	}
    465 
    466       template<typename _U1>
    467         tuple&
    468         operator=(tuple<_U1>&& __in)
    469         {
    470 	  static_cast<_Inherited&>(*this) = std::move(__in);
    471 	  return *this;
    472 	}
    473 
    474       void
    475       swap(tuple& __in)
    476       { _Inherited::_M_swap_impl(__in); }
    477     };
    478 
    479 
    480   /// Gives the type of the ith element of a given tuple type.
    481   template<std::size_t __i, typename _Tp>
    482     struct tuple_element;
    483 
    484   /**
    485    * Recursive case for tuple_element: strip off the first element in
    486    * the tuple and retrieve the (i-1)th element of the remaining tuple.
    487    */
    488   template<std::size_t __i, typename _Head, typename... _Tail>
    489     struct tuple_element<__i, tuple<_Head, _Tail...> >
    490     : tuple_element<__i - 1, tuple<_Tail...> > { };
    491 
    492   /**
    493    * Basis case for tuple_element: The first element is the one we're seeking.
    494    */
    495   template<typename _Head, typename... _Tail>
    496     struct tuple_element<0, tuple<_Head, _Tail...> >
    497     {
    498       typedef _Head type;
    499     };
    500 
    501   /// Finds the size of a given tuple type.
    502   template<typename _Tp>
    503     struct tuple_size;
    504 
    505   /// class tuple_size
    506   template<typename... _Elements>
    507     struct tuple_size<tuple<_Elements...> >
    508     {
    509       static const std::size_t value = sizeof...(_Elements);
    510     };
    511 
    512   template<typename... _Elements>
    513     const std::size_t tuple_size<tuple<_Elements...> >::value;
    514 
    515   template<std::size_t __i, typename _Head, typename... _Tail>
    516     inline typename __add_ref<_Head>::type
    517     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t)
    518     { return __t._M_head(); }
    519 
    520   template<std::size_t __i, typename _Head, typename... _Tail>
    521     inline typename __add_c_ref<_Head>::type
    522     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t)
    523     { return __t._M_head(); }
    524 
    525   // Return a reference (const reference) to the ith element of a tuple.
    526   // Any const or non-const ref elements are returned with their original type.
    527   template<std::size_t __i, typename... _Elements>
    528     inline typename __add_ref<
    529                       typename tuple_element<__i, tuple<_Elements...> >::type
    530                     >::type
    531     get(tuple<_Elements...>& __t)
    532     { return __get_helper<__i>(__t); }
    533 
    534   template<std::size_t __i, typename... _Elements>
    535     inline typename __add_c_ref<
    536                       typename tuple_element<__i, tuple<_Elements...> >::type
    537                     >::type
    538     get(const tuple<_Elements...>& __t)
    539     { return __get_helper<__i>(__t); }
    540 
    541   // This class helps construct the various comparison operations on tuples
    542   template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
    543 	   typename _Tp, typename _Up>
    544     struct __tuple_compare;
    545 
    546   template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up>
    547     struct __tuple_compare<0, __i, __j, _Tp, _Up>
    548     {
    549       static bool __eq(const _Tp& __t, const _Up& __u)
    550       {
    551 	return (get<__i>(__t) == get<__i>(__u) &&
    552 		__tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u));
    553       }
    554      
    555       static bool __less(const _Tp& __t, const _Up& __u)
    556       {
    557 	return ((get<__i>(__t) < get<__i>(__u))
    558 		|| !(get<__i>(__u) < get<__i>(__t)) &&
    559 		__tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u));
    560       }
    561     };
    562 
    563   template<std::size_t __i, typename _Tp, typename _Up>
    564     struct __tuple_compare<0, __i, __i, _Tp, _Up>
    565     {
    566       static bool __eq(const _Tp&, const _Up&)
    567       { return true; }
    568      
    569       static bool __less(const _Tp&, const _Up&)
    570       { return false; }
    571     };
    572 
    573   template<typename... _TElements, typename... _UElements>
    574     bool
    575     operator==(const tuple<_TElements...>& __t,
    576 	       const tuple<_UElements...>& __u)
    577     {
    578       typedef tuple<_TElements...> _Tp;
    579       typedef tuple<_UElements...> _Up;
    580       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
    581 	      0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
    582     }
    583 
    584   template<typename... _TElements, typename... _UElements>
    585     bool
    586     operator<(const tuple<_TElements...>& __t,
    587 	      const tuple<_UElements...>& __u)
    588     {
    589       typedef tuple<_TElements...> _Tp;
    590       typedef tuple<_UElements...> _Up;
    591       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
    592 	      0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
    593     }
    594 
    595   template<typename... _TElements, typename... _UElements>
    596     inline bool
    597     operator!=(const tuple<_TElements...>& __t,
    598 	       const tuple<_UElements...>& __u)
    599     { return !(__t == __u); }
    600 
    601   template<typename... _TElements, typename... _UElements>
    602     inline bool
    603     operator>(const tuple<_TElements...>& __t,
    604 	      const tuple<_UElements...>& __u)
    605     { return __u < __t; }
    606 
    607   template<typename... _TElements, typename... _UElements>
    608     inline bool
    609     operator<=(const tuple<_TElements...>& __t,
    610 	       const tuple<_UElements...>& __u)
    611     { return !(__u < __t); }
    612 
    613   template<typename... _TElements, typename... _UElements>
    614     inline bool
    615     operator>=(const tuple<_TElements...>& __t,
    616 	       const tuple<_UElements...>& __u)
    617     { return !(__t < __u); }
    618 
    619   // NB: DR 705.
    620   template<typename... _Elements>
    621     inline tuple<typename __decay_and_strip<_Elements>::__type...>
    622     make_tuple(_Elements&&... __args)
    623     {
    624       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
    625 	__result_type;
    626       return __result_type(std::forward<_Elements>(__args)...);
    627     }
    628 
    629   template<typename... _Elements>
    630     inline tuple<_Elements&&...>
    631     forward_as_tuple(_Elements&&... __args)
    632     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
    633 
    634   template<std::size_t...> struct __index_holder { };    
    635 
    636   template<std::size_t __i, typename _IdxHolder, typename... _Elements>
    637     struct __index_holder_impl;
    638 
    639   template<std::size_t __i, std::size_t... _Indexes, typename _IdxHolder,
    640 	   typename... _Elements>
    641     struct __index_holder_impl<__i, __index_holder<_Indexes...>,
    642 			       _IdxHolder, _Elements...> 
    643     {
    644       typedef typename __index_holder_impl<__i + 1,
    645 					   __index_holder<_Indexes..., __i>,
    646 					   _Elements...>::type type;
    647     };
    648  
    649   template<std::size_t __i, std::size_t... _Indexes>
    650     struct __index_holder_impl<__i, __index_holder<_Indexes...> >
    651     { typedef __index_holder<_Indexes...> type; };
    652 
    653   template<typename... _Elements>
    654     struct __make_index_holder 
    655     : __index_holder_impl<0, __index_holder<>, _Elements...> { };
    656     
    657   template<typename... _TElements, std::size_t... _TIdx,
    658 	   typename... _UElements, std::size_t... _UIdx> 
    659     inline tuple<_TElements..., _UElements...> 
    660     __tuple_cat_helper(const tuple<_TElements...>& __t,
    661 		       const __index_holder<_TIdx...>&,
    662                        const tuple<_UElements...>& __u,
    663 		       const __index_holder<_UIdx...>&)
    664     { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)...,
    665 						 get<_UIdx>(__u)...); }
    666 
    667   template<typename... _TElements, std::size_t... _TIdx,
    668 	   typename... _UElements, std::size_t... _UIdx> 
    669     inline tuple<_TElements..., _UElements...> 
    670     __tuple_cat_helper(tuple<_TElements...>&& __t,
    671 		       const __index_holder<_TIdx...>&, 
    672 		       const tuple<_UElements...>& __u,
    673 		       const __index_holder<_UIdx...>&)
    674     { return tuple<_TElements..., _UElements...>
    675 	(std::forward<_TElements>(get<_TIdx>(__t))..., get<_UIdx>(__u)...); }
    676 
    677   template<typename... _TElements, std::size_t... _TIdx,
    678 	   typename... _UElements, std::size_t... _UIdx>
    679     inline tuple<_TElements..., _UElements...> 
    680     __tuple_cat_helper(const tuple<_TElements...>& __t,
    681 		       const __index_holder<_TIdx...>&, 
    682 		       tuple<_UElements...>&& __u,
    683 		       const __index_holder<_UIdx...>&)
    684     { return tuple<_TElements..., _UElements...>
    685 	(get<_TIdx>(__t)..., std::forward<_UElements>(get<_UIdx>(__u))...); }
    686 
    687   template<typename... _TElements, std::size_t... _TIdx,
    688 	   typename... _UElements, std::size_t... _UIdx> 
    689     inline tuple<_TElements..., _UElements...> 
    690     __tuple_cat_helper(tuple<_TElements...>&& __t,
    691 		       const __index_holder<_TIdx...>&, 
    692 		       tuple<_UElements...>&& __u,
    693 		       const __index_holder<_UIdx...>&)
    694     { return tuple<_TElements..., _UElements...>
    695 	(std::forward<_TElements>(get<_TIdx>(__t))...,
    696 	 std::forward<_UElements>(get<_UIdx>(__u))...); }
    697 
    698   template<typename... _TElements, typename... _UElements>
    699     inline tuple<_TElements..., _UElements...> 
    700     tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u)
    701     {
    702       return __tuple_cat_helper(__t, typename
    703 				__make_index_holder<_TElements...>::type(),
    704 				__u, typename
    705 				__make_index_holder<_UElements...>::type());
    706     }
    707 
    708   template<typename... _TElements, typename... _UElements>
    709     inline tuple<_TElements..., _UElements...> 
    710     tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u)
    711     {
    712       return __tuple_cat_helper(std::move(__t), typename
    713 				 __make_index_holder<_TElements...>::type(),
    714 				 __u, typename
    715 				 __make_index_holder<_UElements...>::type());
    716     }
    717 
    718   template<typename... _TElements, typename... _UElements>
    719     inline tuple<_TElements..., _UElements...> 
    720     tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u)
    721     {
    722       return __tuple_cat_helper(__t, typename
    723 				__make_index_holder<_TElements...>::type(),
    724 				std::move(__u), typename
    725 				__make_index_holder<_UElements...>::type());
    726     }
    727 
    728   template<typename... _TElements, typename... _UElements>
    729     inline tuple<_TElements..., _UElements...>
    730     tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u)
    731     {
    732       return __tuple_cat_helper(std::move(__t), typename
    733 				__make_index_holder<_TElements...>::type(),
    734 				std::move(__u), typename
    735 				__make_index_holder<_UElements...>::type());
    736     }
    737 
    738   template<typename... _Elements>
    739     inline tuple<_Elements&...>
    740     tie(_Elements&... __args)
    741     { return tuple<_Elements&...>(__args...); }
    742 
    743   template<typename... _Elements>
    744     inline void 
    745     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
    746     { __x.swap(__y); }
    747 
    748   // A class (and instance) which can be used in 'tie' when an element
    749   // of a tuple is not required
    750   struct _Swallow_assign
    751   {
    752     template<class _Tp>
    753       const _Swallow_assign&
    754       operator=(const _Tp&) const
    755       { return *this; }
    756   };
    757 
    758   const _Swallow_assign ignore{};
    759 
    760   /**
    761    * Stores a tuple of indices. Used by bind() to extract the elements
    762    * in a tuple. 
    763    */
    764   template<int... _Indexes>
    765     struct _Index_tuple
    766     {
    767       typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
    768     };
    769 
    770   /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
    771   template<std::size_t _Num>
    772     struct _Build_index_tuple
    773     {
    774       typedef typename _Build_index_tuple<_Num-1>::__type::__next __type;
    775     };
    776 
    777   template<>
    778     struct _Build_index_tuple<0>
    779     {
    780       typedef _Index_tuple<> __type;
    781     };
    782 
    783   // See stl_pair.h...
    784   template<class _T1, class _T2>
    785     template<typename _Tp, typename... _Args>
    786       inline _Tp
    787       pair<_T1, _T2>::
    788       __cons(tuple<_Args...>&& __tuple)
    789       {
    790 	typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
    791 	  _Indexes;
    792 	return __do_cons<_Tp>(std::move(__tuple), _Indexes());
    793       }
    794 
    795   template<class _T1, class _T2>
    796     template<typename _Tp, typename... _Args, int... _Indexes>
    797       inline _Tp
    798       pair<_T1, _T2>::
    799       __do_cons(tuple<_Args...>&& __tuple,
    800 		const _Index_tuple<_Indexes...>&)
    801       { return _Tp(std::forward<_Args>(get<_Indexes>(__tuple))...); }
    802 
    803 _GLIBCXX_END_NAMESPACE_VERSION
    804 } // namespace
    805 
    806 #endif // __GXX_EXPERIMENTAL_CXX0X__
    807 
    808 #endif // _GLIBCXX_TUPLE
    809