functional_fwd.hpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. ///////////////////////////////////////////////////////////////////////////////
  2. /// \file functional_fwd.hpp
  3. ///
  4. // Copyright 2005 Eric Niebler. Distributed under the Boost
  5. // Software License, Version 1.0. (See accompanying file
  6. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_NUMERIC_FUNCTIONAL_FWD_HPP_EAN_08_12_2005
  8. #define BOOST_NUMERIC_FUNCTIONAL_FWD_HPP_EAN_08_12_2005
  9. #include <boost/mpl/if.hpp>
  10. #include <boost/mpl/placeholders.hpp>
  11. #include <boost/utility/enable_if.hpp>
  12. #include <boost/type_traits/is_same.hpp>
  13. #include <boost/type_traits/is_const.hpp>
  14. namespace boost { namespace numeric
  15. {
  16. // For using directives -- this namespace may be re-opened elsewhere
  17. namespace operators
  18. {}
  19. namespace op
  20. {
  21. using mpl::_;
  22. using mpl::_1;
  23. using mpl::_2;
  24. }
  25. namespace functional
  26. {
  27. using namespace operators;
  28. template<typename T>
  29. struct tag
  30. {
  31. typedef void type;
  32. };
  33. template<typename T>
  34. struct tag<T const>
  35. : tag<T>
  36. {};
  37. template<typename T>
  38. struct tag<T volatile>
  39. : tag<T>
  40. {};
  41. template<typename T>
  42. struct tag<T const volatile>
  43. : tag<T>
  44. {};
  45. template<typename T>
  46. struct static_;
  47. template<typename A0, typename A1>
  48. struct are_integral;
  49. }
  50. /// INTERNAL ONLY
  51. ///
  52. #define BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(Name, Op) \
  53. namespace functional \
  54. { \
  55. template<typename Arg, typename EnableIf = void> \
  56. struct Name ## _base; \
  57. template<typename Arg, typename ArgTag = typename tag<Arg>::type> \
  58. struct Name; \
  59. } \
  60. namespace op \
  61. { \
  62. struct Name; \
  63. } \
  64. namespace \
  65. { \
  66. extern op::Name const &Name; \
  67. }
  68. /// INTERNAL ONLY
  69. ///
  70. #define BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(Name) \
  71. namespace functional \
  72. { \
  73. template<typename Left, typename Right, typename EnableIf = void> \
  74. struct result_of_ ## Name; \
  75. template<typename Left, typename Right, typename EnableIf = void> \
  76. struct Name ## _base; \
  77. template< \
  78. typename Left \
  79. , typename Right \
  80. , typename LeftTag = typename tag<Left>::type \
  81. , typename RightTag = typename tag<Right>::type \
  82. > \
  83. struct Name; \
  84. } \
  85. namespace op \
  86. { \
  87. struct Name; \
  88. } \
  89. namespace \
  90. { \
  91. extern op::Name const &Name; \
  92. }
  93. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(plus)
  94. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(minus)
  95. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(multiplies)
  96. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(divides)
  97. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(modulus)
  98. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(greater)
  99. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(greater_equal)
  100. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(less)
  101. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(less_equal)
  102. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(equal_to)
  103. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(not_equal_to)
  104. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(assign)
  105. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(plus_assign)
  106. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(minus_assign)
  107. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(multiplies_assign)
  108. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(divides_assign)
  109. BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(modulus_assign)
  110. BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(unary_plus, +)
  111. BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(unary_minus, -)
  112. BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(complement, ~)
  113. BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(logical_not, !)
  114. #undef BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP
  115. #undef BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP
  116. namespace functional
  117. {
  118. template<typename To, typename From, typename EnableIf = void>
  119. struct promote_base;
  120. template<typename Left, typename Right, typename EnableIf = void>
  121. struct min_assign_base;
  122. template<typename Left, typename Right, typename EnableIf = void>
  123. struct max_assign_base;
  124. template<typename Left, typename Right, typename EnableIf = void>
  125. struct fdiv_base;
  126. template<typename Arg, typename EnableIf = void>
  127. struct as_min_base;
  128. template<typename Arg, typename EnableIf = void>
  129. struct as_max_base;
  130. template<typename Arg, typename EnableIf = void>
  131. struct as_zero_base;
  132. template<typename Arg, typename EnableIf = void>
  133. struct as_one_base;
  134. template<typename To, typename From, typename ToTag = typename tag<To>::type, typename FromTag = typename tag<From>::type>
  135. struct promote;
  136. template<typename Left, typename Right, typename LeftTag = typename tag<Left>::type, typename RightTag = typename tag<Right>::type>
  137. struct min_assign;
  138. template<typename Left, typename Right, typename LeftTag = typename tag<Left>::type, typename RightTag = typename tag<Right>::type>
  139. struct max_assign;
  140. template<typename Left, typename Right, typename LeftTag = typename tag<Left>::type, typename RightTag = typename tag<Right>::type>
  141. struct fdiv;
  142. template<typename Arg, typename Tag = typename tag<Arg>::type>
  143. struct as_min;
  144. template<typename Arg, typename Tag = typename tag<Arg>::type>
  145. struct as_max;
  146. template<typename Arg, typename Tag = typename tag<Arg>::type>
  147. struct as_zero;
  148. template<typename Arg, typename Tag = typename tag<Arg>::type>
  149. struct as_one;
  150. }
  151. namespace op
  152. {
  153. template<typename To>
  154. struct promote;
  155. struct min_assign;
  156. struct max_assign;
  157. struct fdiv;
  158. struct as_min;
  159. struct as_max;
  160. struct as_zero;
  161. struct as_one;
  162. }
  163. namespace
  164. {
  165. extern op::min_assign const &min_assign;
  166. extern op::max_assign const &max_assign;
  167. extern op::fdiv const &fdiv;
  168. extern op::as_min const &as_min;
  169. extern op::as_max const &as_max;
  170. extern op::as_zero const &as_zero;
  171. extern op::as_one const &as_one;
  172. }
  173. template<typename To, typename From>
  174. typename lazy_disable_if<is_const<From>, mpl::if_<is_same<To, From>, To &, To> >::type
  175. promote(From &from);
  176. template<typename To, typename From>
  177. typename mpl::if_<is_same<To const, From const>, To const &, To const>::type
  178. promote(From const &from);
  179. template<typename T>
  180. struct default_;
  181. template<typename T>
  182. struct one;
  183. template<typename T>
  184. struct zero;
  185. template<typename T>
  186. struct one_or_default;
  187. template<typename T>
  188. struct zero_or_default;
  189. }} // namespace boost::numeric
  190. #endif