# tr1/tuple

Go to the documentation of this file.

    00001 // class template tuple -*- C++ -*-
    00002
    00003 // Copyright (C) 2004, 2005, 2006, 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 tr1/tuple
    00026 *  This is a TR1 C++ Library header.
    00027 */
    00028
    00029 // Chris Jefferson <chris@bubblescope.net>
    00030 // Variadic Templates support by Douglas Gregor <doug.gregor@gmail.com>
    00031
    00032 #ifndef _GLIBCXX_TR1_TUPLE
    00033 #define _GLIBCXX_TR1_TUPLE 1
    00034
    00035 #pragma GCC system_header
    00036
    00037 #include <utility>
    00038
    00039 namespace std
    00040 {
    00041 namespace tr1
    00042 {
    00043   // Adds a const reference to a non-reference type.
    00044   template<typename _Tp>
    00045     struct __add_c_ref
    00046     { typedef const _Tp& type; };
    00047
    00048   template<typename _Tp>
    00049     struct __add_c_ref<_Tp&>
    00050     { typedef _Tp& type; };
    00051
    00052   // Adds a reference to a non-reference type.
    00053   template<typename _Tp>
    00054     struct __add_ref
    00055     { typedef _Tp& type; };
    00056
    00057   template<typename _Tp>
    00058     struct __add_ref<_Tp&>
    00059     { typedef _Tp& type; };
    00060
    00061   /**
    00062    * Contains the actual implementation of the @c tuple template, stored
    00063    * as a recursive inheritance hierarchy from the first element (most
    00064    * derived class) to the last (least derived class). The @c Idx
    00065    * parameter gives the 0-based index of the element stored at this
    00066    * point in the hierarchy; we use it to implement a constant-time
    00067    * get() operation.
    00068    */
    00069   template<int _Idx, typename... _Elements>
    00070     struct _Tuple_impl;
    00071
    00072   /**
    00073    * Zero-element tuple implementation. This is the basis case for the
    00074    * inheritance recursion.
    00075    */
    00076   template<int _Idx>
    00077     struct _Tuple_impl<_Idx> { };
    00078
    00079   /**
    00080    * Recursive tuple implementation. Here we store the @c Head element
    00081    * and derive from a @c Tuple_impl containing the remaining elements
    00082    * (which contains the @c Tail).
    00083    */
    00084   template<int _Idx, typename _Head, typename... _Tail>
    00085     struct _Tuple_impl<_Idx, _Head, _Tail...>
    00086     : public _Tuple_impl<_Idx + 1, _Tail...>
    00087     {
    00088       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
    00089
    00090       _Head _M_head;
    00091
    00092       _Inherited&       _M_tail()       { return *this; }
    00093       const _Inherited& _M_tail() const { return *this; }
    00094
    00095       _Tuple_impl() : _Inherited(), _M_head() { }
    00096
    00097       explicit
    00098       _Tuple_impl(typename __add_c_ref<_Head>::type __head,
    00099           typename __add_c_ref<_Tail>::type... __tail)
    00100       : _Inherited(__tail...), _M_head(__head) { }
    00101
    00102       template<typename... _UElements>
    00103       _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
    00104       : _Inherited(__in._M_tail()), _M_head(__in._M_head) { }
    00105
    00106       _Tuple_impl(const _Tuple_impl& __in)
    00107       : _Inherited(__in._M_tail()), _M_head(__in._M_head) { }
    00108
    00109       template<typename... _UElements>
    00110         _Tuple_impl&
    00111         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
    00112         {
    00113       _M_head = __in._M_head;
    00114       _M_tail() = __in._M_tail();
    00115       return *this;
    00116     }
    00117
    00118       _Tuple_impl&
    00119       operator=(const _Tuple_impl& __in)
    00120       {
    00121     _M_head = __in._M_head;
    00122     _M_tail() = __in._M_tail();
    00123     return *this;
    00124       }
    00125     };
    00126
    00127   template<typename... _Elements>
    00128     class tuple : public _Tuple_impl<0, _Elements...>
    00129     {
    00130       typedef _Tuple_impl<0, _Elements...> _Inherited;
    00131
    00132     public:
    00133       tuple() : _Inherited() { }
    00134
    00135       explicit
    00136       tuple(typename __add_c_ref<_Elements>::type... __elements)
    00137       : _Inherited(__elements...) { }
    00138
    00139       template<typename... _UElements>
    00140         tuple(const tuple<_UElements...>& __in)
    00141     : _Inherited(__in) { }
    00142
    00143       tuple(const tuple& __in)
    00144       : _Inherited(__in) { }
    00145
    00146       template<typename... _UElements>
    00147         tuple&
    00148         operator=(const tuple<_UElements...>& __in)
    00149         {
    00150       static_cast<_Inherited&>(*this) = __in;
    00151       return *this;
    00152     }
    00153
    00154       tuple&
    00155       operator=(const tuple& __in)
    00156       {
    00157     static_cast<_Inherited&>(*this) = __in;
    00158     return *this;
    00159       }
    00160     };
    00161
    00162   template<> class tuple<> { };
    00163
    00164   // 2-element tuple, with construction and assignment from a pair.
    00165   template<typename _T1, typename _T2>
    00166     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
    00167     {
    00168       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
    00169
    00170     public:
    00171       tuple() : _Inherited() { }
    00172
    00173       explicit
    00174       tuple(typename __add_c_ref<_T1>::type __a1,
    00175         typename __add_c_ref<_T2>::type __a2)
    00176       : _Inherited(__a1, __a2) { }
    00177
    00178       template<typename _U1, typename _U2>
    00179         tuple(const tuple<_U1, _U2>& __in)
    00180     : _Inherited(__in) { }
    00181
    00182       tuple(const tuple& __in)
    00183       : _Inherited(__in) { }
    00184
    00185       template<typename _U1, typename _U2>
    00186         tuple(const pair<_U1, _U2>& __in)
    00187     : _Inherited(_Tuple_impl<0,
    00188              typename __add_c_ref<_U1>::type,
    00189              typename __add_c_ref<_U2>::type>(__in.first,
    00190                               __in.second))
    00191         { }
    00192
    00193       template<typename _U1, typename _U2>
    00194         tuple&
    00195         operator=(const tuple<_U1, _U2>& __in)
    00196         {
    00197       static_cast<_Inherited&>(*this) = __in;
    00198       return *this;
    00199     }
    00200
    00201       tuple&
    00202       operator=(const tuple& __in)
    00203       {
    00204     static_cast<_Inherited&>(*this) = __in;
    00205     return *this;
    00206       }
    00207
    00208       template<typename _U1, typename _U2>
    00209         tuple&
    00210         operator=(const pair<_U1, _U2>& __in)
    00211         {
    00212       this->_M_head = __in.first;
    00213       this->_M_tail()._M_head = __in.second;
    00214       return *this;
    00215     }
    00216     };
    00217
    00218
    00219   /// Gives the type of the ith element of a given tuple type.
    00220   template<int __i, typename _Tp>
    00221     struct tuple_element;
    00222
    00223   /**
    00224    * Recursive case for tuple_element: strip off the first element in
    00225    * the tuple and retrieve the (i-1)th element of the remaining tuple.
    00226    */
    00227   template<int __i, typename _Head, typename... _Tail>
    00228     struct tuple_element<__i, tuple<_Head, _Tail...> >
    00229     : tuple_element<__i - 1, tuple<_Tail...> > { };
    00230
    00231   /**
    00232    * Basis case for tuple_element: The first element is the one we're seeking.
    00233    */
    00234   template<typename _Head, typename... _Tail>
    00235     struct tuple_element<0, tuple<_Head, _Tail...> >
    00236     {
    00237       typedef _Head type;
    00238     };
    00239
    00240   /// Finds the size of a given tuple type.
    00241   template<typename _Tp>
    00242     struct tuple_size;
    00243
    00244   /// class tuple_size
    00245   template<typename... _Elements>
    00246     struct tuple_size<tuple<_Elements...> >
    00247     {
    00248       static const int value = sizeof...(_Elements);
    00249     };
    00250
    00251   template<typename... _Elements>
    00252     const int tuple_size<tuple<_Elements...> >::value;
    00253
    00254   template<int __i, typename _Head, typename... _Tail>
    00255     inline typename __add_ref<_Head>::type
    00256     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t)
    00257     {
    00258       return __t._M_head;
    00259     }
    00260
    00261   template<int __i, typename _Head, typename... _Tail>
    00262     inline typename __add_c_ref<_Head>::type
    00263     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t)
    00264     {
    00265       return __t._M_head;
    00266     }
    00267
    00268   // Return a reference (const reference) to the ith element of a tuple.
    00269   // Any const or non-const ref elements are returned with their original type.
    00270   template<int __i, typename... _Elements>
    00271     inline typename __add_ref<
    00272                       typename tuple_element<__i, tuple<_Elements...> >::type
    00273                     >::type
    00274     get(tuple<_Elements...>& __t)
    00275     {
    00276       return __get_helper<__i>(__t);
    00277     }
    00278
    00279   template<int __i, typename... _Elements>
    00280     inline typename __add_c_ref<
    00281                       typename tuple_element<__i, tuple<_Elements...> >::type
    00282                     >::type
    00283     get(const tuple<_Elements...>& __t)
    00284     {
    00285       return __get_helper<__i>(__t);
    00286     }
    00287
    00288   // This class helps construct the various comparison operations on tuples
    00289   template<int __check_equal_size, int __i, int __j,
    00290        typename _Tp, typename _Up>
    00291     struct __tuple_compare;
    00292
    00293   template<int __i, int __j, typename _Tp, typename _Up>
    00294     struct __tuple_compare<0, __i, __j, _Tp, _Up>
    00295     {
    00296       static bool __eq(const _Tp& __t, const _Up& __u)
    00297       {
    00298     return (get<__i>(__t) == get<__i>(__u) &&
    00299         __tuple_compare<0, __i+1, __j, _Tp, _Up>::__eq(__t, __u));
    00300       }
    00301
    00302       static bool __less(const _Tp& __t, const _Up& __u)
    00303       {
    00304     return ((get<__i>(__t) < get<__i>(__u))
    00305         || !(get<__i>(__u) < get<__i>(__t)) &&
    00306         __tuple_compare<0, __i+1, __j, _Tp, _Up>::__less(__t, __u));
    00307       }
    00308     };
    00309
    00310   template<int __i, typename _Tp, typename _Up>
    00311     struct __tuple_compare<0, __i, __i, _Tp, _Up>
    00312     {
    00313       static bool __eq(const _Tp&, const _Up&)
    00314       { return true; }
    00315
    00316       static bool __less(const _Tp&, const _Up&)
    00317       { return false; }
    00318     };
    00319
    00320   template<typename... _TElements, typename... _UElements>
    00321     bool
    00322     operator==(const tuple<_TElements...>& __t,
    00323            const tuple<_UElements...>& __u)
    00324     {
    00325       typedef tuple<_TElements...> _Tp;
    00326       typedef tuple<_UElements...> _Up;
    00327       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
    00328           0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
    00329     }
    00330
    00331   template<typename... _TElements, typename... _UElements>
    00332     bool
    00333     operator<(const tuple<_TElements...>& __t,
    00334           const tuple<_UElements...>& __u)
    00335     {
    00336       typedef tuple<_TElements...> _Tp;
    00337       typedef tuple<_UElements...> _Up;
    00338       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
    00339           0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
    00340     }
    00341
    00342   template<typename... _TElements, typename... _UElements>
    00343     inline bool
    00344     operator!=(const tuple<_TElements...>& __t,
    00345            const tuple<_UElements...>& __u)
    00346     { return !(__t == __u); }
    00347
    00348   template<typename... _TElements, typename... _UElements>
    00349     inline bool
    00350     operator>(const tuple<_TElements...>& __t,
    00351           const tuple<_UElements...>& __u)
    00352     { return __u < __t; }
    00353
    00354   template<typename... _TElements, typename... _UElements>
    00355     inline bool
    00356     operator<=(const tuple<_TElements...>& __t,
    00357            const tuple<_UElements...>& __u)
    00358     { return !(__u < __t); }
    00359
    00360   template<typename... _TElements, typename... _UElements>
    00361     inline bool
    00362     operator>=(const tuple<_TElements...>& __t,
    00363            const tuple<_UElements...>& __u)
    00364     { return !(__t < __u); }
    00365
    00366   template<typename _Tp>
    00367     class reference_wrapper;
    00368
    00369   // Helper which adds a reference to a type when given a reference_wrapper
    00370   template<typename _Tp>
    00371     struct __strip_reference_wrapper
    00372     {
    00373       typedef _Tp __type;
    00374     };
    00375
    00376   template<typename _Tp>
    00377     struct __strip_reference_wrapper<reference_wrapper<_Tp> >
    00378     {
    00379       typedef _Tp& __type;
    00380     };
    00381
    00382   template<typename _Tp>
    00383     struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
    00384     {
    00385       typedef _Tp& __type;
    00386     };
    00387
    00388   template<typename... _Elements>
    00389     inline tuple<typename __strip_reference_wrapper<_Elements>::__type...>
    00390     make_tuple(_Elements... __args)
    00391     {
    00392       typedef tuple<typename __strip_reference_wrapper<_Elements>::__type...>
    00393         __result_type;
    00394       return __result_type(__args...);
    00395     }
    00396
    00397   template<typename... _Elements>
    00398     inline tuple<_Elements&...>
    00399     tie(_Elements&... __args)
    00400     {
    00401       return tuple<_Elements&...>(__args...);
    00402     }
    00403
    00404   // A class (and instance) which can be used in 'tie' when an element
    00405   // of a tuple is not required
    00406   struct _Swallow_assign
    00407   {
    00408     template<class _Tp>
    00409       _Swallow_assign&
    00410       operator=(const _Tp&)
    00411       { return *this; }
    00412   };
    00413
    00414   // TODO: Put this in some kind of shared file.
    00415   namespace
    00416   {
    00417     _Swallow_assign ignore;
    00418   }; // anonymous namespace
    00419 }
    00420 }
    00421
    00422 #endif // _GLIBCXX_TR1_TUPLE