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
14namespace 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 static_assert(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 std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, 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, b);
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 std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, 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, a);
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 std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, 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, b);
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 std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, 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, a);
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 std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, 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, b);
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 std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, 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, a);
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 std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, 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, b);
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 std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, 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, a);
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 std::enable_if<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 std::enable_if<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 std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, 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 std::enable_if<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 std::enable_if<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 std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, 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 std::enable_if<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 std::enable_if<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 std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, 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 std::enable_if<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 std::enable_if<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 std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, 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 std::enable_if<boost::multiprecision::detail::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, std::integral_constant<bool, (sizeof(I) > sizeof(std::size_t))>(), std::integral_constant<bool, boost::multiprecision::detail::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 std::enable_if<boost::multiprecision::detail::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, std::integral_constant<bool, (sizeof(I) > sizeof(std::size_t))>(), std::integral_constant<bool, boost::multiprecision::detail::is_signed<I>::value>());
306 eval_right_shift(result.backend(), b);
307 return result;
308 }
309
310 //
311 // If we have rvalue references go all over again with rvalue ref overloads and move semantics.
312 // Note that while it would be tempting to implement these so they return an rvalue reference
313 // (and indeed this would be optimally efficient), this is unsafe due to users propensity to
314 // write:
315 //
316 // const T& t = a * b;
317 //
318 // which would lead to a dangling reference if we didn't return by value. Of course move
319 // semantics help a great deal in return by value, so performance is still pretty good...
320 //
321 template <class B>
322 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator-(number<B, et_off>&& v)
323 {
324 static_assert(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
325 v.backend().negate();
326 return std::move(v);
327 }
328 template <class B>
329 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator~(number<B, et_off>&& v)
330 {
331 eval_complement(v.backend(), v.backend());
332 return std::move(v);
333 }
334 //
335 // Addition:
336 //
337 template <class B>
338 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator+(number<B, et_off>&& a, const number<B, et_off>& b)
339 {
340 using default_ops::eval_add;
341 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
342 eval_add(a.backend(), b.backend());
343 return std::move(a);
344 }
345 template <class B>
346 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator+(const number<B, et_off>& a, number<B, et_off>&& b)
347 {
348 using default_ops::eval_add;
349 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
350 eval_add(b.backend(), a.backend());
351 return std::move(b);
352 }
353 template <class B>
354 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator+(number<B, et_off>&& a, number<B, et_off>&& b)
355 {
356 using default_ops::eval_add;
357 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
358 eval_add(a.backend(), b.backend());
359 return std::move(a);
360 }
361 template <class B, class V>
362 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type
363 operator+(number<B, et_off>&& a, const V& b)
364 {
365 using default_ops::eval_add;
366 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
367 eval_add(a.backend(), number<B, et_off>::canonical_value(b));
368 return std::move(a);
369 }
370 template <class V, class B>
371 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type
372 operator+(const V& a, number<B, et_off>&& b)
373 {
374 using default_ops::eval_add;
375 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
376 eval_add(b.backend(), number<B, et_off>::canonical_value(a));
377 return std::move(b);
378 }
379 //
380 // Subtraction:
381 //
382 template <class B>
383 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator-(number<B, et_off>&& a, const number<B, et_off>& b)
384 {
385 using default_ops::eval_subtract;
386 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
387 eval_subtract(a.backend(), b.backend());
388 return std::move(a);
389 }
390 template <class B>
391 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_signed_number<B>::value, number<B, et_off> >::type operator-(const number<B, et_off>& a, number<B, et_off>&& b)
392 {
393 using default_ops::eval_subtract;
394 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
395 eval_subtract(b.backend(), a.backend());
396 b.backend().negate();
397 return std::move(b);
398 }
399 template <class B>
400 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator-(number<B, et_off>&& a, number<B, et_off>&& b)
401 {
402 using default_ops::eval_subtract;
403 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
404 eval_subtract(a.backend(), b.backend());
405 return std::move(a);
406 }
407 template <class B, class V>
408 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type
409 operator-(number<B, et_off>&& a, const V& b)
410 {
411 using default_ops::eval_subtract;
412 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
413 eval_subtract(a.backend(), number<B, et_off>::canonical_value(b));
414 return std::move(a);
415 }
416 template <class V, class B>
417 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<(is_compatible_arithmetic_type<V, number<B, et_off> >::value && is_signed_number<B>::value) && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type
418 operator-(const V& a, number<B, et_off>&& b)
419 {
420 using default_ops::eval_subtract;
421 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
422 eval_subtract(b.backend(), number<B, et_off>::canonical_value(a));
423 b.backend().negate();
424 return std::move(b);
425 }
426 //
427 // Multiply:
428 //
429 template <class B>
430 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator*(number<B, et_off>&& a, const number<B, et_off>& b)
431 {
432 using default_ops::eval_multiply;
433 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
434 eval_multiply(a.backend(), b.backend());
435 return std::move(a);
436 }
437 template <class B>
438 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator*(const number<B, et_off>& a, number<B, et_off>&& b)
439 {
440 using default_ops::eval_multiply;
441 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
442 eval_multiply(b.backend(), a.backend());
443 return std::move(b);
444 }
445 template <class B>
446 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator*(number<B, et_off>&& a, number<B, et_off>&& b)
447 {
448 using default_ops::eval_multiply;
449 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
450 eval_multiply(a.backend(), b.backend());
451 return std::move(a);
452 }
453 template <class B, class V>
454 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type
455 operator*(number<B, et_off>&& a, const V& b)
456 {
457 using default_ops::eval_multiply;
458 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
459 eval_multiply(a.backend(), number<B, et_off>::canonical_value(b));
460 return std::move(a);
461 }
462 template <class V, class B>
463 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type
464 operator*(const V& a, number<B, et_off>&& b)
465 {
466 using default_ops::eval_multiply;
467 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
468 eval_multiply(b.backend(), number<B, et_off>::canonical_value(a));
469 return std::move(b);
470 }
471 //
472 // divide:
473 //
474 template <class B>
475 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator/(number<B, et_off>&& a, const number<B, et_off>& b)
476 {
477 using default_ops::eval_divide;
478 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
479 eval_divide(a.backend(), b.backend());
480 return std::move(a);
481 }
482 template <class B, class V>
483 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value, number<B, et_off> >::type
484 operator/(number<B, et_off>&& a, const V& b)
485 {
486 using default_ops::eval_divide;
487 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
488 eval_divide(a.backend(), number<B, et_off>::canonical_value(b));
489 return std::move(a);
490 }
491 //
492 // modulus:
493 //
494 template <class B>
495 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator%(number<B, et_off>&& a, const number<B, et_off>& b)
496 {
497 using default_ops::eval_modulus;
498 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
499 eval_modulus(a.backend(), b.backend());
500 return std::move(a);
501 }
502 template <class B, class V>
503 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
504 operator%(number<B, et_off>&& a, const V& b)
505 {
506 using default_ops::eval_modulus;
507 detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
508 eval_modulus(a.backend(), number<B, et_off>::canonical_value(b));
509 return std::move(a);
510 }
511 //
512 // Bitwise or:
513 //
514 template <class B>
515 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator|(number<B, et_off>&& a, const number<B, et_off>& b)
516 {
517 using default_ops::eval_bitwise_or;
518 eval_bitwise_or(a.backend(), b.backend());
519 return std::move(a);
520 }
521 template <class B>
522 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator|(const number<B, et_off>& a, number<B, et_off>&& b)
523 {
524 using default_ops::eval_bitwise_or;
525 eval_bitwise_or(b.backend(), a.backend());
526 return std::move(b);
527 }
528 template <class B>
529 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator|(number<B, et_off>&& a, number<B, et_off>&& b)
530 {
531 using default_ops::eval_bitwise_or;
532 eval_bitwise_or(a.backend(), b.backend());
533 return std::move(a);
534 }
535 template <class B, class V>
536 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
537 operator|(number<B, et_off>&& a, const V& b)
538 {
539 using default_ops::eval_bitwise_or;
540 eval_bitwise_or(a.backend(), number<B, et_off>::canonical_value(b));
541 return std::move(a);
542 }
543 template <class V, class B>
544 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type
545 operator|(const V& a, number<B, et_off>&& b)
546 {
547 using default_ops::eval_bitwise_or;
548 eval_bitwise_or(b.backend(), number<B, et_off>::canonical_value(a));
549 return std::move(b);
550 }
551 //
552 // Bitwise xor:
553 //
554 template <class B>
555 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator^(number<B, et_off>&& a, const number<B, et_off>& b)
556 {
557 using default_ops::eval_bitwise_xor;
558 eval_bitwise_xor(a.backend(), b.backend());
559 return std::move(a);
560 }
561 template <class B>
562 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator^(const number<B, et_off>& a, number<B, et_off>&& b)
563 {
564 using default_ops::eval_bitwise_xor;
565 eval_bitwise_xor(b.backend(), a.backend());
566 return std::move(b);
567 }
568 template <class B>
569 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator^(number<B, et_off>&& a, number<B, et_off>&& b)
570 {
571 using default_ops::eval_bitwise_xor;
572 eval_bitwise_xor(a.backend(), b.backend());
573 return std::move(a);
574 }
575 template <class B, class V>
576 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
577 operator^(number<B, et_off>&& a, const V& b)
578 {
579 using default_ops::eval_bitwise_xor;
580 eval_bitwise_xor(a.backend(), number<B, et_off>::canonical_value(b));
581 return std::move(a);
582 }
583 template <class V, class B>
584 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type
585 operator^(const V& a, number<B, et_off>&& b)
586 {
587 using default_ops::eval_bitwise_xor;
588 eval_bitwise_xor(b.backend(), number<B, et_off>::canonical_value(a));
589 return std::move(b);
590 }
591 //
592 // Bitwise and:
593 //
594 template <class B>
595 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator&(number<B, et_off>&& a, const number<B, et_off>& b)
596 {
597 using default_ops::eval_bitwise_and;
598 eval_bitwise_and(a.backend(), b.backend());
599 return std::move(a);
600 }
601 template <class B>
602 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator&(const number<B, et_off>& a, number<B, et_off>&& b)
603 {
604 using default_ops::eval_bitwise_and;
605 eval_bitwise_and(b.backend(), a.backend());
606 return std::move(b);
607 }
608 template <class B>
609 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator&(number<B, et_off>&& a, number<B, et_off>&& b)
610 {
611 using default_ops::eval_bitwise_and;
612 eval_bitwise_and(a.backend(), b.backend());
613 return std::move(a);
614 }
615 template <class B, class V>
616 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
617 operator&(number<B, et_off>&& a, const V& b)
618 {
619 using default_ops::eval_bitwise_and;
620 eval_bitwise_and(a.backend(), number<B, et_off>::canonical_value(b));
621 return std::move(a);
622 }
623 template <class V, class B>
624 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer) && !is_equivalent_number_type<V, B>::value, number<B, et_off> >::type
625 operator&(const V& a, number<B, et_off>&& b)
626 {
627 using default_ops::eval_bitwise_and;
628 eval_bitwise_and(b.backend(), number<B, et_off>::canonical_value(a));
629 return std::move(b);
630 }
631 //
632 // shifts:
633 //
634 template <class B, class I>
635 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
636 operator<<(number<B, et_off>&& a, const I& b)
637 {
638 using ui_type = typename boost::multiprecision::detail::make_unsigned<I>::type;
639
640 using default_ops::eval_left_shift;
641 eval_left_shift(a.backend(), static_cast<ui_type>(b));
642 return std::move(a);
643 }
644 template <class B, class I>
645 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
646 operator>>(number<B, et_off>&& a, const I& b)
647 {
648 using ui_type = typename boost::multiprecision::detail::make_unsigned<I>::type;
649
650 using default_ops::eval_right_shift;
651 eval_right_shift(a.backend(), static_cast<ui_type>(b));
652 return std::move(a);
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

source code of boost/libs/multiprecision/include/boost/multiprecision/detail/no_et_ops.hpp