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

Generated on Thu Jul 23 21:16:28 2009 for libstdc++ by  doxygen 1.5.8