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>
operator -(const number<B,et_off> & v)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>
operator ~(const number<B,et_off> & v)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>
operator +(const number<B,et_off> & a,const number<B,et_off> & 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
operator +(const number<B,et_off> & a,const V & b)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
operator +(const V & a,const number<B,et_off> & b)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>
operator -(const number<B,et_off> & a,const number<B,et_off> & 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
operator -(const number<B,et_off> & a,const V & b)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
operator -(const V & a,const number<B,et_off> & b)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>
operator *(const number<B,et_off> & a,const number<B,et_off> & 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
operator *(const number<B,et_off> & a,const V & b)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
operator *(const V & a,const number<B,et_off> & b)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>
operator /(const number<B,et_off> & a,const number<B,et_off> & 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
operator /(const number<B,et_off> & a,const V & b)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
operator /(const V & a,const number<B,et_off> & b)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>
operator %(const number<B,et_off> & a,const number<B,et_off> & 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
operator %(const number<B,et_off> & a,const V & b)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
operator %(const V & a,const number<B,et_off> & b)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>
operator |(const number<B,et_off> & a,const number<B,et_off> & 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
operator |(const number<B,et_off> & a,const V & b)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
operator |(const V & a,const number<B,et_off> & b)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>
operator ^(const number<B,et_off> & a,const number<B,et_off> & 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
operator ^(const number<B,et_off> & a,const V & b)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
operator ^(const V & a,const number<B,et_off> & b)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>
operator &(const number<B,et_off> & a,const number<B,et_off> & 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
operator &(const number<B,et_off> & a,const V & b)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
operator &(const V & a,const number<B,et_off> & b)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
operator <<(const number<B,et_off> & a,const I & b)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
operator >>(const number<B,et_off> & a,const I & b)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>
operator -(number<B,et_off> && v)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>
operator ~(number<B,et_off> && v)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>
operator +(number<B,et_off> && a,const number<B,et_off> & 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>
operator +(const number<B,et_off> & a,number<B,et_off> && 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>
operator +(number<B,et_off> && a,number<B,et_off> && 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
operator +(number<B,et_off> && a,const V & b)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
operator +(const V & a,number<B,et_off> && b)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>
operator -(number<B,et_off> && a,const number<B,et_off> & 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>
operator -(const number<B,et_off> & a,number<B,et_off> && 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>
operator -(number<B,et_off> && a,number<B,et_off> && 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
operator -(number<B,et_off> && a,const V & b)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
operator -(const V & a,number<B,et_off> && b)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>
operator *(number<B,et_off> && a,const number<B,et_off> & 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>
operator *(const number<B,et_off> & a,number<B,et_off> && 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>
operator *(number<B,et_off> && a,number<B,et_off> && 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
operator *(number<B,et_off> && a,const V & b)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
operator *(const V & a,number<B,et_off> && b)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>
operator /(number<B,et_off> && a,const number<B,et_off> & 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
operator /(number<B,et_off> && a,const V & b)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>
operator %(number<B,et_off> && a,const number<B,et_off> & 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
operator %(number<B,et_off> && a,const V & b)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>
operator |(number<B,et_off> && a,const number<B,et_off> & 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>
operator |(const number<B,et_off> & a,number<B,et_off> && 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>
operator |(number<B,et_off> && a,number<B,et_off> && 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
operator |(number<B,et_off> && a,const V & b)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
operator |(const V & a,number<B,et_off> && b)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>
operator ^(number<B,et_off> && a,const number<B,et_off> & 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>
operator ^(const number<B,et_off> & a,number<B,et_off> && 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>
operator ^(number<B,et_off> && a,number<B,et_off> && 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
operator ^(number<B,et_off> && a,const V & b)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
operator ^(const V & a,number<B,et_off> && b)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>
operator &(number<B,et_off> && a,const number<B,et_off> & 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>
operator &(const number<B,et_off> & a,number<B,et_off> && 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>
operator &(number<B,et_off> && a,number<B,et_off> && 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
operator &(number<B,et_off> && a,const V & b)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
operator &(const V & a,number<B,et_off> && b)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
operator <<(number<B,et_off> && a,const I & b)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
operator >>(number<B,et_off> && a,const I & b)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
625