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 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>
operator ~(const number<B,et_off> & v)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>
operator +(const number<B,et_off> & a,const number<B,et_off> & 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
operator +(const number<B,et_off> & a,const V & b)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
operator +(const V & a,const number<B,et_off> & b)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>
operator -(const number<B,et_off> & a,const number<B,et_off> & 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
operator -(const number<B,et_off> & a,const V & b)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
operator -(const V & a,const number<B,et_off> & b)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>
operator *(const number<B,et_off> & a,const number<B,et_off> & 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
operator *(const number<B,et_off> & a,const V & b)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
operator *(const V & a,const number<B,et_off> & b)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>
operator /(const number<B,et_off> & a,const number<B,et_off> & 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
operator /(const number<B,et_off> & a,const V & b)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
operator /(const V & a,const number<B,et_off> & b)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>
operator %(const number<B,et_off> & a,const number<B,et_off> & 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
operator %(const number<B,et_off> & a,const V & b)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
operator %(const V & a,const number<B,et_off> & b)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>
operator |(const number<B,et_off> & a,const number<B,et_off> & 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
operator |(const number<B,et_off> & a,const V & b)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
operator |(const V & a,const number<B,et_off> & b)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>
operator ^(const number<B,et_off> & a,const number<B,et_off> & 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
operator ^(const number<B,et_off> & a,const V & b)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
operator ^(const V & a,const number<B,et_off> & b)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>
operator &(const number<B,et_off> & a,const number<B,et_off> & 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
operator &(const number<B,et_off> & a,const V & b)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
operator &(const V & a,const number<B,et_off> & b)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
operator <<(const number<B,et_off> & a,const I & b)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
operator >>(const number<B,et_off> & a,const I & b)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>
operator -(number<B,et_off> && v)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>
operator ~(number<B,et_off> && v)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>
operator +(number<B,et_off> && a,const number<B,et_off> & 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>
operator +(const number<B,et_off> & a,number<B,et_off> && 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>
operator +(number<B,et_off> && a,number<B,et_off> && 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
operator +(number<B,et_off> && a,const V & b)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
operator +(const V & a,number<B,et_off> && b)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>
operator -(number<B,et_off> && a,const number<B,et_off> & 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>
operator -(const number<B,et_off> & a,number<B,et_off> && 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>
operator -(number<B,et_off> && a,number<B,et_off> && 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
operator -(number<B,et_off> && a,const V & b)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
operator -(const V & a,number<B,et_off> && b)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>
operator *(number<B,et_off> && a,const number<B,et_off> & 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>
operator *(const number<B,et_off> & a,number<B,et_off> && 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>
operator *(number<B,et_off> && a,number<B,et_off> && 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
operator *(number<B,et_off> && a,const V & b)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
operator *(const V & a,number<B,et_off> && b)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>
operator /(number<B,et_off> && a,const number<B,et_off> & 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
operator /(number<B,et_off> && a,const V & b)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>
operator %(number<B,et_off> && a,const number<B,et_off> & 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
operator %(number<B,et_off> && a,const V & b)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>
operator |(number<B,et_off> && a,const number<B,et_off> & 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>
operator |(const number<B,et_off> & a,number<B,et_off> && 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>
operator |(number<B,et_off> && a,number<B,et_off> && 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
operator |(number<B,et_off> && a,const V & b)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
operator |(const V & a,number<B,et_off> && b)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>
operator ^(number<B,et_off> && a,const number<B,et_off> & 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>
operator ^(const number<B,et_off> & a,number<B,et_off> && 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>
operator ^(number<B,et_off> && a,number<B,et_off> && 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
operator ^(number<B,et_off> && a,const V & b)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
operator ^(const V & a,number<B,et_off> && b)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>
operator &(number<B,et_off> && a,const number<B,et_off> & 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>
operator &(const number<B,et_off> & a,number<B,et_off> && 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>
operator &(number<B,et_off> && a,number<B,et_off> && 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
operator &(number<B,et_off> && a,const V & b)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
operator &(const V & a,number<B,et_off> && b)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
operator <<(number<B,et_off> && a,const I & b)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
operator >>(number<B,et_off> && a,const I & b)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    }
655 } // namespace boost::multiprecision
656 
657 #ifdef BOOST_MSVC
658 #pragma warning(pop)
659 #endif
660 
661 #endif // BOOST_MP_NO_ET_OPS_HPP
662