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