Home | History | Annotate | Line # | Download | only in tr1
      1   1.1  mrg // class template tuple -*- C++ -*-
      2   1.1  mrg 
      3  1.12  mrg // Copyright (C) 2004-2022 Free Software Foundation, Inc.
      4   1.1  mrg //
      5   1.1  mrg // This file is part of the GNU ISO C++ Library.  This library is free
      6   1.1  mrg // software; you can redistribute it and/or modify it under the
      7   1.1  mrg // terms of the GNU General Public License as published by the
      8   1.1  mrg // Free Software Foundation; either version 3, or (at your option)
      9   1.1  mrg // any later version.
     10   1.1  mrg 
     11   1.1  mrg // This library is distributed in the hope that it will be useful,
     12   1.1  mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   1.1  mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14   1.1  mrg // GNU General Public License for more details.
     15   1.1  mrg 
     16   1.1  mrg // Under Section 7 of GPL version 3, you are granted additional
     17   1.1  mrg // permissions described in the GCC Runtime Library Exception, version
     18   1.1  mrg // 3.1, as published by the Free Software Foundation.
     19   1.1  mrg 
     20   1.1  mrg // You should have received a copy of the GNU General Public License and
     21   1.1  mrg // a copy of the GCC Runtime Library Exception along with this program;
     22   1.1  mrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23   1.1  mrg // <http://www.gnu.org/licenses/>.
     24   1.1  mrg 
     25   1.1  mrg /** @file tr1/tuple
     26   1.1  mrg *  This is a TR1 C++ Library header.
     27   1.1  mrg */
     28   1.1  mrg 
     29   1.1  mrg // Chris Jefferson <chris (a] bubblescope.net>
     30   1.1  mrg // Variadic Templates support by Douglas Gregor <doug.gregor (a] gmail.com>
     31   1.1  mrg 
     32   1.1  mrg #ifndef _GLIBCXX_TR1_TUPLE
     33   1.1  mrg #define _GLIBCXX_TR1_TUPLE 1
     34   1.1  mrg 
     35   1.1  mrg #pragma GCC system_header
     36   1.1  mrg 
     37   1.1  mrg #include <utility>
     38   1.1  mrg 
     39   1.3  mrg namespace std _GLIBCXX_VISIBILITY(default)
     40   1.1  mrg {
     41   1.9  mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
     42   1.9  mrg 
     43   1.1  mrg namespace tr1
     44   1.1  mrg {
     45   1.1  mrg   // Adds a const reference to a non-reference type.
     46   1.1  mrg   template<typename _Tp>
     47   1.1  mrg     struct __add_c_ref
     48   1.1  mrg     { typedef const _Tp& type; };
     49   1.1  mrg 
     50   1.1  mrg   template<typename _Tp>
     51   1.1  mrg     struct __add_c_ref<_Tp&>
     52   1.1  mrg     { typedef _Tp& type; };
     53   1.1  mrg 
     54   1.1  mrg   // Adds a reference to a non-reference type.
     55   1.1  mrg   template<typename _Tp>
     56   1.1  mrg     struct __add_ref
     57   1.1  mrg     { typedef _Tp& type; };
     58   1.1  mrg 
     59   1.1  mrg   template<typename _Tp>
     60   1.1  mrg     struct __add_ref<_Tp&>
     61   1.1  mrg     { typedef _Tp& type; };
     62   1.1  mrg 
     63   1.1  mrg   /**
     64   1.1  mrg    * Contains the actual implementation of the @c tuple template, stored
     65   1.1  mrg    * as a recursive inheritance hierarchy from the first element (most
     66   1.1  mrg    * derived class) to the last (least derived class). The @c Idx
     67   1.1  mrg    * parameter gives the 0-based index of the element stored at this
     68   1.1  mrg    * point in the hierarchy; we use it to implement a constant-time
     69   1.1  mrg    * get() operation.
     70   1.1  mrg    */
     71   1.1  mrg   template<int _Idx, typename... _Elements>
     72   1.1  mrg     struct _Tuple_impl; 
     73   1.1  mrg 
     74   1.1  mrg   /**
     75   1.1  mrg    * Zero-element tuple implementation. This is the basis case for the 
     76   1.1  mrg    * inheritance recursion.
     77   1.1  mrg    */
     78   1.1  mrg   template<int _Idx>
     79   1.1  mrg     struct _Tuple_impl<_Idx> { };
     80   1.1  mrg 
     81   1.1  mrg   /**
     82   1.1  mrg    * Recursive tuple implementation. Here we store the @c Head element
     83   1.1  mrg    * and derive from a @c Tuple_impl containing the remaining elements
     84   1.1  mrg    * (which contains the @c Tail).
     85   1.1  mrg    */
     86   1.1  mrg   template<int _Idx, typename _Head, typename... _Tail>
     87   1.1  mrg     struct _Tuple_impl<_Idx, _Head, _Tail...>
     88   1.1  mrg     : public _Tuple_impl<_Idx + 1, _Tail...>
     89   1.1  mrg     {
     90   1.1  mrg       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
     91   1.1  mrg       
     92   1.1  mrg       _Head _M_head;
     93   1.1  mrg       
     94   1.1  mrg       _Inherited&       _M_tail()       { return *this; }
     95   1.1  mrg       const _Inherited& _M_tail() const { return *this; }
     96   1.1  mrg       
     97   1.1  mrg       _Tuple_impl() : _Inherited(), _M_head() { }
     98   1.1  mrg       
     99   1.1  mrg       explicit 
    100   1.1  mrg       _Tuple_impl(typename __add_c_ref<_Head>::type __head,
    101   1.1  mrg 		  typename __add_c_ref<_Tail>::type... __tail)
    102   1.1  mrg       : _Inherited(__tail...), _M_head(__head) { }
    103   1.1  mrg 
    104   1.1  mrg       template<typename... _UElements>
    105   1.1  mrg       _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
    106   1.1  mrg       : _Inherited(__in._M_tail()), _M_head(__in._M_head) { }
    107   1.1  mrg 
    108   1.1  mrg       _Tuple_impl(const _Tuple_impl& __in)
    109   1.1  mrg       : _Inherited(__in._M_tail()), _M_head(__in._M_head) { }
    110   1.1  mrg      
    111   1.1  mrg       template<typename... _UElements>
    112   1.1  mrg         _Tuple_impl&
    113   1.1  mrg         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
    114   1.1  mrg         {
    115   1.1  mrg 	  _M_head = __in._M_head;
    116   1.1  mrg 	  _M_tail() = __in._M_tail();
    117   1.1  mrg 	  return *this;
    118   1.1  mrg 	}
    119   1.1  mrg 
    120   1.1  mrg       _Tuple_impl&
    121   1.1  mrg       operator=(const _Tuple_impl& __in)
    122   1.1  mrg       {
    123   1.1  mrg 	_M_head = __in._M_head;
    124   1.1  mrg 	_M_tail() = __in._M_tail();
    125   1.1  mrg 	return *this;
    126   1.1  mrg       }
    127   1.1  mrg     };
    128   1.1  mrg 
    129   1.1  mrg   template<typename... _Elements> 
    130   1.1  mrg     class tuple : public _Tuple_impl<0, _Elements...>
    131   1.1  mrg     {
    132   1.1  mrg       typedef _Tuple_impl<0, _Elements...> _Inherited;
    133   1.1  mrg 
    134   1.1  mrg     public:
    135   1.1  mrg       tuple() : _Inherited() { }
    136   1.1  mrg 
    137   1.1  mrg       explicit
    138   1.1  mrg       tuple(typename __add_c_ref<_Elements>::type... __elements)
    139   1.1  mrg       : _Inherited(__elements...) { }
    140   1.1  mrg 
    141   1.1  mrg       template<typename... _UElements>
    142   1.1  mrg         tuple(const tuple<_UElements...>& __in)
    143   1.1  mrg 	: _Inherited(__in) { }
    144   1.1  mrg 
    145   1.1  mrg       tuple(const tuple& __in)
    146   1.1  mrg       : _Inherited(__in) { }
    147   1.1  mrg 
    148   1.1  mrg       template<typename... _UElements>
    149   1.1  mrg         tuple&
    150   1.1  mrg         operator=(const tuple<_UElements...>& __in)
    151   1.1  mrg         {
    152   1.1  mrg 	  static_cast<_Inherited&>(*this) = __in;
    153   1.1  mrg 	  return *this;
    154   1.1  mrg 	}
    155   1.1  mrg 
    156   1.1  mrg       tuple&
    157   1.1  mrg       operator=(const tuple& __in)
    158   1.1  mrg       {
    159   1.1  mrg 	static_cast<_Inherited&>(*this) = __in;
    160   1.1  mrg 	return *this;
    161   1.1  mrg       }
    162   1.1  mrg     };
    163   1.1  mrg 
    164   1.1  mrg   template<> class tuple<> { };
    165   1.1  mrg 
    166   1.1  mrg   // 2-element tuple, with construction and assignment from a pair.
    167   1.1  mrg   template<typename _T1, typename _T2>
    168   1.1  mrg     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
    169   1.1  mrg     {
    170   1.1  mrg       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
    171   1.1  mrg 
    172   1.1  mrg     public:
    173   1.1  mrg       tuple() : _Inherited() { }
    174   1.1  mrg 
    175   1.1  mrg       explicit
    176   1.1  mrg       tuple(typename __add_c_ref<_T1>::type __a1,
    177   1.1  mrg 	    typename __add_c_ref<_T2>::type __a2)
    178   1.1  mrg       : _Inherited(__a1, __a2) { }
    179   1.1  mrg 
    180   1.1  mrg       template<typename _U1, typename _U2>
    181   1.1  mrg         tuple(const tuple<_U1, _U2>& __in)
    182   1.1  mrg 	: _Inherited(__in) { }
    183   1.1  mrg 
    184   1.1  mrg       tuple(const tuple& __in)
    185   1.1  mrg       : _Inherited(__in) { }
    186   1.1  mrg 
    187   1.1  mrg       template<typename _U1, typename _U2>
    188   1.1  mrg         tuple(const pair<_U1, _U2>& __in)
    189   1.1  mrg 	: _Inherited(_Tuple_impl<0, 
    190   1.1  mrg 		     typename __add_c_ref<_U1>::type,
    191   1.1  mrg 		     typename __add_c_ref<_U2>::type>(__in.first, 
    192   1.1  mrg 						      __in.second))
    193   1.1  mrg         { }
    194   1.1  mrg   
    195   1.1  mrg       template<typename _U1, typename _U2>
    196   1.1  mrg         tuple&
    197   1.1  mrg         operator=(const tuple<_U1, _U2>& __in)
    198   1.1  mrg         {
    199   1.1  mrg 	  static_cast<_Inherited&>(*this) = __in;
    200   1.1  mrg 	  return *this;
    201   1.1  mrg 	}
    202   1.1  mrg 
    203   1.1  mrg       tuple&
    204   1.1  mrg       operator=(const tuple& __in)
    205   1.1  mrg       {
    206   1.1  mrg 	static_cast<_Inherited&>(*this) = __in;
    207   1.1  mrg 	return *this;
    208   1.1  mrg       }
    209   1.1  mrg 
    210   1.1  mrg       template<typename _U1, typename _U2>
    211   1.1  mrg         tuple&
    212   1.1  mrg         operator=(const pair<_U1, _U2>& __in)
    213   1.1  mrg         {
    214   1.1  mrg 	  this->_M_head = __in.first;
    215   1.1  mrg 	  this->_M_tail()._M_head = __in.second;
    216   1.1  mrg 	  return *this;
    217   1.1  mrg 	}
    218   1.1  mrg     };
    219   1.1  mrg 
    220   1.1  mrg   
    221   1.1  mrg   /// Gives the type of the ith element of a given tuple type.
    222   1.1  mrg   template<int __i, typename _Tp>
    223   1.1  mrg     struct tuple_element;
    224   1.1  mrg 
    225   1.1  mrg   /**
    226   1.1  mrg    * Recursive case for tuple_element: strip off the first element in
    227   1.1  mrg    * the tuple and retrieve the (i-1)th element of the remaining tuple.
    228   1.1  mrg    */
    229   1.1  mrg   template<int __i, typename _Head, typename... _Tail>
    230   1.1  mrg     struct tuple_element<__i, tuple<_Head, _Tail...> >
    231   1.1  mrg     : tuple_element<__i - 1, tuple<_Tail...> > { };
    232   1.1  mrg 
    233   1.1  mrg   /**
    234   1.1  mrg    * Basis case for tuple_element: The first element is the one we're seeking.
    235   1.1  mrg    */
    236   1.1  mrg   template<typename _Head, typename... _Tail>
    237   1.1  mrg     struct tuple_element<0, tuple<_Head, _Tail...> >
    238   1.1  mrg     {
    239   1.1  mrg       typedef _Head type;
    240   1.1  mrg     };
    241   1.1  mrg 
    242   1.1  mrg   /// Finds the size of a given tuple type.
    243   1.1  mrg   template<typename _Tp>
    244   1.1  mrg     struct tuple_size;
    245   1.1  mrg 
    246   1.1  mrg   /// class tuple_size
    247   1.1  mrg   template<typename... _Elements>
    248   1.1  mrg     struct tuple_size<tuple<_Elements...> >
    249   1.1  mrg     {
    250   1.1  mrg       static const int value = sizeof...(_Elements);
    251   1.1  mrg     };
    252   1.1  mrg 
    253   1.1  mrg   template<typename... _Elements>
    254   1.1  mrg     const int tuple_size<tuple<_Elements...> >::value;
    255   1.1  mrg 
    256   1.1  mrg   template<int __i, typename _Head, typename... _Tail>
    257   1.1  mrg     inline typename __add_ref<_Head>::type
    258   1.1  mrg     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t)
    259   1.1  mrg     {
    260   1.1  mrg       return __t._M_head;
    261   1.1  mrg     }
    262   1.1  mrg 
    263   1.1  mrg   template<int __i, typename _Head, typename... _Tail>
    264   1.1  mrg     inline typename __add_c_ref<_Head>::type
    265   1.1  mrg     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t)
    266   1.1  mrg     {
    267   1.1  mrg       return __t._M_head;
    268   1.1  mrg     }
    269   1.1  mrg 
    270   1.1  mrg   // Return a reference (const reference) to the ith element of a tuple.
    271   1.1  mrg   // Any const or non-const ref elements are returned with their original type.
    272   1.1  mrg   template<int __i, typename... _Elements>
    273   1.1  mrg     inline typename __add_ref<
    274   1.1  mrg                       typename tuple_element<__i, tuple<_Elements...> >::type
    275   1.1  mrg                     >::type
    276   1.1  mrg     get(tuple<_Elements...>& __t)
    277   1.1  mrg     { 
    278   1.1  mrg       return __get_helper<__i>(__t); 
    279   1.1  mrg     }
    280   1.1  mrg 
    281   1.1  mrg   template<int __i, typename... _Elements>
    282   1.1  mrg     inline typename __add_c_ref<
    283   1.1  mrg                       typename tuple_element<__i, tuple<_Elements...> >::type
    284   1.1  mrg                     >::type
    285   1.1  mrg     get(const tuple<_Elements...>& __t)
    286   1.1  mrg     {
    287   1.1  mrg       return __get_helper<__i>(__t);
    288   1.1  mrg     }
    289   1.1  mrg 
    290   1.1  mrg   // This class helps construct the various comparison operations on tuples
    291   1.1  mrg   template<int __check_equal_size, int __i, int __j,
    292   1.1  mrg 	   typename _Tp, typename _Up>
    293   1.1  mrg     struct __tuple_compare;
    294   1.1  mrg 
    295   1.1  mrg   template<int __i, int __j, typename _Tp, typename _Up>
    296   1.1  mrg     struct __tuple_compare<0, __i, __j, _Tp, _Up>
    297   1.1  mrg     {
    298   1.1  mrg       static bool __eq(const _Tp& __t, const _Up& __u)
    299   1.1  mrg       {
    300   1.1  mrg 	return (get<__i>(__t) == get<__i>(__u) &&
    301   1.1  mrg 		__tuple_compare<0, __i+1, __j, _Tp, _Up>::__eq(__t, __u));
    302   1.1  mrg       }
    303   1.1  mrg      
    304   1.1  mrg       static bool __less(const _Tp& __t, const _Up& __u)
    305   1.1  mrg       {
    306   1.1  mrg 	return ((get<__i>(__t) < get<__i>(__u))
    307   1.1  mrg 		|| !(get<__i>(__u) < get<__i>(__t)) &&
    308   1.1  mrg 		__tuple_compare<0, __i+1, __j, _Tp, _Up>::__less(__t, __u));
    309   1.1  mrg       }
    310   1.1  mrg     };
    311   1.1  mrg 
    312   1.1  mrg   template<int __i, typename _Tp, typename _Up>
    313   1.1  mrg     struct __tuple_compare<0, __i, __i, _Tp, _Up>
    314   1.1  mrg     {
    315   1.1  mrg       static bool __eq(const _Tp&, const _Up&)
    316   1.1  mrg       { return true; }
    317   1.1  mrg      
    318   1.1  mrg       static bool __less(const _Tp&, const _Up&)
    319   1.1  mrg       { return false; }
    320   1.1  mrg     };
    321   1.1  mrg 
    322   1.1  mrg   template<typename... _TElements, typename... _UElements>
    323   1.1  mrg     bool
    324   1.1  mrg     operator==(const tuple<_TElements...>& __t,
    325   1.1  mrg 	       const tuple<_UElements...>& __u)
    326   1.1  mrg     {
    327   1.1  mrg       typedef tuple<_TElements...> _Tp;
    328   1.1  mrg       typedef tuple<_UElements...> _Up;
    329   1.1  mrg       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
    330   1.1  mrg 	      0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
    331   1.1  mrg     }
    332   1.1  mrg 
    333   1.1  mrg   template<typename... _TElements, typename... _UElements>
    334   1.1  mrg     bool
    335   1.1  mrg     operator<(const tuple<_TElements...>& __t,
    336   1.1  mrg 	      const tuple<_UElements...>& __u)
    337   1.1  mrg     {
    338   1.1  mrg       typedef tuple<_TElements...> _Tp;
    339   1.1  mrg       typedef tuple<_UElements...> _Up;
    340   1.1  mrg       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
    341   1.1  mrg 	      0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
    342   1.1  mrg     }
    343   1.1  mrg 
    344   1.1  mrg   template<typename... _TElements, typename... _UElements>
    345   1.1  mrg     inline bool
    346   1.1  mrg     operator!=(const tuple<_TElements...>& __t,
    347   1.1  mrg 	       const tuple<_UElements...>& __u)
    348   1.1  mrg     { return !(__t == __u); }
    349   1.1  mrg 
    350   1.1  mrg   template<typename... _TElements, typename... _UElements>
    351   1.1  mrg     inline bool
    352   1.1  mrg     operator>(const tuple<_TElements...>& __t,
    353   1.1  mrg 	      const tuple<_UElements...>& __u)
    354   1.1  mrg     { return __u < __t; }
    355   1.1  mrg 
    356   1.1  mrg   template<typename... _TElements, typename... _UElements>
    357   1.1  mrg     inline bool
    358   1.1  mrg     operator<=(const tuple<_TElements...>& __t,
    359   1.1  mrg 	       const tuple<_UElements...>& __u)
    360   1.1  mrg     { return !(__u < __t); }
    361   1.1  mrg 
    362   1.1  mrg   template<typename... _TElements, typename... _UElements>
    363   1.1  mrg     inline bool
    364   1.1  mrg     operator>=(const tuple<_TElements...>& __t,
    365   1.1  mrg 	       const tuple<_UElements...>& __u)
    366   1.1  mrg     { return !(__t < __u); }
    367   1.1  mrg 
    368   1.1  mrg   template<typename _Tp>
    369   1.1  mrg     class reference_wrapper;
    370   1.1  mrg 
    371   1.1  mrg   // Helper which adds a reference to a type when given a reference_wrapper
    372   1.1  mrg   template<typename _Tp>
    373   1.1  mrg     struct __strip_reference_wrapper
    374   1.1  mrg     {
    375   1.1  mrg       typedef _Tp __type;
    376   1.1  mrg     };
    377   1.1  mrg 
    378   1.1  mrg   template<typename _Tp>
    379   1.1  mrg     struct __strip_reference_wrapper<reference_wrapper<_Tp> >
    380   1.1  mrg     {
    381   1.1  mrg       typedef _Tp& __type;
    382   1.1  mrg     };
    383   1.1  mrg 
    384   1.1  mrg   template<typename _Tp>
    385   1.1  mrg     struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
    386   1.1  mrg     {
    387   1.1  mrg       typedef _Tp& __type;
    388   1.1  mrg     };
    389   1.1  mrg 
    390   1.1  mrg   template<typename... _Elements>
    391   1.1  mrg     inline tuple<typename __strip_reference_wrapper<_Elements>::__type...>
    392   1.1  mrg     make_tuple(_Elements... __args)
    393   1.1  mrg     {
    394   1.1  mrg       typedef tuple<typename __strip_reference_wrapper<_Elements>::__type...>
    395   1.1  mrg         __result_type;
    396   1.1  mrg       return __result_type(__args...);
    397   1.1  mrg     }
    398   1.1  mrg 
    399   1.1  mrg   template<typename... _Elements>
    400   1.1  mrg     inline tuple<_Elements&...>
    401   1.1  mrg     tie(_Elements&... __args)
    402   1.1  mrg     {
    403   1.1  mrg       return tuple<_Elements&...>(__args...);
    404   1.1  mrg     }
    405   1.1  mrg 
    406   1.1  mrg   // A class (and instance) which can be used in 'tie' when an element
    407   1.1  mrg   // of a tuple is not required
    408   1.1  mrg   struct _Swallow_assign
    409   1.1  mrg   {
    410   1.1  mrg     template<class _Tp>
    411   1.1  mrg       _Swallow_assign&
    412   1.1  mrg       operator=(const _Tp&)
    413   1.1  mrg       { return *this; }
    414   1.1  mrg   };
    415   1.1  mrg 
    416   1.1  mrg   // TODO: Put this in some kind of shared file.
    417   1.1  mrg   namespace
    418   1.1  mrg   {
    419   1.1  mrg     _Swallow_assign ignore;
    420   1.1  mrg   }; // anonymous namespace
    421   1.9  mrg }
    422   1.3  mrg 
    423   1.3  mrg _GLIBCXX_END_NAMESPACE_VERSION
    424   1.1  mrg }
    425   1.1  mrg 
    426   1.1  mrg #endif // _GLIBCXX_TR1_TUPLE
    427