# tr1/tuple

Go to the documentation of this file.

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