Micro template library A library for building device drivers
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

226 lines
6.5 KiB

  1. /*!
  2. * \file operations.h
  3. * \brief Integral constant operations and logical operations
  4. *
  5. * \copyright
  6. * Copyright (C) 2018 Christos Choutouridis <christos@choutouridis.net>\n
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation, either version 3
  10. * of the License, or (at your option) any later version.\n
  11. * This program 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 Lesser General Public License for more details.\n
  15. * You should have received a copy of the GNU Lesser General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #ifndef __utl_meta_operations_h__
  19. #define __utl_meta_operations_h__
  20. #include <utl/core/impl.h>
  21. #include <utl/meta/selection.h>
  22. /*!
  23. * \ingroup meta
  24. * \defgroup logic_operations Logic Operations
  25. * logic operators and type relations support
  26. */
  27. //! @{
  28. namespace utl {
  29. namespace meta{
  30. /*!
  31. * \name Logical relation for types
  32. */
  33. //! @{
  34. //! Negate the *bool* constant parameter and return bool_
  35. template <bool B>
  36. using not_c = bool_<!B>;
  37. //! negate the bool_ parameter and return bool_
  38. template<typename Tp>
  39. using not_ = not_c<Tp::type::value>;
  40. //! \name OR implementation
  41. //! @{
  42. namespace details {
  43. template<typename...> struct _or_;
  44. template<>
  45. struct _or_<> : false_ { };
  46. template<typename T1>
  47. struct _or_<T1> : T1 { };
  48. template<typename T1, typename T2>
  49. struct _or_ <T1, T2>
  50. : if_<T1, T1, T2> { };
  51. template<typename T1, typename T2, typename T3, typename... Tn>
  52. struct _or_<T1, T2, T3, Tn...>
  53. : if_<T1, T1, _or_<T2, T3, Tn...>> { };
  54. }
  55. //! Operator or for bool_ types
  56. //! \tparam Ts Variadic args of type bool_
  57. //! \return Logical or as bool_
  58. template <typename... Ts>
  59. using or_ = eval_t<details::_or_<Ts...>>;
  60. //! @}
  61. //! \name AND implementation
  62. //! @{
  63. namespace details {
  64. template<typename...> struct _and_;
  65. template<>
  66. struct _and_<>
  67. : true_ { };
  68. template<typename T1>
  69. struct _and_ <T1>
  70. : T1 { };
  71. template<typename T1, typename T2>
  72. struct _and_<T1, T2>
  73. : if_<T1, T2, T1> { };
  74. template<typename T1, typename T2, typename T3, typename... Tn>
  75. struct _and_<T1, T2, T3, Tn...>
  76. : if_<T1, _and_<T2, T3, Tn...>, T1> { };
  77. }
  78. //! Operator and for bool_ types
  79. //! \tparam Ts Variadic args of type bool_
  80. //! \return Logical and as bool_
  81. template <typename... Ts>
  82. using and_ = eval_t<details::_and_<Ts...>>;
  83. //! @}
  84. //! \name same
  85. //! @{
  86. template<typename T1, typename T2>
  87. struct same_ : false_ { };
  88. template<typename Tp>
  89. struct same_ <Tp, Tp> : true_ { };
  90. template<typename T1, typename T2>
  91. using not_same_ = not_<eval_t<same_<T1, T2>>>;
  92. //! @}
  93. //! @}
  94. }}
  95. //! @}
  96. /*!
  97. * \ingroup meta
  98. * \defgroup integral_operators integral operators
  99. * Type arithmetic and operations
  100. */
  101. //! @{
  102. namespace utl {
  103. namespace meta {
  104. /*!
  105. * \name Math operations
  106. */
  107. //! @{
  108. //! Negation
  109. template <typename Tp>
  110. using negate = integral_<decltype(-Tp()), -Tp()>;
  111. //! Addition
  112. template <typename Tp1, typename Tp2>
  113. using add = integral_<
  114. decltype(Tp1() + Tp2()),
  115. Tp1() + Tp2()
  116. >;
  117. //! Multiplication
  118. template <typename Tp1, typename Tp2>
  119. using mult = integral_<
  120. decltype(Tp2() * Tp2()),
  121. Tp1() * Tp2()
  122. >;
  123. //! Division
  124. template <typename Tp1, typename Tp2>
  125. using divide = integral_<
  126. decltype(Tp2() / Tp2()),
  127. Tp1() / Tp2()
  128. >;
  129. //! Modulo
  130. template <typename Tp1, typename Tp2>
  131. using modulo = integral_<
  132. decltype(Tp1() % Tp2()),
  133. Tp1() % Tp2()
  134. >;
  135. //! Substruction
  136. template <typename Tp1, typename Tp2>
  137. using sub = add<Tp1, negate<Tp2>>;
  138. //! Increase
  139. template <typename Tp>
  140. using inc = add<Tp, int_<1>>;
  141. //! decrease
  142. template <typename Tp>
  143. using dec = add<Tp, int_<-1>>;
  144. //! @}
  145. /*!
  146. * \name Comparison operations
  147. */
  148. //! @{
  149. //! \return a true-valued Integral Constant if Tp1 and Tp2 are equal.
  150. template <typename Tp1, typename Tp2> using comp_eq = bool_<Tp1() == Tp2()>;
  151. //! \return a true-valued Integral Constant if Tp1 is less than Tp2.
  152. template <typename Tp1, typename Tp2> using comp_lt = bool_<(Tp1() < Tp2())>;
  153. //! Not equal
  154. template <typename Tp1, typename Tp2> using comp_ne = not_<comp_eq<Tp1, Tp2>>;
  155. //! Greater than
  156. template <typename Tp1, typename Tp2> using comp_gt = comp_lt <Tp2, Tp1>;
  157. //! Less or equal
  158. template <typename Tp1, typename Tp2> using comp_le = not_<comp_lt<Tp2, Tp1>>;
  159. //! Greater or equal
  160. template <typename Tp1, typename Tp2> using comp_ge = not_<comp_lt<Tp1, Tp2>>;
  161. //! @}
  162. /*!
  163. * \name Bitwise operations
  164. */
  165. //! @{
  166. //! \return bitwise not (~) operation of its argument.
  167. template <typename T> using bitnot_ = integral_<typename T::valueType, (typename T::valueType)(~T())>;
  168. //! \return bitwise and (&) operation of its arguments
  169. template <typename Tp1, typename Tp2>
  170. using bitand_ = integral_<decltype(Tp1() & Tp2()), Tp1() & Tp2()>;
  171. //! \return bitwise or (|) operation of its arguments.
  172. template <typename Tp1, typename Tp2>
  173. using bitor_ = integral_<decltype(Tp1() | Tp2()), Tp1() | Tp2()>;
  174. //! \return bitwise xor (^) operation of its arguments.
  175. template <typename Tp1, typename Tp2>
  176. using bitxor_ = integral_<decltype(Tp1() ^ Tp2()), Tp1() ^ Tp2()>;
  177. //! \return the result of bitwise shift left (<<) operation on Tp.
  178. template <typename Tp, typename shift>
  179. using shift_left = integral_<typename Tp::value_type, (typename Tp::value_type)(Tp() << shift())>;
  180. //! \return the result of bitwise shift right (>>) operation on Tp.
  181. template <typename Tp, typename shift>
  182. using shift_right = integral_<typename Tp::value_type, (typename Tp::value_type)(Tp() >> shift())>;
  183. //! @}
  184. }}
  185. //!@}
  186. #endif /* __utl_meta_operations_h__ */