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