Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:22

0001 ///////////////////////////////////////////////////////////////////////////////
0002 //  Copyright 2012 John Maddock. Distributed under the Boost
0003 //  Software License, Version 1.0. (See accompanying file
0004 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_MP_NO_ET_OPS_HPP
0007 #define BOOST_MP_NO_ET_OPS_HPP
0008 
0009 #ifdef BOOST_MSVC
0010 #pragma warning(push)
0011 #pragma warning(disable : 4714)
0012 #endif
0013 
0014 namespace boost {
0015    namespace multiprecision {
0016 
0017       //
0018       // Operators for non-expression template enabled number.
0019       // NOTE: this is not a complete header - really just a suffix to default_ops.hpp.
0020       // NOTE: these operators have to be defined after the methods in default_ops.hpp.
0021       //
0022       template <class B>
0023       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator-(const number<B, et_off>& v)
0024       {
0025          static_assert(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
0026          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(v);
0027          number<B, et_off>                                                    result(v);
0028          result.backend().negate();
0029          return result;
0030       }
0031       template <class B>
0032       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator~(const number<B, et_off>& v)
0033       {
0034          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(v);
0035          number<B, et_off>                                                    result;
0036          eval_complement(result.backend(), v.backend());
0037          return result;
0038       }
0039       //
0040       // Addition:
0041       //
0042       template <class B>
0043       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator+(const number<B, et_off>& a, const number<B, et_off>& b)
0044       {
0045          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0046          number<B, et_off>                                                    result;
0047          using default_ops::eval_add;
0048          eval_add(result.backend(), a.backend(), b.backend());
0049          return result;
0050       }
0051       template <class B, class V>
0052       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
0053          operator+(const number<B, et_off>& a, const V& b)
0054       {
0055          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0056          number<B, et_off>                                                    result;
0057          using default_ops::eval_add;
0058          eval_add(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
0059          return result;
0060       }
0061       template <class V, class B>
0062       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
0063          operator+(const V& a, const number<B, et_off>& b)
0064       {
0065          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b, a);
0066          number<B, et_off>                                                    result;
0067          using default_ops::eval_add;
0068          eval_add(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
0069          return result;
0070       }
0071       //
0072       // Subtraction:
0073       //
0074       template <class B>
0075       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator-(const number<B, et_off>& a, const number<B, et_off>& b)
0076       {
0077          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0078          number<B, et_off>                                                    result;
0079          using default_ops::eval_subtract;
0080          eval_subtract(result.backend(), a.backend(), b.backend());
0081          return result;
0082       }
0083       template <class B, class V>
0084       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
0085          operator-(const number<B, et_off>& a, const V& b)
0086       {
0087          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0088          number<B, et_off>                                                    result;
0089          using default_ops::eval_subtract;
0090          eval_subtract(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
0091          return result;
0092       }
0093       template <class V, class B>
0094       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
0095          operator-(const V& a, const number<B, et_off>& b)
0096       {
0097          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b, a);
0098          number<B, et_off>                                                    result;
0099          using default_ops::eval_subtract;
0100          eval_subtract(result.backend(), number<B, et_off>::canonical_value(a), b.backend());
0101          return result;
0102       }
0103       //
0104       // Multiply:
0105       //
0106       template <class B>
0107       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator*(const number<B, et_off>& a, const number<B, et_off>& b)
0108       {
0109          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0110          number<B, et_off>                                                    result;
0111          using default_ops::eval_multiply;
0112          eval_multiply(result.backend(), a.backend(), b.backend());
0113          return result;
0114       }
0115       template <class B, class V>
0116       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
0117          operator*(const number<B, et_off>& a, const V& b)
0118       {
0119          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0120          number<B, et_off>                                                    result;
0121          using default_ops::eval_multiply;
0122          eval_multiply(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
0123          return result;
0124       }
0125       template <class V, class B>
0126       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
0127          operator*(const V& a, const number<B, et_off>& b)
0128       {
0129          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b, a);
0130          number<B, et_off>                                                    result;
0131          using default_ops::eval_multiply;
0132          eval_multiply(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
0133          return result;
0134       }
0135       //
0136       // divide:
0137       //
0138       template <class B>
0139       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator/(const number<B, et_off>& a, const number<B, et_off>& b)
0140       {
0141          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0142          number<B, et_off>                                                    result;
0143          using default_ops::eval_divide;
0144          eval_divide(result.backend(), a.backend(), b.backend());
0145          return result;
0146       }
0147       template <class B, class V>
0148       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
0149          operator/(const number<B, et_off>& a, const V& b)
0150       {
0151          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0152          number<B, et_off>                                                    result;
0153          using default_ops::eval_divide;
0154          eval_divide(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
0155          return result;
0156       }
0157       template <class V, class B>
0158       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
0159          operator/(const V& a, const number<B, et_off>& b)
0160       {
0161          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b, a);
0162          number<B, et_off>                                                    result;
0163          using default_ops::eval_divide;
0164          eval_divide(result.backend(), number<B, et_off>::canonical_value(a), b.backend());
0165          return result;
0166       }
0167       //
0168       // modulus:
0169       //
0170       template <class B>
0171       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)
0172       {
0173          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0174          number<B, et_off>                                                    result;
0175          using default_ops::eval_modulus;
0176          eval_modulus(result.backend(), a.backend(), b.backend());
0177          return result;
0178       }
0179       template <class B, class V>
0180       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
0181          operator%(const number<B, et_off>& a, const V& b)
0182       {
0183          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a);
0184          number<B, et_off>                                                    result;
0185          using default_ops::eval_modulus;
0186          eval_modulus(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
0187          return result;
0188       }
0189       template <class V, class B>
0190       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
0191          operator%(const V& a, const number<B, et_off>& b)
0192       {
0193          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b);
0194          number<B, et_off>                                                    result;
0195          using default_ops::eval_modulus;
0196          eval_modulus(result.backend(), number<B, et_off>::canonical_value(a), b.backend());
0197          return result;
0198       }
0199       //
0200       // Bitwise or:
0201       //
0202       template <class B>
0203       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)
0204       {
0205          number<B, et_off> result;
0206          using default_ops::eval_bitwise_or;
0207          eval_bitwise_or(result.backend(), a.backend(), b.backend());
0208          return result;
0209       }
0210       template <class B, class V>
0211       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
0212          operator|(const number<B, et_off>& a, const V& b)
0213       {
0214          number<B, et_off> result;
0215          using default_ops::eval_bitwise_or;
0216          eval_bitwise_or(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
0217          return result;
0218       }
0219       template <class V, class B>
0220       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
0221          operator|(const V& a, const number<B, et_off>& b)
0222       {
0223          number<B, et_off> result;
0224          using default_ops::eval_bitwise_or;
0225          eval_bitwise_or(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
0226          return result;
0227       }
0228       //
0229       // Bitwise xor:
0230       //
0231       template <class B>
0232       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)
0233       {
0234          number<B, et_off> result;
0235          using default_ops::eval_bitwise_xor;
0236          eval_bitwise_xor(result.backend(), a.backend(), b.backend());
0237          return result;
0238       }
0239       template <class B, class V>
0240       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
0241          operator^(const number<B, et_off>& a, const V& b)
0242       {
0243          number<B, et_off> result;
0244          using default_ops::eval_bitwise_xor;
0245          eval_bitwise_xor(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
0246          return result;
0247       }
0248       template <class V, class B>
0249       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
0250          operator^(const V& a, const number<B, et_off>& b)
0251       {
0252          number<B, et_off> result;
0253          using default_ops::eval_bitwise_xor;
0254          eval_bitwise_xor(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
0255          return result;
0256       }
0257       //
0258       // Bitwise and:
0259       //
0260       template <class B>
0261       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)
0262       {
0263          number<B, et_off> result;
0264          using default_ops::eval_bitwise_and;
0265          eval_bitwise_and(result.backend(), a.backend(), b.backend());
0266          return result;
0267       }
0268       template <class B, class V>
0269       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
0270          operator&(const number<B, et_off>& a, const V& b)
0271       {
0272          number<B, et_off> result;
0273          using default_ops::eval_bitwise_and;
0274          eval_bitwise_and(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
0275          return result;
0276       }
0277       template <class V, class B>
0278       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
0279          operator&(const V& a, const number<B, et_off>& b)
0280       {
0281          number<B, et_off> result;
0282          using default_ops::eval_bitwise_and;
0283          eval_bitwise_and(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
0284          return result;
0285       }
0286       //
0287       // shifts:
0288       //
0289       template <class B, class I>
0290       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
0291          operator<<(const number<B, et_off>& a, const I& b)
0292       {
0293          number<B, et_off> result(a);
0294          using default_ops::eval_left_shift;
0295          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>());
0296          eval_left_shift(result.backend(), b);
0297          return result;
0298       }
0299       template <class B, class I>
0300       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
0301          operator>>(const number<B, et_off>& a, const I& b)
0302       {
0303          number<B, et_off> result(a);
0304          using default_ops::eval_right_shift;
0305          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>());
0306          eval_right_shift(result.backend(), b);
0307          return result;
0308       }
0309 
0310       //
0311       // If we have rvalue references go all over again with rvalue ref overloads and move semantics.
0312       // Note that while it would be tempting to implement these so they return an rvalue reference
0313       // (and indeed this would be optimally efficient), this is unsafe due to users propensity to
0314       // write:
0315       //
0316       // const T& t = a * b;
0317       //
0318       // which would lead to a dangling reference if we didn't return by value.  Of course move
0319       // semantics help a great deal in return by value, so performance is still pretty good...
0320       //
0321       template <class B>
0322       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator-(number<B, et_off>&& v)
0323       {
0324          static_assert(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
0325          v.backend().negate();
0326          return std::move(v);
0327       }
0328       template <class B>
0329       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)
0330       {
0331          eval_complement(v.backend(), v.backend());
0332          return std::move(v);
0333       }
0334       //
0335       // Addition:
0336       //
0337       template <class B>
0338       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator+(number<B, et_off>&& a, const number<B, et_off>& b)
0339       {
0340          using default_ops::eval_add;
0341          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0342          eval_add(a.backend(), b.backend());
0343          return std::move(a);
0344       }
0345       template <class B>
0346       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator+(const number<B, et_off>& a, number<B, et_off>&& b)
0347       {
0348          using default_ops::eval_add;
0349          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0350          eval_add(b.backend(), a.backend());
0351          return std::move(b);
0352       }
0353       template <class B>
0354       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator+(number<B, et_off>&& a, number<B, et_off>&& b)
0355       {
0356          using default_ops::eval_add;
0357          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0358          eval_add(a.backend(), b.backend());
0359          return std::move(a);
0360       }
0361       template <class B, class V>
0362       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
0363          operator+(number<B, et_off>&& a, const V& b)
0364       {
0365          using default_ops::eval_add;
0366          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0367          eval_add(a.backend(), number<B, et_off>::canonical_value(b));
0368          return std::move(a);
0369       }
0370       template <class V, class B>
0371       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
0372          operator+(const V& a, number<B, et_off>&& b)
0373       {
0374          using default_ops::eval_add;
0375          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0376          eval_add(b.backend(), number<B, et_off>::canonical_value(a));
0377          return std::move(b);
0378       }
0379       //
0380       // Subtraction:
0381       //
0382       template <class B>
0383       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator-(number<B, et_off>&& a, const number<B, et_off>& b)
0384       {
0385          using default_ops::eval_subtract;
0386          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0387          eval_subtract(a.backend(), b.backend());
0388          return std::move(a);
0389       }
0390       template <class B>
0391       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)
0392       {
0393          using default_ops::eval_subtract;
0394          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0395          eval_subtract(b.backend(), a.backend());
0396          b.backend().negate();
0397          return std::move(b);
0398       }
0399       template <class B>
0400       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator-(number<B, et_off>&& a, number<B, et_off>&& b)
0401       {
0402          using default_ops::eval_subtract;
0403          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0404          eval_subtract(a.backend(), b.backend());
0405          return std::move(a);
0406       }
0407       template <class B, class V>
0408       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
0409          operator-(number<B, et_off>&& a, const V& b)
0410       {
0411          using default_ops::eval_subtract;
0412          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0413          eval_subtract(a.backend(), number<B, et_off>::canonical_value(b));
0414          return std::move(a);
0415       }
0416       template <class V, class B>
0417       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
0418          operator-(const V& a, number<B, et_off>&& b)
0419       {
0420          using default_ops::eval_subtract;
0421          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0422          eval_subtract(b.backend(), number<B, et_off>::canonical_value(a));
0423          b.backend().negate();
0424          return std::move(b);
0425       }
0426       //
0427       // Multiply:
0428       //
0429       template <class B>
0430       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator*(number<B, et_off>&& a, const number<B, et_off>& b)
0431       {
0432          using default_ops::eval_multiply;
0433          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0434          eval_multiply(a.backend(), b.backend());
0435          return std::move(a);
0436       }
0437       template <class B>
0438       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator*(const number<B, et_off>& a, number<B, et_off>&& b)
0439       {
0440          using default_ops::eval_multiply;
0441          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0442          eval_multiply(b.backend(), a.backend());
0443          return std::move(b);
0444       }
0445       template <class B>
0446       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator*(number<B, et_off>&& a, number<B, et_off>&& b)
0447       {
0448          using default_ops::eval_multiply;
0449          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0450          eval_multiply(a.backend(), b.backend());
0451          return std::move(a);
0452       }
0453       template <class B, class V>
0454       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
0455          operator*(number<B, et_off>&& a, const V& b)
0456       {
0457          using default_ops::eval_multiply;
0458          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0459          eval_multiply(a.backend(), number<B, et_off>::canonical_value(b));
0460          return std::move(a);
0461       }
0462       template <class V, class B>
0463       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
0464          operator*(const V& a, number<B, et_off>&& b)
0465       {
0466          using default_ops::eval_multiply;
0467          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0468          eval_multiply(b.backend(), number<B, et_off>::canonical_value(a));
0469          return std::move(b);
0470       }
0471       //
0472       // divide:
0473       //
0474       template <class B>
0475       BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR number<B, et_off> operator/(number<B, et_off>&& a, const number<B, et_off>& b)
0476       {
0477          using default_ops::eval_divide;
0478          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0479          eval_divide(a.backend(), b.backend());
0480          return std::move(a);
0481       }
0482       template <class B, class V>
0483       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
0484          operator/(number<B, et_off>&& a, const V& b)
0485       {
0486          using default_ops::eval_divide;
0487          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0488          eval_divide(a.backend(), number<B, et_off>::canonical_value(b));
0489          return std::move(a);
0490       }
0491       //
0492       // modulus:
0493       //
0494       template <class B>
0495       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)
0496       {
0497          using default_ops::eval_modulus;
0498          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0499          eval_modulus(a.backend(), b.backend());
0500          return std::move(a);
0501       }
0502       template <class B, class V>
0503       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
0504          operator%(number<B, et_off>&& a, const V& b)
0505       {
0506          using default_ops::eval_modulus;
0507          detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
0508          eval_modulus(a.backend(), number<B, et_off>::canonical_value(b));
0509          return std::move(a);
0510       }
0511       //
0512       // Bitwise or:
0513       //
0514       template <class B>
0515       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)
0516       {
0517          using default_ops::eval_bitwise_or;
0518          eval_bitwise_or(a.backend(), b.backend());
0519          return std::move(a);
0520       }
0521       template <class B>
0522       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)
0523       {
0524          using default_ops::eval_bitwise_or;
0525          eval_bitwise_or(b.backend(), a.backend());
0526          return std::move(b);
0527       }
0528       template <class B>
0529       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)
0530       {
0531          using default_ops::eval_bitwise_or;
0532          eval_bitwise_or(a.backend(), b.backend());
0533          return std::move(a);
0534       }
0535       template <class B, class V>
0536       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
0537          operator|(number<B, et_off>&& a, const V& b)
0538       {
0539          using default_ops::eval_bitwise_or;
0540          eval_bitwise_or(a.backend(), number<B, et_off>::canonical_value(b));
0541          return std::move(a);
0542       }
0543       template <class V, class B>
0544       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
0545          operator|(const V& a, number<B, et_off>&& b)
0546       {
0547          using default_ops::eval_bitwise_or;
0548          eval_bitwise_or(b.backend(), number<B, et_off>::canonical_value(a));
0549          return std::move(b);
0550       }
0551       //
0552       // Bitwise xor:
0553       //
0554       template <class B>
0555       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)
0556       {
0557          using default_ops::eval_bitwise_xor;
0558          eval_bitwise_xor(a.backend(), b.backend());
0559          return std::move(a);
0560       }
0561       template <class B>
0562       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)
0563       {
0564          using default_ops::eval_bitwise_xor;
0565          eval_bitwise_xor(b.backend(), a.backend());
0566          return std::move(b);
0567       }
0568       template <class B>
0569       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)
0570       {
0571          using default_ops::eval_bitwise_xor;
0572          eval_bitwise_xor(a.backend(), b.backend());
0573          return std::move(a);
0574       }
0575       template <class B, class V>
0576       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
0577          operator^(number<B, et_off>&& a, const V& b)
0578       {
0579          using default_ops::eval_bitwise_xor;
0580          eval_bitwise_xor(a.backend(), number<B, et_off>::canonical_value(b));
0581          return std::move(a);
0582       }
0583       template <class V, class B>
0584       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
0585          operator^(const V& a, number<B, et_off>&& b)
0586       {
0587          using default_ops::eval_bitwise_xor;
0588          eval_bitwise_xor(b.backend(), number<B, et_off>::canonical_value(a));
0589          return std::move(b);
0590       }
0591       //
0592       // Bitwise and:
0593       //
0594       template <class B>
0595       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)
0596       {
0597          using default_ops::eval_bitwise_and;
0598          eval_bitwise_and(a.backend(), b.backend());
0599          return std::move(a);
0600       }
0601       template <class B>
0602       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)
0603       {
0604          using default_ops::eval_bitwise_and;
0605          eval_bitwise_and(b.backend(), a.backend());
0606          return std::move(b);
0607       }
0608       template <class B>
0609       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)
0610       {
0611          using default_ops::eval_bitwise_and;
0612          eval_bitwise_and(a.backend(), b.backend());
0613          return std::move(a);
0614       }
0615       template <class B, class V>
0616       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
0617          operator&(number<B, et_off>&& a, const V& b)
0618       {
0619          using default_ops::eval_bitwise_and;
0620          eval_bitwise_and(a.backend(), number<B, et_off>::canonical_value(b));
0621          return std::move(a);
0622       }
0623       template <class V, class B>
0624       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
0625          operator&(const V& a, number<B, et_off>&& b)
0626       {
0627          using default_ops::eval_bitwise_and;
0628          eval_bitwise_and(b.backend(), number<B, et_off>::canonical_value(a));
0629          return std::move(b);
0630       }
0631       //
0632       // shifts:
0633       //
0634       template <class B, class I>
0635       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
0636          operator<<(number<B, et_off>&& a, const I& b)
0637       {
0638          using ui_type = typename boost::multiprecision::detail::make_unsigned<I>::type;
0639 
0640          using default_ops::eval_left_shift;
0641          eval_left_shift(a.backend(), static_cast<ui_type>(b));
0642          return std::move(a);
0643       }
0644       template <class B, class I>
0645       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
0646          operator>>(number<B, et_off>&& a, const I& b)
0647       {
0648          using ui_type = typename boost::multiprecision::detail::make_unsigned<I>::type;
0649 
0650          using default_ops::eval_right_shift;
0651          eval_right_shift(a.backend(), static_cast<ui_type>(b));
0652          return std::move(a);
0653       }
0654    }
0655 } // namespace boost::multiprecision
0656 
0657 #ifdef BOOST_MSVC
0658 #pragma warning(pop)
0659 #endif
0660 
0661 #endif // BOOST_MP_NO_ET_OPS_HPP