libstdc++
tuple
Go to the documentation of this file.
00001 // <tuple> -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file include/tuple
00026  *  This is a Standard C++ Library header.
00027  */
00028 
00029 #ifndef _GLIBCXX_TUPLE
00030 #define _GLIBCXX_TUPLE 1
00031 
00032 #pragma GCC system_header
00033 
00034 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00035 # include <bits/c++0x_warning.h>
00036 #else
00037 
00038 #include <utility>
00039 
00040 namespace std _GLIBCXX_VISIBILITY(default)
00041 {
00042 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00043 
00044   // Adds a const reference to a non-reference type.
00045   template<typename _Tp>
00046     struct __add_c_ref
00047     { typedef const _Tp& type; };
00048 
00049   template<typename _Tp>
00050     struct __add_c_ref<_Tp&>
00051     { typedef _Tp& type; };
00052 
00053   // Adds a reference to a non-reference type.
00054   template<typename _Tp>
00055     struct __add_ref
00056     { typedef _Tp& type; };
00057 
00058   template<typename _Tp>
00059     struct __add_ref<_Tp&>
00060     { typedef _Tp& type; };
00061 
00062   template<std::size_t _Idx, typename _Head, bool _IsEmpty>
00063     struct _Head_base;
00064 
00065   template<std::size_t _Idx, typename _Head>
00066     struct _Head_base<_Idx, _Head, true>
00067     : public _Head
00068     {
00069       constexpr _Head_base()
00070       : _Head() { }
00071 
00072       constexpr _Head_base(const _Head& __h)
00073       : _Head(__h) { }
00074 
00075       template<typename _UHead>
00076         _Head_base(_UHead&& __h)
00077     : _Head(std::forward<_UHead>(__h)) { }
00078 
00079       _Head&       _M_head()       { return *this; }
00080       const _Head& _M_head() const { return *this; }
00081     
00082       void 
00083       _M_swap_impl(_Head& __h)
00084       {
00085     using std::swap;
00086     swap(__h, _M_head());
00087       }
00088     };
00089 
00090   template<std::size_t _Idx, typename _Head>
00091     struct _Head_base<_Idx, _Head, false>
00092     {
00093       constexpr _Head_base()
00094       : _M_head_impl() { }
00095 
00096       constexpr _Head_base(const _Head& __h)
00097       : _M_head_impl(__h) { }
00098 
00099       template<typename _UHead>
00100         _Head_base(_UHead&& __h)
00101     : _M_head_impl(std::forward<_UHead>(__h)) { }
00102 
00103       _Head&       _M_head()       { return _M_head_impl; }
00104       const _Head& _M_head() const { return _M_head_impl; }        
00105 
00106       void
00107       _M_swap_impl(_Head& __h)
00108       { 
00109     using std::swap;
00110     swap(__h, _M_head());
00111       }
00112 
00113       _Head _M_head_impl; 
00114     };
00115 
00116   /**
00117    * Contains the actual implementation of the @c tuple template, stored
00118    * as a recursive inheritance hierarchy from the first element (most
00119    * derived class) to the last (least derived class). The @c Idx
00120    * parameter gives the 0-based index of the element stored at this
00121    * point in the hierarchy; we use it to implement a constant-time
00122    * get() operation.
00123    */
00124   template<std::size_t _Idx, typename... _Elements>
00125     struct _Tuple_impl; 
00126 
00127   /**
00128    * Zero-element tuple implementation. This is the basis case for the 
00129    * inheritance recursion.
00130    */
00131   template<std::size_t _Idx>
00132     struct _Tuple_impl<_Idx>
00133     { 
00134     protected:
00135       void _M_swap_impl(_Tuple_impl&) { /* no-op */ }
00136     };
00137 
00138   /**
00139    * Recursive tuple implementation. Here we store the @c Head element
00140    * and derive from a @c Tuple_impl containing the remaining elements
00141    * (which contains the @c Tail).
00142    */
00143   template<std::size_t _Idx, typename _Head, typename... _Tail>
00144     struct _Tuple_impl<_Idx, _Head, _Tail...>
00145     : public _Tuple_impl<_Idx + 1, _Tail...>,
00146       private _Head_base<_Idx, _Head, std::is_empty<_Head>::value>
00147     {
00148       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
00149       typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base;
00150 
00151       _Head&            _M_head()       { return _Base::_M_head(); }
00152       const _Head&      _M_head() const { return _Base::_M_head(); }
00153 
00154       _Inherited&       _M_tail()       { return *this; }
00155       const _Inherited& _M_tail() const { return *this; }
00156 
00157       constexpr _Tuple_impl()
00158       : _Inherited(), _Base() { }
00159 
00160       explicit 
00161       constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
00162       : _Inherited(__tail...), _Base(__head) { }
00163 
00164       template<typename _UHead, typename... _UTail> 
00165         explicit
00166         _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
00167     : _Inherited(std::forward<_UTail>(__tail)...),
00168       _Base(std::forward<_UHead>(__head)) { }
00169 
00170       constexpr _Tuple_impl(const _Tuple_impl&) = default;
00171 
00172       _Tuple_impl(_Tuple_impl&& __in)
00173       : _Inherited(std::move(__in._M_tail())), 
00174     _Base(std::forward<_Head>(__in._M_head())) { }
00175 
00176       template<typename... _UElements>
00177         _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
00178     : _Inherited(__in._M_tail()), _Base(__in._M_head()) { }
00179 
00180       template<typename _UHead, typename... _UTails>
00181         _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
00182     : _Inherited(std::move(__in._M_tail())),
00183       _Base(std::forward<_UHead>(__in._M_head())) { }
00184 
00185       _Tuple_impl&
00186       operator=(const _Tuple_impl& __in)
00187       {
00188     _M_head() = __in._M_head();
00189     _M_tail() = __in._M_tail();
00190     return *this;
00191       }
00192 
00193       _Tuple_impl&
00194       operator=(_Tuple_impl&& __in)
00195       {
00196     _M_head() = std::forward<_Head>(__in._M_head());
00197     _M_tail() = std::move(__in._M_tail());
00198     return *this;
00199       }
00200 
00201       template<typename... _UElements>
00202         _Tuple_impl&
00203         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
00204         {
00205       _M_head() = __in._M_head();
00206       _M_tail() = __in._M_tail();
00207       return *this;
00208     }
00209 
00210       template<typename _UHead, typename... _UTails>
00211         _Tuple_impl&
00212         operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
00213         {
00214       _M_head() = std::forward<_UHead>(__in._M_head());
00215       _M_tail() = std::move(__in._M_tail());
00216       return *this;
00217     }
00218 
00219     protected:
00220       void
00221       _M_swap_impl(_Tuple_impl& __in)
00222       {
00223     _Base::_M_swap_impl(__in._M_head());
00224     _Inherited::_M_swap_impl(__in._M_tail());
00225       }
00226     };
00227 
00228   /// tuple
00229   template<typename... _Elements> 
00230     class tuple : public _Tuple_impl<0, _Elements...>
00231     {
00232       typedef _Tuple_impl<0, _Elements...> _Inherited;
00233 
00234     public:
00235       constexpr tuple()
00236       : _Inherited() { }
00237 
00238       explicit
00239       constexpr tuple(const _Elements&... __elements)
00240       : _Inherited(__elements...) { }
00241 
00242       template<typename... _UElements, typename = typename
00243            std::enable_if<sizeof...(_UElements)
00244                   == sizeof...(_Elements)>::type>
00245         explicit
00246         tuple(_UElements&&... __elements)
00247     : _Inherited(std::forward<_UElements>(__elements)...) { }
00248 
00249       constexpr tuple(const tuple&) = default;
00250 
00251       tuple(tuple&& __in)
00252       : _Inherited(static_cast<_Inherited&&>(__in)) { }
00253 
00254       template<typename... _UElements, typename = typename
00255            std::enable_if<sizeof...(_UElements)
00256                   == sizeof...(_Elements)>::type>
00257         tuple(const tuple<_UElements...>& __in)
00258         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
00259         { }
00260 
00261       template<typename... _UElements, typename = typename
00262            std::enable_if<sizeof...(_UElements)
00263                   == sizeof...(_Elements)>::type>
00264         tuple(tuple<_UElements...>&& __in)
00265         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
00266 
00267       tuple&
00268       operator=(const tuple& __in)
00269       {
00270     static_cast<_Inherited&>(*this) = __in;
00271     return *this;
00272       }
00273 
00274       tuple&
00275       operator=(tuple&& __in)
00276       {
00277     static_cast<_Inherited&>(*this) = std::move(__in);
00278     return *this;
00279       }
00280 
00281       template<typename... _UElements, typename = typename
00282            std::enable_if<sizeof...(_UElements)
00283                   == sizeof...(_Elements)>::type>
00284         tuple&
00285         operator=(const tuple<_UElements...>& __in)
00286         {
00287       static_cast<_Inherited&>(*this) = __in;
00288       return *this;
00289     }
00290 
00291       template<typename... _UElements, typename = typename
00292            std::enable_if<sizeof...(_UElements)
00293                   == sizeof...(_Elements)>::type>
00294         tuple&
00295         operator=(tuple<_UElements...>&& __in)
00296         {
00297       static_cast<_Inherited&>(*this) = std::move(__in);
00298       return *this;
00299     }
00300 
00301       void
00302       swap(tuple& __in)
00303       { _Inherited::_M_swap_impl(__in); }
00304     };
00305 
00306   template<>  
00307     class tuple<>
00308     {
00309     public:
00310       void swap(tuple&) { /* no-op */ }
00311     };
00312 
00313   /// tuple (2-element), with construction and assignment from a pair.
00314   template<typename _T1, typename _T2>
00315     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
00316     {
00317       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
00318 
00319     public:
00320       constexpr tuple()
00321       : _Inherited() { }
00322 
00323       explicit
00324       constexpr tuple(const _T1& __a1, const _T2& __a2)
00325       : _Inherited(__a1, __a2) { }
00326 
00327       template<typename _U1, typename _U2>
00328         explicit
00329         tuple(_U1&& __a1, _U2&& __a2)
00330     : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
00331 
00332       constexpr tuple(const tuple&) = default;
00333 
00334       tuple(tuple&& __in)
00335       : _Inherited(static_cast<_Inherited&&>(__in)) { }
00336 
00337       template<typename _U1, typename _U2>
00338         tuple(const tuple<_U1, _U2>& __in)
00339     : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
00340 
00341       template<typename _U1, typename _U2>
00342         tuple(tuple<_U1, _U2>&& __in)
00343     : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
00344 
00345       template<typename _U1, typename _U2>
00346         tuple(const pair<_U1, _U2>& __in)
00347     : _Inherited(__in.first, __in.second) { }
00348 
00349       template<typename _U1, typename _U2>
00350         tuple(pair<_U1, _U2>&& __in)
00351     : _Inherited(std::forward<_U1>(__in.first),
00352              std::forward<_U2>(__in.second)) { }
00353 
00354       tuple&
00355       operator=(const tuple& __in)
00356       {
00357     static_cast<_Inherited&>(*this) = __in;
00358     return *this;
00359       }
00360 
00361       tuple&
00362       operator=(tuple&& __in)
00363       {
00364     static_cast<_Inherited&>(*this) = std::move(__in);
00365     return *this;
00366       }
00367 
00368       template<typename _U1, typename _U2>
00369         tuple&
00370         operator=(const tuple<_U1, _U2>& __in)
00371         {
00372       static_cast<_Inherited&>(*this) = __in;
00373       return *this;
00374     }
00375 
00376       template<typename _U1, typename _U2>
00377         tuple&
00378         operator=(tuple<_U1, _U2>&& __in)
00379         {
00380       static_cast<_Inherited&>(*this) = std::move(__in);
00381       return *this;
00382     }
00383 
00384       template<typename _U1, typename _U2>
00385         tuple&
00386         operator=(const pair<_U1, _U2>& __in)
00387         {
00388       this->_M_head() = __in.first;
00389       this->_M_tail()._M_head() = __in.second;
00390       return *this;
00391     }
00392 
00393       template<typename _U1, typename _U2>
00394         tuple&
00395         operator=(pair<_U1, _U2>&& __in)
00396         {
00397       this->_M_head() = std::forward<_U1>(__in.first);
00398       this->_M_tail()._M_head() = std::forward<_U2>(__in.second);
00399       return *this;
00400     }
00401 
00402       void
00403       swap(tuple& __in)
00404       { 
00405     using std::swap;
00406     swap(this->_M_head(), __in._M_head());
00407     swap(this->_M_tail()._M_head(), __in._M_tail()._M_head());  
00408       }
00409     };
00410 
00411   /// tuple (1-element).
00412   template<typename _T1>
00413     class tuple<_T1> : public _Tuple_impl<0, _T1>
00414     {
00415       typedef _Tuple_impl<0, _T1> _Inherited;
00416 
00417     public:
00418       constexpr tuple()
00419       : _Inherited() { }
00420 
00421       explicit
00422       constexpr tuple(const _T1& __a1)
00423       : _Inherited(__a1) { }
00424 
00425       template<typename _U1, typename = typename
00426            std::enable_if<std::is_convertible<_U1, _T1>::value>::type>
00427         explicit
00428         tuple(_U1&& __a1)
00429     : _Inherited(std::forward<_U1>(__a1)) { }
00430 
00431       constexpr tuple(const tuple&) = default;
00432 
00433       tuple(tuple&& __in)
00434       : _Inherited(static_cast<_Inherited&&>(__in)) { }
00435 
00436       template<typename _U1>
00437         tuple(const tuple<_U1>& __in)
00438     : _Inherited(static_cast<const _Tuple_impl<0, _U1>&>(__in)) { }
00439 
00440       template<typename _U1>
00441         tuple(tuple<_U1>&& __in)
00442     : _Inherited(static_cast<_Tuple_impl<0, _U1>&&>(__in)) { }
00443 
00444       tuple&
00445       operator=(const tuple& __in)
00446       {
00447     static_cast<_Inherited&>(*this) = __in;
00448     return *this;
00449       }
00450 
00451       tuple&
00452       operator=(tuple&& __in)
00453       {
00454     static_cast<_Inherited&>(*this) = std::move(__in);
00455     return *this;
00456       }
00457 
00458       template<typename _U1>
00459         tuple&
00460         operator=(const tuple<_U1>& __in)
00461         {
00462       static_cast<_Inherited&>(*this) = __in;
00463       return *this;
00464     }
00465 
00466       template<typename _U1>
00467         tuple&
00468         operator=(tuple<_U1>&& __in)
00469         {
00470       static_cast<_Inherited&>(*this) = std::move(__in);
00471       return *this;
00472     }
00473 
00474       void
00475       swap(tuple& __in)
00476       { _Inherited::_M_swap_impl(__in); }
00477     };
00478 
00479 
00480   /// Gives the type of the ith element of a given tuple type.
00481   template<std::size_t __i, typename _Tp>
00482     struct tuple_element;
00483 
00484   /**
00485    * Recursive case for tuple_element: strip off the first element in
00486    * the tuple and retrieve the (i-1)th element of the remaining tuple.
00487    */
00488   template<std::size_t __i, typename _Head, typename... _Tail>
00489     struct tuple_element<__i, tuple<_Head, _Tail...> >
00490     : tuple_element<__i - 1, tuple<_Tail...> > { };
00491 
00492   /**
00493    * Basis case for tuple_element: The first element is the one we're seeking.
00494    */
00495   template<typename _Head, typename... _Tail>
00496     struct tuple_element<0, tuple<_Head, _Tail...> >
00497     {
00498       typedef _Head type;
00499     };
00500 
00501   /// Finds the size of a given tuple type.
00502   template<typename _Tp>
00503     struct tuple_size;
00504 
00505   /// class tuple_size
00506   template<typename... _Elements>
00507     struct tuple_size<tuple<_Elements...> >
00508     {
00509       static const std::size_t value = sizeof...(_Elements);
00510     };
00511 
00512   template<typename... _Elements>
00513     const std::size_t tuple_size<tuple<_Elements...> >::value;
00514 
00515   template<std::size_t __i, typename _Head, typename... _Tail>
00516     inline typename __add_ref<_Head>::type
00517     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t)
00518     { return __t._M_head(); }
00519 
00520   template<std::size_t __i, typename _Head, typename... _Tail>
00521     inline typename __add_c_ref<_Head>::type
00522     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t)
00523     { return __t._M_head(); }
00524 
00525   // Return a reference (const reference) to the ith element of a tuple.
00526   // Any const or non-const ref elements are returned with their original type.
00527   template<std::size_t __i, typename... _Elements>
00528     inline typename __add_ref<
00529                       typename tuple_element<__i, tuple<_Elements...> >::type
00530                     >::type
00531     get(tuple<_Elements...>& __t)
00532     { return __get_helper<__i>(__t); }
00533 
00534   template<std::size_t __i, typename... _Elements>
00535     inline typename __add_c_ref<
00536                       typename tuple_element<__i, tuple<_Elements...> >::type
00537                     >::type
00538     get(const tuple<_Elements...>& __t)
00539     { return __get_helper<__i>(__t); }
00540 
00541   // This class helps construct the various comparison operations on tuples
00542   template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
00543        typename _Tp, typename _Up>
00544     struct __tuple_compare;
00545 
00546   template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up>
00547     struct __tuple_compare<0, __i, __j, _Tp, _Up>
00548     {
00549       static bool __eq(const _Tp& __t, const _Up& __u)
00550       {
00551     return (get<__i>(__t) == get<__i>(__u) &&
00552         __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u));
00553       }
00554      
00555       static bool __less(const _Tp& __t, const _Up& __u)
00556       {
00557     return ((get<__i>(__t) < get<__i>(__u))
00558         || !(get<__i>(__u) < get<__i>(__t)) &&
00559         __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u));
00560       }
00561     };
00562 
00563   template<std::size_t __i, typename _Tp, typename _Up>
00564     struct __tuple_compare<0, __i, __i, _Tp, _Up>
00565     {
00566       static bool __eq(const _Tp&, const _Up&)
00567       { return true; }
00568      
00569       static bool __less(const _Tp&, const _Up&)
00570       { return false; }
00571     };
00572 
00573   template<typename... _TElements, typename... _UElements>
00574     bool
00575     operator==(const tuple<_TElements...>& __t,
00576            const tuple<_UElements...>& __u)
00577     {
00578       typedef tuple<_TElements...> _Tp;
00579       typedef tuple<_UElements...> _Up;
00580       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
00581           0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
00582     }
00583 
00584   template<typename... _TElements, typename... _UElements>
00585     bool
00586     operator<(const tuple<_TElements...>& __t,
00587           const tuple<_UElements...>& __u)
00588     {
00589       typedef tuple<_TElements...> _Tp;
00590       typedef tuple<_UElements...> _Up;
00591       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
00592           0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
00593     }
00594 
00595   template<typename... _TElements, typename... _UElements>
00596     inline bool
00597     operator!=(const tuple<_TElements...>& __t,
00598            const tuple<_UElements...>& __u)
00599     { return !(__t == __u); }
00600 
00601   template<typename... _TElements, typename... _UElements>
00602     inline bool
00603     operator>(const tuple<_TElements...>& __t,
00604           const tuple<_UElements...>& __u)
00605     { return __u < __t; }
00606 
00607   template<typename... _TElements, typename... _UElements>
00608     inline bool
00609     operator<=(const tuple<_TElements...>& __t,
00610            const tuple<_UElements...>& __u)
00611     { return !(__u < __t); }
00612 
00613   template<typename... _TElements, typename... _UElements>
00614     inline bool
00615     operator>=(const tuple<_TElements...>& __t,
00616            const tuple<_UElements...>& __u)
00617     { return !(__t < __u); }
00618 
00619   // NB: DR 705.
00620   template<typename... _Elements>
00621     inline tuple<typename __decay_and_strip<_Elements>::__type...>
00622     make_tuple(_Elements&&... __args)
00623     {
00624       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
00625     __result_type;
00626       return __result_type(std::forward<_Elements>(__args)...);
00627     }
00628 
00629   template<typename... _Elements>
00630     inline tuple<_Elements&&...>
00631     forward_as_tuple(_Elements&&... __args)
00632     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
00633 
00634   template<std::size_t...> struct __index_holder { };    
00635 
00636   template<std::size_t __i, typename _IdxHolder, typename... _Elements>
00637     struct __index_holder_impl;
00638 
00639   template<std::size_t __i, std::size_t... _Indexes, typename _IdxHolder,
00640        typename... _Elements>
00641     struct __index_holder_impl<__i, __index_holder<_Indexes...>,
00642                    _IdxHolder, _Elements...> 
00643     {
00644       typedef typename __index_holder_impl<__i + 1,
00645                        __index_holder<_Indexes..., __i>,
00646                        _Elements...>::type type;
00647     };
00648  
00649   template<std::size_t __i, std::size_t... _Indexes>
00650     struct __index_holder_impl<__i, __index_holder<_Indexes...> >
00651     { typedef __index_holder<_Indexes...> type; };
00652 
00653   template<typename... _Elements>
00654     struct __make_index_holder 
00655     : __index_holder_impl<0, __index_holder<>, _Elements...> { };
00656     
00657   template<typename... _TElements, std::size_t... _TIdx,
00658        typename... _UElements, std::size_t... _UIdx> 
00659     inline tuple<_TElements..., _UElements...> 
00660     __tuple_cat_helper(const tuple<_TElements...>& __t,
00661                const __index_holder<_TIdx...>&,
00662                        const tuple<_UElements...>& __u,
00663                const __index_holder<_UIdx...>&)
00664     { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)...,
00665                          get<_UIdx>(__u)...); }
00666 
00667   template<typename... _TElements, std::size_t... _TIdx,
00668        typename... _UElements, std::size_t... _UIdx> 
00669     inline tuple<_TElements..., _UElements...> 
00670     __tuple_cat_helper(tuple<_TElements...>&& __t,
00671                const __index_holder<_TIdx...>&, 
00672                const tuple<_UElements...>& __u,
00673                const __index_holder<_UIdx...>&)
00674     { return tuple<_TElements..., _UElements...>
00675     (std::forward<_TElements>(get<_TIdx>(__t))..., get<_UIdx>(__u)...); }
00676 
00677   template<typename... _TElements, std::size_t... _TIdx,
00678        typename... _UElements, std::size_t... _UIdx>
00679     inline tuple<_TElements..., _UElements...> 
00680     __tuple_cat_helper(const tuple<_TElements...>& __t,
00681                const __index_holder<_TIdx...>&, 
00682                tuple<_UElements...>&& __u,
00683                const __index_holder<_UIdx...>&)
00684     { return tuple<_TElements..., _UElements...>
00685     (get<_TIdx>(__t)..., std::forward<_UElements>(get<_UIdx>(__u))...); }
00686 
00687   template<typename... _TElements, std::size_t... _TIdx,
00688        typename... _UElements, std::size_t... _UIdx> 
00689     inline tuple<_TElements..., _UElements...> 
00690     __tuple_cat_helper(tuple<_TElements...>&& __t,
00691                const __index_holder<_TIdx...>&, 
00692                tuple<_UElements...>&& __u,
00693                const __index_holder<_UIdx...>&)
00694     { return tuple<_TElements..., _UElements...>
00695     (std::forward<_TElements>(get<_TIdx>(__t))...,
00696      std::forward<_UElements>(get<_UIdx>(__u))...); }
00697 
00698   template<typename... _TElements, typename... _UElements>
00699     inline tuple<_TElements..., _UElements...> 
00700     tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u)
00701     {
00702       return __tuple_cat_helper(__t, typename
00703                 __make_index_holder<_TElements...>::type(),
00704                 __u, typename
00705                 __make_index_holder<_UElements...>::type());
00706     }
00707 
00708   template<typename... _TElements, typename... _UElements>
00709     inline tuple<_TElements..., _UElements...> 
00710     tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u)
00711     {
00712       return __tuple_cat_helper(std::move(__t), typename
00713                  __make_index_holder<_TElements...>::type(),
00714                  __u, typename
00715                  __make_index_holder<_UElements...>::type());
00716     }
00717 
00718   template<typename... _TElements, typename... _UElements>
00719     inline tuple<_TElements..., _UElements...> 
00720     tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u)
00721     {
00722       return __tuple_cat_helper(__t, typename
00723                 __make_index_holder<_TElements...>::type(),
00724                 std::move(__u), typename
00725                 __make_index_holder<_UElements...>::type());
00726     }
00727 
00728   template<typename... _TElements, typename... _UElements>
00729     inline tuple<_TElements..., _UElements...>
00730     tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u)
00731     {
00732       return __tuple_cat_helper(std::move(__t), typename
00733                 __make_index_holder<_TElements...>::type(),
00734                 std::move(__u), typename
00735                 __make_index_holder<_UElements...>::type());
00736     }
00737 
00738   template<typename... _Elements>
00739     inline tuple<_Elements&...>
00740     tie(_Elements&... __args)
00741     { return tuple<_Elements&...>(__args...); }
00742 
00743   template<typename... _Elements>
00744     inline void 
00745     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
00746     { __x.swap(__y); }
00747 
00748   // A class (and instance) which can be used in 'tie' when an element
00749   // of a tuple is not required
00750   struct _Swallow_assign
00751   {
00752     template<class _Tp>
00753       const _Swallow_assign&
00754       operator=(const _Tp&) const
00755       { return *this; }
00756   };
00757 
00758   const _Swallow_assign ignore{};
00759 
00760   /**
00761    * Stores a tuple of indices. Used by bind() to extract the elements
00762    * in a tuple. 
00763    */
00764   template<int... _Indexes>
00765     struct _Index_tuple
00766     {
00767       typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
00768     };
00769 
00770   /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
00771   template<std::size_t _Num>
00772     struct _Build_index_tuple
00773     {
00774       typedef typename _Build_index_tuple<_Num-1>::__type::__next __type;
00775     };
00776 
00777   template<>
00778     struct _Build_index_tuple<0>
00779     {
00780       typedef _Index_tuple<> __type;
00781     };
00782 
00783   // See stl_pair.h...
00784   template<class _T1, class _T2>
00785     template<typename _Tp, typename... _Args>
00786       inline _Tp
00787       pair<_T1, _T2>::
00788       __cons(tuple<_Args...>&& __tuple)
00789       {
00790     typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
00791       _Indexes;
00792     return __do_cons<_Tp>(std::move(__tuple), _Indexes());
00793       }
00794 
00795   template<class _T1, class _T2>
00796     template<typename _Tp, typename... _Args, int... _Indexes>
00797       inline _Tp
00798       pair<_T1, _T2>::
00799       __do_cons(tuple<_Args...>&& __tuple,
00800         const _Index_tuple<_Indexes...>&)
00801       { return _Tp(std::forward<_Args>(get<_Indexes>(__tuple))...); }
00802 
00803 _GLIBCXX_END_NAMESPACE_VERSION
00804 } // namespace
00805 
00806 #endif // __GXX_EXPERIMENTAL_CXX0X__
00807 
00808 #endif // _GLIBCXX_TUPLE