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