File indexing completed on 2024-06-23 05:21:36

0001 #ifndef __MOCKITOPP_TR1_TUPLE_HPP__
0002 #define __MOCKITOPP_TR1_TUPLE_HPP__
0003 
0004 #include <mockitopp/detail/util/tr1_type_traits.hpp>
0005 
0006 include(`mockitopp/detail/m4/ENUM_BINARY_PARAMS.m4')dnl
0007 include(`mockitopp/detail/m4/ENUM_SHIFTED_PARAMS.m4')dnl
0008 include(`mockitopp/detail/m4/ENUM_PARAMS.m4')dnl
0009 include(`mockitopp/detail/m4/REPEAT.m4')dnl
0010 include(`mockitopp/detail/m4/REPEAT_FROM_TO.m4')dnl
0011 /** 
0012  * partial implementation of tr1 <tuple>
0013  * for internal mockitopp use
0014  *
0015  * unsupported functionality:
0016  *
0017  *   get
0018  *   make_tuple
0019  *   tie
0020  *   tuple_element
0021  *   tuple_size
0022  */
0023 namespace mockitopp
0024 {
0025    namespace detail
0026    {
0027       namespace tr1
0028       {
0029          struct tuple_null_type {};
0030 
0031          template <typename H, typename T>
0032          struct tuple_cons
0033          {
0034             H head_;
0035             T tail_;
0036 
0037             tuple_cons(typename add_reference<typename add_const<H>::type>::type head,
0038                        typename add_reference<typename add_const<T>::type>::type tail)
0039                : head_(head)
0040                , tail_(tail)
0041                {}
0042          };
0043 
0044          // MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY element template
0045          template <M4_ENUM_BINARY_PARAMS(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY, typename T, = tuple_null_type, M4_INTERCEPT)>
0046          struct tuple : tuple_cons<T0, tuple<M4_ENUM_SHIFTED_PARAMS(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY), T), tuple_null_type> >
0047          {
0048             tuple(M4_ENUM_BINARY_PARAMS(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY, typename add_reference<typename add_const<T, >::type>::type t))
0049                : tuple_cons<T0, tuple<M4_ENUM_SHIFTED_PARAMS(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY), T), tuple_null_type> >
0050                   (t0, tuple<M4_ENUM_SHIFTED_PARAMS(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY), T), tuple_null_type>
0051                      (M4_ENUM_SHIFTED_PARAMS(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY), t)))
0052                {}
0053          };
0054 
0055 define(`TUPLE_NULL_TYPE_TRAILING_PARAM', `, tuple_null_type')dnl
0056 define(`TUPLE_TEMPLATE',
0057 `        // $1 element template
0058          template <M4_ENUM_PARAMS($1, typename T)>
0059          struct tuple<M4_ENUM_PARAMS($1, T)M4_REPEAT(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY-$1), `TUPLE_NULL_TYPE_TRAILING_PARAM')>
0060             : tuple_cons<T0, tuple<M4_ENUM_SHIFTED_PARAMS($1, T)> >
0061          {
0062             tuple(M4_ENUM_BINARY_PARAMS($1, typename add_reference<typename add_const<T, >::type>::type t))
0063                : tuple_cons<T0, tuple<M4_ENUM_SHIFTED_PARAMS($1, T)> >
0064                   (t0, tuple<M4_ENUM_SHIFTED_PARAMS($1, T)>
0065                      (M4_ENUM_SHIFTED_PARAMS($1, t)))
0066                {}
0067          };
0068 
0069 ')dnl
0070 M4_REPEAT_FROM_TO(2, eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY), `TUPLE_TEMPLATE')
0071 
0072          // 1 element template
0073          template <M4_ENUM_PARAMS(1, typename T)>
0074          struct tuple<M4_ENUM_PARAMS(1, T)M4_REPEAT(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY - 1), `TUPLE_NULL_TYPE_TRAILING_PARAM')>
0075             : tuple_cons<T0, tuple_null_type>
0076          {
0077             tuple(M4_ENUM_BINARY_PARAMS(1, typename add_reference<typename add_const<T, >::type>::type t))
0078                : tuple_cons<T0, tuple_null_type>
0079                   (t0, tuple_null_type())
0080             {}
0081          };
0082 
0083          // 0 element template
0084 define(`TUPLE_NULL_TYPE_PARAM', `tuple_null_type M4_COMMA_IF(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY-1-$1))')dnl
0085          template <>
0086          struct tuple<M4_REPEAT(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY, `TUPLE_NULL_TYPE_PARAM')>
0087             : tuple_cons<tuple_null_type, tuple_null_type>
0088          {
0089             tuple()
0090                : tuple_cons<tuple_null_type, tuple_null_type>
0091                   (tuple_null_type(), tuple_null_type())
0092             {}
0093          };
0094       } // namespace tr1
0095    } // namespace detail
0096 } // namespace mockitopp
0097 
0098 inline bool operator== (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return true;  }
0099 inline bool operator!= (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return false; }
0100 inline bool operator<  (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return false; }
0101 inline bool operator<= (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return true;  }
0102 inline bool operator>  (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return false; }
0103 inline bool operator>= (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return true;  }
0104 
0105 template <typename L0, typename L1, typename R0, typename R1>
0106 inline bool operator== (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
0107    { return (lhs.head_ == rhs.head_) && (lhs.tail_ == rhs.tail_); }
0108 
0109 template <typename L0, typename L1, typename R0, typename R1>
0110 inline bool operator!= (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
0111    { return !(lhs == rhs); }
0112 
0113 template <typename L0, typename L1, typename R0, typename R1>
0114 inline bool operator< (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
0115    { return (lhs.head_ < rhs.head_) || (lhs.tail_ < rhs.tail_); }
0116 
0117 template <typename L0, typename L1, typename R0, typename R1>
0118 inline bool operator<= (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
0119    { return (lhs == rhs) || (lhs < rhs); }
0120 
0121 template <typename L0, typename L1, typename R0, typename R1>
0122 inline bool operator> (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
0123    { return (lhs.head_ > rhs.head_) && (lhs.tail_ > rhs.tail_); }
0124 
0125 template <typename L0, typename L1, typename R0, typename R1>
0126 inline bool operator>= (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
0127    { return (lhs == rhs) || (lhs > rhs); }
0128 
0129 #endif //__MOCKITOPP_TR1_TUPLE_HPP__