Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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