# tuple

Go to the documentation of this file.

    00001 // <tuple> -*- C++ -*-
    00002
    00003 // Copyright (C) 2007, 2008 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 2, 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 // You should have received a copy of the GNU General Public License
    00017 // along with this library; see the file COPYING.  If not, write to
    00018 // the Free Software Foundation, 51 Franklin Street, Fifth Floor,
    00019 // Boston, MA 02110-1301, USA.
    00020
    00021 // As a special exception, you may use this file as part of a free software
    00022 // library without restriction.  Specifically, if other files instantiate
    00023 // templates or use macros or inline functions from this file, or you compile
    00024 // this file and link it with other files to produce an executable, this
    00025 // file does not by itself cause the resulting executable to be covered by
    00026 // the GNU General Public License.  This exception does not however
    00027 // invalidate any other reasons why the executable file might be covered by
    00028 // the GNU General Public License.
    00029
    00030 /** @file include/tuple
    00031  *  This is a Standard C++ Library header.
    00032  */
    00033
    00034 #ifndef _GLIBCXX_CXX0X_TUPLE
    00035 #define _GLIBCXX_CXX0X_TUPLE 1
    00036
    00037 #pragma GCC system_header
    00038
    00039 #ifndef __GXX_EXPERIMENTAL_CXX0X__
    00040 # include <c++0x_warning.h>
    00041 #endif
    00042
    00043 #include <utility>
    00044
    00045 namespace std
    00046 {
    00047   // Adds a const reference to a non-reference type.
    00048   template<typename _Tp>
    00049     struct __add_c_ref
    00050     { typedef const _Tp& type; };
    00051
    00052   template<typename _Tp>
    00053     struct __add_c_ref<_Tp&>
    00054     { typedef _Tp& type; };
    00055
    00056   // Adds a reference to a non-reference type.
    00057   template<typename _Tp>
    00058     struct __add_ref
    00059     { typedef _Tp& type; };
    00060
    00061   template<typename _Tp>
    00062     struct __add_ref<_Tp&>
    00063     { typedef _Tp& type; };
    00064
    00065   template<int _Idx, typename _Head, bool _IsEmpty>
    00066     struct _Head_base;
    00067
    00068   template<int _Idx, typename _Head>
    00069     struct _Head_base<_Idx, _Head, true>
    00070     : public _Head
    00071     {
    00072       _Head_base()
    00073       : _Head() { }
    00074
    00075       _Head_base(const _Head& __h)
    00076       : _Head(__h) { }
    00077
    00078       template<typename _UHead>
    00079       _Head_base(_UHead&& __h)
    00080       : _Head(std::forward<_UHead>(__h)) { }
    00081
    00082       _Head&       _M_head()       { return *this; }
    00083       const _Head& _M_head() const { return *this; }
    00084     };
    00085
    00086   template<int _Idx, typename _Head>
    00087     struct _Head_base<_Idx, _Head, false>
    00088     {
    00089       _Head_base()
    00090       : _M_head_impl() { }
    00091
    00092       _Head_base(const _Head& __h)
    00093       : _M_head_impl(__h) { }
    00094
    00095       template<typename _UHead>
    00096       _Head_base(_UHead&& __h)
    00097       : _M_head_impl(std::forward<_UHead>(__h)) { }
    00098
    00099       _Head&       _M_head()       { return _M_head_impl; }
    00100       const _Head& _M_head() const { return _M_head_impl; }
    00101
    00102       _Head _M_head_impl;
    00103     };
    00104
    00105   /**
    00106    * Contains the actual implementation of the @c tuple template, stored
    00107    * as a recursive inheritance hierarchy from the first element (most
    00108    * derived class) to the last (least derived class). The @c Idx
    00109    * parameter gives the 0-based index of the element stored at this
    00110    * point in the hierarchy; we use it to implement a constant-time
    00111    * get() operation.
    00112    */
    00113   template<int _Idx, typename... _Elements>
    00114     struct _Tuple_impl;
    00115
    00116   /**
    00117    * Zero-element tuple implementation. This is the basis case for the
    00118    * inheritance recursion.
    00119    */
    00120   template<int _Idx>
    00121     struct _Tuple_impl<_Idx> { };
    00122
    00123   /**
    00124    * Recursive tuple implementation. Here we store the @c Head element
    00125    * and derive from a @c Tuple_impl containing the remaining elements
    00126    * (which contains the @c Tail).
    00127    */
    00128   template<int _Idx, typename _Head, typename... _Tail>
    00129     struct _Tuple_impl<_Idx, _Head, _Tail...>
    00130     : public _Tuple_impl<_Idx + 1, _Tail...>,
    00131       private _Head_base<_Idx, _Head, std::is_empty<_Head>::value>
    00132     {
    00133       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
    00134       typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base;
    00135
    00136       _Head&            _M_head()       { return _Base::_M_head(); }
    00137       const _Head&      _M_head() const { return _Base::_M_head(); }
    00138
    00139       _Inherited&       _M_tail()       { return *this; }
    00140       const _Inherited& _M_tail() const { return *this; }
    00141
    00142       _Tuple_impl()
    00143       : _Inherited(), _Base() { }
    00144
    00145       explicit
    00146       _Tuple_impl(const _Head& __head, const _Tail&... __tail)
    00147       : _Inherited(__tail...), _Base(__head) { }
    00148
    00149       template<typename _UHead, typename... _UTail>
    00150         explicit
    00151         _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
    00152     : _Inherited(std::forward<_UTail>(__tail)...),
    00153       _Base(std::forward<_UHead>(__head)) { }
    00154
    00155       _Tuple_impl(const _Tuple_impl& __in)
    00156       : _Inherited(__in._M_tail()), _Base(__in._M_head()) { }
    00157
    00158       _Tuple_impl(_Tuple_impl&& __in)
    00159       : _Inherited(std::move<_Inherited&&>(__in._M_tail())),
    00160     _Base(std::forward<_Head>(__in._M_head())) { }
    00161
    00162       template<typename... _UElements>
    00163         _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
    00164     : _Inherited(__in._M_tail()), _Base(__in._M_head()) { }
    00165
    00166       template<typename... _UElements>
    00167         _Tuple_impl(_Tuple_impl<_Idx, _UElements...>&& __in)
    00168     : _Inherited(std::move<typename _Tuple_impl<_Idx, _UElements...>::
    00169              _Inherited&&>(__in._M_tail())),
    00170       _Base(std::forward<typename _Tuple_impl<_Idx, _UElements...>::
    00171         _Base>(__in._M_head())) { }
    00172
    00173       _Tuple_impl&
    00174       operator=(const _Tuple_impl& __in)
    00175       {
    00176     _M_head() = __in._M_head();
    00177     _M_tail() = __in._M_tail();
    00178     return *this;
    00179       }
    00180
    00181       _Tuple_impl&
    00182       operator=(_Tuple_impl&& __in)
    00183       {
    00184     _M_head() = std::move(__in._M_head());
    00185     _M_tail() = std::move(__in._M_tail());
    00186     return *this;
    00187       }
    00188
    00189       template<typename... _UElements>
    00190         _Tuple_impl&
    00191         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
    00192         {
    00193       _M_head() = __in._M_head();
    00194       _M_tail() = __in._M_tail();
    00195       return *this;
    00196     }
    00197
    00198       template<typename... _UElements>
    00199         _Tuple_impl&
    00200         operator=(_Tuple_impl<_Idx, _UElements...>&& __in)
    00201         {
    00202       _M_head() = std::move(__in._M_head());
    00203       _M_tail() = std::move(__in._M_tail());
    00204       return *this;
    00205     }
    00206     };
    00207
    00208   /// tuple
    00209   template<typename... _Elements>
    00210     class tuple : public _Tuple_impl<0, _Elements...>
    00211     {
    00212       typedef _Tuple_impl<0, _Elements...> _Inherited;
    00213
    00214     public:
    00215       tuple()
    00216       : _Inherited() { }
    00217
    00218       explicit
    00219       tuple(const _Elements&... __elements)
    00220       : _Inherited(__elements...) { }
    00221
    00222       template<typename... _UElements>
    00223         explicit
    00224         tuple(_UElements&&... __elements)
    00225     : _Inherited(std::forward<_UElements>(__elements)...) { }
    00226
    00227       tuple(const tuple& __in)
    00228       : _Inherited(static_cast<const _Inherited&>(__in)) { }
    00229
    00230       tuple(tuple&& __in)
    00231       : _Inherited(std::move<_Inherited>(__in)) { }
    00232
    00233       template<typename... _UElements>
    00234         tuple(const tuple<_UElements...>& __in)
    00235     : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    00236     { }
    00237
    00238       template<typename... _UElements>
    00239         tuple(tuple<_UElements...>&& __in)
    00240     : _Inherited(std::move<_Tuple_impl<0, _UElements...> >(__in)) { }
    00241
    00242       // XXX http://gcc.gnu.org/ml/libstdc++/2008-02/msg00047.html
    00243       template<typename... _UElements>
    00244         tuple(tuple<_UElements...>& __in)
    00245     : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
    00246     { }
    00247
    00248       tuple&
    00249       operator=(const tuple& __in)
    00250       {
    00251     static_cast<_Inherited&>(*this) = __in;
    00252     return *this;
    00253       }
    00254
    00255       tuple&
    00256       operator=(tuple&& __in)
    00257       {
    00258     static_cast<_Inherited&>(*this) = std::move(__in);
    00259     return *this;
    00260       }
    00261
    00262       template<typename... _UElements>
    00263         tuple&
    00264         operator=(const tuple<_UElements...>& __in)
    00265         {
    00266       static_cast<_Inherited&>(*this) = __in;
    00267       return *this;
    00268     }
    00269
    00270       template<typename... _UElements>
    00271         tuple&
    00272         operator=(tuple<_UElements...>&& __in)
    00273         {
    00274       static_cast<_Inherited&>(*this) = std::move(__in);
    00275       return *this;
    00276     }
    00277     };
    00278
    00279
    00280   template<>
    00281     class tuple<> { };
    00282
    00283   /// tuple (2-element), with construction and assignment from a pair.
    00284   template<typename _T1, typename _T2>
    00285     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
    00286     {
    00287       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
    00288
    00289     public:
    00290       tuple()
    00291       : _Inherited() { }
    00292
    00293       explicit
    00294       tuple(const _T1& __a1, const _T2& __a2)
    00295       : _Inherited(__a1, __a2) { }
    00296
    00297       template<typename _U1, typename _U2>
    00298         explicit
    00299         tuple(_U1&& __a1, _U2&& __a2)
    00300     : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
    00301
    00302       tuple(const tuple& __in)
    00303       : _Inherited(static_cast<const _Inherited&>(__in)) { }
    00304
    00305       tuple(tuple&& __in)
    00306       : _Inherited(std::move<_Inherited>(__in)) { }
    00307
    00308       template<typename _U1, typename _U2>
    00309         tuple(const tuple<_U1, _U2>& __in)
    00310     : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
    00311
    00312       template<typename _U1, typename _U2>
    00313         tuple(tuple<_U1, _U2>&& __in)
    00314     : _Inherited(std::move<_Tuple_impl<0, _U1, _U2> >(__in)) { }
    00315
    00316       template<typename _U1, typename _U2>
    00317         tuple(const pair<_U1, _U2>& __in)
    00318     : _Inherited(__in.first, __in.second) { }
    00319
    00320       template<typename _U1, typename _U2>
    00321         tuple(pair<_U1, _U2>&& __in)
    00322     : _Inherited(std::move(__in.first), std::move(__in.second)) { }
    00323
    00324       tuple&
    00325       operator=(const tuple& __in)
    00326       {
    00327     static_cast<_Inherited&>(*this) = __in;
    00328     return *this;
    00329       }
    00330
    00331       tuple&
    00332       operator=(tuple&& __in)
    00333       {
    00334     static_cast<_Inherited&>(*this) = std::move(__in);
    00335     return *this;
    00336       }
    00337
    00338       template<typename _U1, typename _U2>
    00339         tuple&
    00340         operator=(const tuple<_U1, _U2>& __in)
    00341         {
    00342       static_cast<_Inherited&>(*this) = __in;
    00343       return *this;
    00344     }
    00345
    00346       template<typename _U1, typename _U2>
    00347         tuple&
    00348         operator=(tuple<_U1, _U2>&& __in)
    00349         {
    00350       static_cast<_Inherited&>(*this) = std::move(__in);
    00351       return *this;
    00352     }
    00353
    00354       template<typename _U1, typename _U2>
    00355         tuple&
    00356         operator=(const pair<_U1, _U2>& __in)
    00357         {
    00358       this->_M_head() = __in.first;
    00359       this->_M_tail()._M_head() = __in.second;
    00360       return *this;
    00361     }
    00362
    00363       template<typename _U1, typename _U2>
    00364         tuple&
    00365         operator=(pair<_U1, _U2>&& __in)
    00366         {
    00367       this->_M_head() = std::move(__in.first);
    00368       this->_M_tail()._M_head() = std::move(__in.second);
    00369       return *this;
    00370     }
    00371     };
    00372
    00373
    00374   /// Gives the type of the ith element of a given tuple type.
    00375   template<int __i, typename _Tp>
    00376     struct tuple_element;
    00377
    00378   /**
    00379    * Recursive case for tuple_element: strip off the first element in
    00380    * the tuple and retrieve the (i-1)th element of the remaining tuple.
    00381    */
    00382   template<int __i, typename _Head, typename... _Tail>
    00383     struct tuple_element<__i, tuple<_Head, _Tail...> >
    00384     : tuple_element<__i - 1, tuple<_Tail...> > { };
    00385
    00386   /**
    00387    * Basis case for tuple_element: The first element is the one we're seeking.
    00388    */
    00389   template<typename _Head, typename... _Tail>
    00390     struct tuple_element<0, tuple<_Head, _Tail...> >
    00391     {
    00392       typedef _Head type;
    00393     };
    00394
    00395   /// Finds the size of a given tuple type.
    00396   template<typename _Tp>
    00397     struct tuple_size;
    00398
    00399   /// class tuple_size
    00400   template<typename... _Elements>
    00401     struct tuple_size<tuple<_Elements...> >
    00402     {
    00403       static const int value = sizeof...(_Elements);
    00404     };
    00405
    00406   template<typename... _Elements>
    00407     const int tuple_size<tuple<_Elements...> >::value;
    00408
    00409   template<int __i, typename _Head, typename... _Tail>
    00410     inline typename __add_ref<_Head>::type
    00411     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t)
    00412     { return __t._M_head(); }
    00413
    00414   template<int __i, typename _Head, typename... _Tail>
    00415     inline typename __add_c_ref<_Head>::type
    00416     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t)
    00417     { return __t._M_head(); }
    00418
    00419   // Return a reference (const reference) to the ith element of a tuple.
    00420   // Any const or non-const ref elements are returned with their original type.
    00421   template<int __i, typename... _Elements>
    00422     inline typename __add_ref<
    00423                       typename tuple_element<__i, tuple<_Elements...> >::type
    00424                     >::type
    00425     get(tuple<_Elements...>& __t)
    00426     { return __get_helper<__i>(__t); }
    00427
    00428   template<int __i, typename... _Elements>
    00429     inline typename __add_c_ref<
    00430                       typename tuple_element<__i, tuple<_Elements...> >::type
    00431                     >::type
    00432     get(const tuple<_Elements...>& __t)
    00433     { return __get_helper<__i>(__t); }
    00434
    00435   // This class helps construct the various comparison operations on tuples
    00436   template<int __check_equal_size, int __i, int __j,
    00437        typename _Tp, typename _Up>
    00438     struct __tuple_compare;
    00439
    00440   template<int __i, int __j, typename _Tp, typename _Up>
    00441     struct __tuple_compare<0, __i, __j, _Tp, _Up>
    00442     {
    00443       static bool __eq(const _Tp& __t, const _Up& __u)
    00444       {
    00445     return (get<__i>(__t) == get<__i>(__u) &&
    00446         __tuple_compare<0, __i+1, __j, _Tp, _Up>::__eq(__t, __u));
    00447       }
    00448
    00449       static bool __less(const _Tp& __t, const _Up& __u)
    00450       {
    00451     return ((get<__i>(__t) < get<__i>(__u))
    00452         || !(get<__i>(__u) < get<__i>(__t)) &&
    00453         __tuple_compare<0, __i+1, __j, _Tp, _Up>::__less(__t, __u));
    00454       }
    00455     };
    00456
    00457   template<int __i, typename _Tp, typename _Up>
    00458     struct __tuple_compare<0, __i, __i, _Tp, _Up>
    00459     {
    00460       static bool __eq(const _Tp&, const _Up&)
    00461       { return true; }
    00462
    00463       static bool __less(const _Tp&, const _Up&)
    00464       { return false; }
    00465     };
    00466
    00467   template<typename... _TElements, typename... _UElements>
    00468     bool
    00469     operator==(const tuple<_TElements...>& __t,
    00470            const tuple<_UElements...>& __u)
    00471     {
    00472       typedef tuple<_TElements...> _Tp;
    00473       typedef tuple<_UElements...> _Up;
    00474       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
    00475           0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
    00476     }
    00477
    00478   template<typename... _TElements, typename... _UElements>
    00479     bool
    00480     operator<(const tuple<_TElements...>& __t,
    00481           const tuple<_UElements...>& __u)
    00482     {
    00483       typedef tuple<_TElements...> _Tp;
    00484       typedef tuple<_UElements...> _Up;
    00485       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
    00486           0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
    00487     }
    00488
    00489   template<typename... _TElements, typename... _UElements>
    00490     inline bool
    00491     operator!=(const tuple<_TElements...>& __t,
    00492            const tuple<_UElements...>& __u)
    00493     { return !(__t == __u); }
    00494
    00495   template<typename... _TElements, typename... _UElements>
    00496     inline bool
    00497     operator>(const tuple<_TElements...>& __t,
    00498           const tuple<_UElements...>& __u)
    00499     { return __u < __t; }
    00500
    00501   template<typename... _TElements, typename... _UElements>
    00502     inline bool
    00503     operator<=(const tuple<_TElements...>& __t,
    00504            const tuple<_UElements...>& __u)
    00505     { return !(__u < __t); }
    00506
    00507   template<typename... _TElements, typename... _UElements>
    00508     inline bool
    00509     operator>=(const tuple<_TElements...>& __t,
    00510            const tuple<_UElements...>& __u)
    00511     { return !(__t < __u); }
    00512
    00513   // NB: DR 705.
    00514   template<typename... _Elements>
    00515     inline tuple<typename __decay_and_strip<_Elements>::__type...>
    00516     make_tuple(_Elements&&... __args)
    00517     {
    00518       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
    00519     __result_type;
    00520       return __result_type(std::forward<_Elements>(__args)...);
    00521     }
    00522
    00523   template<int...> struct __index_holder { };
    00524
    00525   template<int __i, typename _IdxHolder, typename... _Elements>
    00526     struct __index_holder_impl;
    00527
    00528   template<int __i, int... _Indexes, typename _IdxHolder, typename... _Elements>
    00529     struct __index_holder_impl<__i, __index_holder<_Indexes...>,
    00530                    _IdxHolder, _Elements...>
    00531     {
    00532       typedef typename __index_holder_impl<__i + 1,
    00533                        __index_holder<_Indexes..., __i>,
    00534                        _Elements...>::type type;
    00535     };
    00536
    00537   template<int __i, int... _Indexes>
    00538     struct __index_holder_impl<__i, __index_holder<_Indexes...> >
    00539     { typedef __index_holder<_Indexes...> type; };
    00540
    00541   template<typename... _Elements>
    00542     struct __make_index_holder
    00543     : __index_holder_impl<0, __index_holder<>, _Elements...> { };
    00544
    00545   template<typename... _TElements, int... _TIdx,
    00546        typename... _UElements, int... _UIdx>
    00547     inline tuple<_TElements..., _UElements...>
    00548     __tuple_cat_helper(const tuple<_TElements...>& __t,
    00549                const __index_holder<_TIdx...>&,
    00550                        const tuple<_UElements...>& __u,
    00551                const __index_holder<_UIdx...>&)
    00552     { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)...,
    00553                          get<_UIdx>(__u)...); }
    00554
    00555   template<typename... _TElements, int... _TIdx,
    00556        typename... _UElements, int... _UIdx>
    00557     inline tuple<_TElements..., _UElements...>
    00558     __tuple_cat_helper(tuple<_TElements...>&& __t,
    00559                const __index_holder<_TIdx...>&,
    00560                const tuple<_UElements...>& __u,
    00561                const __index_holder<_UIdx...>&)
    00562     { return tuple<_TElements..., _UElements...>
    00563     (std::move(get<_TIdx>(__t))..., get<_UIdx>(__u)...); }
    00564
    00565   template<typename... _TElements, int... _TIdx,
    00566        typename... _UElements, int... _UIdx>
    00567     inline tuple<_TElements..., _UElements...>
    00568     __tuple_cat_helper(const tuple<_TElements...>& __t,
    00569                const __index_holder<_TIdx...>&,
    00570                tuple<_UElements...>&& __u,
    00571                const __index_holder<_UIdx...>&)
    00572     { return tuple<_TElements..., _UElements...>
    00573     (get<_TIdx>(__t)..., std::move(get<_UIdx>(__u))...); }
    00574
    00575   template<typename... _TElements, int... _TIdx,
    00576        typename... _UElements, int... _UIdx>
    00577     inline tuple<_TElements..., _UElements...>
    00578     __tuple_cat_helper(tuple<_TElements...>&& __t,
    00579                const __index_holder<_TIdx...>&,
    00580                tuple<_UElements...>&& __u,
    00581                const __index_holder<_UIdx...>&)
    00582     { return tuple<_TElements..., _UElements...>
    00583     (std::move(get<_TIdx>(__t))..., std::move(get<_UIdx>(__u))...); }
    00584
    00585   template<typename... _TElements, typename... _UElements>
    00586     inline tuple<_TElements..., _UElements...>
    00587     tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u)
    00588     {
    00589       return __tuple_cat_helper(__t, typename
    00590                 __make_index_holder<_TElements...>::type(),
    00591                 __u, typename
    00592                 __make_index_holder<_UElements...>::type());
    00593     }
    00594
    00595   template<typename... _TElements, typename... _UElements>
    00596     inline tuple<_TElements..., _UElements...>
    00597     tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u)
    00598     {
    00599       return __tuple_cat_helper(std::move(__t), typename
    00600                  __make_index_holder<_TElements...>::type(),
    00601                  __u, typename
    00602                  __make_index_holder<_UElements...>::type());
    00603     }
    00604
    00605   template<typename... _TElements, typename... _UElements>
    00606     inline tuple<_TElements..., _UElements...>
    00607     tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u)
    00608     {
    00609       return __tuple_cat_helper(__t, typename
    00610                 __make_index_holder<_TElements...>::type(),
    00611                 std::move(__u), typename
    00612                 __make_index_holder<_UElements...>::type());
    00613     }
    00614
    00615   template<typename... _TElements, typename... _UElements>
    00616     inline tuple<_TElements..., _UElements...>
    00617     tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u)
    00618     {
    00619       return __tuple_cat_helper(std::move(__t), typename
    00620                 __make_index_holder<_TElements...>::type(),
    00621                 std::move(__u), typename
    00622                 __make_index_holder<_UElements...>::type());
    00623     }
    00624
    00625   template<typename... _Elements>
    00626     inline tuple<_Elements&...>
    00627     tie(_Elements&... __args)
    00628     { return tuple<_Elements&...>(__args...); }
    00629
    00630   // A class (and instance) which can be used in 'tie' when an element
    00631   // of a tuple is not required
    00632   struct _Swallow_assign
    00633   {
    00634     template<class _Tp>
    00635       _Swallow_assign&
    00636       operator=(const _Tp&)
    00637       { return *this; }
    00638   };
    00639
    00640   // TODO: Put this in some kind of shared file.
    00641   namespace
    00642   {
    00643     _Swallow_assign ignore;
    00644   }; // anonymous namespace
    00645 }
    00646
    00647 #endif // _GLIBCXX_CXX0X_TUPLE