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