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 }} // namespace boost::multiprecision
655
656 #ifdef BOOST_MSVC
657 #pragma warning(pop)
658 #endif
659
660 #endif // BOOST_MP_NO_ET_OPS_HPP
661