tuple

Go to the documentation of this file.
00001 // <tuple> -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009, 2010 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
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&) = default;
00164 
00165       _Tuple_impl(_Tuple_impl&& __in)
00166       : _Inherited(std::move(__in._M_tail())),
00167     _Base(std::forward<_Head>(__in._M_head())) { }
00168 
00169       template<typename... _UElements>
00170         _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
00171     : _Inherited(__in._M_tail()), _Base(__in._M_head()) { }
00172 
00173       template<typename... _UElements>
00174         _Tuple_impl(_Tuple_impl<_Idx, _UElements...>&& __in)
00175     : _Inherited(std::move(__in._M_tail())),
00176       _Base(std::move(__in._M_head())) { }
00177 
00178       _Tuple_impl&
00179       operator=(const _Tuple_impl& __in)
00180       {
00181     _M_head() = __in._M_head();
00182     _M_tail() = __in._M_tail();
00183     return *this;
00184       }
00185 
00186       _Tuple_impl&
00187       operator=(_Tuple_impl&& __in)
00188       {
00189     _M_head() = std::move(__in._M_head());
00190     _M_tail() = std::move(__in._M_tail());
00191     return *this;
00192       }
00193 
00194       template<typename... _UElements>
00195         _Tuple_impl&
00196         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
00197         {
00198       _M_head() = __in._M_head();
00199       _M_tail() = __in._M_tail();
00200       return *this;
00201     }
00202 
00203       template<typename... _UElements>
00204         _Tuple_impl&
00205         operator=(_Tuple_impl<_Idx, _UElements...>&& __in)
00206         {
00207       _M_head() = std::move(__in._M_head());
00208       _M_tail() = std::move(__in._M_tail());
00209       return *this;
00210     }
00211 
00212     protected:
00213       void
00214       _M_swap_impl(_Tuple_impl& __in)
00215       {
00216     _Base::_M_swap_impl(__in._M_head());
00217     _Inherited::_M_swap_impl(__in._M_tail());
00218       }
00219     };
00220 
00221   /// tuple
00222   template<typename... _Elements> 
00223     class tuple : public _Tuple_impl<0, _Elements...>
00224     {
00225       typedef _Tuple_impl<0, _Elements...> _Inherited;
00226 
00227     public:
00228       tuple()
00229       : _Inherited() { }
00230 
00231       explicit
00232       tuple(const _Elements&... __elements)
00233       : _Inherited(__elements...) { }
00234 
00235       template<typename... _UElements, typename = typename
00236            std::enable_if<sizeof...(_UElements)
00237                   == sizeof...(_Elements)>::type>
00238         explicit
00239         tuple(_UElements&&... __elements)
00240     : _Inherited(std::forward<_UElements>(__elements)...) { }
00241 
00242       tuple(const tuple&) = default;
00243 
00244       tuple(tuple&& __in)
00245       : _Inherited(static_cast<_Inherited&&>(__in)) { }
00246 
00247       template<typename... _UElements, typename = typename
00248            std::enable_if<sizeof...(_UElements)
00249                   == sizeof...(_Elements)>::type>
00250         tuple(const tuple<_UElements...>& __in)
00251         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
00252         { }
00253 
00254       template<typename... _UElements, typename = typename
00255            std::enable_if<sizeof...(_UElements)
00256                   == sizeof...(_Elements)>::type>
00257         tuple(tuple<_UElements...>&& __in)
00258         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
00259 
00260       tuple&
00261       operator=(const tuple& __in)
00262       {
00263     static_cast<_Inherited&>(*this) = __in;
00264     return *this;
00265       }
00266 
00267       tuple&
00268       operator=(tuple&& __in)
00269       {
00270     static_cast<_Inherited&>(*this) = std::move(__in);
00271     return *this;
00272       }
00273 
00274       template<typename... _UElements, typename = typename
00275            std::enable_if<sizeof...(_UElements)
00276                   == sizeof...(_Elements)>::type>
00277         tuple&
00278         operator=(const tuple<_UElements...>& __in)
00279         {
00280       static_cast<_Inherited&>(*this) = __in;
00281       return *this;
00282     }
00283 
00284       template<typename... _UElements, typename = typename
00285            std::enable_if<sizeof...(_UElements)
00286                   == sizeof...(_Elements)>::type>
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   template<>  
00300     class tuple<>
00301     {
00302     public:
00303       void swap(tuple&) { /* no-op */ }
00304     };
00305 
00306   /// tuple (2-element), with construction and assignment from a pair.
00307   template<typename _T1, typename _T2>
00308     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
00309     {
00310       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
00311 
00312     public:
00313       tuple()
00314       : _Inherited() { }
00315 
00316       explicit
00317       tuple(const _T1& __a1, const _T2& __a2)
00318       : _Inherited(__a1, __a2) { }
00319 
00320       template<typename _U1, typename _U2>
00321         explicit
00322         tuple(_U1&& __a1, _U2&& __a2)
00323     : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
00324 
00325       tuple(const tuple&) = default;
00326 
00327       tuple(tuple&& __in)
00328       : _Inherited(static_cast<_Inherited&&>(__in)) { }
00329 
00330       template<typename _U1, typename _U2>
00331         tuple(const tuple<_U1, _U2>& __in)
00332     : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
00333 
00334       template<typename _U1, typename _U2>
00335         tuple(tuple<_U1, _U2>&& __in)
00336     : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
00337 
00338       template<typename _U1, typename _U2>
00339         tuple(const pair<_U1, _U2>& __in)
00340     : _Inherited(__in.first, __in.second) { }
00341 
00342       template<typename _U1, typename _U2>
00343         tuple(pair<_U1, _U2>&& __in)
00344     : _Inherited(std::forward<_U1>(__in.first),
00345              std::forward<_U2>(__in.second)) { }
00346 
00347       tuple&
00348       operator=(const tuple& __in)
00349       {
00350     static_cast<_Inherited&>(*this) = __in;
00351     return *this;
00352       }
00353 
00354       tuple&
00355       operator=(tuple&& __in)
00356       {
00357     static_cast<_Inherited&>(*this) = std::move(__in);
00358     return *this;
00359       }
00360 
00361       template<typename _U1, typename _U2>
00362         tuple&
00363         operator=(const tuple<_U1, _U2>& __in)
00364         {
00365       static_cast<_Inherited&>(*this) = __in;
00366       return *this;
00367     }
00368 
00369       template<typename _U1, typename _U2>
00370         tuple&
00371         operator=(tuple<_U1, _U2>&& __in)
00372         {
00373       static_cast<_Inherited&>(*this) = std::move(__in);
00374       return *this;
00375     }
00376 
00377       template<typename _U1, typename _U2>
00378         tuple&
00379         operator=(const pair<_U1, _U2>& __in)
00380         {
00381       this->_M_head() = __in.first;
00382       this->_M_tail()._M_head() = __in.second;
00383       return *this;
00384     }
00385 
00386       template<typename _U1, typename _U2>
00387         tuple&
00388         operator=(pair<_U1, _U2>&& __in)
00389         {
00390       this->_M_head() = std::forward<_U1>(__in.first);
00391       this->_M_tail()._M_head() = std::forward<_U2>(__in.second);
00392       return *this;
00393     }
00394 
00395       void
00396       swap(tuple& __in)
00397       { 
00398     using std::swap;
00399     swap(this->_M_head(), __in._M_head());
00400     swap(this->_M_tail()._M_head(), __in._M_tail()._M_head());  
00401       }
00402     };
00403 
00404   /// tuple (1-element).
00405   template<typename _T1>
00406     class tuple<_T1> : public _Tuple_impl<0, _T1>
00407     {
00408       typedef _Tuple_impl<0, _T1> _Inherited;
00409 
00410     public:
00411       tuple()
00412       : _Inherited() { }
00413 
00414       explicit
00415       tuple(const _T1& __a1)
00416       : _Inherited(__a1) { }
00417 
00418       template<typename _U1, typename = typename
00419            std::enable_if<std::is_convertible<_U1, _T1>::value>::type>
00420         explicit
00421         tuple(_U1&& __a1)
00422     : _Inherited(std::forward<_U1>(__a1)) { }
00423 
00424       tuple(const tuple&) = default;
00425 
00426       tuple(tuple&& __in)
00427       : _Inherited(static_cast<_Inherited&&>(__in)) { }
00428 
00429       template<typename _U1>
00430         tuple(const tuple<_U1>& __in)
00431         : _Inherited(static_cast<const _Tuple_impl<0, _U1>&>(__in)) { }
00432 
00433       template<typename _U1>
00434         tuple(tuple<_U1>&& __in)
00435     : _Inherited(static_cast<_Tuple_impl<0, _U1>&&>(__in)) { }
00436 
00437       tuple&
00438       operator=(const tuple& __in)
00439       {
00440     static_cast<_Inherited&>(*this) = __in;
00441     return *this;
00442       }
00443 
00444       tuple&
00445       operator=(tuple&& __in)
00446       {
00447     static_cast<_Inherited&>(*this) = std::move(__in);
00448     return *this;
00449       }
00450 
00451       template<typename _U1>
00452         tuple&
00453         operator=(const tuple<_U1>& __in)
00454         {
00455       static_cast<_Inherited&>(*this) = __in;
00456       return *this;
00457     }
00458 
00459       template<typename _U1>
00460         tuple&
00461         operator=(tuple<_U1>&& __in)
00462         {
00463       static_cast<_Inherited&>(*this) = std::move(__in);
00464       return *this;
00465     }
00466 
00467       void
00468       swap(tuple& __in)
00469       { _Inherited::_M_swap_impl(__in); }
00470     };
00471 
00472 
00473   /// Gives the type of the ith element of a given tuple type.
00474   template<std::size_t __i, typename _Tp>
00475     struct tuple_element;
00476 
00477   /**
00478    * Recursive case for tuple_element: strip off the first element in
00479    * the tuple and retrieve the (i-1)th element of the remaining tuple.
00480    */
00481   template<std::size_t __i, typename _Head, typename... _Tail>
00482     struct tuple_element<__i, tuple<_Head, _Tail...> >
00483     : tuple_element<__i - 1, tuple<_Tail...> > { };
00484 
00485   /**
00486    * Basis case for tuple_element: The first element is the one we're seeking.
00487    */
00488   template<typename _Head, typename... _Tail>
00489     struct tuple_element<0, tuple<_Head, _Tail...> >
00490     {
00491       typedef _Head type;
00492     };
00493 
00494   /// Finds the size of a given tuple type.
00495   template<typename _Tp>
00496     struct tuple_size;
00497 
00498   /// class tuple_size
00499   template<typename... _Elements>
00500     struct tuple_size<tuple<_Elements...> >
00501     {
00502       static const std::size_t value = sizeof...(_Elements);
00503     };
00504 
00505   template<typename... _Elements>
00506     const std::size_t tuple_size<tuple<_Elements...> >::value;
00507 
00508   template<std::size_t __i, typename _Head, typename... _Tail>
00509     inline typename __add_ref<_Head>::type
00510     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t)
00511     { return __t._M_head(); }
00512 
00513   template<std::size_t __i, typename _Head, typename... _Tail>
00514     inline typename __add_c_ref<_Head>::type
00515     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t)
00516     { return __t._M_head(); }
00517 
00518   // Return a reference (const reference) to the ith element of a tuple.
00519   // Any const or non-const ref elements are returned with their original type.
00520   template<std::size_t __i, typename... _Elements>
00521     inline typename __add_ref<
00522                       typename tuple_element<__i, tuple<_Elements...> >::type
00523                     >::type
00524     get(tuple<_Elements...>& __t)
00525     { return __get_helper<__i>(__t); }
00526 
00527   template<std::size_t __i, typename... _Elements>
00528     inline typename __add_c_ref<
00529                       typename tuple_element<__i, tuple<_Elements...> >::type
00530                     >::type
00531     get(const tuple<_Elements...>& __t)
00532     { return __get_helper<__i>(__t); }
00533 
00534   // This class helps construct the various comparison operations on tuples
00535   template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
00536        typename _Tp, typename _Up>
00537     struct __tuple_compare;
00538 
00539   template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up>
00540     struct __tuple_compare<0, __i, __j, _Tp, _Up>
00541     {
00542       static bool __eq(const _Tp& __t, const _Up& __u)
00543       {
00544     return (get<__i>(__t) == get<__i>(__u) &&
00545         __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u));
00546       }
00547      
00548       static bool __less(const _Tp& __t, const _Up& __u)
00549       {
00550     return ((get<__i>(__t) < get<__i>(__u))
00551         || !(get<__i>(__u) < get<__i>(__t)) &&
00552         __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u));
00553       }
00554     };
00555 
00556   template<std::size_t __i, typename _Tp, typename _Up>
00557     struct __tuple_compare<0, __i, __i, _Tp, _Up>
00558     {
00559       static bool __eq(const _Tp&, const _Up&)
00560       { return true; }
00561      
00562       static bool __less(const _Tp&, const _Up&)
00563       { return false; }
00564     };
00565 
00566   template<typename... _TElements, typename... _UElements>
00567     bool
00568     operator==(const tuple<_TElements...>& __t,
00569            const tuple<_UElements...>& __u)
00570     {
00571       typedef tuple<_TElements...> _Tp;
00572       typedef tuple<_UElements...> _Up;
00573       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
00574           0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
00575     }
00576 
00577   template<typename... _TElements, typename... _UElements>
00578     bool
00579     operator<(const tuple<_TElements...>& __t,
00580           const tuple<_UElements...>& __u)
00581     {
00582       typedef tuple<_TElements...> _Tp;
00583       typedef tuple<_UElements...> _Up;
00584       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
00585           0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
00586     }
00587 
00588   template<typename... _TElements, typename... _UElements>
00589     inline bool
00590     operator!=(const tuple<_TElements...>& __t,
00591            const tuple<_UElements...>& __u)
00592     { return !(__t == __u); }
00593 
00594   template<typename... _TElements, typename... _UElements>
00595     inline bool
00596     operator>(const tuple<_TElements...>& __t,
00597           const tuple<_UElements...>& __u)
00598     { return __u < __t; }
00599 
00600   template<typename... _TElements, typename... _UElements>
00601     inline bool
00602     operator<=(const tuple<_TElements...>& __t,
00603            const tuple<_UElements...>& __u)
00604     { return !(__u < __t); }
00605 
00606   template<typename... _TElements, typename... _UElements>
00607     inline bool
00608     operator>=(const tuple<_TElements...>& __t,
00609            const tuple<_UElements...>& __u)
00610     { return !(__t < __u); }
00611 
00612   // NB: DR 705.
00613   template<typename... _Elements>
00614     inline tuple<typename __decay_and_strip<_Elements>::__type...>
00615     make_tuple(_Elements&&... __args)
00616     {
00617       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
00618     __result_type;
00619       return __result_type(std::forward<_Elements>(__args)...);
00620     }
00621 
00622   template<typename... _Elements>
00623     inline tuple<_Elements&&...>
00624     forward_as_tuple(_Elements&&... __args)
00625     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
00626 
00627   template<std::size_t...> struct __index_holder { };    
00628 
00629   template<std::size_t __i, typename _IdxHolder, typename... _Elements>
00630     struct __index_holder_impl;
00631 
00632   template<std::size_t __i, std::size_t... _Indexes, typename _IdxHolder,
00633        typename... _Elements>
00634     struct __index_holder_impl<__i, __index_holder<_Indexes...>,
00635                    _IdxHolder, _Elements...> 
00636     {
00637       typedef typename __index_holder_impl<__i + 1,
00638                        __index_holder<_Indexes..., __i>,
00639                        _Elements...>::type type;
00640     };
00641  
00642   template<std::size_t __i, std::size_t... _Indexes>
00643     struct __index_holder_impl<__i, __index_holder<_Indexes...> >
00644     { typedef __index_holder<_Indexes...> type; };
00645 
00646   template<typename... _Elements>
00647     struct __make_index_holder 
00648     : __index_holder_impl<0, __index_holder<>, _Elements...> { };
00649     
00650   template<typename... _TElements, std::size_t... _TIdx,
00651        typename... _UElements, std::size_t... _UIdx> 
00652     inline tuple<_TElements..., _UElements...> 
00653     __tuple_cat_helper(const tuple<_TElements...>& __t,
00654                const __index_holder<_TIdx...>&,
00655                        const tuple<_UElements...>& __u,
00656                const __index_holder<_UIdx...>&)
00657     { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)...,
00658                          get<_UIdx>(__u)...); }
00659 
00660   template<typename... _TElements, std::size_t... _TIdx,
00661        typename... _UElements, std::size_t... _UIdx> 
00662     inline tuple<_TElements..., _UElements...> 
00663     __tuple_cat_helper(tuple<_TElements...>&& __t,
00664                const __index_holder<_TIdx...>&, 
00665                const tuple<_UElements...>& __u,
00666                const __index_holder<_UIdx...>&)
00667     { return tuple<_TElements..., _UElements...>
00668     (std::move(get<_TIdx>(__t))..., get<_UIdx>(__u)...); }
00669 
00670   template<typename... _TElements, std::size_t... _TIdx,
00671        typename... _UElements, std::size_t... _UIdx>
00672     inline tuple<_TElements..., _UElements...> 
00673     __tuple_cat_helper(const tuple<_TElements...>& __t,
00674                const __index_holder<_TIdx...>&, 
00675                tuple<_UElements...>&& __u,
00676                const __index_holder<_UIdx...>&)
00677     { return tuple<_TElements..., _UElements...>
00678     (get<_TIdx>(__t)..., std::move(get<_UIdx>(__u))...); }
00679 
00680   template<typename... _TElements, std::size_t... _TIdx,
00681        typename... _UElements, std::size_t... _UIdx> 
00682     inline tuple<_TElements..., _UElements...> 
00683     __tuple_cat_helper(tuple<_TElements...>&& __t,
00684                const __index_holder<_TIdx...>&, 
00685                tuple<_UElements...>&& __u,
00686                const __index_holder<_UIdx...>&)
00687     { return tuple<_TElements..., _UElements...>
00688     (std::move(get<_TIdx>(__t))..., std::move(get<_UIdx>(__u))...); }
00689 
00690   template<typename... _TElements, typename... _UElements>
00691     inline tuple<_TElements..., _UElements...> 
00692     tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u)
00693     {
00694       return __tuple_cat_helper(__t, typename
00695                 __make_index_holder<_TElements...>::type(),
00696                 __u, typename
00697                 __make_index_holder<_UElements...>::type());
00698     }
00699 
00700   template<typename... _TElements, typename... _UElements>
00701     inline tuple<_TElements..., _UElements...> 
00702     tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u)
00703     {
00704       return __tuple_cat_helper(std::move(__t), typename
00705                  __make_index_holder<_TElements...>::type(),
00706                  __u, typename
00707                  __make_index_holder<_UElements...>::type());
00708     }
00709 
00710   template<typename... _TElements, typename... _UElements>
00711     inline tuple<_TElements..., _UElements...> 
00712     tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u)
00713     {
00714       return __tuple_cat_helper(__t, typename
00715                 __make_index_holder<_TElements...>::type(),
00716                 std::move(__u), typename
00717                 __make_index_holder<_UElements...>::type());
00718     }
00719 
00720   template<typename... _TElements, typename... _UElements>
00721     inline tuple<_TElements..., _UElements...>
00722     tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u)
00723     {
00724       return __tuple_cat_helper(std::move(__t), typename
00725                 __make_index_holder<_TElements...>::type(),
00726                 std::move(__u), typename
00727                 __make_index_holder<_UElements...>::type());
00728     }
00729 
00730   template<typename... _Elements>
00731     inline tuple<_Elements&...>
00732     tie(_Elements&... __args)
00733     { return tuple<_Elements&...>(__args...); }
00734 
00735   template<typename... _Elements>
00736     inline void 
00737     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
00738     { __x.swap(__y); }
00739 
00740   // A class (and instance) which can be used in 'tie' when an element
00741   // of a tuple is not required
00742   struct _Swallow_assign
00743   {
00744     template<class _Tp>
00745       const _Swallow_assign&
00746       operator=(const _Tp&) const
00747       { return *this; }
00748   };
00749 
00750   const _Swallow_assign ignore{};
00751 
00752   /**
00753    * Stores a tuple of indices. Used by bind() to extract the elements
00754    * in a tuple. 
00755    */
00756   template<int... _Indexes>
00757     struct _Index_tuple
00758     {
00759       typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
00760     };
00761 
00762   /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
00763   template<std::size_t _Num>
00764     struct _Build_index_tuple
00765     {
00766       typedef typename _Build_index_tuple<_Num-1>::__type::__next __type;
00767     };
00768 
00769   template<>
00770     struct _Build_index_tuple<0>
00771     {
00772       typedef _Index_tuple<> __type;
00773     };
00774 
00775   // See stl_pair.h...
00776   template<class _T1, class _T2>
00777     template<typename _Tp, typename... _Args>
00778       inline _Tp
00779       pair<_T1, _T2>::
00780       __cons(tuple<_Args...>&& __tuple)
00781       {
00782     typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
00783       _Indexes;
00784     return __do_cons<_Tp>(std::move(__tuple), _Indexes());
00785       }
00786 
00787   template<class _T1, class _T2>
00788     template<typename _Tp, typename... _Args, int... _Indexes>
00789       inline _Tp
00790       pair<_T1, _T2>::
00791       __do_cons(tuple<_Args...>&& __tuple,
00792         const _Index_tuple<_Indexes...>&)
00793       { return _Tp(std::forward<_Args>(get<_Indexes>(__tuple))...); }
00794 }
00795 
00796 #endif // __GXX_EXPERIMENTAL_CXX0X__
00797 
00798 #endif // _GLIBCXX_TUPLE