]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/multiprecision/detail/no_et_ops.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / multiprecision / detail / no_et_ops.hpp
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