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 | |