diff options
Diffstat (limited to 'boost/multiprecision')
29 files changed, 803 insertions, 492 deletions
diff --git a/boost/multiprecision/concepts/mp_number_archetypes.hpp b/boost/multiprecision/concepts/mp_number_archetypes.hpp index e52044adbf..5d5d841710 100644 --- a/boost/multiprecision/concepts/mp_number_archetypes.hpp +++ b/boost/multiprecision/concepts/mp_number_archetypes.hpp @@ -26,8 +26,8 @@ namespace concepts{ struct number_backend_float_architype { - typedef mpl::list<long long> signed_types; - typedef mpl::list<unsigned long long> unsigned_types; + typedef mpl::list<boost::long_long_type> signed_types; + typedef mpl::list<boost::ulong_long_type> unsigned_types; typedef mpl::list<long double> float_types; typedef int exponent_type; @@ -46,13 +46,13 @@ struct number_backend_float_architype std::cout << "Assignment (" << m_value << ")" << std::endl; return *this; } - number_backend_float_architype& operator = (unsigned long long i) + number_backend_float_architype& operator = (boost::ulong_long_type i) { m_value = i; std::cout << "UInt Assignment (" << i << ")" << std::endl; return *this; } - number_backend_float_architype& operator = (long long i) + number_backend_float_architype& operator = (boost::long_long_type i) { m_value = i; std::cout << "Int Assignment (" << i << ")" << std::endl; @@ -112,12 +112,12 @@ struct number_backend_float_architype std::cout << "Comparison" << std::endl; return m_value > o.m_value ? 1 : (m_value < o.m_value ? -1 : 0); } - int compare(long long i)const + int compare(boost::long_long_type i)const { std::cout << "Comparison with int" << std::endl; return m_value > i ? 1 : (m_value < i ? -1 : 0); } - int compare(unsigned long long i)const + int compare(boost::ulong_long_type i)const { std::cout << "Comparison with unsigned" << std::endl; return m_value > i ? 1 : (m_value < i ? -1 : 0); @@ -151,13 +151,13 @@ inline void eval_divide(number_backend_float_architype& result, const number_bac result.m_value /= o.m_value; } -inline void eval_convert_to(unsigned long long* result, const number_backend_float_architype& val) +inline void eval_convert_to(boost::ulong_long_type* result, const number_backend_float_architype& val) { - *result = static_cast<unsigned long long>(val.m_value); + *result = static_cast<boost::ulong_long_type>(val.m_value); } -inline void eval_convert_to(long long* result, const number_backend_float_architype& val) +inline void eval_convert_to(boost::long_long_type* result, const number_backend_float_architype& val) { - *result = static_cast<long long>(val.m_value); + *result = static_cast<boost::long_long_type>(val.m_value); } inline void eval_convert_to(long double* result, number_backend_float_architype& val) { diff --git a/boost/multiprecision/cpp_bin_float.hpp b/boost/multiprecision/cpp_bin_float.hpp index 9a4ceff587..4c00799843 100644 --- a/boost/multiprecision/cpp_bin_float.hpp +++ b/boost/multiprecision/cpp_bin_float.hpp @@ -21,7 +21,7 @@ enum digit_base_type #ifdef BOOST_MSVC #pragma warning(push) -#pragma warning(disable:4522) // multiple assignment operators specified +#pragma warning(disable:4522 6326) // multiple assignment operators specified, comparison of two constants #endif namespace detail{ @@ -37,7 +37,7 @@ template <unsigned Digits, digit_base_type DigitBase = digit_base_10, class Allo class cpp_bin_float { public: - static const unsigned bit_count = DigitBase == digit_base_2 ? Digits : (Digits * 1000uL) / 301uL + ((Digits * 1000uL) % 301 ? 2u : 1u); + static const unsigned bit_count = DigitBase == digit_base_2 ? Digits : (Digits * 1000uL) / 301uL + (((Digits * 1000uL) % 301) ? 2u : 1u); typedef cpp_int_backend<is_void<Allocator>::value ? bit_count : 0, bit_count, is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator> rep_type; typedef cpp_int_backend<is_void<Allocator>::value ? 2 * bit_count : 0, 2 * bit_count, is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator> double_rep_type; @@ -67,9 +67,9 @@ private: exponent_type m_exponent; bool m_sign; public: - cpp_bin_float() BOOST_NOEXCEPT_IF(noexcept(rep_type())) : m_data(), m_exponent(exponent_nan), m_sign(false) {} + cpp_bin_float() BOOST_MP_NOEXCEPT_IF(noexcept(rep_type())) : m_data(), m_exponent(exponent_nan), m_sign(false) {} - cpp_bin_float(const cpp_bin_float &o) BOOST_NOEXCEPT_IF(noexcept(rep_type(std::declval<const rep_type&>()))) + cpp_bin_float(const cpp_bin_float &o) BOOST_MP_NOEXCEPT_IF(noexcept(rep_type(std::declval<const rep_type&>()))) : m_data(o.m_data), m_exponent(o.m_exponent), m_sign(o.m_sign) {} template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE> @@ -104,7 +104,7 @@ public: this->assign_float(f); } - cpp_bin_float& operator=(const cpp_bin_float &o) BOOST_NOEXCEPT_IF(noexcept(std::declval<rep_type&>() = std::declval<const rep_type&>())) + cpp_bin_float& operator=(const cpp_bin_float &o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<rep_type&>() = std::declval<const rep_type&>())) { m_data = o.m_data; m_exponent = o.m_exponent; @@ -773,6 +773,10 @@ inline typename enable_if_c<is_signed<S>::value>::type eval_multiply(cpp_bin_flo template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &u, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &v) { +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:6326) // comparison of two constants +#endif using default_ops::eval_subtract; using default_ops::eval_qr; using default_ops::eval_bit_test; @@ -882,7 +886,7 @@ inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, Mi // how we'll be rounding. // BOOST_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)); - static const unsigned lshift = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits ? 2 : limb_bits; + static const unsigned lshift = (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits) ? 2 : limb_bits; eval_left_shift(q, lshift); res.exponent() -= lshift; eval_left_shift(r, 1u); @@ -893,6 +897,9 @@ inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, Mi q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u); } copy_and_round(res, q); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif } template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> @@ -904,6 +911,10 @@ inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, Mi template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U> inline typename enable_if_c<is_unsigned<U>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &u, const U &v) { +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:6326) // comparison of two constants +#endif using default_ops::eval_subtract; using default_ops::eval_qr; using default_ops::eval_bit_test; @@ -1000,6 +1011,9 @@ inline typename enable_if_c<is_unsigned<U>::value>::type eval_divide(cpp_bin_flo q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u); } copy_and_round(res, q); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif } template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U> @@ -1045,7 +1059,7 @@ inline bool eval_eq(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, } template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_convert_to(long long *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) +inline void eval_convert_to(boost::long_long_type *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) { switch(arg.exponent()) { @@ -1055,7 +1069,7 @@ inline void eval_convert_to(long long *res, const cpp_bin_float<Digits, DigitBas case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - *res = (std::numeric_limits<long long>::max)(); + *res = (std::numeric_limits<boost::long_long_type>::max)(); if(arg.sign()) *res = -*res; return; @@ -1068,14 +1082,14 @@ inline void eval_convert_to(long long *res, const cpp_bin_float<Digits, DigitBas *res = 0; return; } - if(arg.sign() && (arg.compare((std::numeric_limits<long long>::min)()) <= 0)) + if(arg.sign() && (arg.compare((std::numeric_limits<boost::long_long_type>::min)()) <= 0)) { - *res = (std::numeric_limits<long long>::min)(); + *res = (std::numeric_limits<boost::long_long_type>::min)(); return; } - else if(!arg.sign() && (arg.compare((std::numeric_limits<long long>::max)()) >= 0)) + else if(!arg.sign() && (arg.compare((std::numeric_limits<boost::long_long_type>::max)()) >= 0)) { - *res = (std::numeric_limits<long long>::max)(); + *res = (std::numeric_limits<boost::long_long_type>::max)(); return; } eval_right_shift(man, shift); @@ -1087,7 +1101,7 @@ inline void eval_convert_to(long long *res, const cpp_bin_float<Digits, DigitBas } template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE> -inline void eval_convert_to(unsigned long long *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) +inline void eval_convert_to(boost::ulong_long_type *res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> &arg) { switch(arg.exponent()) { @@ -1097,7 +1111,7 @@ inline void eval_convert_to(unsigned long long *res, const cpp_bin_float<Digits, case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan: BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity: - *res = (std::numeric_limits<unsigned long long>::max)(); + *res = (std::numeric_limits<boost::ulong_long_type>::max)(); return; } typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits()); @@ -1110,8 +1124,8 @@ inline void eval_convert_to(unsigned long long *res, const cpp_bin_float<Digits, } else if(shift < 0) { - // TODO: what if we have fewer cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count than a long long? - *res = (std::numeric_limits<long long>::max)(); + // TODO: what if we have fewer cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count than a boost::long_long_type? + *res = (std::numeric_limits<boost::long_long_type>::max)(); return; } eval_right_shift(man, shift); @@ -1462,9 +1476,9 @@ public: return -(max)(); } BOOST_STATIC_CONSTEXPR int digits = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count; - BOOST_STATIC_CONSTEXPR int digits10 = digits * 301 / 1000; + BOOST_STATIC_CONSTEXPR int digits10 = (digits - 1) * 301 / 1000; // Is this really correct??? - BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2; + BOOST_STATIC_CONSTEXPR int max_digits10 = (digits * 301 / 1000) + 2; BOOST_STATIC_CONSTEXPR bool is_signed = true; BOOST_STATIC_CONSTEXPR bool is_integer = false; BOOST_STATIC_CONSTEXPR bool is_exact = false; diff --git a/boost/multiprecision/cpp_bin_float/io.hpp b/boost/multiprecision/cpp_bin_float/io.hpp index ae3ab38e1d..88d5ddd053 100644 --- a/boost/multiprecision/cpp_bin_float/io.hpp +++ b/boost/multiprecision/cpp_bin_float/io.hpp @@ -282,7 +282,7 @@ cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& cpp_bin_float #ifdef BOOST_MP_STRESS_IO boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 32; #else - boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits ? limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits : 0) + limb_bits; + boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + ((cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) ? (limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) : 0) + limb_bits; #endif boost::int64_t error = 0; boost::intmax_t calc_exp = 0; @@ -384,9 +384,9 @@ cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& cpp_bin_float { // Too many bits in q and the bits in q indicate a tie, but we can break that using r, // note that the radius of error in r is error/2 * q: - int shift = gb - (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1; - q >>= shift; - final_exponent += static_cast<Exponent>(shift); + int lshift = gb - (int)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1; + q >>= lshift; + final_exponent += static_cast<Exponent>(lshift); BOOST_ASSERT((msb(q) >= cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)); if(error && (r < (error / 2) * q)) roundup = -1; @@ -525,7 +525,7 @@ std::string cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::s #ifdef BOOST_MP_STRESS_IO boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 32; #else - boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits ? limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits : 0) + limb_bits; + boost::intmax_t max_bits = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + ((cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) ? (limb_bits - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count % limb_bits) : 0) + limb_bits; if(power10) max_bits += (msb(boost::multiprecision::detail::abs(power10)) / 8) * limb_bits; #endif diff --git a/boost/multiprecision/cpp_dec_float.hpp b/boost/multiprecision/cpp_dec_float.hpp index d19abafec4..737f925067 100644 --- a/boost/multiprecision/cpp_dec_float.hpp +++ b/boost/multiprecision/cpp_dec_float.hpp @@ -34,6 +34,11 @@ // #include <boost/math/policies/policy.hpp> +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:6326) // comparison of two constants +#endif + namespace boost{ namespace multiprecision{ namespace backends{ @@ -59,8 +64,8 @@ private: BOOST_STATIC_ASSERT_MSG(sizeof(ExponentType) > 1, "ExponentType is too small."); public: - typedef mpl::list<long long> signed_types; - typedef mpl::list<unsigned long long> unsigned_types; + typedef mpl::list<boost::long_long_type> signed_types; + typedef mpl::list<boost::ulong_long_type> unsigned_types; typedef mpl::list<long double> float_types; typedef ExponentType exponent_type; @@ -165,7 +170,7 @@ private: public: // Constructors - cpp_dec_float() BOOST_NOEXCEPT_IF(noexcept(array_type())) : + cpp_dec_float() BOOST_MP_NOEXCEPT_IF(noexcept(array_type())) : data(), exp (static_cast<ExponentType>(0)), neg (false), @@ -210,7 +215,7 @@ public: from_unsigned_long_long(i); } - cpp_dec_float(const cpp_dec_float& f) BOOST_NOEXCEPT_IF(noexcept(array_type(std::declval<const array_type&>()))) : + cpp_dec_float(const cpp_dec_float& f) BOOST_MP_NOEXCEPT_IF(noexcept(array_type(std::declval<const array_type&>()))) : data (f.data), exp (f.exp), neg (f.neg), @@ -284,21 +289,21 @@ public: static const cpp_dec_float& zero() { init.do_nothing(); - static cpp_dec_float val(static_cast<unsigned long long>(0u)); + static cpp_dec_float val(static_cast<boost::ulong_long_type>(0u)); return val; } static const cpp_dec_float& one() { init.do_nothing(); - static cpp_dec_float val(static_cast<unsigned long long>(1u)); + static cpp_dec_float val(static_cast<boost::ulong_long_type>(1u)); return val; } static const cpp_dec_float& two() { init.do_nothing(); - static cpp_dec_float val(static_cast<unsigned long long>(2u)); + static cpp_dec_float val(static_cast<boost::ulong_long_type>(2u)); return val; } @@ -348,21 +353,21 @@ public: static const cpp_dec_float& long_long_max() { init.do_nothing(); - static cpp_dec_float val((std::numeric_limits<long long>::max)()); + static cpp_dec_float val((std::numeric_limits<boost::long_long_type>::max)()); return val; } static const cpp_dec_float& long_long_min() { init.do_nothing(); - static cpp_dec_float val((std::numeric_limits<long long>::min)()); + static cpp_dec_float val((std::numeric_limits<boost::long_long_type>::min)()); return val; } static const cpp_dec_float& ulong_long_max() { init.do_nothing(); - static cpp_dec_float val((std::numeric_limits<unsigned long long>::max)()); + static cpp_dec_float val((std::numeric_limits<boost::ulong_long_type>::max)()); return val; } @@ -374,7 +379,7 @@ public: } // Basic operations. - cpp_dec_float& operator=(const cpp_dec_float& v) BOOST_NOEXCEPT_IF(noexcept(std::declval<array_type&>() = std::declval<const array_type&>())) + cpp_dec_float& operator=(const cpp_dec_float& v) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<array_type&>() = std::declval<const array_type&>())) { data = v.data; exp = v.exp; @@ -397,7 +402,7 @@ public: return *this; } - cpp_dec_float& operator=(long long v) + cpp_dec_float& operator=(boost::long_long_type v) { if(v < 0) { @@ -409,7 +414,7 @@ public: return *this; } - cpp_dec_float& operator=(unsigned long long v) + cpp_dec_float& operator=(boost::ulong_long_type v) { from_unsigned_long_long(v); return *this; @@ -428,22 +433,22 @@ public: cpp_dec_float& operator*=(const cpp_dec_float& v); cpp_dec_float& operator/=(const cpp_dec_float& v); - cpp_dec_float& add_unsigned_long_long(const unsigned long long n) + cpp_dec_float& add_unsigned_long_long(const boost::ulong_long_type n) { cpp_dec_float t; t.from_unsigned_long_long(n); return *this += t; } - cpp_dec_float& sub_unsigned_long_long(const unsigned long long n) + cpp_dec_float& sub_unsigned_long_long(const boost::ulong_long_type n) { cpp_dec_float t; t.from_unsigned_long_long(n); return *this -= t; } - cpp_dec_float& mul_unsigned_long_long(const unsigned long long n); - cpp_dec_float& div_unsigned_long_long(const unsigned long long n); + cpp_dec_float& mul_unsigned_long_long(const boost::ulong_long_type n); + cpp_dec_float& div_unsigned_long_long(const boost::ulong_long_type n); // Elementary primitives. cpp_dec_float& calculate_inv (); @@ -503,8 +508,8 @@ public: double extract_double() const; long double extract_long_double() const; - signed long long extract_signed_long_long() const; - unsigned long long extract_unsigned_long_long() const; + boost::long_long_type extract_signed_long_long() const; + boost::ulong_long_type extract_unsigned_long_long() const; void extract_parts(double& mantissa, ExponentType& exponent) const; cpp_dec_float extract_integer_part() const; @@ -522,7 +527,7 @@ public: prec_elem = (std::min)(cpp_dec_float_elem_number, (std::max)(elems, static_cast<boost::int32_t>(2))); } } - static cpp_dec_float pow2(long long i); + static cpp_dec_float pow2(boost::long_long_type i); ExponentType order()const { const bool bo_order_is_zero = ((!(isfinite)()) || (data[0] == static_cast<boost::uint32_t>(0u))); @@ -590,7 +595,7 @@ private: static bool data_elem_is_non_nine_predicate(const boost::uint32_t& d) { return (d != static_cast<boost::uint32_t>(cpp_dec_float::cpp_dec_float_elem_mask - 1)); } static bool char_is_nonzero_predicate(const char& c) { return (c != static_cast<char>('0')); } - void from_unsigned_long_long(const unsigned long long u); + void from_unsigned_long_long(const boost::ulong_long_type u); int cmp_data(const array_type& vd) const; @@ -970,9 +975,9 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone } template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::mul_unsigned_long_long(const unsigned long long n) +cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::mul_unsigned_long_long(const boost::ulong_long_type n) { - // Multiply *this with a constant unsigned long long. + // Multiply *this with a constant boost::ulong_long_type. // Evaluate the sign of the result. const bool b_neg = neg; @@ -1003,7 +1008,7 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone return *this = zero(); } - if(n >= static_cast<unsigned long long>(cpp_dec_float_elem_mask)) + if(n >= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask)) { neg = b_neg; cpp_dec_float t; @@ -1011,7 +1016,7 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone return operator*=(t); } - if(n == static_cast<unsigned long long>(1u)) + if(n == static_cast<boost::ulong_long_type>(1u)) { neg = b_neg; return *this; @@ -1050,9 +1055,9 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone } template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::div_unsigned_long_long(const unsigned long long n) +cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::div_unsigned_long_long(const boost::ulong_long_type n) { - // Divide *this by a constant unsigned long long. + // Divide *this by a constant boost::ulong_long_type. // Evaluate the sign of the result. const bool b_neg = neg; @@ -1074,7 +1079,7 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone return *this; } - if(n == static_cast<unsigned long long>(0u)) + if(n == static_cast<boost::ulong_long_type>(0u)) { // Divide by 0. if(iszero()) @@ -1096,7 +1101,7 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone return *this; } - if(n >= static_cast<unsigned long long>(cpp_dec_float_elem_mask)) + if(n >= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask)) { neg = b_neg; cpp_dec_float t; @@ -1584,58 +1589,58 @@ long double cpp_dec_float<Digits10, ExponentType, Allocator>::extract_long_doubl } template <unsigned Digits10, class ExponentType, class Allocator> -signed long long cpp_dec_float<Digits10, ExponentType, Allocator>::extract_signed_long_long() const +boost::long_long_type cpp_dec_float<Digits10, ExponentType, Allocator>::extract_signed_long_long() const { // Extracts a signed long long from *this. - // If (x > maximum of signed long long) or (x < minimum of signed long long), - // then the maximum or minimum of signed long long is returned accordingly. + // If (x > maximum of long long) or (x < minimum of long long), + // then the maximum or minimum of long long is returned accordingly. if(exp < static_cast<ExponentType>(0)) { - return static_cast<signed long long>(0); + return static_cast<boost::long_long_type>(0); } const bool b_neg = isneg(); - unsigned long long val; + boost::ulong_long_type val; if((!b_neg) && (compare(long_long_max()) > 0)) { - return (std::numeric_limits<signed long long>::max)(); + return (std::numeric_limits<boost::long_long_type>::max)(); } else if(b_neg && (compare(long_long_min()) < 0)) { - return (std::numeric_limits<signed long long>::min)(); + return (std::numeric_limits<boost::long_long_type>::min)(); } else { - // Extract the data into an unsigned long long value. + // Extract the data into an boost::ulong_long_type value. cpp_dec_float<Digits10, ExponentType, Allocator> xn(extract_integer_part()); if(xn.isneg()) xn.negate(); - val = static_cast<unsigned long long>(xn.data[0]); + val = static_cast<boost::ulong_long_type>(xn.data[0]); const boost::int32_t imax = (std::min)(static_cast<boost::int32_t>(static_cast<boost::int32_t>(xn.exp) / cpp_dec_float_elem_digits10), static_cast<boost::int32_t>(cpp_dec_float_elem_number - static_cast<boost::int32_t>(1))); for(boost::int32_t i = static_cast<boost::int32_t>(1); i <= imax; i++) { - val *= static_cast<unsigned long long>(cpp_dec_float_elem_mask); - val += static_cast<unsigned long long>(xn.data[i]); + val *= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask); + val += static_cast<boost::ulong_long_type>(xn.data[i]); } } if (!b_neg) { - return static_cast<signed long long>(val); + return static_cast<boost::long_long_type>(val); } else { // This strange expression avoids a hardware trap in the corner case - // that val is the most negative value permitted in long long. + // that val is the most negative value permitted in boost::long_long_type. // See https://svn.boost.org/trac/boost/ticket/9740. // - signed long long sval = static_cast<signed long long>(val - 1); + boost::long_long_type sval = static_cast<boost::long_long_type>(val - 1); sval = -sval; --sval; return sval; @@ -1643,43 +1648,43 @@ signed long long cpp_dec_float<Digits10, ExponentType, Allocator>::extract_signe } template <unsigned Digits10, class ExponentType, class Allocator> -unsigned long long cpp_dec_float<Digits10, ExponentType, Allocator>::extract_unsigned_long_long() const +boost::ulong_long_type cpp_dec_float<Digits10, ExponentType, Allocator>::extract_unsigned_long_long() const { - // Extracts an unsigned long long from *this. - // If x exceeds the maximum of unsigned long long, - // then the maximum of unsigned long long is returned. - // If x is negative, then the unsigned long long cast of - // the signed long long extracted value is returned. + // Extracts an boost::ulong_long_type from *this. + // If x exceeds the maximum of boost::ulong_long_type, + // then the maximum of boost::ulong_long_type is returned. + // If x is negative, then the boost::ulong_long_type cast of + // the long long extracted value is returned. if(isneg()) { - return static_cast<unsigned long long>(extract_signed_long_long()); + return static_cast<boost::ulong_long_type>(extract_signed_long_long()); } if(exp < static_cast<ExponentType>(0)) { - return static_cast<unsigned long long>(0u); + return static_cast<boost::ulong_long_type>(0u); } const cpp_dec_float<Digits10, ExponentType, Allocator> xn(extract_integer_part()); - unsigned long long val; + boost::ulong_long_type val; if(xn.compare(ulong_long_max()) > 0) { - return (std::numeric_limits<unsigned long long>::max)(); + return (std::numeric_limits<boost::ulong_long_type>::max)(); } else { - // Extract the data into an unsigned long long value. - val = static_cast<unsigned long long>(xn.data[0]); + // Extract the data into an boost::ulong_long_type value. + val = static_cast<boost::ulong_long_type>(xn.data[0]); const boost::int32_t imax = (std::min)(static_cast<boost::int32_t>(static_cast<boost::int32_t>(xn.exp) / cpp_dec_float_elem_digits10), static_cast<boost::int32_t>(cpp_dec_float_elem_number - static_cast<boost::int32_t>(1))); for(boost::int32_t i = static_cast<boost::int32_t>(1); i <= imax; i++) { - val *= static_cast<unsigned long long>(cpp_dec_float_elem_mask); - val += static_cast<unsigned long long>(xn.data[i]); + val *= static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask); + val += static_cast<boost::ulong_long_type>(xn.data[i]); } } @@ -2209,8 +2214,8 @@ cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float(const double man template <unsigned Digits10, class ExponentType, class Allocator> cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator= (long double a) { - // Christopher Kormanyos's original code used a cast to long long here, but that fails - // when long double has more digits than a long long. + // Christopher Kormanyos's original code used a cast to boost::long_long_type here, but that fails + // when long double has more digits than a boost::long_long_type. using std::frexp; using std::ldexp; using std::floor; @@ -2259,7 +2264,7 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone } template <unsigned Digits10, class ExponentType, class Allocator> -void cpp_dec_float<Digits10, ExponentType, Allocator>::from_unsigned_long_long(const unsigned long long u) +void cpp_dec_float<Digits10, ExponentType, Allocator>::from_unsigned_long_long(const boost::ulong_long_type u) { std::fill(data.begin(), data.end(), static_cast<boost::uint32_t>(0u)); @@ -2270,14 +2275,14 @@ void cpp_dec_float<Digits10, ExponentType, Allocator>::from_unsigned_long_long(c std::size_t i =static_cast<std::size_t>(0u); - unsigned long long uu = u; + boost::ulong_long_type uu = u; - boost::uint32_t temp[(std::numeric_limits<unsigned long long>::digits10 / static_cast<int>(cpp_dec_float_elem_digits10)) + 3] = { static_cast<boost::uint32_t>(0u) }; + boost::uint32_t temp[(std::numeric_limits<boost::ulong_long_type>::digits10 / static_cast<int>(cpp_dec_float_elem_digits10)) + 3] = { static_cast<boost::uint32_t>(0u) }; - while(uu != static_cast<unsigned long long>(0u)) + while(uu != static_cast<boost::ulong_long_type>(0u)) { - temp[i] = static_cast<boost::uint32_t>(uu % static_cast<unsigned long long>(cpp_dec_float_elem_mask)); - uu = static_cast<unsigned long long>(uu / static_cast<unsigned long long>(cpp_dec_float_elem_mask)); + temp[i] = static_cast<boost::uint32_t>(uu % static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask)); + uu = static_cast<boost::ulong_long_type>(uu / static_cast<boost::ulong_long_type>(cpp_dec_float_elem_mask)); ++i; } @@ -2351,7 +2356,7 @@ boost::uint32_t cpp_dec_float<Digits10, ExponentType, Allocator>::div_loop_n(boo } template <unsigned Digits10, class ExponentType, class Allocator> -cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(const long long p) +cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(const boost::long_long_type p) { // Create a static const table of p^2 for -128 < p < +128. // Note: The size of this table must be odd-numbered and @@ -2488,24 +2493,24 @@ cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, Exponen cpp_dec_float("0.5"), one(), two(), - cpp_dec_float(static_cast<unsigned long long>(4)), - cpp_dec_float(static_cast<unsigned long long>(8)), - cpp_dec_float(static_cast<unsigned long long>(16)), - cpp_dec_float(static_cast<unsigned long long>(32)), - cpp_dec_float(static_cast<unsigned long long>(64)), - cpp_dec_float(static_cast<unsigned long long>(128)), - cpp_dec_float(static_cast<unsigned long long>(256)), - cpp_dec_float(static_cast<unsigned long long>(512)), - cpp_dec_float(static_cast<unsigned long long>(1024)), - cpp_dec_float(static_cast<unsigned long long>(2048)), - cpp_dec_float(static_cast<unsigned long long>(4096)), - cpp_dec_float(static_cast<unsigned long long>(8192)), - cpp_dec_float(static_cast<unsigned long long>(16384)), - cpp_dec_float(static_cast<unsigned long long>(32768)), - cpp_dec_float(static_cast<unsigned long long>(65536)), - cpp_dec_float(static_cast<unsigned long long>(131072)), - cpp_dec_float(static_cast<unsigned long long>(262144)), - cpp_dec_float(static_cast<unsigned long long>(524288)), + cpp_dec_float(static_cast<boost::ulong_long_type>(4)), + cpp_dec_float(static_cast<boost::ulong_long_type>(8)), + cpp_dec_float(static_cast<boost::ulong_long_type>(16)), + cpp_dec_float(static_cast<boost::ulong_long_type>(32)), + cpp_dec_float(static_cast<boost::ulong_long_type>(64)), + cpp_dec_float(static_cast<boost::ulong_long_type>(128)), + cpp_dec_float(static_cast<boost::ulong_long_type>(256)), + cpp_dec_float(static_cast<boost::ulong_long_type>(512)), + cpp_dec_float(static_cast<boost::ulong_long_type>(1024)), + cpp_dec_float(static_cast<boost::ulong_long_type>(2048)), + cpp_dec_float(static_cast<boost::ulong_long_type>(4096)), + cpp_dec_float(static_cast<boost::ulong_long_type>(8192)), + cpp_dec_float(static_cast<boost::ulong_long_type>(16384)), + cpp_dec_float(static_cast<boost::ulong_long_type>(32768)), + cpp_dec_float(static_cast<boost::ulong_long_type>(65536)), + cpp_dec_float(static_cast<boost::ulong_long_type>(131072)), + cpp_dec_float(static_cast<boost::ulong_long_type>(262144)), + cpp_dec_float(static_cast<boost::ulong_long_type>(524288)), cpp_dec_float(static_cast<boost::uint64_t>(1uL << 20u)), cpp_dec_float(static_cast<boost::uint64_t>(1uL << 21u)), cpp_dec_float(static_cast<boost::uint64_t>(1uL << 22u)), @@ -2616,16 +2621,16 @@ cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, Exponen cpp_dec_float("1.701411834604692317316873037158841057280000000000000000000000000000000000000000000000000000000000000e38") }}; - if((p > static_cast<long long>(-128)) && (p < static_cast<long long>(+128))) + if((p > static_cast<boost::long_long_type>(-128)) && (p < static_cast<boost::long_long_type>(+128))) { return p2_data[static_cast<std::size_t>(p + ((p2_data.size() - 1u) / 2u))]; } else { // Compute and return 2^p. - if(p < static_cast<long long>(0)) + if(p < static_cast<boost::long_long_type>(0)) { - return pow2(static_cast<long long>(-p)).calculate_inv(); + return pow2(static_cast<boost::long_long_type>(-p)).calculate_inv(); } else { @@ -2659,28 +2664,28 @@ inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result } template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const unsigned long long& o) +inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o) { result.add_unsigned_long_long(o); } template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const unsigned long long& o) +inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o) { result.sub_unsigned_long_long(o); } template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const unsigned long long& o) +inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o) { result.mul_unsigned_long_long(o); } template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const unsigned long long& o) +inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const boost::ulong_long_type& o) { result.div_unsigned_long_long(o); } template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, long long o) +inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o) { if(o < 0) result.sub_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o)); @@ -2688,7 +2693,7 @@ inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, l result.add_unsigned_long_long(o); } template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, long long o) +inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o) { if(o < 0) result.add_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o)); @@ -2696,7 +2701,7 @@ inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& resu result.sub_unsigned_long_long(o); } template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, long long o) +inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o) { if(o < 0) { @@ -2707,7 +2712,7 @@ inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& resu result.mul_unsigned_long_long(o); } template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, long long o) +inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, boost::long_long_type o) { if(o < 0) { @@ -2719,12 +2724,12 @@ inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result } template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_convert_to(unsigned long long* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val) +inline void eval_convert_to(boost::ulong_long_type* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val) { *result = val.extract_unsigned_long_long(); } template <unsigned Digits10, class ExponentType, class Allocator> -inline void eval_convert_to(long long* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val) +inline void eval_convert_to(boost::long_long_type* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val) { *result = val.extract_signed_long_long(); } @@ -2834,18 +2839,18 @@ inline void eval_scalbn(cpp_dec_float<Digits10, ExponentType, Allocator>& result template <unsigned Digits10, class ExponentType, class Allocator, class ArgType> inline void eval_ldexp(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x, ArgType e) { - const long long the_exp = static_cast<long long>(e); + const boost::long_long_type the_exp = static_cast<boost::long_long_type>(e); if((the_exp > (std::numeric_limits<ExponentType>::max)()) || (the_exp < (std::numeric_limits<ExponentType>::min)())) BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Exponent value is out of range."))); result = x; - if ((the_exp > static_cast<long long>(-std::numeric_limits<long long>::digits)) && (the_exp < static_cast<long long>(0))) - result.div_unsigned_long_long(1ULL << static_cast<long long>(-the_exp)); - else if((the_exp < static_cast<long long>( std::numeric_limits<long long>::digits)) && (the_exp > static_cast<long long>(0))) + if ((the_exp > static_cast<boost::long_long_type>(-std::numeric_limits<boost::long_long_type>::digits)) && (the_exp < static_cast<boost::long_long_type>(0))) + result.div_unsigned_long_long(1ULL << static_cast<boost::long_long_type>(-the_exp)); + else if((the_exp < static_cast<boost::long_long_type>( std::numeric_limits<boost::long_long_type>::digits)) && (the_exp > static_cast<boost::long_long_type>(0))) result.mul_unsigned_long_long(1ULL << the_exp); - else if(the_exp != static_cast<long long>(0)) + else if(the_exp != static_cast<boost::long_long_type>(0)) result *= cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(e); } @@ -3078,4 +3083,8 @@ struct precision< boost::multiprecision::number<boost::multiprecision::cpp_dec_f }} // namespaces boost::math +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + #endif diff --git a/boost/multiprecision/cpp_int.hpp b/boost/multiprecision/cpp_int.hpp index 311f7c16da..d451567bb9 100644 --- a/boost/multiprecision/cpp_int.hpp +++ b/boost/multiprecision/cpp_int.hpp @@ -35,7 +35,7 @@ namespace backends{ #ifdef BOOST_MSVC // warning C4127: conditional expression is constant #pragma warning(push) -#pragma warning(disable:4127 4351 4293 4996 4307 4702) +#pragma warning(disable:4127 4351 4293 4996 4307 4702 6285) #endif template <unsigned MinBits = 0, unsigned MaxBits = 0, cpp_integer_type SignType = signed_magnitude, cpp_int_check_type Checked = unchecked, class Allocator = typename mpl::if_c<MinBits && (MinBits == MaxBits), void, std::allocator<limb_type> >::type > @@ -181,8 +181,8 @@ public: BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = 1u << (limb_bits - 1)); BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits - ? MinBits / limb_bits + (MinBits % limb_bits ? 1 : 0) - : sizeof(limb_data) / sizeof(limb_type)); + ? (MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0)) + : (sizeof(limb_data) / sizeof(limb_type))); BOOST_STATIC_CONSTANT(bool, variable = true); private: @@ -243,7 +243,7 @@ public: } void resize(unsigned new_size, unsigned min_size) { - static const unsigned max_limbs = MaxBits / (CHAR_BIT * sizeof(limb_type)) + (MaxBits % (CHAR_BIT * sizeof(limb_type)) ? 1 : 0); + static const unsigned max_limbs = MaxBits / (CHAR_BIT * sizeof(limb_type)) + ((MaxBits % (CHAR_BIT * sizeof(limb_type))) ? 1 : 0); // We never resize beyond MaxSize: if(new_size > max_limbs) new_size = max_limbs; @@ -402,9 +402,9 @@ public: BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(limb_type) * CHAR_BIT); BOOST_STATIC_CONSTANT(limb_type, max_limb_value = ~static_cast<limb_type>(0u)); BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = 1u << (limb_bits - 1)); - BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + (MinBits % limb_bits ? 1 : 0)); + BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0)); BOOST_STATIC_CONSTANT(bool, variable = false); - BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = MinBits % limb_bits ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0))); + BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = (MinBits % limb_bits) ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0))); BOOST_STATIC_ASSERT_MSG(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs"); private: @@ -466,12 +466,12 @@ public: m_sign = false; } } - BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { m_limbs = static_cast<boost::uint16_t>((std::min)(new_size, internal_limb_count)); detail::verify_new_size(m_limbs, min_size, checked_type()); } - BOOST_MP_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { limb_pointer p = limbs(); detail::verify_limb_mask(m_limbs == internal_limb_count, p[internal_limb_count-1], upper_limb_mask, checked_type()); @@ -554,9 +554,9 @@ public: BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(limb_type) * CHAR_BIT); BOOST_STATIC_CONSTANT(limb_type, max_limb_value = ~static_cast<limb_type>(0u)); BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = 1u << (limb_bits - 1)); - BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + (MinBits % limb_bits ? 1 : 0)); + BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0)); BOOST_STATIC_CONSTANT(bool, variable = false); - BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = MinBits % limb_bits ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0))); + BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = (MinBits % limb_bits) ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0))); BOOST_STATIC_ASSERT_MSG(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs"); private: @@ -581,12 +581,12 @@ public: // BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT : m_wrapper(i), m_limbs(1) {} - BOOST_MP_FORCEINLINE cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE cpp_int_base(signed_limb_type i)BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) : m_wrapper(limb_type(i < 0 ? static_cast<limb_type>(-static_cast<signed_double_limb_type>(i)) : i)), m_limbs(1) { if(i < 0) negate(); } #ifdef BOOST_LITTLE_ENDIAN BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT : m_wrapper(i), m_limbs(i > max_limb_value ? 2 : 1) {} - BOOST_MP_FORCEINLINE cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE cpp_int_base(signed_double_limb_type i)BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) : m_wrapper(double_limb_type(i < 0 ? static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) : i)), m_limbs(i < 0 ? (static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i)) > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)) { @@ -607,13 +607,13 @@ public: BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return m_wrapper.m_data; } BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return m_wrapper.m_data; } BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return false; } - BOOST_MP_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT_IF((Checked == unchecked)) { if(b) negate(); } - BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void sign(bool b) BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { if(b) negate(); } + BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { m_limbs = (std::min)(new_size, internal_limb_count); detail::verify_new_size(m_limbs, min_size, checked_type()); } - BOOST_MP_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { limb_pointer p = limbs(); detail::verify_limb_mask(m_limbs == internal_limb_count, p[internal_limb_count-1], upper_limb_mask, checked_type()); @@ -643,7 +643,7 @@ private: } void check_negate(const mpl::int_<unchecked>&){} public: - void negate() BOOST_NOEXCEPT_IF((Checked == unchecked)) + void negate() BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { // Not so much a negate as a complement - this gets called when subtraction // would result in a "negative" number: @@ -689,7 +689,7 @@ const bool cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, fal #endif // // Traits classes to figure out a native type with N bits, these vary from boost::uint_t<N> only -// because some platforms have native integer types longer than long long, "really long long" anyone?? +// because some platforms have native integer types longer than boost::long_long_type, "really boost::long_long_type" anyone?? // template <unsigned N, bool s> struct trivial_limb_type_imp @@ -704,7 +704,7 @@ struct trivial_limb_type_imp<N, true> }; template <unsigned N> -struct trivial_limb_type : public trivial_limb_type_imp<N, N <= sizeof(long long) * CHAR_BIT> {}; +struct trivial_limb_type : public trivial_limb_type_imp<N, N <= sizeof(boost::long_long_type) * CHAR_BIT> {}; // // Backend for fixed precision signed-magnitude type which will fit entirely inside a "double_limb_type": // @@ -750,7 +750,7 @@ protected: void check_in_range(T, const mpl::int_<C>&) BOOST_NOEXCEPT {} template <class T> - void check_in_range(T val) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type()))) + void check_in_range(T val) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type()))) { check_in_range(val, checked_type()); } @@ -760,17 +760,17 @@ public: // Direct construction: // template <class SI> - BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>()))) + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == unchecked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>()))) : m_data(i < 0 ? static_cast<local_limb_type>(static_cast<typename make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask) : static_cast<local_limb_type>(i)& limb_mask), m_sign(i < 0) {} template <class SI> - BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == checked) >::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>()))) + BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>()))) : m_data(i < 0 ? (static_cast<local_limb_type>(static_cast<typename make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask)) : static_cast<local_limb_type>(i)& limb_mask), m_sign(i < 0) { check_in_range(i); } template <class UI> BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == unchecked)>::type const* = 0) BOOST_NOEXCEPT : m_data(static_cast<local_limb_type>(i) & limb_mask), m_sign(false) {} template <class UI> - BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == checked)>::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>()))) + BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == checked)>::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>()))) : m_data(static_cast<local_limb_type>(i) & limb_mask), m_sign(false) { check_in_range(i); } template <class F> BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(F i, typename boost::enable_if_c<is_floating_point<F>::value && (Checked == unchecked)>::type const* = 0) BOOST_NOEXCEPT @@ -810,7 +810,7 @@ public: { detail::verify_new_size(2, min_size, checked_type()); } - BOOST_MP_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { if(!m_data) m_sign = false; // zero is always unsigned @@ -893,7 +893,7 @@ protected: BOOST_MP_FORCEINLINE void check_in_range(T, const mpl::int_<C>&, const boost::integral_constant<bool, B>&) BOOST_NOEXCEPT {} template <class T> - BOOST_MP_FORCEINLINE void check_in_range(T val) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type(), is_signed<T>()))) + BOOST_MP_FORCEINLINE void check_in_range(T val) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type(), is_signed<T>()))) { check_in_range(val, checked_type(), is_signed<T>()); } @@ -906,16 +906,16 @@ public: BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT : m_data(i < 0 ? (1 + ~static_cast<local_limb_type>(-i)) & limb_mask : static_cast<local_limb_type>(i) & limb_mask) {} template <class SI> - BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == checked) >::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>()))) + BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>()))) : m_data(i < 0 ? 1 + ~static_cast<local_limb_type>(-i) : static_cast<local_limb_type>(i)) { check_in_range(i); } template <class UI> BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT : m_data(static_cast<local_limb_type>(i) & limb_mask) {} template <class UI> - BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == checked) >::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>()))) + BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>()))) : m_data(static_cast<local_limb_type>(i)) { check_in_range(i); } template <class F> - BOOST_MP_FORCEINLINE cpp_int_base(F i, typename boost::enable_if<is_floating_point<F> >::type const* = 0) BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE cpp_int_base(F i, typename boost::enable_if<is_floating_point<F> >::type const* = 0) BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) : m_data(static_cast<local_limb_type>(std::fabs(i)) & limb_mask) { check_in_range(i); @@ -939,7 +939,7 @@ public: BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return &m_data; } BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return &m_data; } BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return false; } - BOOST_MP_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void sign(bool b) BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { if(b) negate(); @@ -948,7 +948,7 @@ public: { detail::verify_new_size(2, min_size, checked_type()); } - BOOST_MP_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { detail::verify_limb_mask(true, m_data, limb_mask, checked_type()); m_data &= limb_mask; @@ -962,7 +962,7 @@ public: { m_data = o.m_data; } - BOOST_MP_FORCEINLINE void negate() BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void negate() BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { if(Checked == checked) { @@ -1025,13 +1025,13 @@ public: trivial_tag, mpl::list< signed char, short, int, long, - long long, signed_double_limb_type>, + boost::long_long_type, signed_double_limb_type>, mpl::list<signed_limb_type, signed_double_limb_type> >::type signed_types; typedef typename mpl::if_< trivial_tag, mpl::list<unsigned char, unsigned short, unsigned, - unsigned long, unsigned long long, double_limb_type>, + unsigned long, boost::ulong_long_type, double_limb_type>, mpl::list<limb_type, double_limb_type> >::type unsigned_types; typedef typename mpl::if_< @@ -1042,7 +1042,7 @@ public: typedef mpl::int_<Checked> checked_type; BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend() BOOST_NOEXCEPT{} - BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(const cpp_int_backend& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value) : base_type(o) {} + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF(boost::is_void<Allocator>::value) : base_type(o) {} #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(cpp_int_backend&& o) BOOST_NOEXCEPT : base_type(static_cast<base_type&&>(o)) {} @@ -1051,7 +1051,7 @@ public: // Direct construction from arithmetic type: // template <class Arg> - BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(Arg i, typename boost::enable_if_c<is_allowed_cpp_int_base_conversion<Arg, base_type>::value >::type const* = 0)BOOST_NOEXCEPT_IF(noexcept(base_type(std::declval<Arg>()))) + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(Arg i, typename boost::enable_if_c<is_allowed_cpp_int_base_conversion<Arg, base_type>::value >::type const* = 0)BOOST_MP_NOEXCEPT_IF(noexcept(base_type(std::declval<Arg>()))) : base_type(i) {} private: @@ -1140,13 +1140,13 @@ public: : base_type(static_cast<const base_type&>(a), tag){} #endif - BOOST_MP_FORCEINLINE cpp_int_backend& operator = (const cpp_int_backend& o) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().assign(std::declval<const cpp_int_backend&>()))) + BOOST_MP_FORCEINLINE cpp_int_backend& operator = (const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().assign(std::declval<const cpp_int_backend&>()))) { this->assign(o); return *this; } #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - BOOST_MP_FORCEINLINE cpp_int_backend& operator = (cpp_int_backend&& o) BOOST_NOEXCEPT_IF(noexcept(std::declval<base_type&>() = std::declval<base_type>())) + BOOST_MP_FORCEINLINE cpp_int_backend& operator = (cpp_int_backend&& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<base_type&>() = std::declval<base_type>())) { *static_cast<base_type*>(this) = static_cast<base_type&&>(o); return *this; @@ -1155,7 +1155,7 @@ public: private: template <class A> typename boost::enable_if<is_unsigned<A> >::type do_assign_arithmetic(A val, const mpl::true_&) - BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>()))) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>()))) { this->check_in_range(val); *this->limbs() = static_cast<typename self_type::local_limb_type>(val); @@ -1163,7 +1163,7 @@ private: } template <class A> typename boost::disable_if_c<is_unsigned<A>::value || !is_integral<A>::value >::type do_assign_arithmetic(A val, const mpl::true_&) - BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>())) && noexcept(std::declval<cpp_int_backend>().sign(true))) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().check_in_range(std::declval<A>())) && noexcept(std::declval<cpp_int_backend>().sign(true))) { this->check_in_range(val); *this->limbs() = (val < 0) ? static_cast<typename self_type::local_limb_type>(boost::multiprecision::detail::unsigned_abs(val)) : static_cast<typename self_type::local_limb_type>(val); @@ -1184,7 +1184,7 @@ private: *this->limbs() = i; this->sign(false); } - BOOST_MP_FORCEINLINE void do_assign_arithmetic(signed_limb_type i, const mpl::false_&) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().sign(true))) + BOOST_MP_FORCEINLINE void do_assign_arithmetic(signed_limb_type i, const mpl::false_&) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().sign(true))) { this->resize(1, 1); *this->limbs() = static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(i)); @@ -1200,7 +1200,7 @@ private: this->resize(p[1] ? 2 : 1, p[1] ? 2 : 1); this->sign(false); } - void do_assign_arithmetic(signed_double_limb_type i, const mpl::false_&) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().sign(true))) + void do_assign_arithmetic(signed_double_limb_type i, const mpl::false_&) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().sign(true))) { BOOST_STATIC_ASSERT(sizeof(i) == 2 * sizeof(limb_type)); BOOST_STATIC_ASSERT(base_type::internal_limb_count >= 2); @@ -1224,6 +1224,13 @@ private: using std::ldexp; using std::floor; + if(a < 0) + { + do_assign_arithmetic(-a, mpl::false_()); + this->sign(true); + return; + } + if (a == 0) { *this = static_cast<limb_type>(0u); } @@ -1263,7 +1270,7 @@ private: } public: template <class Arithmetic> - BOOST_MP_FORCEINLINE cpp_int_backend& operator = (Arithmetic val) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().do_assign_arithmetic(std::declval<Arithmetic>(), trivial_tag()))) + BOOST_MP_FORCEINLINE cpp_int_backend& operator = (Arithmetic val) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_backend>().do_assign_arithmetic(std::declval<Arithmetic>(), trivial_tag()))) { do_assign_arithmetic(val, trivial_tag()); return *this; @@ -1548,7 +1555,7 @@ private: limb_type shift = base == 8 ? 3 : 4; limb_type mask = static_cast<limb_type>((1u << shift) - 1); cpp_int_backend t(*this); - result.assign(Bits / shift + (Bits % shift ? 1 : 0), '0'); + result.assign(Bits / shift + ((Bits % shift) ? 1 : 0), '0'); std::string::difference_type pos = result.size() - 1; for(unsigned i = 0; i < Bits / shift; ++i) { diff --git a/boost/multiprecision/cpp_int/add.hpp b/boost/multiprecision/cpp_int/add.hpp index f9c9b85ebb..372998d672 100644 --- a/boost/multiprecision/cpp_int/add.hpp +++ b/boost/multiprecision/cpp_int/add.hpp @@ -14,7 +14,7 @@ namespace boost{ namespace multiprecision{ namespace backends{ // This is the key addition routine where all the argument types are non-trivial cpp_int's: // template <class CppInt1, class CppInt2, class CppInt3> -inline void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BOOST_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value) +inline void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value) { using std::swap; @@ -81,7 +81,7 @@ inline void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BO // As above, but for adding a single limb to a non-trivial cpp_int: // template <class CppInt1, class CppInt2> -inline void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o) BOOST_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value) +inline void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value) { // Addition using modular arithmetic. // Nothing fancy, just let uintmax_t take the strain: @@ -119,7 +119,7 @@ inline void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o) // Core subtraction routine for all non-trivial cpp_int's: // template <class CppInt1, class CppInt2, class CppInt3> -inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BOOST_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value) +inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value) { using std::swap; @@ -203,7 +203,7 @@ inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& // And again to subtract a single limb: // template <class CppInt1, class CppInt2> -inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const limb_type& b) BOOST_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value) +inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const limb_type& b) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value) { // Subtract one limb. // Nothing fancy, just let uintmax_t take the strain: @@ -264,7 +264,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type eval_add( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { eval_add(result, result, o); } @@ -273,7 +273,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit eval_add( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(a.sign() != b.sign()) { @@ -284,7 +284,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit } template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type - eval_add(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + eval_add(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(result.sign()) { @@ -298,7 +298,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi eval_add( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(a.sign()) { @@ -311,7 +311,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type eval_add( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const signed_limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(o < 0) eval_subtract(result, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o))); @@ -323,7 +323,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi eval_add( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const signed_limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(o < 0) eval_subtract(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o))); @@ -336,7 +336,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type eval_subtract( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(result.sign()) { @@ -350,7 +350,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi eval_subtract( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(a.sign()) { @@ -365,7 +365,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type eval_subtract( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const signed_limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(o) { @@ -380,7 +380,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi eval_subtract( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const signed_limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(o) { @@ -395,7 +395,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type - eval_increment(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + eval_increment(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { static const limb_type one = 1; if(!result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value)) @@ -407,7 +407,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi } template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type - eval_decrement(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + eval_decrement(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { static const limb_type one = 1; if(!result.sign() && result.limbs()[0]) @@ -421,7 +421,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type eval_subtract( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { eval_subtract(result, result, o); } @@ -430,7 +430,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi eval_subtract( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(a.sign() != b.sign()) { @@ -453,7 +453,7 @@ inline typename enable_if_c< >::type eval_add( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(result.sign() != o.sign()) { @@ -478,7 +478,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c< && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value >::type eval_add(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); result.normalize(); @@ -493,7 +493,7 @@ inline typename enable_if_c< >::type eval_subtract( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(result.sign() != o.sign()) { @@ -518,7 +518,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c< >::type eval_subtract( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); result.normalize(); diff --git a/boost/multiprecision/cpp_int/bitwise.hpp b/boost/multiprecision/cpp_int/bitwise.hpp index 98277d69fe..a39e2590cb 100644 --- a/boost/multiprecision/cpp_int/bitwise.hpp +++ b/boost/multiprecision/cpp_int/bitwise.hpp @@ -24,11 +24,27 @@ void is_valid_bitwise_op( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& , const mpl::int_<unchecked>&){} +template <unsigned MinBits1, unsigned MaxBits1, cpp_int_check_type Checked1, class Allocator1> +void is_valid_bitwise_op( + const cpp_int_backend<MinBits1, MaxBits1, signed_magnitude, Checked1, Allocator1>& result, const mpl::int_<checked>&) +{ + if(result.sign()) + BOOST_THROW_EXCEPTION(std::range_error("Bitwise operations on negative values results in undefined behavior.")); +} + +template <unsigned MinBits1, unsigned MaxBits1, cpp_int_check_type Checked1, class Allocator1> +void is_valid_bitwise_op( + const cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1>&, const mpl::int_<checked>&){} + +template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> +void is_valid_bitwise_op( + cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&, const mpl::int_<unchecked>&){} + template <class CppInt1, class CppInt2, class Op> void bitwise_op( CppInt1& result, const CppInt2& o, - Op op, const mpl::true_&) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<CppInt1>::value)) + Op op, const mpl::true_&) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<CppInt1>::value)) { // // There are 4 cases: @@ -143,7 +159,6 @@ void bitwise_op( // if(static_cast<signed_limb_type>(next_limb) < 0) { - result.sign(true); double_limb_type carry = 1; for(unsigned i = 0; i < x; ++i) { @@ -151,6 +166,13 @@ void bitwise_op( pr[i] = static_cast<limb_type>(carry); carry >>= CppInt1::limb_bits; } + if(carry) + { + result.resize(x + 1, x); + if(result.size() > x) + result.limbs()[x] = static_cast<limb_type>(carry); + } + result.sign(true); } else result.sign(false); @@ -162,7 +184,7 @@ template <class CppInt1, class CppInt2, class Op> void bitwise_op( CppInt1& result, const CppInt2& o, - Op op, const mpl::false_&) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<CppInt1>::value)) + Op op, const mpl::false_&) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<CppInt1>::value)) { // // Both arguments are unsigned types, very simple case handled as a special case. @@ -195,7 +217,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type eval_bitwise_and( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { bitwise_op(result, o, bit_and(), mpl::bool_<std::numeric_limits<number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::is_signed || std::numeric_limits<number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> > >::is_signed>()); @@ -205,7 +227,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type eval_bitwise_or( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { bitwise_op(result, o, bit_or(), mpl::bool_<std::numeric_limits<number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::is_signed || std::numeric_limits<number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> > >::is_signed>()); @@ -215,7 +237,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type eval_bitwise_xor( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { bitwise_op(result, o, bit_xor(), mpl::bool_<std::numeric_limits<number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::is_signed || std::numeric_limits<number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> > >::is_signed>()); @@ -255,7 +277,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_ BOOST_MP_FORCEINLINE typename enable_if_c<is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type eval_complement( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { BOOST_STATIC_ASSERT_MSG(((Checked1 != checked) || (Checked2 != checked)), "Attempt to take the complement of a signed type results in undefined behavior."); // Increment and negate: @@ -268,7 +290,7 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_ BOOST_MP_FORCEINLINE typename enable_if_c<is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value >::type eval_complement( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { unsigned os = o.size(); result.resize(UINT_MAX, os); @@ -283,8 +305,9 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type eval_left_shift( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - double_limb_type s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + double_limb_type s) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { + is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); if(!s) return; @@ -359,18 +382,26 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type eval_right_shift( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - double_limb_type s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + double_limb_type s) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { + is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); if(!s) return; + bool is_neg = result.sign(); + if(is_neg) + eval_increment(result); + limb_type offset = static_cast<limb_type>(s / cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits); limb_type shift = static_cast<limb_type>(s % cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits); unsigned ors = result.size(); unsigned rs = ors; if(offset >= rs) { - result = limb_type(0); + if(is_neg) + result = signed_limb_type(-1); + else + result = limb_type(0); return; } rs -= offset; @@ -379,7 +410,10 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit --rs; if(rs == 0) { - result = limb_type(0); + if(is_neg) + result = signed_limb_type(-1); + else + result = limb_type(0); return; } unsigned i = 0; @@ -399,6 +433,8 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit pr[i] = pr[i + offset]; } result.resize(rs, rs); + if(is_neg) + eval_decrement(result); } // @@ -406,17 +442,19 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit // template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class T> BOOST_MP_FORCEINLINE typename enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::type - eval_left_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, T s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + eval_left_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, T s) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { + is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); *result.limbs() = detail::checked_left_shift(*result.limbs(), s, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); result.normalize(); } template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class T> BOOST_MP_FORCEINLINE typename enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::type - eval_right_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, T s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + eval_right_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, T s) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { // Nothing to check here... just make sure we don't invoke undefined behavior: + is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); *result.limbs() = (static_cast<unsigned>(s) >= sizeof(*result.limbs()) * CHAR_BIT) ? 0 : *result.limbs() >> s; } @@ -428,7 +466,7 @@ inline typename enable_if_c< >::type eval_bitwise_and( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); @@ -465,7 +503,7 @@ inline typename enable_if_c< >::type eval_bitwise_and( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { *result.limbs() &= *o.limbs(); } @@ -478,7 +516,7 @@ inline typename enable_if_c< >::type eval_bitwise_or( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); @@ -516,7 +554,7 @@ inline typename enable_if_c< >::type eval_bitwise_or( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { *result.limbs() |= *o.limbs(); } @@ -529,7 +567,7 @@ inline typename enable_if_c< >::type eval_bitwise_xor( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); @@ -566,7 +604,7 @@ inline typename enable_if_c< >::type eval_bitwise_xor( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { *result.limbs() ^= *o.limbs(); } @@ -579,7 +617,7 @@ inline typename enable_if_c< >::type eval_complement( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { BOOST_STATIC_ASSERT_MSG(((Checked1 != checked) || (Checked2 != checked)), "Attempt to take the complement of a signed type results in undefined behavior."); // @@ -607,7 +645,7 @@ inline typename enable_if_c< >::type eval_complement( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { *result.limbs() = ~*o.limbs(); result.normalize(); diff --git a/boost/multiprecision/cpp_int/checked.hpp b/boost/multiprecision/cpp_int/checked.hpp index bf3bc650c0..cafe50ea49 100644 --- a/boost/multiprecision/cpp_int/checked.hpp +++ b/boost/multiprecision/cpp_int/checked.hpp @@ -128,7 +128,7 @@ inline A checked_divide(A a, A b, const mpl::int_<unchecked>&) } template <class A> -inline A checked_left_shift(A a, unsigned long long shift, const mpl::int_<checked>&) +inline A checked_left_shift(A a, boost::ulong_long_type shift, const mpl::int_<checked>&) { if(a && shift) { @@ -138,7 +138,7 @@ inline A checked_left_shift(A a, unsigned long long shift, const mpl::int_<check return a << shift; } template <class A> -inline A checked_left_shift(A a, unsigned long long shift, const mpl::int_<unchecked>&) +inline A checked_left_shift(A a, boost::ulong_long_type shift, const mpl::int_<unchecked>&) { return (shift >= sizeof(A) * CHAR_BIT) ? 0 : a << shift; } diff --git a/boost/multiprecision/cpp_int/cpp_int_config.hpp b/boost/multiprecision/cpp_int/cpp_int_config.hpp index 0b8b33d3a7..eb88f3da80 100644 --- a/boost/multiprecision/cpp_int/cpp_int_config.hpp +++ b/boost/multiprecision/cpp_int/cpp_int_config.hpp @@ -19,7 +19,7 @@ namespace detail{ // // These traits calculate the largest type in the list -// [unsigned] long long, long, int, which has the specified number +// [unsigned] boost::long_long_type, long, int, which has the specified number // of bits. Note that intN_t and boost::int_t<N> find the first // member of the above list, not the last. We want the last in the // list to ensure that mixed arithmetic operations are as efficient @@ -29,8 +29,8 @@ template <unsigned N> struct largest_signed_type { typedef typename mpl::if_c< - 1 + std::numeric_limits<long long>::digits == N, - long long, + 1 + std::numeric_limits<boost::long_long_type>::digits == N, + boost::long_long_type, typename mpl::if_c< 1 + std::numeric_limits<long>::digits == N, long, @@ -47,8 +47,8 @@ template <unsigned N> struct largest_unsigned_type { typedef typename mpl::if_c< - std::numeric_limits<unsigned long long>::digits == N, - unsigned long long, + std::numeric_limits<boost::ulong_long_type>::digits == N, + boost::ulong_long_type, typename mpl::if_c< std::numeric_limits<unsigned long>::digits == N, unsigned long, diff --git a/boost/multiprecision/cpp_int/divide.hpp b/boost/multiprecision/cpp_int/divide.hpp index b5c9b5e220..c94bc71498 100644 --- a/boost/multiprecision/cpp_int/divide.hpp +++ b/boost/multiprecision/cpp_int/divide.hpp @@ -540,7 +540,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi signed_limb_type b) { bool s = a.sign(); - divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>* >(0), a, static_cast<limb_type>(std::abs(b)), result); + divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>* >(0), a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(b)), result); result.sign(s); } diff --git a/boost/multiprecision/cpp_int/misc.hpp b/boost/multiprecision/cpp_int/misc.hpp index 266edac2ed..a124710c28 100644 --- a/boost/multiprecision/cpp_int/misc.hpp +++ b/boost/multiprecision/cpp_int/misc.hpp @@ -55,7 +55,7 @@ inline Integer negate_integer(Integer i, const mpl::false_&) BOOST_NOEXCEPT template <class R, unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> inline typename enable_if_c<is_integral<R>::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, void>::type - eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& backend) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& backend) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { typedef mpl::int_<Checked1> checked_type; check_in_range<R>(backend, checked_type()); @@ -76,7 +76,7 @@ inline typename enable_if_c<is_integral<R>::value && !is_trivial_cpp_int<cpp_int template <class R, unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> inline typename enable_if_c<is_floating_point<R>::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, void>::type - eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& backend) BOOST_NOEXCEPT_IF(is_arithmetic<R>::value) + eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& backend) BOOST_MP_NOEXCEPT_IF(is_arithmetic<R>::value) { typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::const_limb_pointer p = backend.limbs(); unsigned shift = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits; @@ -104,7 +104,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi } template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type - eval_abs(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + eval_abs(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { result = val; result.sign(false); @@ -234,7 +234,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& x, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& y, cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& q, - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { divide_unsigned_helper(&q, x, y, r); q.sign(x.sign() != y.sign()); @@ -247,7 +247,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& x, limb_type y, cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& q, - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { divide_unsigned_helper(&q, x, y, r); q.sign(x.sign()); @@ -259,7 +259,7 @@ inline typename enable_if_c<is_integral<U>::value>::type eval_qr( const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& x, U y, cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& q, - cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& r) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { using default_ops::eval_qr; cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(y); @@ -511,7 +511,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<is_trivial_cpp_int<cpp_int_backend<Min // This one is only enabled for unchecked cpp_int's, for checked int's we need the checking in the default version: template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> BOOST_MP_FORCEINLINE typename enable_if_c<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && (Checked1 == unchecked)>::type - eval_lcm(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + eval_lcm(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { *result.limbs() = boost::integer::lcm(*a.limbs(), *b.limbs()); result.normalize(); // result may overflow the specified number of bits diff --git a/boost/multiprecision/cpp_int/multiply.hpp b/boost/multiprecision/cpp_int/multiply.hpp index fd569faa00..226bc9d192 100644 --- a/boost/multiprecision/cpp_int/multiply.hpp +++ b/boost/multiprecision/cpp_int/multiply.hpp @@ -15,7 +15,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit eval_multiply( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(!val) { @@ -67,7 +67,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit eval_multiply( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { // Very simple long multiplication, only usable for small numbers of limb_type's // but that's the typical use case for this type anyway: @@ -130,10 +130,12 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit for(unsigned j = 0; j < inner_limit; ++j) { BOOST_ASSERT(i+j < result.size()); +#if (!defined(__GLIBCXX__) && !defined(__GLIBCPP__)) || !BOOST_WORKAROUND(BOOST_GCC_VERSION, <= 50100) BOOST_ASSERT(!std::numeric_limits<double_limb_type>::is_specialized || ((std::numeric_limits<double_limb_type>::max)() - carry > static_cast<double_limb_type>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value) * static_cast<double_limb_type>(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value))); +#endif carry += static_cast<double_limb_type>(pa[i]) * static_cast<double_limb_type>(pb[j]); BOOST_ASSERT(!std::numeric_limits<double_limb_type>::is_specialized || ((std::numeric_limits<double_limb_type>::max)() - carry >= pr[i+j])); carry += pr[i + j]; @@ -157,14 +159,14 @@ template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type eval_multiply( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { eval_multiply(result, result, a); } template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type - eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { eval_multiply(result, result, val); } @@ -174,7 +176,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi eval_multiply( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(val <= (std::numeric_limits<limb_type>::max)()) { @@ -189,7 +191,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type - eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { eval_multiply(result, result, val); } @@ -199,7 +201,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi eval_multiply( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const signed_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const signed_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(val > 0) eval_multiply(result, a, static_cast<limb_type>(val)); @@ -212,7 +214,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<Mi template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type - eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { eval_multiply(result, result, val); } @@ -222,7 +224,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit eval_multiply( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, - const signed_double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const signed_double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { if(val > 0) { @@ -244,7 +246,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1> BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type - eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + eval_multiply(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const signed_double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { eval_multiply(result, result, val); } @@ -261,7 +263,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c< >::type eval_multiply( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { *result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); result.sign(result.sign() != o.sign()); @@ -275,7 +277,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c< >::type eval_multiply( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { *result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); result.normalize(); @@ -291,7 +293,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c< eval_multiply( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { *result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); result.sign(a.sign() != b.sign()); @@ -306,7 +308,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c< eval_multiply( cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, - const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) + const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)) { *result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type()); result.normalize(); diff --git a/boost/multiprecision/cpp_int/serialize.hpp b/boost/multiprecision/cpp_int/serialize.hpp index bdf4758a6e..042a9f89f7 100644 --- a/boost/multiprecision/cpp_int/serialize.hpp +++ b/boost/multiprecision/cpp_int/serialize.hpp @@ -49,7 +49,7 @@ void do_serialize(Archive& ar, Int& val, mpl::false_ const&, mpl::false_ const&, std::size_t limb_count; std::size_t byte_count; ar & byte_count; - limb_count = byte_count / sizeof(limb_type) + (byte_count % sizeof(limb_type) ? 1 : 0); + limb_count = byte_count / sizeof(limb_type) + ((byte_count % sizeof(limb_type)) ? 1 : 0); val.resize(limb_count, limb_count); limb_type* pl = val.limbs(); for(std::size_t i = 0; i < limb_count; ++i) diff --git a/boost/multiprecision/detail/bitscan.hpp b/boost/multiprecision/detail/bitscan.hpp index 40602a939b..ce1cdc8d18 100644 --- a/boost/multiprecision/detail/bitscan.hpp +++ b/boost/multiprecision/detail/bitscan.hpp @@ -124,7 +124,7 @@ BOOST_FORCEINLINE unsigned find_lsb(unsigned long mask, mpl::int_<2> const&) { return __builtin_ctzl(mask); } -BOOST_FORCEINLINE unsigned find_lsb(unsigned long long mask, mpl::int_<3> const&) +BOOST_FORCEINLINE unsigned find_lsb(boost::ulong_long_type mask, mpl::int_<3> const&) { return __builtin_ctzll(mask); } @@ -136,9 +136,9 @@ BOOST_FORCEINLINE unsigned find_msb(unsigned long mask, mpl::int_<2> const&) { return sizeof(unsigned long) * CHAR_BIT - 1 - __builtin_clzl(mask); } -BOOST_FORCEINLINE unsigned find_msb(unsigned long long mask, mpl::int_<3> const&) +BOOST_FORCEINLINE unsigned find_msb(boost::ulong_long_type mask, mpl::int_<3> const&) { - return sizeof(unsigned long long) * CHAR_BIT - 1 - __builtin_clzll(mask); + return sizeof(boost::ulong_long_type) * CHAR_BIT - 1 - __builtin_clzll(mask); } template <class Unsigned> @@ -152,7 +152,7 @@ BOOST_FORCEINLINE unsigned find_lsb(Unsigned mask) sizeof(Unsigned) <= sizeof(unsigned long), mpl::int_<2>, typename mpl::if_c< - sizeof(Unsigned) <= sizeof(unsigned long long), + sizeof(Unsigned) <= sizeof(boost::ulong_long_type), mpl::int_<3>, mpl::int_<0> >::type @@ -171,7 +171,7 @@ BOOST_FORCEINLINE unsigned find_msb(Unsigned mask) sizeof(Unsigned) <= sizeof(unsigned long), mpl::int_<2>, typename mpl::if_c< - sizeof(Unsigned) <= sizeof(unsigned long long), + sizeof(Unsigned) <= sizeof(boost::ulong_long_type), mpl::int_<3>, mpl::int_<0> >::type diff --git a/boost/multiprecision/detail/default_ops.hpp b/boost/multiprecision/detail/default_ops.hpp index bf51a58295..01fbe181df 100644 --- a/boost/multiprecision/detail/default_ops.hpp +++ b/boost/multiprecision/detail/default_ops.hpp @@ -1219,7 +1219,7 @@ inline typename B::exponent_type eval_ilogb(const B& val) template <class B> inline void eval_logb(B& result, const B& val) { - typedef typename boost::mpl::if_c<boost::is_same<boost::intmax_t, long>::value, long long, boost::intmax_t>::type max_t; + typedef typename boost::mpl::if_c<boost::is_same<boost::intmax_t, long>::value, boost::long_long_type, boost::intmax_t>::type max_t; result = static_cast<max_t>(eval_ilogb(val)); } template <class B, class A> @@ -1436,29 +1436,29 @@ inline long ltrunc(const number<T, ExpressionTemplates>& v) } #ifndef BOOST_NO_LONG_LONG template <class tag, class A1, class A2, class A3, class A4, class Policy> -inline long long lltrunc(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol) +inline boost::long_long_type lltrunc(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol) { typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type; number_type r = trunc(v, pol); - if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !(boost::math::isfinite)(v)) + if((r > (std::numeric_limits<boost::long_long_type>::max)()) || r < (std::numeric_limits<boost::long_long_type>::min)() || !(boost::math::isfinite)(v)) return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, number_type(v), 0LL, pol); - return r.template convert_to<long long>(); + return r.template convert_to<boost::long_long_type>(); } template <class tag, class A1, class A2, class A3, class A4> -inline long long lltrunc(const detail::expression<tag, A1, A2, A3, A4>& v) +inline boost::long_long_type lltrunc(const detail::expression<tag, A1, A2, A3, A4>& v) { return lltrunc(v, boost::math::policies::policy<>()); } template <class T, expression_template_option ExpressionTemplates, class Policy> -inline long long lltrunc(const number<T, ExpressionTemplates>& v, const Policy& pol) +inline boost::long_long_type lltrunc(const number<T, ExpressionTemplates>& v, const Policy& pol) { number<T, ExpressionTemplates> r = trunc(v, pol); - if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !(boost::math::isfinite)(v)) + if((r > (std::numeric_limits<boost::long_long_type>::max)()) || r < (std::numeric_limits<boost::long_long_type>::min)() || !(boost::math::isfinite)(v)) return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, v, 0LL, pol); - return r.template convert_to<long long>(); + return r.template convert_to<boost::long_long_type>(); } template <class T, expression_template_option ExpressionTemplates> -inline long long lltrunc(const number<T, ExpressionTemplates>& v) +inline boost::long_long_type lltrunc(const number<T, ExpressionTemplates>& v) { return lltrunc(v, boost::math::policies::policy<>()); } @@ -1534,29 +1534,29 @@ inline long lround(const number<T, ExpressionTemplates>& v) } #ifndef BOOST_NO_LONG_LONG template <class tag, class A1, class A2, class A3, class A4, class Policy> -inline long long llround(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol) +inline boost::long_long_type llround(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol) { typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type; number_type r = round(v, pol); - if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !(boost::math::isfinite)(v)) + if((r > (std::numeric_limits<boost::long_long_type>::max)()) || r < (std::numeric_limits<boost::long_long_type>::min)() || !(boost::math::isfinite)(v)) return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, number_type(v), 0LL, pol); - return r.template convert_to<long long>(); + return r.template convert_to<boost::long_long_type>(); } template <class tag, class A1, class A2, class A3, class A4> -inline long long llround(const detail::expression<tag, A1, A2, A3, A4>& v) +inline boost::long_long_type llround(const detail::expression<tag, A1, A2, A3, A4>& v) { return llround(v, boost::math::policies::policy<>()); } template <class T, expression_template_option ExpressionTemplates, class Policy> -inline long long llround(const number<T, ExpressionTemplates>& v, const Policy& pol) +inline boost::long_long_type llround(const number<T, ExpressionTemplates>& v, const Policy& pol) { number<T, ExpressionTemplates> r = round(v, pol); - if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !(boost::math::isfinite)(v)) + if((r > (std::numeric_limits<boost::long_long_type>::max)()) || r < (std::numeric_limits<boost::long_long_type>::min)() || !(boost::math::isfinite)(v)) return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, v, 0LL, pol); - return r.template convert_to<long long>(); + return r.template convert_to<boost::long_long_type>(); } template <class T, expression_template_option ExpressionTemplates> -inline long long llround(const number<T, ExpressionTemplates>& v) +inline boost::long_long_type llround(const number<T, ExpressionTemplates>& v) { return llround(v, boost::math::policies::policy<>()); } @@ -1612,7 +1612,7 @@ frexp(const detail::expression<tag, A1, A2, A3, A4>& v, long* pint) return BOOST_MP_MOVE(frexp(static_cast<number_type>(v), pint)); } template <class T, expression_template_option ExpressionTemplates> -inline typename enable_if_c<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, long long* pint) +inline typename enable_if_c<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, boost::long_long_type* pint) { using default_ops::eval_frexp; number<T, ExpressionTemplates> result; @@ -1621,7 +1621,7 @@ inline typename enable_if_c<number_category<T>::value == number_kind_floating_po } template <class tag, class A1, class A2, class A3, class A4> inline typename enable_if_c<number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_floating_point, typename detail::expression<tag, A1, A2, A3, A4>::result_type>::type -frexp(const detail::expression<tag, A1, A2, A3, A4>& v, long long* pint) +frexp(const detail::expression<tag, A1, A2, A3, A4>& v, boost::long_long_type* pint) { typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type; return BOOST_MP_MOVE(frexp(static_cast<number_type>(v), pint)); @@ -2104,8 +2104,8 @@ HETERO_BINARY_OP_FUNCTOR_B(ldexp, int, number_kind_floating_point) //HETERO_BINARY_OP_FUNCTOR_B(frexp, int*, number_kind_floating_point) HETERO_BINARY_OP_FUNCTOR_B(ldexp, long, number_kind_floating_point) //HETERO_BINARY_OP_FUNCTOR_B(frexp, long*, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR_B(ldexp, long long, number_kind_floating_point) -//HETERO_BINARY_OP_FUNCTOR_B(frexp, long long*, number_kind_floating_point) +HETERO_BINARY_OP_FUNCTOR_B(ldexp, boost::long_long_type, number_kind_floating_point) +//HETERO_BINARY_OP_FUNCTOR_B(frexp, boost::long_long_type*, number_kind_floating_point) BINARY_OP_FUNCTOR(pow, number_kind_floating_point) BINARY_OP_FUNCTOR(fmod, number_kind_floating_point) BINARY_OP_FUNCTOR(atan2, number_kind_floating_point) @@ -2114,7 +2114,7 @@ UNARY_OP_FUNCTOR(logb, number_kind_floating_point) HETERO_BINARY_OP_FUNCTOR(scalbn, short, number_kind_floating_point) HETERO_BINARY_OP_FUNCTOR_B(scalbn, int, number_kind_floating_point) HETERO_BINARY_OP_FUNCTOR_B(scalbn, long, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR_B(scalbn, long long, number_kind_floating_point) +HETERO_BINARY_OP_FUNCTOR_B(scalbn, boost::long_long_type, number_kind_floating_point) // // Integer functions: diff --git a/boost/multiprecision/detail/functions/pow.hpp b/boost/multiprecision/detail/functions/pow.hpp index 5b54a1a9a8..b58d6b07be 100644 --- a/boost/multiprecision/detail/functions/pow.hpp +++ b/boost/multiprecision/detail/functions/pow.hpp @@ -12,6 +12,11 @@ // This file has no include guards or namespaces - it's expanded inline inside default_ops.hpp // +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:6326) // comparison of two constants +#endif + namespace detail{ template<typename T, typename U> @@ -160,7 +165,7 @@ void hyp1F0(T& H1F0, const T& a, const T& x) si_type n; T term, part; - static const unsigned series_limit = + static const si_type series_limit = boost::multiprecision::detail::digits2<number<T, et_on> >::value < 100 ? 100 : boost::multiprecision::detail::digits2<number<T, et_on> >::value; // Series expansion of hyperg_1f0(a; ; x). @@ -692,3 +697,6 @@ inline void eval_tanh(T& result, const T& x) eval_divide(result, c); } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif diff --git a/boost/multiprecision/detail/functions/trig.hpp b/boost/multiprecision/detail/functions/trig.hpp index baa42be38c..5d4e2639c2 100644 --- a/boost/multiprecision/detail/functions/trig.hpp +++ b/boost/multiprecision/detail/functions/trig.hpp @@ -12,6 +12,11 @@ // This file has no include guards or namespaces - it's expanded inline inside default_ops.hpp // +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:6326) // comparison of two constants +#endif + template <class T> void hyp0F1(T& result, const T& b, const T& x) { @@ -494,12 +499,12 @@ void eval_asin(T& result, const T& x) // Newton-Raphson iteration while(current_digits < target_precision) { - T s, c; - eval_sin(s, result); - eval_cos(c, result); - eval_subtract(s, xx); - eval_divide(s, c); - eval_subtract(result, s); + T sine, cosine; + eval_sin(sine, result); + eval_cos(cosine, result); + eval_subtract(sine, xx); + eval_divide(sine, cosine); + eval_subtract(result, sine); current_digits *= 2; /* @@ -770,3 +775,6 @@ inline typename enable_if<is_arithmetic<A>, void>::type eval_atan2(T& result, co eval_atan2(result, c, a); } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif diff --git a/boost/multiprecision/detail/generic_interconvert.hpp b/boost/multiprecision/detail/generic_interconvert.hpp index 690723be8b..d1fa028d30 100644 --- a/boost/multiprecision/detail/generic_interconvert.hpp +++ b/boost/multiprecision/detail/generic_interconvert.hpp @@ -10,7 +10,7 @@ #ifdef BOOST_MSVC #pragma warning(push) -#pragma warning(disable:4127) +#pragma warning(disable:4127 6326) #endif namespace boost{ namespace multiprecision{ namespace detail{ @@ -314,7 +314,7 @@ typename enable_if_c<is_number<To>::value || is_floating_point<To>::value>::type if(shift > 0) num <<= shift; else if(shift < 0) - denom <<= std::abs(shift); + denom <<= boost::multiprecision::detail::unsigned_abs(shift); Integer q, r; divide_qr(num, denom, q, r); int q_bits = msb(q); @@ -392,7 +392,7 @@ template <class To, class From> void generic_interconvert_float2rational(To& to, const From& from, const mpl::int_<2>& /*radix*/) { typedef typename mpl::front<typename To::unsigned_types>::type ui_type; - static const int shift = std::numeric_limits<long long>::digits; + static const int shift = std::numeric_limits<boost::long_long_type>::digits; typename From::exponent_type e; typename component_type<number<To> >::type num, denom; number<From> val(from); @@ -401,7 +401,7 @@ void generic_interconvert_float2rational(To& to, const From& from, const mpl::in { val = ldexp(val, shift); e -= shift; - long long ll = boost::math::lltrunc(val); + boost::long_long_type ll = boost::math::lltrunc(val); val -= ll; num <<= shift; num += ll; @@ -430,7 +430,7 @@ void generic_interconvert_float2rational(To& to, const From& from, const mpl::in val = scalbn(val, -e); while(val) { - long long ll = boost::math::lltrunc(val); + boost::long_long_type ll = boost::math::lltrunc(val); val -= ll; val = scalbn(val, 1); num *= Radix; diff --git a/boost/multiprecision/detail/number_base.hpp b/boost/multiprecision/detail/number_base.hpp index 09c86e6ce0..d725779091 100644 --- a/boost/multiprecision/detail/number_base.hpp +++ b/boost/multiprecision/detail/number_base.hpp @@ -25,7 +25,19 @@ # define BOOST_MP_FORCEINLINE inline #endif -namespace boost{ namespace multiprecision{ +#if defined(BOOST_GCC) && (BOOST_GCC <= 40700) +# define BOOST_MP_NOEXCEPT_IF(x) +#else +# define BOOST_MP_NOEXCEPT_IF(x) BOOST_NOEXCEPT_IF(x) +#endif + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:6326) +#endif + +namespace boost{ + namespace multiprecision{ enum expression_template_option { @@ -72,13 +84,13 @@ struct is_compatible_arithmetic_type namespace detail{ // -// Workaround for missing abs(long long) and abs(__int128) on some compilers: +// Workaround for missing abs(boost::long_long_type) and abs(__int128) on some compilers: // template <class T> BOOST_CONSTEXPR typename enable_if_c<(is_signed<T>::value || is_floating_point<T>::value), T>::type abs(T t) BOOST_NOEXCEPT { // This strange expression avoids a hardware trap in the corner case - // that val is the most negative value permitted in long long. + // that val is the most negative value permitted in boost::long_long_type. // See https://svn.boost.org/trac/boost/ticket/9740. return t < 0 ? T(1u) + T(-(t + 1)) : t; } @@ -94,7 +106,7 @@ template <class T> BOOST_CONSTEXPR typename enable_if_c<(is_signed<T>::value || is_floating_point<T>::value), typename make_unsigned<T>::type>::type unsigned_abs(T t) BOOST_NOEXCEPT { // This strange expression avoids a hardware trap in the corner case - // that val is the most negative value permitted in long long. + // that val is the most negative value permitted in boost::long_long_type. // See https://svn.boost.org/trac/boost/ticket/9740. return t < 0 ? static_cast<typename make_unsigned<T>::type>(1u) + static_cast<typename make_unsigned<T>::type>(-(t + 1)) : static_cast<typename make_unsigned<T>::type>(t); } @@ -814,6 +826,10 @@ namespace constants{ }} +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + #endif // BOOST_MATH_BIG_NUM_BASE_HPP diff --git a/boost/multiprecision/detail/number_compare.hpp b/boost/multiprecision/detail/number_compare.hpp index d1606ad73d..e9e510d302 100644 --- a/boost/multiprecision/detail/number_compare.hpp +++ b/boost/multiprecision/detail/number_compare.hpp @@ -6,6 +6,8 @@ #ifndef BOOST_MP_COMPARE_HPP #define BOOST_MP_COMPARE_HPP +#include <boost/multiprecision/traits/is_backend.hpp> + // // Comparison operators for number. // @@ -14,61 +16,82 @@ namespace boost{ namespace multiprecision{ namespace default_ops{ +// +// The dispatching mechanism used here to deal with differently typed arguments +// could be better replaced with enable_if overloads, but that breaks MSVC-12 +// under strange and hard to reproduce circumstances. +// template <class B> inline bool eval_eq(const B& a, const B& b) { return a.compare(b) == 0; } -// -// For the default version which compares to some arbitrary type convertible to -// our number type, we don't know what value the ExpressionTemplates parameter to -// class number should be. We generally prefer ExpressionTemplates to be enabled -// in case type A is itself an expression template, but we need to test both options -// with is_convertible in case A has an implicit conversion operator to number<B,something>. -// This is the case with many uBlas types for example. -// -template <class B, class A> -inline bool eval_eq(const B& a, const A& b) -{ - typedef typename mpl::if_c< - is_convertible<A, number<B, et_on> >::value, - number<B, et_on>, - number<B, et_off> >::type mp_type; - mp_type t(b); +template <class T, class U> +inline bool eval_eq_imp(const T& a, const U& b, const mpl::true_&) +{ + typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b); return eval_eq(a, t.backend()); } +template <class T, class U> +inline bool eval_eq_imp(const T& a, const U& b, const mpl::false_&) +{ + typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a); + return eval_eq(t.backend(), b); +} +template <class T, class U> +inline bool eval_eq(const T& a, const U& b) +{ + typedef mpl::bool_<boost::multiprecision::detail::is_first_backend<T, U>::value> tag_type; + return eval_eq_imp(a, b, tag_type()); +} template <class B> inline bool eval_lt(const B& a, const B& b) { return a.compare(b) < 0; } -template <class B, class A> -inline bool eval_lt(const B& a, const A& b) +template <class T, class U> +inline bool eval_lt_imp(const T& a, const U& b, const mpl::true_&) { - typedef typename mpl::if_c< - is_convertible<A, number<B, et_on> >::value, - number<B, et_on>, - number<B, et_off> >::type mp_type; - mp_type t(b); + typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b); return eval_lt(a, t.backend()); } +template <class T, class U> +inline bool eval_lt_imp(const T& a, const U& b, const mpl::false_&) +{ + typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a); + return eval_lt(t.backend(), b); +} +template <class T, class U> +inline bool eval_lt(const T& a, const U& b) +{ + typedef mpl::bool_<boost::multiprecision::detail::is_first_backend<T, U>::value> tag_type; + return eval_lt_imp(a, b, tag_type()); +} template <class B> inline bool eval_gt(const B& a, const B& b) { return a.compare(b) > 0; } -template <class B, class A> -inline bool eval_gt(const B& a, const A& b) +template <class T, class U> +inline bool eval_gt_imp(const T& a, const U& b, const mpl::true_&) { - typedef typename mpl::if_c< - is_convertible<A, number<B, et_on> >::value, - number<B, et_on>, - number<B, et_off> >::type mp_type; - mp_type t(b); + typename boost::multiprecision::detail::number_from_backend<T, U>::type t(b); return eval_gt(a, t.backend()); } +template <class T, class U> +inline bool eval_gt_imp(const T& a, const U& b, const mpl::false_&) +{ + typename boost::multiprecision::detail::number_from_backend<U, T>::type t(a); + return eval_gt(t.backend(), b); +} +template <class T, class U> +inline bool eval_gt(const T& a, const U& b) +{ + typedef mpl::bool_<boost::multiprecision::detail::is_first_backend<T, U>::value> tag_type; + return eval_gt_imp(a, b, tag_type()); +} } // namespace default_ops @@ -91,12 +114,42 @@ template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B, ex struct is_valid_mixed_compare<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> > : public mpl::bool_<is_convertible<expression<tag, Arg1, Arg2, Arg3, Arg4>, number<B, ET> >::value> {}; +template <class Backend, expression_template_option ExpressionTemplates> +inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Backend>::value != number_kind_floating_point, bool>::type is_unordered_value(const number<Backend, ExpressionTemplates>&) +{ + return false; +} +template <class Backend, expression_template_option ExpressionTemplates> +inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Backend>::value == number_kind_floating_point, bool>::type is_unordered_value(const number<Backend, ExpressionTemplates>& a) +{ + using default_ops::eval_fpclassify; + return eval_fpclassify(a.backend()) == FP_NAN; +} + +template <class Arithmetic> +inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Arithmetic>::value != number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic&) +{ + return false; +} +template <class Arithmetic> +inline BOOST_CONSTEXPR typename boost::enable_if_c<number_category<Arithmetic>::value == number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic& a) +{ + return (boost::math::isnan)(a); +} + +template <class T, class U> +inline BOOST_CONSTEXPR bool is_unordered_comparison(const T& a, const U& b) +{ + return is_unordered_value(a) || is_unordered_value(b); +} + } template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> inline bool operator == (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return false; return eval_eq(a.backend(), b.backend()); } template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> @@ -104,6 +157,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre operator == (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return false; return eval_eq(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); } template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> @@ -111,6 +165,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre operator == (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return false; return eval_eq(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); } template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> @@ -120,6 +175,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; using default_ops::eval_eq; result_type t(b); + if(detail::is_unordered_comparison(a, t)) return false; return eval_eq(t.backend(), result_type::canonical_value(a)); } template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> @@ -129,6 +185,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; using default_ops::eval_eq; result_type t(a); + if(detail::is_unordered_comparison(t, b)) return false; return eval_eq(t.backend(), result_type::canonical_value(b)); } template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> @@ -138,6 +195,7 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A using default_ops::eval_eq; typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return false; return eval_eq(t.backend(), t2.backend()); } @@ -145,6 +203,7 @@ template <class Backend, expression_template_option ExpressionTemplates, class B inline bool operator != (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return true; return !eval_eq(a.backend(), b.backend()); } template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> @@ -152,6 +211,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre operator != (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return true; return !eval_eq(a.backend(), number<Backend, et_on>::canonical_value(b)); } template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> @@ -159,6 +219,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre operator != (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return true; return !eval_eq(b.backend(), number<Backend, et_on>::canonical_value(a)); } template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> @@ -168,6 +229,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; using default_ops::eval_eq; result_type t(b); + if(detail::is_unordered_comparison(a, t)) return true; return !eval_eq(t.backend(), result_type::canonical_value(a)); } template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> @@ -177,6 +239,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; using default_ops::eval_eq; result_type t(a); + if(detail::is_unordered_comparison(t, b)) return true; return !eval_eq(t.backend(), result_type::canonical_value(b)); } template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> @@ -186,6 +249,7 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A using default_ops::eval_eq; typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return true; return !eval_eq(t.backend(), t2.backend()); } @@ -193,6 +257,7 @@ template <class Backend, expression_template_option ExpressionTemplates, class B inline bool operator < (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; return eval_lt(a.backend(), b.backend()); } template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> @@ -200,6 +265,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre operator < (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; return eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); } template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> @@ -207,6 +273,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre operator < (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; return eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); } template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> @@ -216,6 +283,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; using default_ops::eval_gt; result_type t(b); + if(detail::is_unordered_comparison(a, t)) return false; return eval_gt(t.backend(), result_type::canonical_value(a)); } template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> @@ -225,6 +293,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; using default_ops::eval_lt; result_type t(a); + if(detail::is_unordered_comparison(t, b)) return false; return eval_lt(t.backend(), result_type::canonical_value(b)); } template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> @@ -234,6 +303,7 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A using default_ops::eval_lt; typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return false; return eval_lt(t.backend(), t2.backend()); } @@ -241,6 +311,7 @@ template <class Backend, expression_template_option ExpressionTemplates, class B inline bool operator > (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; return eval_gt(a.backend(), b.backend()); } template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> @@ -248,6 +319,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre operator > (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; return eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); } template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> @@ -255,6 +327,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre operator > (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; return eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); } template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> @@ -264,7 +337,8 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; using default_ops::eval_lt; result_type t(b); - return eval_lt(t.backend(), result_type::canonical_value(a)); + if(detail::is_unordered_comparison(a, t)) return false; + return a > t; } template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type @@ -273,7 +347,8 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; using default_ops::eval_gt; result_type t(a); - return eval_gt(t.backend(), result_type::canonical_value(b)); + if(detail::is_unordered_comparison(t, b)) return false; + return t > b; } template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type @@ -282,13 +357,15 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A using default_ops::eval_gt; typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); - return eval_gt(t.backend(), t2.backend()); + if(detail::is_unordered_comparison(t, t2)) return false; + return t > t2; } template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2> inline bool operator <= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; return !eval_gt(a.backend(), b.backend()); } template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> @@ -296,6 +373,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre operator <= (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; return !eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); } template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> @@ -303,6 +381,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre operator <= (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; return !eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); } template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> @@ -311,7 +390,10 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr { typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; using default_ops::eval_lt; + if(detail::is_unordered_value(a) || detail::is_unordered_value(b)) + return false; result_type t(b); + if(detail::is_unordered_comparison(a, t)) return false; return !eval_lt(t.backend(), result_type::canonical_value(a)); } template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> @@ -321,6 +403,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; using default_ops::eval_gt; result_type t(a); + if(detail::is_unordered_comparison(t, b)) return false; return !eval_gt(t.backend(), result_type::canonical_value(b)); } template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> @@ -330,6 +413,7 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A using default_ops::eval_gt; typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return false; return !eval_gt(t.backend(), t2.backend()); } @@ -337,6 +421,7 @@ template <class Backend, expression_template_option ExpressionTemplates, class B inline bool operator >= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b) { using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; return !eval_lt(a.backend(), b.backend()); } template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic> @@ -344,6 +429,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre operator >= (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b) { using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; return !eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b)); } template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates> @@ -351,6 +437,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre operator >= (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b) { using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; return !eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a)); } template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4> @@ -360,6 +447,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; using default_ops::eval_gt; result_type t(b); + if(detail::is_unordered_comparison(a, t)) return false; return !eval_gt(t.backend(), result_type::canonical_value(a)); } template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic> @@ -369,6 +457,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type; using default_ops::eval_lt; result_type t(a); + if(detail::is_unordered_comparison(t, b)) return false; return !eval_lt(t.backend(), result_type::canonical_value(b)); } template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b> @@ -378,6 +467,7 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A using default_ops::eval_lt; typename detail::expression<Tag, A1, A2, A3, A4>::result_type t(a); typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return false; return !eval_lt(t.backend(), t2.backend()); } diff --git a/boost/multiprecision/float128.hpp b/boost/multiprecision/float128.hpp index 6e2958e07f..cd70fa009b 100644 --- a/boost/multiprecision/float128.hpp +++ b/boost/multiprecision/float128.hpp @@ -127,9 +127,9 @@ namespace backends{ struct float128_backend { - typedef mpl::list<signed char, short, int, long, long long> signed_types; + typedef mpl::list<signed char, short, int, long, boost::long_long_type> signed_types; typedef mpl::list<unsigned char, unsigned short, - unsigned int, unsigned long, unsigned long long> unsigned_types; + unsigned int, unsigned long, boost::ulong_long_type> unsigned_types; typedef mpl::list<float, double, long double> float_types; typedef int exponent_type; @@ -534,7 +534,7 @@ public: static number_type (max)() BOOST_NOEXCEPT { return 1.18973149535723176508575932662800702e4932Q; } static number_type lowest() BOOST_NOEXCEPT { return -(max)(); } BOOST_STATIC_CONSTEXPR int digits = 113; - BOOST_STATIC_CONSTEXPR int digits10 = 34; + BOOST_STATIC_CONSTEXPR int digits10 = 33; BOOST_STATIC_CONSTEXPR int max_digits10 = 36; BOOST_STATIC_CONSTEXPR bool is_signed = true; BOOST_STATIC_CONSTEXPR bool is_integer = false; @@ -564,57 +564,57 @@ public: }; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_specialized; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_specialized; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits; +BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits10; +BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits10; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_digits10; +BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_digits10; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_signed; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_signed; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_integer; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_integer; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_exact; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_exact; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::radix; +BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::radix; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent; +BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent; +BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent10; +BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent10; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent10; +BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent10; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_infinity; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_infinity; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_quiet_NaN; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_quiet_NaN; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_signaling_NaN; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_signaling_NaN; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm_loss; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm_loss; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_iec559; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_iec559; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_bounded; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_bounded; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_modulo; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_modulo; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::traps; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::traps; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::tinyness_before; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::tinyness_before; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::round_style; +BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::round_style; template <boost::multiprecision::expression_template_option ExpressionTemplates> -const float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm; +BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm; } // namespace std diff --git a/boost/multiprecision/gmp.hpp b/boost/multiprecision/gmp.hpp index 3b020d07c5..6351f7ea48 100644 --- a/boost/multiprecision/gmp.hpp +++ b/boost/multiprecision/gmp.hpp @@ -59,10 +59,15 @@ namespace detail{ template <unsigned digits10> struct gmp_float_imp { - typedef mpl::list<long, long long> signed_types; - typedef mpl::list<unsigned long, unsigned long long> unsigned_types; - typedef mpl::list<double, long double> float_types; - typedef long exponent_type; +#ifdef BOOST_HAS_LONG_LONG + typedef mpl::list<long, boost::long_long_type> signed_types; + typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types; +#else + typedef mpl::list<long> signed_types; + typedef mpl::list<unsigned long> unsigned_types; +#endif + typedef mpl::list<double, long double> float_types; + typedef long exponent_type; gmp_float_imp() BOOST_NOEXCEPT {} @@ -100,37 +105,48 @@ struct gmp_float_imp return *this; } #endif - gmp_float_imp& operator = (unsigned long long i) + +#ifdef BOOST_HAS_LONG_LONG +#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) + gmp_float_imp& operator = (boost::ulong_long_type i) + { + *this = static_cast<unsigned long>(i); + return *this; + } +#else + gmp_float_imp& operator = (boost::ulong_long_type i) { if(m_data[0]._mp_d == 0) mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1); + boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL); unsigned shift = 0; mpf_t t; mpf_init2(t, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); mpf_set_ui(m_data, 0); while(i) { - mpf_set_ui(t, static_cast<unsigned>(i & mask)); + mpf_set_ui(t, static_cast<unsigned long>(i & mask)); if(shift) mpf_mul_2exp(t, t, shift); mpf_add(m_data, m_data, t); - shift += std::numeric_limits<unsigned>::digits; - i >>= std::numeric_limits<unsigned>::digits; + shift += std::numeric_limits<unsigned long>::digits; + i >>= std::numeric_limits<unsigned long>::digits; } mpf_clear(t); return *this; } - gmp_float_imp& operator = (long long i) +#endif + gmp_float_imp& operator = (boost::long_long_type i) { if(m_data[0]._mp_d == 0) mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); bool neg = i < 0; - *this = static_cast<unsigned long long>(boost::multiprecision::detail::unsigned_abs(i)); + *this = static_cast<boost::ulong_long_type>(boost::multiprecision::detail::unsigned_abs(i)); if(neg) mpf_neg(m_data, m_data); return *this; } +#endif gmp_float_imp& operator = (unsigned long i) { if(m_data[0]._mp_d == 0) @@ -627,7 +643,7 @@ inline void eval_add(gmp_float<digits10>& result, long i) if(i > 0) mpf_add_ui(result.data(), result.data(), i); else - mpf_sub_ui(result.data(), result.data(), std::abs(i)); + mpf_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); } template <unsigned digits10> inline void eval_subtract(gmp_float<digits10>& result, long i) @@ -635,12 +651,12 @@ inline void eval_subtract(gmp_float<digits10>& result, long i) if(i > 0) mpf_sub_ui(result.data(), result.data(), i); else - mpf_add_ui(result.data(), result.data(), std::abs(i)); + mpf_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); } template <unsigned digits10> inline void eval_multiply(gmp_float<digits10>& result, long i) { - mpf_mul_ui(result.data(), result.data(), std::abs(i)); + mpf_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); if(i < 0) mpf_neg(result.data(), result.data()); } @@ -649,7 +665,7 @@ inline void eval_divide(gmp_float<digits10>& result, long i) { if(i == 0) BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpf_div_ui(result.data(), result.data(), std::abs(i)); + mpf_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); if(i < 0) mpf_neg(result.data(), result.data()); } @@ -843,13 +859,13 @@ inline void eval_convert_to(double* result, const gmp_float<digits10>& val) BOOS } #ifdef BOOST_HAS_LONG_LONG template <unsigned digits10> -inline void eval_convert_to(long long* result, const gmp_float<digits10>& val) +inline void eval_convert_to(boost::long_long_type* result, const gmp_float<digits10>& val) { gmp_float<digits10> t(val); if(eval_get_sign(t) < 0) t.negate(); - long digits = std::numeric_limits<long long>::digits - std::numeric_limits<long>::digits; + long digits = std::numeric_limits<boost::long_long_type>::digits - std::numeric_limits<long>::digits; if(digits > 0) mpf_div_2exp(t.data(), t.data(), digits); @@ -857,9 +873,9 @@ inline void eval_convert_to(long long* result, const gmp_float<digits10>& val) if(!mpf_fits_slong_p(t.data())) { if(eval_get_sign(val) < 0) - *result = (std::numeric_limits<long long>::min)(); + *result = (std::numeric_limits<boost::long_long_type>::min)(); else - *result = (std::numeric_limits<long long>::max)(); + *result = (std::numeric_limits<boost::long_long_type>::max)(); return; }; @@ -878,18 +894,18 @@ inline void eval_convert_to(long long* result, const gmp_float<digits10>& val) *result = -*result; } template <unsigned digits10> -inline void eval_convert_to(unsigned long long* result, const gmp_float<digits10>& val) +inline void eval_convert_to(boost::ulong_long_type* result, const gmp_float<digits10>& val) { gmp_float<digits10> t(val); - long digits = std::numeric_limits<long long>::digits - std::numeric_limits<long>::digits; + long digits = std::numeric_limits<boost::long_long_type>::digits - std::numeric_limits<long>::digits; if(digits > 0) mpf_div_2exp(t.data(), t.data(), digits); if(!mpf_fits_ulong_p(t.data())) { - *result = (std::numeric_limits<long long>::max)(); + *result = (std::numeric_limits<boost::long_long_type>::max)(); return; } @@ -969,8 +985,13 @@ inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& v struct gmp_int { - typedef mpl::list<long, long long> signed_types; - typedef mpl::list<unsigned long, unsigned long long> unsigned_types; +#ifdef BOOST_HAS_LONG_LONG + typedef mpl::list<long, boost::long_long_type> signed_types; + typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types; +#else + typedef mpl::list<long> signed_types; + typedef mpl::list<unsigned long> unsigned_types; +#endif typedef mpl::list<double, long double> float_types; gmp_int() @@ -1026,28 +1047,37 @@ struct gmp_int return *this; } #endif - gmp_int& operator = (unsigned long long i) +#ifdef BOOST_HAS_LONG_LONG +#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) + gmp_int& operator = (boost::ulong_long_type i) + { + *this = static_cast<unsigned long>(i); + return *this; + } +#else + gmp_int& operator = (boost::ulong_long_type i) { if(m_data[0]._mp_d == 0) mpz_init(this->m_data); - unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1); + boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL); unsigned shift = 0; mpz_t t; mpz_set_ui(m_data, 0); mpz_init_set_ui(t, 0); while(i) { - mpz_set_ui(t, static_cast<unsigned>(i & mask)); + mpz_set_ui(t, static_cast<unsigned long>(i & mask)); if(shift) mpz_mul_2exp(t, t, shift); mpz_add(m_data, m_data, t); - shift += std::numeric_limits<unsigned>::digits; - i >>= std::numeric_limits<unsigned>::digits; + shift += std::numeric_limits<unsigned long>::digits; + i >>= std::numeric_limits<unsigned long>::digits; } mpz_clear(t); return *this; } - gmp_int& operator = (long long i) +#endif + gmp_int& operator = (boost::long_long_type i) { if(m_data[0]._mp_d == 0) mpz_init(this->m_data); @@ -1057,6 +1087,7 @@ struct gmp_int mpz_neg(m_data, m_data); return *this; } +#endif gmp_int& operator = (unsigned long i) { if(m_data[0]._mp_d == 0) @@ -1379,19 +1410,19 @@ inline void eval_subtract(gmp_int& t, long i) } inline void eval_multiply(gmp_int& t, long i) { - mpz_mul_ui(t.data(), t.data(), std::abs(i)); + mpz_mul_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i)); if(i < 0) mpz_neg(t.data(), t.data()); } inline void eval_modulus(gmp_int& t, long i) { - mpz_tdiv_r_ui(t.data(), t.data(), std::abs(i)); + mpz_tdiv_r_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i)); } inline void eval_divide(gmp_int& t, long i) { if(i == 0) BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpz_tdiv_q_ui(t.data(), t.data(), std::abs(i)); + mpz_tdiv_q_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i)); if(i < 0) mpz_neg(t.data(), t.data()); } @@ -1491,19 +1522,19 @@ inline void eval_subtract(gmp_int& t, const gmp_int& p, long i) } inline void eval_multiply(gmp_int& t, const gmp_int& p, long i) { - mpz_mul_ui(t.data(), p.data(), std::abs(i)); + mpz_mul_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i)); if(i < 0) mpz_neg(t.data(), t.data()); } inline void eval_modulus(gmp_int& t, const gmp_int& p, long i) { - mpz_tdiv_r_ui(t.data(), p.data(), std::abs(i)); + mpz_tdiv_r_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i)); } inline void eval_divide(gmp_int& t, const gmp_int& p, long i) { if(i == 0) BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpz_tdiv_q_ui(t.data(), p.data(), std::abs(i)); + mpz_tdiv_q_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i)); if(i < 0) mpz_neg(t.data(), t.data()); } @@ -1582,12 +1613,12 @@ inline typename enable_if_c<(is_unsigned<I>::value && (sizeof(I) <= sizeof(unsig template <class I> inline typename enable_if_c<(is_signed<I>::value && (sizeof(I) <= sizeof(long)))>::type eval_gcd(gmp_int& result, const gmp_int& a, const I b) { - mpz_gcd_ui(result.data(), a.data(), std::abs(b)); + mpz_gcd_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b)); } template <class I> inline typename enable_if_c<is_signed<I>::value && ((sizeof(I) <= sizeof(long)))>::type eval_lcm(gmp_int& result, const gmp_int& a, const I b) { - mpz_lcm_ui(result.data(), a.data(), std::abs(b)); + mpz_lcm_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b)); } inline void eval_integer_sqrt(gmp_int& s, gmp_int& r, const gmp_int& x) @@ -1664,8 +1695,7 @@ inline typename enable_if<is_unsigned<Integer>, Integer>::type eval_integer_modu template <class Integer> inline typename enable_if<is_signed<Integer>, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val) { - typedef typename make_unsigned<Integer>::type unsigned_type; - return eval_integer_modulus(x, static_cast<unsigned_type>(std::abs(val))); + return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val)); } inline void eval_powm(gmp_int& result, const gmp_int& base, const gmp_int& p, const gmp_int& m) { @@ -1706,9 +1736,14 @@ void eval_add(gmp_rational& t, const gmp_rational& o); struct gmp_rational { - typedef mpl::list<long, long long> signed_types; - typedef mpl::list<unsigned long, unsigned long long> unsigned_types; - typedef mpl::list<double, long double> float_types; +#ifdef BOOST_HAS_LONG_LONG + typedef mpl::list<long, boost::long_long_type> signed_types; + typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types; +#else + typedef mpl::list<long> signed_types; + typedef mpl::list<unsigned long> unsigned_types; +#endif + typedef mpl::list<double, long double> float_types; gmp_rational() { @@ -1757,28 +1792,24 @@ struct gmp_rational return *this; } #endif - gmp_rational& operator = (unsigned long long i) +#ifdef BOOST_HAS_LONG_LONG +#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) + gmp_rational& operator = (boost::ulong_long_type i) + { + *this = static_cast<unsigned long>(i); + return *this; + } +#else + gmp_rational& operator = (boost::ulong_long_type i) { if(m_data[0]._mp_den._mp_d == 0) mpq_init(m_data); - unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1); - unsigned shift = 0; - mpq_t t; - mpq_set_ui(m_data, 0, 1); - mpq_init(t); - while(i) - { - mpq_set_ui(t, static_cast<unsigned>(i & mask), 1); - if(shift) - mpq_mul_2exp(t, t, shift); - mpq_add(m_data, m_data, t); - shift += std::numeric_limits<unsigned>::digits; - i >>= std::numeric_limits<unsigned>::digits; - } - mpq_clear(t); + gmp_int zi; + zi = i; + mpq_set_z(m_data, zi.data()); return *this; } - gmp_rational& operator = (long long i) + gmp_rational& operator = (boost::long_long_type i) { if(m_data[0]._mp_den._mp_d == 0) mpq_init(m_data); @@ -1788,6 +1819,8 @@ struct gmp_rational mpq_neg(m_data, m_data); return *this; } +#endif +#endif gmp_rational& operator = (unsigned long i) { if(m_data[0]._mp_den._mp_d == 0) diff --git a/boost/multiprecision/integer.hpp b/boost/multiprecision/integer.hpp index 4432f1e971..e4c8bf8b6c 100644 --- a/boost/multiprecision/integer.hpp +++ b/boost/multiprecision/integer.hpp @@ -48,17 +48,17 @@ namespace detail{ // // Figure out the kind of integer that has twice as many bits as some builtin // integer type I. Use a native type if we can (including types which may not -// be recognised by boost::int_t because they're larger than long long), +// be recognised by boost::int_t because they're larger than boost::long_long_type), // otherwise synthesize a cpp_int to do the job. // template <class I> struct double_integer { static const unsigned int_t_digits = - 2 * sizeof(I) <= sizeof(long long) ? std::numeric_limits<I>::digits * 2 : 1; + 2 * sizeof(I) <= sizeof(boost::long_long_type) ? std::numeric_limits<I>::digits * 2 : 1; typedef typename mpl::if_c< - 2 * sizeof(I) <= sizeof(long long), + 2 * sizeof(I) <= sizeof(boost::long_long_type), typename mpl::if_c< is_signed<I>::value, typename boost::int_t<int_t_digits>::least, diff --git a/boost/multiprecision/mpfi.hpp b/boost/multiprecision/mpfi.hpp index 81503f7108..8d13981ceb 100644 --- a/boost/multiprecision/mpfi.hpp +++ b/boost/multiprecision/mpfi.hpp @@ -55,8 +55,13 @@ struct mpfi_float_imp; template <unsigned digits10> struct mpfi_float_imp { - typedef mpl::list<long, long long> signed_types; - typedef mpl::list<unsigned long, unsigned long long> unsigned_types; +#ifdef BOOST_HAS_LONG_LONG + typedef mpl::list<long, boost::long_long_type> signed_types; + typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types; +#else + typedef mpl::list<long> signed_types; + typedef mpl::list<unsigned long> unsigned_types; +#endif typedef mpl::list<double, long double> float_types; typedef long exponent_type; @@ -97,8 +102,9 @@ struct mpfi_float_imp return *this; } #endif +#ifdef BOOST_HAS_LONG_LONG #ifdef _MPFR_H_HAVE_INTMAX_T - mpfi_float_imp& operator = (unsigned long long i) + mpfi_float_imp& operator = (boost::ulong_long_type i) { if(m_data[0].left._mpfr_d == 0) mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); @@ -106,7 +112,7 @@ struct mpfi_float_imp mpfr_set_uj(right_data(), i, GMP_RNDU); return *this; } - mpfi_float_imp& operator = (long long i) + mpfi_float_imp& operator = (boost::long_long_type i) { if(m_data[0].left._mpfr_d == 0) mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); @@ -115,28 +121,28 @@ struct mpfi_float_imp return *this; } #else - mpfi_float_imp& operator = (unsigned long long i) + mpfi_float_imp& operator = (boost::ulong_long_type i) { if(m_data[0].left._mpfr_d == 0) mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1); + boost::ulong_long_type mask = (((1uLL << (std::numeric_limits<unsigned long>::digits - 1) - 1) << 1) | 1u); unsigned shift = 0; mpfi_t t; - mpfi_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))); + mpfi_init2(t, (std::max)(static_cast<unsigned long>(std::numeric_limits<boost::ulong_long_type>::digits), static_cast<unsigned long>(multiprecision::detail::digits10_2_2(digits10)))); mpfi_set_ui(m_data, 0); while(i) { - mpfi_set_ui(t, static_cast<unsigned>(i & mask)); + mpfi_set_ui(t, static_cast<unsigned long>(i & mask)); if(shift) mpfi_mul_2exp(t, t, shift); mpfi_add(m_data, m_data, t); - shift += std::numeric_limits<unsigned>::digits; - i >>= std::numeric_limits<unsigned>::digits; + shift += std::numeric_limits<unsigned long>::digits; + i >>= std::numeric_limits<unsigned long>::digits; } mpfi_clear(t); return *this; } - mpfi_float_imp& operator = (long long i) + mpfi_float_imp& operator = (boost::long_long_type i) { if(m_data[0].left._mpfr_d == 0) mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); @@ -147,6 +153,7 @@ struct mpfi_float_imp return *this; } #endif +#endif mpfi_float_imp& operator = (unsigned long i) { if(m_data[0].left._mpfr_d == 0) @@ -731,14 +738,14 @@ inline void eval_convert_to(long* result, const mpfi_float_backend<digits10>& va } #ifdef _MPFR_H_HAVE_INTMAX_T template <unsigned digits10> -inline void eval_convert_to(unsigned long long* result, const mpfi_float_backend<digits10>& val) +inline void eval_convert_to(boost::ulong_long_type* result, const mpfi_float_backend<digits10>& val) { mpfr_float_backend<digits10> t; mpfi_mid(t.data(), val.data()); eval_convert_to(result, t); } template <unsigned digits10> -inline void eval_convert_to(long long* result, const mpfi_float_backend<digits10>& val) +inline void eval_convert_to(boost::long_long_type* result, const mpfi_float_backend<digits10>& val) { mpfr_float_backend<digits10> t; mpfi_mid(t.data(), val.data()); diff --git a/boost/multiprecision/mpfr.hpp b/boost/multiprecision/mpfr.hpp index 36298c143e..dcf0044cdd 100644 --- a/boost/multiprecision/mpfr.hpp +++ b/boost/multiprecision/mpfr.hpp @@ -63,8 +63,13 @@ struct mpfr_float_imp; template <unsigned digits10> struct mpfr_float_imp<digits10, allocate_dynamic> { - typedef mpl::list<long, long long> signed_types; - typedef mpl::list<unsigned long, unsigned long long> unsigned_types; +#ifdef BOOST_HAS_LONG_LONG + typedef mpl::list<long, boost::long_long_type> signed_types; + typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types; +#else + typedef mpl::list<long> signed_types; + typedef mpl::list<unsigned long> unsigned_types; +#endif typedef mpl::list<double, long double> float_types; typedef long exponent_type; @@ -105,15 +110,16 @@ struct mpfr_float_imp<digits10, allocate_dynamic> return *this; } #endif +#ifdef BOOST_HAS_LONG_LONG #ifdef _MPFR_H_HAVE_INTMAX_T - mpfr_float_imp& operator = (unsigned long long i) + mpfr_float_imp& operator = (boost::ulong_long_type i) { if(m_data[0]._mpfr_d == 0) mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); mpfr_set_uj(m_data, i, GMP_RNDN); return *this; } - mpfr_float_imp& operator = (long long i) + mpfr_float_imp& operator = (boost::long_long_type i) { if(m_data[0]._mpfr_d == 0) mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); @@ -121,28 +127,28 @@ struct mpfr_float_imp<digits10, allocate_dynamic> return *this; } #else - mpfr_float_imp& operator = (unsigned long long i) + mpfr_float_imp& operator = (boost::ulong_long_type i) { if(m_data[0]._mpfr_d == 0) mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1); + boost::ulong_long_type mask = (((1uLL << (std::numeric_limits<unsigned long>::digits - 1) - 1) << 1) | 1uLL); unsigned shift = 0; mpfr_t t; - mpfr_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10)))); + mpfr_init2(t, (std::max)(static_cast<unsigned long>(std::numeric_limits<boost::ulong_long_type>::digits), static_cast<unsigned long>(multiprecision::detail::digits10_2_2(digits10)))); mpfr_set_ui(m_data, 0, GMP_RNDN); while(i) { - mpfr_set_ui(t, static_cast<unsigned>(i & mask), GMP_RNDN); + mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN); if(shift) mpfr_mul_2exp(t, t, shift, GMP_RNDN); mpfr_add(m_data, m_data, t, GMP_RNDN); - shift += std::numeric_limits<unsigned>::digits; - i >>= std::numeric_limits<unsigned>::digits; + shift += std::numeric_limits<unsigned long>::digits; + i >>= std::numeric_limits<unsigned long>::digits; } mpfr_clear(t); return *this; } - mpfr_float_imp& operator = (long long i) + mpfr_float_imp& operator = (boost::long_long_type i) { if(m_data[0]._mpfr_d == 0) mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); @@ -153,6 +159,7 @@ struct mpfr_float_imp<digits10, allocate_dynamic> return *this; } #endif +#endif mpfr_float_imp& operator = (unsigned long i) { if(m_data[0]._mpfr_d == 0) @@ -363,8 +370,13 @@ protected: template <unsigned digits10> struct mpfr_float_imp<digits10, allocate_stack> { - typedef mpl::list<long, long long> signed_types; - typedef mpl::list<unsigned long, unsigned long long> unsigned_types; +#ifdef BOOST_HAS_LONG_LONG + typedef mpl::list<long, boost::long_long_type> signed_types; + typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types; +#else + typedef mpl::list<long> signed_types; + typedef mpl::list<unsigned long> unsigned_types; +#endif typedef mpl::list<double, long double> float_types; typedef long exponent_type; @@ -392,21 +404,22 @@ struct mpfr_float_imp<digits10, allocate_stack> mpfr_set(m_data, o.m_data, GMP_RNDN); return *this; } +#ifdef BOOST_HAS_LONG_LONG #ifdef _MPFR_H_HAVE_INTMAX_T - mpfr_float_imp& operator = (unsigned long long i) + mpfr_float_imp& operator = (boost::ulong_long_type i) { mpfr_set_uj(m_data, i, GMP_RNDN); return *this; } - mpfr_float_imp& operator = (long long i) + mpfr_float_imp& operator = (boost::long_long_type i) { mpfr_set_sj(m_data, i, GMP_RNDN); return *this; } #else - mpfr_float_imp& operator = (unsigned long long i) + mpfr_float_imp& operator = (boost::ulong_long_type i) { - unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1); + boost::ulong_long_type mask = (((1uLL << (std::numeric_limits<unsigned long>::digits - 1) - 1) << 1) | 1uL); unsigned shift = 0; mpfr_t t; mp_limb_t t_limbs[limb_count]; @@ -415,16 +428,16 @@ struct mpfr_float_imp<digits10, allocate_stack> mpfr_set_ui(m_data, 0, GMP_RNDN); while(i) { - mpfr_set_ui(t, static_cast<unsigned>(i & mask), GMP_RNDN); + mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN); if(shift) mpfr_mul_2exp(t, t, shift, GMP_RNDN); mpfr_add(m_data, m_data, t, GMP_RNDN); - shift += std::numeric_limits<unsigned>::digits; - i >>= std::numeric_limits<unsigned>::digits; + shift += std::numeric_limits<unsigned long>::digits; + i >>= std::numeric_limits<unsigned long>::digits; } return *this; } - mpfr_float_imp& operator = (long long i) + mpfr_float_imp& operator = (boost::long_long_type i) { bool neg = i < 0; *this = boost::multiprecision::detail::unsigned_abs(i); @@ -433,6 +446,7 @@ struct mpfr_float_imp<digits10, allocate_stack> return *this; } #endif +#endif mpfr_float_imp& operator = (unsigned long i) { mpfr_set_ui(m_data, i, GMP_RNDN); @@ -817,11 +831,14 @@ struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0 mpfr_float_backend& operator=(const mpfr_float_backend& o) { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, mpfr_get_prec(o.data())); - else - mpfr_set_prec(this->m_data, mpfr_get_prec(o.data())); - mpfr_set(this->m_data, o.data(), GMP_RNDN); + if(this != &o) + { + if(this->m_data[0]._mpfr_d == 0) + mpfr_init2(this->m_data, mpfr_get_prec(o.data())); + else + mpfr_set_prec(this->m_data, mpfr_get_prec(o.data())); + mpfr_set(this->m_data, o.data(), GMP_RNDN); + } return *this; } #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES @@ -1192,7 +1209,7 @@ inline void eval_convert_to(long* result, const mpfr_float_backend<digits10, All } #ifdef _MPFR_H_HAVE_INTMAX_T template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend<digits10, AllocationType>& val) +inline void eval_convert_to(boost::ulong_long_type* result, const mpfr_float_backend<digits10, AllocationType>& val) { if(mpfr_nan_p(val.data())) { @@ -1201,7 +1218,7 @@ inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend *result = mpfr_get_uj(val.data(), GMP_RNDZ); } template <unsigned digits10, mpfr_allocation_type AllocationType> -inline void eval_convert_to(long long* result, const mpfr_float_backend<digits10, AllocationType>& val) +inline void eval_convert_to(boost::long_long_type* result, const mpfr_float_backend<digits10, AllocationType>& val) { if(mpfr_nan_p(val.data())) { diff --git a/boost/multiprecision/number.hpp b/boost/multiprecision/number.hpp index c977958ea5..92242847de 100644 --- a/boost/multiprecision/number.hpp +++ b/boost/multiprecision/number.hpp @@ -31,7 +31,7 @@ namespace boost{ namespace multiprecision{ // warning C4127: conditional expression is constant // warning C4714: function marked as __forceinline not inlined #pragma warning(push) -#pragma warning(disable:4127 4714) +#pragma warning(disable:4127 4714 6326) #endif template <class Backend, expression_template_option ExpressionTemplates> @@ -40,8 +40,8 @@ class number typedef number<Backend, ExpressionTemplates> self_type; public: typedef Backend backend_type; - BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number() BOOST_NOEXCEPT_IF(noexcept(Backend())) {} - BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number& e) BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>()))) : m_backend(e.m_backend){} + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number() BOOST_MP_NOEXCEPT_IF(noexcept(Backend())) {} + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number& e) BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>()))) : m_backend(e.m_backend){} template <class V> BOOST_MP_FORCEINLINE number(const V& v, typename boost::enable_if_c< (boost::is_arithmetic<V>::value || is_same<std::string, V>::value || is_convertible<V, const char*>::value) @@ -57,11 +57,11 @@ public: && !detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value >::type* = 0) #ifndef BOOST_INTEL - BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<typename detail::canonical<V, Backend>::type const&>()))) + BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<typename detail::canonical<V, Backend>::type const&>()))) #endif : m_backend(canonical_value(v)) {} BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number& e, unsigned digits10) - BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>(), std::declval<unsigned>()))) + BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>(), std::declval<unsigned>()))) : m_backend(e.m_backend, digits10){} template <class V> explicit BOOST_MP_FORCEINLINE number(const V& v, typename boost::enable_if_c< @@ -69,7 +69,7 @@ public: && !detail::is_explicitly_convertible<typename detail::canonical<V, Backend>::type, Backend>::value && detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value >::type* = 0) - BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<typename detail::canonical<V, Backend>::type const&>())) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<typename detail::canonical<V, Backend>::type const&>())) { m_backend = canonical_value(v); } @@ -79,7 +79,7 @@ public: && (detail::is_restricted_conversion<typename detail::canonical<V, Backend>::type, Backend>::value || !is_convertible<typename detail::canonical<V, Backend>::type, Backend>::value) >::type* = 0) - BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<typename detail::canonical<V, Backend>::type const&>()))) + BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<typename detail::canonical<V, Backend>::type const&>()))) : m_backend(canonical_value(v)) {} /* // @@ -95,12 +95,12 @@ public: */ template<expression_template_option ET> BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number<Backend, ET>& val) - BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>()))) : m_backend(val.backend()) {} + BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend const&>()))) : m_backend(val.backend()) {} template <class Other, expression_template_option ET> BOOST_MP_FORCEINLINE number(const number<Other, ET>& val, typename boost::enable_if_c<(boost::is_convertible<Other, Backend>::value && !detail::is_restricted_conversion<Other, Backend>::value)>::type* = 0) - BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<Other const&>()))) + BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Other const&>()))) : m_backend(val.backend()) {} template <class Other, expression_template_option ET> @@ -117,7 +117,7 @@ public: explicit BOOST_MP_FORCEINLINE number(const number<Other, ET>& val, typename boost::enable_if_c< (detail::is_explicitly_convertible<Other, Backend>::value && (detail::is_restricted_conversion<Other, Backend>::value || !boost::is_convertible<Other, Backend>::value)) - >::type* = 0) BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<Other const&>()))) + >::type* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Other const&>()))) : m_backend(val.backend()) {} template <class V> @@ -149,7 +149,7 @@ public: } BOOST_MP_FORCEINLINE number& operator=(const number& e) - BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<Backend const&>())) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<Backend const&>())) { m_backend = e.m_backend; return *this; @@ -158,14 +158,14 @@ public: template <class V> BOOST_MP_FORCEINLINE typename boost::enable_if<is_convertible<V, self_type>, number<Backend, ExpressionTemplates>& >::type operator=(const V& v) - BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<const typename detail::canonical<V, Backend>::type&>())) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<const typename detail::canonical<V, Backend>::type&>())) { m_backend = canonical_value(v); return *this; } template <class V> BOOST_MP_FORCEINLINE number<Backend, ExpressionTemplates>& assign(const V& v) - BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<const typename detail::canonical<V, Backend>::type&>())) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<const typename detail::canonical<V, Backend>::type&>())) { m_backend = canonical_value(v); return *this; @@ -196,9 +196,9 @@ public: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(number&& r) - BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend>()))) + BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval<Backend>()))) : m_backend(static_cast<Backend&&>(r.m_backend)){} - BOOST_MP_FORCEINLINE number& operator=(number&& r) BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<Backend>())) + BOOST_MP_FORCEINLINE number& operator=(number&& r) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend&>() = std::declval<Backend>())) { m_backend = static_cast<Backend&&>(r.m_backend); return *this; @@ -547,7 +547,7 @@ public: // // swap: // - BOOST_MP_FORCEINLINE void swap(self_type& other) BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend>().swap(std::declval<Backend&>()))) + BOOST_MP_FORCEINLINE void swap(self_type& other) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend>().swap(std::declval<Backend&>()))) { m_backend.swap(other.backend()); } @@ -664,7 +664,7 @@ public: // Comparison: // BOOST_MP_FORCEINLINE int compare(const number<Backend, ExpressionTemplates>& o)const - BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend>().compare(std::declval<Backend>()))) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<Backend>().compare(std::declval<Backend>()))) { return m_backend.compare(o.m_backend); } @@ -1726,7 +1726,7 @@ inline std::istream& operator >> (std::istream& is, number<Backend, ExpressionTe template <class Backend, expression_template_option ExpressionTemplates> BOOST_MP_FORCEINLINE void swap(number<Backend, ExpressionTemplates>& a, number<Backend, ExpressionTemplates>& b) - BOOST_NOEXCEPT_IF(noexcept(std::declval<number<Backend, ExpressionTemplates>&>() = std::declval<number<Backend, ExpressionTemplates>&>())) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<number<Backend, ExpressionTemplates>&>() = std::declval<number<Backend, ExpressionTemplates>&>())) { a.swap(b); } diff --git a/boost/multiprecision/rational_adaptor.hpp b/boost/multiprecision/rational_adaptor.hpp index 3e294aabb2..e3cec0e482 100644 --- a/boost/multiprecision/rational_adaptor.hpp +++ b/boost/multiprecision/rational_adaptor.hpp @@ -34,12 +34,12 @@ struct rational_adaptor typedef typename IntBackend::unsigned_types unsigned_types; typedef typename IntBackend::float_types float_types; - rational_adaptor() BOOST_NOEXCEPT_IF(noexcept(rational_type())) {} - rational_adaptor(const rational_adaptor& o) BOOST_NOEXCEPT_IF(noexcept(std::declval<rational_type&>() = std::declval<const rational_type&>())) + rational_adaptor() BOOST_MP_NOEXCEPT_IF(noexcept(rational_type())) {} + rational_adaptor(const rational_adaptor& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<rational_type&>() = std::declval<const rational_type&>())) { m_value = o.m_value; } - rational_adaptor(const IntBackend& o) BOOST_NOEXCEPT_IF(noexcept(rational_type(std::declval<const IntBackend&>()))) : m_value(o) {} + rational_adaptor(const IntBackend& o) BOOST_MP_NOEXCEPT_IF(noexcept(rational_type(std::declval<const IntBackend&>()))) : m_value(o) {} template <class U> rational_adaptor(const U& u, typename enable_if_c<is_convertible<U, IntBackend>::value>::type* = 0) @@ -57,9 +57,9 @@ struct rational_adaptor } #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - rational_adaptor(rational_adaptor&& o) BOOST_NOEXCEPT_IF(noexcept(rational_type(std::declval<rational_type>()))) : m_value(static_cast<rational_type&&>(o.m_value)) {} - rational_adaptor(IntBackend&& o) BOOST_NOEXCEPT_IF(noexcept(rational_type(std::declval<IntBackend>()))) : m_value(static_cast<IntBackend&&>(o)) {} - rational_adaptor& operator = (rational_adaptor&& o) BOOST_NOEXCEPT_IF(noexcept(std::declval<rational_type&>() = std::declval<rational_type>())) + rational_adaptor(rational_adaptor&& o) BOOST_MP_NOEXCEPT_IF(noexcept(rational_type(std::declval<rational_type>()))) : m_value(static_cast<rational_type&&>(o.m_value)) {} + rational_adaptor(IntBackend&& o) BOOST_MP_NOEXCEPT_IF(noexcept(rational_type(std::declval<IntBackend>()))) : m_value(static_cast<IntBackend&&>(o)) {} + rational_adaptor& operator = (rational_adaptor&& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<rational_type&>() = std::declval<rational_type>())) { m_value = static_cast<rational_type&&>(o.m_value); return *this; @@ -134,7 +134,7 @@ struct rational_adaptor v2 = 1; if(*s) { - BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Could parse the string \"") + p + std::string("\" as a valid rational number."))); + BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Could not parse the string \"") + p + std::string("\" as a valid rational number."))); } data().assign(v1, v2); return *this; diff --git a/boost/multiprecision/tommath.hpp b/boost/multiprecision/tommath.hpp index 8abee83c4a..9c373443c6 100644 --- a/boost/multiprecision/tommath.hpp +++ b/boost/multiprecision/tommath.hpp @@ -38,8 +38,8 @@ void eval_add(tommath_int& t, const tommath_int& o); struct tommath_int { - typedef mpl::list<boost::int32_t, long long> signed_types; - typedef mpl::list<boost::uint32_t, unsigned long long> unsigned_types; + typedef mpl::list<boost::int32_t, boost::long_long_type> signed_types; + typedef mpl::list<boost::uint32_t, boost::ulong_long_type> unsigned_types; typedef mpl::list<long double> float_types; tommath_int() @@ -70,11 +70,11 @@ struct tommath_int detail::check_tommath_result(mp_copy(const_cast< ::mp_int*>(&o.m_data), &m_data)); return *this; } - tommath_int& operator = (unsigned long long i) + tommath_int& operator = (boost::ulong_long_type i) { if(m_data.dp == 0) detail::check_tommath_result(mp_init(&m_data)); - unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1); + boost::ulong_long_type mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1); unsigned shift = 0; ::mp_int t; detail::check_tommath_result(mp_init(&t)); @@ -91,7 +91,7 @@ struct tommath_int mp_clear(&t); return *this; } - tommath_int& operator = (long long i) + tommath_int& operator = (boost::long_long_type i) { if(m_data.dp == 0) detail::check_tommath_result(mp_init(&m_data)); @@ -118,7 +118,7 @@ struct tommath_int if(m_data.dp == 0) detail::check_tommath_result(mp_init(&m_data)); bool neg = i < 0; - *this = static_cast<boost::uint32_t>(std::abs(i)); + *this = boost::multiprecision::detail::unsigned_abs(i); if(neg) detail::check_tommath_result(mp_neg(&m_data, &m_data)); return *this; @@ -222,7 +222,7 @@ struct tommath_int unsigned shift = radix == 8 ? 3 : 4; unsigned block_count = DIGIT_BIT / shift; unsigned block_shift = shift * block_count; - unsigned long long val, block; + boost::ulong_long_type val, block; while(*s) { block = 0; @@ -536,7 +536,7 @@ inline void eval_complement(tommath_int& result, const tommath_int& u) // Create a mask providing the extra bits we need and add to result: tommath_int mask; - mask = static_cast<long long>((1u << padding) - 1); + mask = static_cast<boost::long_long_type>((1u << padding) - 1); eval_left_shift(mask, shift); add(result, mask); } @@ -640,8 +640,7 @@ inline typename enable_if<is_unsigned<Integer>, Integer>::type eval_integer_modu template <class Integer> inline typename enable_if<is_signed<Integer>, Integer>::type eval_integer_modulus(const tommath_int& x, Integer val) { - typedef typename make_unsigned<Integer>::type unsigned_type; - return eval_integer_modulus(x, static_cast<unsigned_type>(std::abs(val))); + return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val)); } } // namespace backends diff --git a/boost/multiprecision/traits/is_backend.hpp b/boost/multiprecision/traits/is_backend.hpp new file mode 100644 index 0000000000..9b23c86665 --- /dev/null +++ b/boost/multiprecision/traits/is_backend.hpp @@ -0,0 +1,63 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_MP_IS_BACKEND_HPP +#define BOOST_MP_IS_BACKEND_HPP + +#include <boost/mpl/has_xxx.hpp> +#include <boost/type_traits/conditional.hpp> +#include <boost/type_traits/is_convertible.hpp> +#include <boost/multiprecision/detail/number_base.hpp> + +namespace boost{ namespace multiprecision{ namespace detail{ + + BOOST_MPL_HAS_XXX_TRAIT_DEF(signed_types); + BOOST_MPL_HAS_XXX_TRAIT_DEF(unsigned_types); + BOOST_MPL_HAS_XXX_TRAIT_DEF(float_types); + + template <class T> + struct is_backend + { + static const bool value = has_signed_types<T>::value && has_unsigned_types<T>::value && has_float_types<T>::value; + }; + + template <class Backend> + struct other_backend + { + typedef typename boost::conditional< + boost::is_same<number<Backend>, number<Backend, et_on> >::value, + number<Backend, et_off>, number<Backend, et_on> >::type type; + }; + + template <class B, class V> + struct number_from_backend + { + typedef typename boost::conditional < + boost::is_convertible<V, number<B> >::value, + number<B>, + typename other_backend<B>::type > ::type type; + }; + + template <bool b, class T, class U> + struct is_first_backend_imp{ static const bool value = false; }; + template <class T, class U> + struct is_first_backend_imp<true, T, U>{ static const bool value = is_convertible<U, number<T, et_on> >::value || is_convertible<U, number<T, et_off> >::value; }; + + template <class T, class U> + struct is_first_backend : is_first_backend_imp<is_backend<T>::value, T, U> {}; + + template <bool b, class T, class U> + struct is_second_backend_imp{ static const bool value = false; }; + template <class T, class U> + struct is_second_backend_imp<true, T, U>{ static const bool value = (is_convertible<T, number<U, et_on> >::value || is_convertible<T, number<U, et_off> >::value) && !is_first_backend<T, U>::value; }; + + template <class T, class U> + struct is_second_backend : is_second_backend_imp<is_backend<U>::value, T, U> {}; + +} +} +} + +#endif // BOOST_MP_IS_BACKEND_HPP |