Micro template library A library for building device drivers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

133 lines
4.5 KiB

  1. /*!
  2. * \file operators.h
  3. * \brief Template meta-programming integral constant arithmetic
  4. *
  5. * Copyright (C) 2018-2019 Christos Choutouridis
  6. *
  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.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef __utl_meta_arithmetic_h__
  21. #define __utl_meta_arithmetic_h__
  22. #include <utl/core/impl.h>
  23. #include <utl/meta/logical.h>
  24. /*!
  25. * \ingroup meta
  26. * \defgroup integral operators
  27. * Type arithmetic and operators
  28. */
  29. //! @{
  30. namespace utl {
  31. namespace meta {
  32. /*!
  33. * Math operations
  34. * requires IntegralConstant(_Tp)
  35. */
  36. //! @{
  37. //! Negation
  38. template <typename _Tp>
  39. using negate = integral_<decltype(-_Tp()), -_Tp()>;
  40. //! Addition
  41. template <typename _Tp1, typename _Tp2>
  42. using add = integral_<
  43. decltype(_Tp1() + _Tp2()),
  44. _Tp1() + _Tp2()
  45. >;
  46. //! Multiplication
  47. template <typename _Tp1, typename _Tp2>
  48. using mult = integral_<
  49. decltype(_Tp2() * _Tp2()),
  50. _Tp1() * _Tp2()
  51. >;
  52. //! Division
  53. template <typename _Tp1, typename _Tp2>
  54. using divide = integral_<
  55. decltype(_Tp2() / _Tp2()),
  56. _Tp1() / _Tp2()
  57. >;
  58. //! Modulo
  59. template <typename _Tp1, typename _Tp2>
  60. using modulo = integral_<
  61. decltype(_Tp1() % _Tp2()),
  62. _Tp1() % _Tp2()
  63. >;
  64. //! Substruction
  65. template <typename _Tp1, typename _Tp2>
  66. using sub = add<_Tp1, negate<_Tp2>>;
  67. //! Increase
  68. template <typename _Tp>
  69. using inc = add<_Tp, int_<1>>;
  70. //! decrease
  71. template <typename _Tp>
  72. using dec = add<_Tp, int_<-1>>;
  73. //! @}
  74. /*!
  75. * Comparison operations
  76. * requires IntegralConstant(_Tp)
  77. */
  78. //! @{
  79. //! \return a true-valued Integral Constant if _Tp1 and _Tp2 are equal.
  80. template <typename _Tp1, typename _Tp2> using comp_eq = bool_<_Tp1() == _Tp2()>;
  81. //! \return a true-valued Integral Constant if _Tp1 is less than _Tp2.
  82. template <typename _Tp1, typename _Tp2> using comp_lt = bool_<(_Tp1() < _Tp2())>;
  83. //! Not equal
  84. template <typename _Tp1, typename _Tp2> using comp_ne = not_<comp_eq<_Tp1, _Tp2>>;
  85. //! Greater than
  86. template <typename _Tp1, typename _Tp2> using comp_gt = comp_lt <_Tp2, _Tp1>;
  87. //! Less or equal
  88. template <typename _Tp1, typename _Tp2> using comp_le = not_<comp_lt<_Tp2, _Tp1>>;
  89. //! Greater or equal
  90. template <typename _Tp1, typename _Tp2> using comp_ge = not_<comp_lt<_Tp1, _Tp2>>;
  91. //! @}
  92. /*!
  93. * Bitwise operations
  94. * requires IntegralConstant(_Tp)
  95. */
  96. //! @{
  97. //! \return bitwise not (~) operation of its argument.
  98. template <typename _T> using bitnot_ = integral_<typename _T::value_type, (typename _T::value_type)(~_T())>;
  99. //! \return bitwise and (&) operation of its arguments
  100. template <typename _Tp1, typename _Tp2>
  101. using bitand_ = integral_<decltype(_Tp1() & _Tp2()), _Tp1() & _Tp2()>;
  102. //! \return bitwise or (|) operation of its arguments.
  103. template <typename _Tp1, typename _Tp2>
  104. using bitor_ = integral_<decltype(_Tp1() | _Tp2()), _Tp1() | _Tp2()>;
  105. //! \return bitwise xor (^) operation of its arguments.
  106. template <typename _Tp1, typename _Tp2>
  107. using bitxor_ = integral_<decltype(_Tp1() ^ _Tp2()), _Tp1() ^ _Tp2()>;
  108. //! \return the result of bitwise shift left (<<) operation on _Tp.
  109. template <typename _Tp, typename shift>
  110. using shift_left = integral_<typename _Tp::value_type, (typename _Tp::value_type)(_Tp() << shift())>;
  111. //! \return the result of bitwise shift right (>>) operation on _Tp.
  112. template <typename _Tp, typename shift>
  113. using shift_right = integral_<typename _Tp::value_type, (typename _Tp::value_type)(_Tp() >> shift())>;
  114. //! @}
  115. }}
  116. //!@}
  117. #endif /* __utl_meta_integral_h__ */