# tuple

Go to the documentation of this file.

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