Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 // Copyright 2012 John Maddock. Distributed under the Boost
|
Chris@16
|
3 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5
|
Chris@16
|
6 #ifndef BOOST_MP_NO_ET_OPS_HPP
|
Chris@16
|
7 #define BOOST_MP_NO_ET_OPS_HPP
|
Chris@16
|
8
|
Chris@16
|
9 #ifdef BOOST_MSVC
|
Chris@16
|
10 #pragma warning(push)
|
Chris@16
|
11 #pragma warning(disable: 4714)
|
Chris@16
|
12 #endif
|
Chris@16
|
13
|
Chris@16
|
14 namespace boost{
|
Chris@16
|
15 namespace multiprecision{
|
Chris@16
|
16
|
Chris@16
|
17 //
|
Chris@16
|
18 // Operators for non-expression template enabled number.
|
Chris@16
|
19 // NOTE: this is not a complete header - really just a suffix to default_ops.hpp.
|
Chris@16
|
20 // NOTE: these operators have to be defined after the methods in default_ops.hpp.
|
Chris@16
|
21 //
|
Chris@16
|
22 template <class B>
|
Chris@16
|
23 BOOST_MP_FORCEINLINE number<B, et_off> operator - (const number<B, et_off>& v)
|
Chris@16
|
24 {
|
Chris@16
|
25 BOOST_STATIC_ASSERT_MSG(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
|
Chris@16
|
26 number<B, et_off> result(v);
|
Chris@16
|
27 result.backend().negate();
|
Chris@16
|
28 return BOOST_MP_MOVE(result);
|
Chris@16
|
29 }
|
Chris@16
|
30 template <class B>
|
Chris@16
|
31 BOOST_MP_FORCEINLINE number<B, et_off> operator ~ (const number<B, et_off>& v)
|
Chris@16
|
32 {
|
Chris@16
|
33 number<B, et_off> result;
|
Chris@16
|
34 eval_complement(result.backend(), v.backend());
|
Chris@16
|
35 return BOOST_MP_MOVE(result);
|
Chris@16
|
36 }
|
Chris@16
|
37 //
|
Chris@16
|
38 // Addition:
|
Chris@16
|
39 //
|
Chris@16
|
40 template <class B>
|
Chris@16
|
41 BOOST_MP_FORCEINLINE number<B, et_off> operator + (const number<B, et_off>& a, const number<B, et_off>& b)
|
Chris@16
|
42 {
|
Chris@16
|
43 number<B, et_off> result;
|
Chris@16
|
44 using default_ops::eval_add;
|
Chris@16
|
45 eval_add(result.backend(), a.backend(), b.backend());
|
Chris@16
|
46 return BOOST_MP_MOVE(result);
|
Chris@16
|
47 }
|
Chris@16
|
48 template <class B, class V>
|
Chris@16
|
49 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
50 operator + (const number<B, et_off>& a, const V& b)
|
Chris@16
|
51 {
|
Chris@16
|
52 number<B, et_off> result;
|
Chris@16
|
53 using default_ops::eval_add;
|
Chris@16
|
54 eval_add(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
55 return BOOST_MP_MOVE(result);
|
Chris@16
|
56 }
|
Chris@16
|
57 template <class V, class B>
|
Chris@16
|
58 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
59 operator + (const V& a, const number<B, et_off>& b)
|
Chris@16
|
60 {
|
Chris@16
|
61 number<B, et_off> result;
|
Chris@16
|
62 using default_ops::eval_add;
|
Chris@16
|
63 eval_add(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
|
Chris@16
|
64 return BOOST_MP_MOVE(result);
|
Chris@16
|
65 }
|
Chris@16
|
66 //
|
Chris@16
|
67 // Subtraction:
|
Chris@16
|
68 //
|
Chris@16
|
69 template <class B>
|
Chris@16
|
70 BOOST_MP_FORCEINLINE number<B, et_off> operator - (const number<B, et_off>& a, const number<B, et_off>& b)
|
Chris@16
|
71 {
|
Chris@16
|
72 number<B, et_off> result;
|
Chris@16
|
73 using default_ops::eval_subtract;
|
Chris@16
|
74 eval_subtract(result.backend(), a.backend(), b.backend());
|
Chris@16
|
75 return BOOST_MP_MOVE(result);
|
Chris@16
|
76 }
|
Chris@16
|
77 template <class B, class V>
|
Chris@16
|
78 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
79 operator - (const number<B, et_off>& a, const V& b)
|
Chris@16
|
80 {
|
Chris@16
|
81 number<B, et_off> result;
|
Chris@16
|
82 using default_ops::eval_subtract;
|
Chris@16
|
83 eval_subtract(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
84 return BOOST_MP_MOVE(result);
|
Chris@16
|
85 }
|
Chris@16
|
86 template <class V, class B>
|
Chris@16
|
87 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
88 operator - (const V& a, const number<B, et_off>& b)
|
Chris@16
|
89 {
|
Chris@16
|
90 number<B, et_off> result;
|
Chris@16
|
91 using default_ops::eval_subtract;
|
Chris@16
|
92 eval_subtract(result.backend(), number<B, et_off>::canonical_value(a), b.backend());
|
Chris@16
|
93 return BOOST_MP_MOVE(result);
|
Chris@16
|
94 }
|
Chris@16
|
95 //
|
Chris@16
|
96 // Multiply:
|
Chris@16
|
97 //
|
Chris@16
|
98 template <class B>
|
Chris@16
|
99 BOOST_MP_FORCEINLINE number<B, et_off> operator * (const number<B, et_off>& a, const number<B, et_off>& b)
|
Chris@16
|
100 {
|
Chris@16
|
101 number<B, et_off> result;
|
Chris@16
|
102 using default_ops::eval_multiply;
|
Chris@16
|
103 eval_multiply(result.backend(), a.backend(), b.backend());
|
Chris@16
|
104 return BOOST_MP_MOVE(result);
|
Chris@16
|
105 }
|
Chris@16
|
106 template <class B, class V>
|
Chris@16
|
107 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
108 operator * (const number<B, et_off>& a, const V& b)
|
Chris@16
|
109 {
|
Chris@16
|
110 number<B, et_off> result;
|
Chris@16
|
111 using default_ops::eval_multiply;
|
Chris@16
|
112 eval_multiply(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
113 return BOOST_MP_MOVE(result);
|
Chris@16
|
114 }
|
Chris@16
|
115 template <class V, class B>
|
Chris@16
|
116 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
117 operator * (const V& a, const number<B, et_off>& b)
|
Chris@16
|
118 {
|
Chris@16
|
119 number<B, et_off> result;
|
Chris@16
|
120 using default_ops::eval_multiply;
|
Chris@16
|
121 eval_multiply(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
|
Chris@16
|
122 return BOOST_MP_MOVE(result);
|
Chris@16
|
123 }
|
Chris@16
|
124 //
|
Chris@16
|
125 // divide:
|
Chris@16
|
126 //
|
Chris@16
|
127 template <class B>
|
Chris@16
|
128 BOOST_MP_FORCEINLINE number<B, et_off> operator / (const number<B, et_off>& a, const number<B, et_off>& b)
|
Chris@16
|
129 {
|
Chris@16
|
130 number<B, et_off> result;
|
Chris@16
|
131 using default_ops::eval_divide;
|
Chris@16
|
132 eval_divide(result.backend(), a.backend(), b.backend());
|
Chris@16
|
133 return BOOST_MP_MOVE(result);
|
Chris@16
|
134 }
|
Chris@16
|
135 template <class B, class V>
|
Chris@16
|
136 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
137 operator / (const number<B, et_off>& a, const V& b)
|
Chris@16
|
138 {
|
Chris@16
|
139 number<B, et_off> result;
|
Chris@16
|
140 using default_ops::eval_divide;
|
Chris@16
|
141 eval_divide(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
142 return BOOST_MP_MOVE(result);
|
Chris@16
|
143 }
|
Chris@16
|
144 template <class V, class B>
|
Chris@16
|
145 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
146 operator / (const V& a, const number<B, et_off>& b)
|
Chris@16
|
147 {
|
Chris@16
|
148 number<B, et_off> result;
|
Chris@16
|
149 using default_ops::eval_divide;
|
Chris@16
|
150 eval_divide(result.backend(), number<B, et_off>::canonical_value(a), b.backend());
|
Chris@16
|
151 return BOOST_MP_MOVE(result);
|
Chris@16
|
152 }
|
Chris@16
|
153 //
|
Chris@16
|
154 // modulus:
|
Chris@16
|
155 //
|
Chris@16
|
156 template <class B>
|
Chris@16
|
157 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator % (const number<B, et_off>& a, const number<B, et_off>& b)
|
Chris@16
|
158 {
|
Chris@16
|
159 number<B, et_off> result;
|
Chris@16
|
160 using default_ops::eval_modulus;
|
Chris@16
|
161 eval_modulus(result.backend(), a.backend(), b.backend());
|
Chris@16
|
162 return BOOST_MP_MOVE(result);
|
Chris@16
|
163 }
|
Chris@16
|
164 template <class B, class V>
|
Chris@16
|
165 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
166 operator % (const number<B, et_off>& a, const V& b)
|
Chris@16
|
167 {
|
Chris@16
|
168 number<B, et_off> result;
|
Chris@16
|
169 using default_ops::eval_modulus;
|
Chris@16
|
170 eval_modulus(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
171 return BOOST_MP_MOVE(result);
|
Chris@16
|
172 }
|
Chris@16
|
173 template <class V, class B>
|
Chris@16
|
174 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
175 operator % (const V& a, const number<B, et_off>& b)
|
Chris@16
|
176 {
|
Chris@16
|
177 number<B, et_off> result;
|
Chris@16
|
178 using default_ops::eval_modulus;
|
Chris@16
|
179 eval_modulus(result.backend(), number<B, et_off>::canonical_value(a), b.backend());
|
Chris@16
|
180 return BOOST_MP_MOVE(result);
|
Chris@16
|
181 }
|
Chris@16
|
182 //
|
Chris@16
|
183 // Bitwise or:
|
Chris@16
|
184 //
|
Chris@16
|
185 template <class B>
|
Chris@16
|
186 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator | (const number<B, et_off>& a, const number<B, et_off>& b)
|
Chris@16
|
187 {
|
Chris@16
|
188 number<B, et_off> result;
|
Chris@16
|
189 using default_ops::eval_bitwise_or;
|
Chris@16
|
190 eval_bitwise_or(result.backend(), a.backend(), b.backend());
|
Chris@16
|
191 return BOOST_MP_MOVE(result);
|
Chris@16
|
192 }
|
Chris@16
|
193 template <class B, class V>
|
Chris@16
|
194 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
195 operator | (const number<B, et_off>& a, const V& b)
|
Chris@16
|
196 {
|
Chris@16
|
197 number<B, et_off> result;
|
Chris@16
|
198 using default_ops::eval_bitwise_or;
|
Chris@16
|
199 eval_bitwise_or(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
200 return BOOST_MP_MOVE(result);
|
Chris@16
|
201 }
|
Chris@16
|
202 template <class V, class B>
|
Chris@16
|
203 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
204 operator | (const V& a, const number<B, et_off>& b)
|
Chris@16
|
205 {
|
Chris@16
|
206 number<B, et_off> result;
|
Chris@16
|
207 using default_ops::eval_bitwise_or;
|
Chris@16
|
208 eval_bitwise_or(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
|
Chris@16
|
209 return BOOST_MP_MOVE(result);
|
Chris@16
|
210 }
|
Chris@16
|
211 //
|
Chris@16
|
212 // Bitwise xor:
|
Chris@16
|
213 //
|
Chris@16
|
214 template <class B>
|
Chris@16
|
215 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator ^ (const number<B, et_off>& a, const number<B, et_off>& b)
|
Chris@16
|
216 {
|
Chris@16
|
217 number<B, et_off> result;
|
Chris@16
|
218 using default_ops::eval_bitwise_xor;
|
Chris@16
|
219 eval_bitwise_xor(result.backend(), a.backend(), b.backend());
|
Chris@16
|
220 return BOOST_MP_MOVE(result);
|
Chris@16
|
221 }
|
Chris@16
|
222 template <class B, class V>
|
Chris@16
|
223 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
224 operator ^ (const number<B, et_off>& a, const V& b)
|
Chris@16
|
225 {
|
Chris@16
|
226 number<B, et_off> result;
|
Chris@16
|
227 using default_ops::eval_bitwise_xor;
|
Chris@16
|
228 eval_bitwise_xor(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
229 return BOOST_MP_MOVE(result);
|
Chris@16
|
230 }
|
Chris@16
|
231 template <class V, class B>
|
Chris@16
|
232 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
233 operator ^ (const V& a, const number<B, et_off>& b)
|
Chris@16
|
234 {
|
Chris@16
|
235 number<B, et_off> result;
|
Chris@16
|
236 using default_ops::eval_bitwise_xor;
|
Chris@16
|
237 eval_bitwise_xor(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
|
Chris@16
|
238 return BOOST_MP_MOVE(result);
|
Chris@16
|
239 }
|
Chris@16
|
240 //
|
Chris@16
|
241 // Bitwise and:
|
Chris@16
|
242 //
|
Chris@16
|
243 template <class B>
|
Chris@16
|
244 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator & (const number<B, et_off>& a, const number<B, et_off>& b)
|
Chris@16
|
245 {
|
Chris@16
|
246 number<B, et_off> result;
|
Chris@16
|
247 using default_ops::eval_bitwise_and;
|
Chris@16
|
248 eval_bitwise_and(result.backend(), a.backend(), b.backend());
|
Chris@16
|
249 return BOOST_MP_MOVE(result);
|
Chris@16
|
250 }
|
Chris@16
|
251 template <class B, class V>
|
Chris@16
|
252 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
253 operator & (const number<B, et_off>& a, const V& b)
|
Chris@16
|
254 {
|
Chris@16
|
255 number<B, et_off> result;
|
Chris@16
|
256 using default_ops::eval_bitwise_and;
|
Chris@16
|
257 eval_bitwise_and(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
258 return BOOST_MP_MOVE(result);
|
Chris@16
|
259 }
|
Chris@16
|
260 template <class V, class B>
|
Chris@16
|
261 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
262 operator & (const V& a, const number<B, et_off>& b)
|
Chris@16
|
263 {
|
Chris@16
|
264 number<B, et_off> result;
|
Chris@16
|
265 using default_ops::eval_bitwise_and;
|
Chris@16
|
266 eval_bitwise_and(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
|
Chris@16
|
267 return BOOST_MP_MOVE(result);
|
Chris@16
|
268 }
|
Chris@16
|
269 //
|
Chris@16
|
270 // shifts:
|
Chris@16
|
271 //
|
Chris@16
|
272 template <class B, class I>
|
Chris@16
|
273 BOOST_MP_FORCEINLINE typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
274 operator << (const number<B, et_off>& a, const I& b)
|
Chris@16
|
275 {
|
Chris@16
|
276 number<B, et_off> result(a);
|
Chris@16
|
277 using default_ops::eval_left_shift;
|
Chris@16
|
278 detail::check_shift_range(b, mpl::bool_<(sizeof(I) > sizeof(std::size_t))>(), is_signed<I>());
|
Chris@16
|
279 eval_left_shift(result.backend(), b);
|
Chris@16
|
280 return BOOST_MP_MOVE(result);
|
Chris@16
|
281 }
|
Chris@16
|
282 template <class B, class I>
|
Chris@16
|
283 BOOST_MP_FORCEINLINE typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
284 operator >> (const number<B, et_off>& a, const I& b)
|
Chris@16
|
285 {
|
Chris@16
|
286 number<B, et_off> result(a);
|
Chris@16
|
287 using default_ops::eval_right_shift;
|
Chris@16
|
288 detail::check_shift_range(b, mpl::bool_<(sizeof(I) > sizeof(std::size_t))>(), is_signed<I>());
|
Chris@16
|
289 eval_right_shift(result.backend(), b);
|
Chris@16
|
290 return BOOST_MP_MOVE(result);
|
Chris@16
|
291 }
|
Chris@16
|
292
|
Chris@16
|
293 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !(defined(__GNUC__) && ((__GNUC__ == 4) && (__GNUC_MINOR__ < 5)))
|
Chris@16
|
294 //
|
Chris@16
|
295 // If we have rvalue references go all over again with rvalue ref overloads and move semantics.
|
Chris@16
|
296 // Note that while it would be tempting to implement these so they return an rvalue reference
|
Chris@16
|
297 // (and indeed this would be optimally efficient), this is unsafe due to users propensity to
|
Chris@16
|
298 // write:
|
Chris@16
|
299 //
|
Chris@16
|
300 // const T& t = a * b;
|
Chris@16
|
301 //
|
Chris@16
|
302 // which would lead to a dangling reference if we didn't return by value. Of course move
|
Chris@16
|
303 // semantics help a great deal in return by value, so performance is still pretty good...
|
Chris@16
|
304 //
|
Chris@16
|
305 template <class B>
|
Chris@16
|
306 BOOST_MP_FORCEINLINE number<B, et_off> operator - (number<B, et_off>&& v)
|
Chris@16
|
307 {
|
Chris@16
|
308 BOOST_STATIC_ASSERT_MSG(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
|
Chris@16
|
309 v.backend().negate();
|
Chris@16
|
310 return static_cast<number<B, et_off>&&>(v);
|
Chris@16
|
311 }
|
Chris@16
|
312 template <class B>
|
Chris@16
|
313 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator ~ (number<B, et_off>&& v)
|
Chris@16
|
314 {
|
Chris@16
|
315 eval_complement(v.backend(), v.backend());
|
Chris@16
|
316 return static_cast<number<B, et_off>&&>(v);
|
Chris@16
|
317 }
|
Chris@16
|
318 //
|
Chris@16
|
319 // Addition:
|
Chris@16
|
320 //
|
Chris@16
|
321 template <class B>
|
Chris@16
|
322 BOOST_MP_FORCEINLINE number<B, et_off> operator + (number<B, et_off>&& a, const number<B, et_off>& b)
|
Chris@16
|
323 {
|
Chris@16
|
324 using default_ops::eval_add;
|
Chris@16
|
325 eval_add(a.backend(), b.backend());
|
Chris@16
|
326 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
327 }
|
Chris@16
|
328 template <class B>
|
Chris@16
|
329 BOOST_MP_FORCEINLINE number<B, et_off> operator + (const number<B, et_off>& a, number<B, et_off>&& b)
|
Chris@16
|
330 {
|
Chris@16
|
331 using default_ops::eval_add;
|
Chris@16
|
332 eval_add(b.backend(), a.backend());
|
Chris@16
|
333 return static_cast<number<B, et_off>&&>(b);
|
Chris@16
|
334 }
|
Chris@16
|
335 template <class B>
|
Chris@16
|
336 BOOST_MP_FORCEINLINE number<B, et_off> operator + (number<B, et_off>&& a, number<B, et_off>&& b)
|
Chris@16
|
337 {
|
Chris@16
|
338 using default_ops::eval_add;
|
Chris@16
|
339 eval_add(a.backend(), b.backend());
|
Chris@16
|
340 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
341 }
|
Chris@16
|
342 template <class B, class V>
|
Chris@16
|
343 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
344 operator + (number<B, et_off>&& a, const V& b)
|
Chris@16
|
345 {
|
Chris@16
|
346 using default_ops::eval_add;
|
Chris@16
|
347 eval_add(a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
348 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
349 }
|
Chris@16
|
350 template <class V, class B>
|
Chris@16
|
351 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
352 operator + (const V& a, number<B, et_off>&& b)
|
Chris@16
|
353 {
|
Chris@16
|
354 using default_ops::eval_add;
|
Chris@16
|
355 eval_add(b.backend(), number<B, et_off>::canonical_value(a));
|
Chris@16
|
356 return static_cast<number<B, et_off>&&>(b);
|
Chris@16
|
357 }
|
Chris@16
|
358 //
|
Chris@16
|
359 // Subtraction:
|
Chris@16
|
360 //
|
Chris@16
|
361 template <class B>
|
Chris@16
|
362 BOOST_MP_FORCEINLINE number<B, et_off> operator - (number<B, et_off>&& a, const number<B, et_off>& b)
|
Chris@16
|
363 {
|
Chris@16
|
364 using default_ops::eval_subtract;
|
Chris@16
|
365 eval_subtract(a.backend(), b.backend());
|
Chris@16
|
366 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
367 }
|
Chris@16
|
368 template <class B>
|
Chris@16
|
369 BOOST_MP_FORCEINLINE typename enable_if<is_signed_number<B>, number<B, et_off> >::type operator - (const number<B, et_off>& a, number<B, et_off>&& b)
|
Chris@16
|
370 {
|
Chris@16
|
371 using default_ops::eval_subtract;
|
Chris@16
|
372 eval_subtract(b.backend(), a.backend());
|
Chris@16
|
373 b.backend().negate();
|
Chris@16
|
374 return static_cast<number<B, et_off>&&>(b);
|
Chris@16
|
375 }
|
Chris@16
|
376 template <class B>
|
Chris@16
|
377 BOOST_MP_FORCEINLINE number<B, et_off> operator - (number<B, et_off>&& a, number<B, et_off>&& b)
|
Chris@16
|
378 {
|
Chris@16
|
379 using default_ops::eval_subtract;
|
Chris@16
|
380 eval_subtract(a.backend(), b.backend());
|
Chris@16
|
381 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
382 }
|
Chris@16
|
383 template <class B, class V>
|
Chris@16
|
384 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
385 operator - (number<B, et_off>&& a, const V& b)
|
Chris@16
|
386 {
|
Chris@16
|
387 using default_ops::eval_subtract;
|
Chris@16
|
388 eval_subtract(a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
389 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
390 }
|
Chris@16
|
391 template <class V, class B>
|
Chris@16
|
392 BOOST_MP_FORCEINLINE typename enable_if_c<(is_compatible_arithmetic_type<V, number<B, et_off> >::value && is_signed_number<B>::value), number<B, et_off> >::type
|
Chris@16
|
393 operator - (const V& a, number<B, et_off>&& b)
|
Chris@16
|
394 {
|
Chris@16
|
395 using default_ops::eval_subtract;
|
Chris@16
|
396 eval_subtract(b.backend(), number<B, et_off>::canonical_value(a));
|
Chris@16
|
397 b.backend().negate();
|
Chris@16
|
398 return static_cast<number<B, et_off>&&>(b);
|
Chris@16
|
399 }
|
Chris@16
|
400 //
|
Chris@16
|
401 // Multiply:
|
Chris@16
|
402 //
|
Chris@16
|
403 template <class B>
|
Chris@16
|
404 BOOST_MP_FORCEINLINE number<B, et_off> operator * (number<B, et_off>&& a, const number<B, et_off>& b)
|
Chris@16
|
405 {
|
Chris@16
|
406 using default_ops::eval_multiply;
|
Chris@16
|
407 eval_multiply(a.backend(), b.backend());
|
Chris@16
|
408 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
409 }
|
Chris@16
|
410 template <class B>
|
Chris@16
|
411 BOOST_MP_FORCEINLINE number<B, et_off> operator * (const number<B, et_off>& a, number<B, et_off>&& b)
|
Chris@16
|
412 {
|
Chris@16
|
413 using default_ops::eval_multiply;
|
Chris@16
|
414 eval_multiply(b.backend(), a.backend());
|
Chris@16
|
415 return static_cast<number<B, et_off>&&>(b);
|
Chris@16
|
416 }
|
Chris@16
|
417 template <class B>
|
Chris@16
|
418 BOOST_MP_FORCEINLINE number<B, et_off> operator * (number<B, et_off>&& a, number<B, et_off>&& b)
|
Chris@16
|
419 {
|
Chris@16
|
420 using default_ops::eval_multiply;
|
Chris@16
|
421 eval_multiply(a.backend(), b.backend());
|
Chris@16
|
422 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
423 }
|
Chris@16
|
424 template <class B, class V>
|
Chris@16
|
425 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
426 operator * (number<B, et_off>&& a, const V& b)
|
Chris@16
|
427 {
|
Chris@16
|
428 using default_ops::eval_multiply;
|
Chris@16
|
429 eval_multiply(a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
430 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
431 }
|
Chris@16
|
432 template <class V, class B>
|
Chris@16
|
433 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
434 operator * (const V& a, number<B, et_off>&& b)
|
Chris@16
|
435 {
|
Chris@16
|
436 using default_ops::eval_multiply;
|
Chris@16
|
437 eval_multiply(b.backend(), number<B, et_off>::canonical_value(a));
|
Chris@16
|
438 return static_cast<number<B, et_off>&&>(b);
|
Chris@16
|
439 }
|
Chris@16
|
440 //
|
Chris@16
|
441 // divide:
|
Chris@16
|
442 //
|
Chris@16
|
443 template <class B>
|
Chris@16
|
444 BOOST_MP_FORCEINLINE number<B, et_off> operator / (number<B, et_off>&& a, const number<B, et_off>& b)
|
Chris@16
|
445 {
|
Chris@16
|
446 using default_ops::eval_divide;
|
Chris@16
|
447 eval_divide(a.backend(), b.backend());
|
Chris@16
|
448 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
449 }
|
Chris@16
|
450 template <class B, class V>
|
Chris@16
|
451 BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
Chris@16
|
452 operator / (number<B, et_off>&& a, const V& b)
|
Chris@16
|
453 {
|
Chris@16
|
454 using default_ops::eval_divide;
|
Chris@16
|
455 eval_divide(a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
456 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
457 }
|
Chris@16
|
458 //
|
Chris@16
|
459 // modulus:
|
Chris@16
|
460 //
|
Chris@16
|
461 template <class B>
|
Chris@16
|
462 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator % (number<B, et_off>&& a, const number<B, et_off>& b)
|
Chris@16
|
463 {
|
Chris@16
|
464 using default_ops::eval_modulus;
|
Chris@16
|
465 eval_modulus(a.backend(), b.backend());
|
Chris@16
|
466 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
467 }
|
Chris@16
|
468 template <class B, class V>
|
Chris@16
|
469 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
470 operator % (number<B, et_off>&& a, const V& b)
|
Chris@16
|
471 {
|
Chris@16
|
472 using default_ops::eval_modulus;
|
Chris@16
|
473 eval_modulus(a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
474 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
475 }
|
Chris@16
|
476 //
|
Chris@16
|
477 // Bitwise or:
|
Chris@16
|
478 //
|
Chris@16
|
479 template <class B>
|
Chris@16
|
480 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator | (number<B, et_off>&& a, const number<B, et_off>& b)
|
Chris@16
|
481 {
|
Chris@16
|
482 using default_ops::eval_bitwise_or;
|
Chris@16
|
483 eval_bitwise_or(a.backend(), b.backend());
|
Chris@16
|
484 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
485 }
|
Chris@16
|
486 template <class B>
|
Chris@16
|
487 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator | (const number<B, et_off>& a, number<B, et_off>&& b)
|
Chris@16
|
488 {
|
Chris@16
|
489 using default_ops::eval_bitwise_or;
|
Chris@16
|
490 eval_bitwise_or(b.backend(), a.backend());
|
Chris@16
|
491 return static_cast<number<B, et_off>&&>(b);
|
Chris@16
|
492 }
|
Chris@16
|
493 template <class B>
|
Chris@16
|
494 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator | (number<B, et_off>&& a, number<B, et_off>&& b)
|
Chris@16
|
495 {
|
Chris@16
|
496 using default_ops::eval_bitwise_or;
|
Chris@16
|
497 eval_bitwise_or(a.backend(), b.backend());
|
Chris@16
|
498 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
499 }
|
Chris@16
|
500 template <class B, class V>
|
Chris@16
|
501 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
502 operator | (number<B, et_off>&& a, const V& b)
|
Chris@16
|
503 {
|
Chris@16
|
504 using default_ops::eval_bitwise_or;
|
Chris@16
|
505 eval_bitwise_or(a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
506 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
507 }
|
Chris@16
|
508 template <class V, class B>
|
Chris@16
|
509 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
510 operator | (const V& a, number<B, et_off>&& b)
|
Chris@16
|
511 {
|
Chris@16
|
512 using default_ops::eval_bitwise_or;
|
Chris@16
|
513 eval_bitwise_or(b.backend(), number<B, et_off>::canonical_value(a));
|
Chris@16
|
514 return static_cast<number<B, et_off>&&>(b);
|
Chris@16
|
515 }
|
Chris@16
|
516 //
|
Chris@16
|
517 // Bitwise xor:
|
Chris@16
|
518 //
|
Chris@16
|
519 template <class B>
|
Chris@16
|
520 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator ^ (number<B, et_off>&& a, const number<B, et_off>& b)
|
Chris@16
|
521 {
|
Chris@16
|
522 using default_ops::eval_bitwise_xor;
|
Chris@16
|
523 eval_bitwise_xor(a.backend(), b.backend());
|
Chris@16
|
524 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
525 }
|
Chris@16
|
526 template <class B>
|
Chris@16
|
527 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator ^ (const number<B, et_off>& a, number<B, et_off>&& b)
|
Chris@16
|
528 {
|
Chris@16
|
529 using default_ops::eval_bitwise_xor;
|
Chris@16
|
530 eval_bitwise_xor(b.backend(), a.backend());
|
Chris@16
|
531 return static_cast<number<B, et_off>&&>(b);
|
Chris@16
|
532 }
|
Chris@16
|
533 template <class B>
|
Chris@16
|
534 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator ^ (number<B, et_off>&& a, number<B, et_off>&& b)
|
Chris@16
|
535 {
|
Chris@16
|
536 using default_ops::eval_bitwise_xor;
|
Chris@16
|
537 eval_bitwise_xor(a.backend(), b.backend());
|
Chris@16
|
538 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
539 }
|
Chris@16
|
540 template <class B, class V>
|
Chris@16
|
541 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
542 operator ^ (number<B, et_off>&& a, const V& b)
|
Chris@16
|
543 {
|
Chris@16
|
544 using default_ops::eval_bitwise_xor;
|
Chris@16
|
545 eval_bitwise_xor(a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
546 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
547 }
|
Chris@16
|
548 template <class V, class B>
|
Chris@16
|
549 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
550 operator ^ (const V& a, number<B, et_off>&& b)
|
Chris@16
|
551 {
|
Chris@16
|
552 using default_ops::eval_bitwise_xor;
|
Chris@16
|
553 eval_bitwise_xor(b.backend(), number<B, et_off>::canonical_value(a));
|
Chris@16
|
554 return static_cast<number<B, et_off>&&>(b);
|
Chris@16
|
555 }
|
Chris@16
|
556 //
|
Chris@16
|
557 // Bitwise and:
|
Chris@16
|
558 //
|
Chris@16
|
559 template <class B>
|
Chris@16
|
560 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator & (number<B, et_off>&& a, const number<B, et_off>& b)
|
Chris@16
|
561 {
|
Chris@16
|
562 using default_ops::eval_bitwise_and;
|
Chris@16
|
563 eval_bitwise_and(a.backend(), b.backend());
|
Chris@16
|
564 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
565 }
|
Chris@16
|
566 template <class B>
|
Chris@16
|
567 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator & (const number<B, et_off>& a, number<B, et_off>&& b)
|
Chris@16
|
568 {
|
Chris@16
|
569 using default_ops::eval_bitwise_and;
|
Chris@16
|
570 eval_bitwise_and(b.backend(), a.backend());
|
Chris@16
|
571 return static_cast<number<B, et_off>&&>(b);
|
Chris@16
|
572 }
|
Chris@16
|
573 template <class B>
|
Chris@16
|
574 BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator & (number<B, et_off>&& a, number<B, et_off>&& b)
|
Chris@16
|
575 {
|
Chris@16
|
576 using default_ops::eval_bitwise_and;
|
Chris@16
|
577 eval_bitwise_and(a.backend(), b.backend());
|
Chris@16
|
578 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
579 }
|
Chris@16
|
580 template <class B, class V>
|
Chris@16
|
581 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
582 operator & (number<B, et_off>&& a, const V& b)
|
Chris@16
|
583 {
|
Chris@16
|
584 using default_ops::eval_bitwise_and;
|
Chris@16
|
585 eval_bitwise_and(a.backend(), number<B, et_off>::canonical_value(b));
|
Chris@16
|
586 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
587 }
|
Chris@16
|
588 template <class V, class B>
|
Chris@16
|
589 BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
590 operator & (const V& a, number<B, et_off>&& b)
|
Chris@16
|
591 {
|
Chris@16
|
592 using default_ops::eval_bitwise_and;
|
Chris@16
|
593 eval_bitwise_and(b.backend(), number<B, et_off>::canonical_value(a));
|
Chris@16
|
594 return static_cast<number<B, et_off>&&>(b);
|
Chris@16
|
595 }
|
Chris@16
|
596 //
|
Chris@16
|
597 // shifts:
|
Chris@16
|
598 //
|
Chris@16
|
599 template <class B, class I>
|
Chris@16
|
600 BOOST_MP_FORCEINLINE typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
601 operator << (number<B, et_off>&& a, const I& b)
|
Chris@16
|
602 {
|
Chris@16
|
603 using default_ops::eval_left_shift;
|
Chris@16
|
604 eval_left_shift(a.backend(), b);
|
Chris@16
|
605 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
606 }
|
Chris@16
|
607 template <class B, class I>
|
Chris@16
|
608 BOOST_MP_FORCEINLINE typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
Chris@16
|
609 operator >> (number<B, et_off>&& a, const I& b)
|
Chris@16
|
610 {
|
Chris@16
|
611 using default_ops::eval_right_shift;
|
Chris@16
|
612 eval_right_shift(a.backend(), b);
|
Chris@16
|
613 return static_cast<number<B, et_off>&&>(a);
|
Chris@16
|
614 }
|
Chris@16
|
615
|
Chris@16
|
616 #endif
|
Chris@16
|
617
|
Chris@16
|
618 }} // namespaces
|
Chris@16
|
619
|
Chris@16
|
620 #ifdef BOOST_MSVC
|
Chris@16
|
621 #pragma warning(pop)
|
Chris@16
|
622 #endif
|
Chris@16
|
623
|
Chris@16
|
624 #endif // BOOST_MP_NO_ET_OPS_HPP
|