diff options
Diffstat (limited to 'boost/multiprecision/cpp_int.hpp')
-rw-r--r-- | boost/multiprecision/cpp_int.hpp | 102 |
1 files changed, 58 insertions, 44 deletions
diff --git a/boost/multiprecision/cpp_int.hpp b/boost/multiprecision/cpp_int.hpp index 2713b7ec11..311f7c16da 100644 --- a/boost/multiprecision/cpp_int.hpp +++ b/boost/multiprecision/cpp_int.hpp @@ -1,4 +1,4 @@ -/////////////////////////////////////////////////////////////// +//////////////////3///////////////////////////////////////////// // Copyright 2012 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_ @@ -354,6 +354,9 @@ public: std::swap(m_internal, o.m_internal); std::swap(m_limbs, o.m_limbs); } +protected: + template <class A> + void check_in_range(const A&) BOOST_NOEXCEPT {} }; #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION @@ -477,9 +480,11 @@ public: if((m_limbs == 1) && (!*p)) m_sign = false; // zero is always unsigned } - BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base() : m_wrapper(limb_type(0u)), m_limbs(1), m_sign(false) {} + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base()BOOST_NOEXCEPT : m_wrapper(limb_type(0u)), m_limbs(1), m_sign(false) {} + // Not defaulted, it breaks constexpr support in the Intel compiler for some reason: + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& o)BOOST_NOEXCEPT + : m_wrapper(o.m_wrapper), m_limbs(o.m_limbs), m_sign(o.m_sign) {} // Defaulted functions: - //BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& i)BOOST_NOEXCEPT; //~cpp_int_base() BOOST_NOEXCEPT {} void assign(const cpp_int_base& o) BOOST_NOEXCEPT @@ -512,6 +517,9 @@ public: std::swap(m_sign, o.m_sign); std::swap(m_limbs, o.m_limbs); } +protected: + template <class A> + void check_in_range(const A&) BOOST_NOEXCEPT {} }; #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION @@ -615,8 +623,9 @@ public: BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base() BOOST_NOEXCEPT : m_wrapper(limb_type(0u)), m_limbs(1) {} + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT + : m_wrapper(o.m_wrapper), m_limbs(o.m_limbs) {} // Defaulted functions: - //BOOST_MP_FORCEINLINE cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT; //~cpp_int_base() BOOST_NOEXCEPT {} BOOST_MP_FORCEINLINE void assign(const cpp_int_base& o) BOOST_NOEXCEPT @@ -660,6 +669,9 @@ public: std::swap(m_wrapper.m_data[i], o.m_wrapper.m_data[i]); std::swap(m_limbs, o.m_limbs); } +protected: + template <class A> + void check_in_range(const A&) BOOST_NOEXCEPT {} }; #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION @@ -735,10 +747,10 @@ protected: BOOST_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent.")); } template <class T, int C> - void check_in_range(T, const mpl::int_<C>&){} + void check_in_range(T, const mpl::int_<C>&) BOOST_NOEXCEPT {} template <class T> - void check_in_range(T val) + void check_in_range(T val) BOOST_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<T>(), checked_type()))) { check_in_range(val, checked_type()); } @@ -748,34 +760,34 @@ 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((Checked == unchecked)) + 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>()))) : 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((Checked == unchecked)) + 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>()))) : 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_IF((Checked == unchecked)) + 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((Checked == unchecked)) + 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>()))) : 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_IF((Checked == unchecked)) + 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 : m_data(static_cast<local_limb_type>(std::fabs(i)) & limb_mask), m_sign(i < 0) {} template <class F> - BOOST_MP_FORCEINLINE cpp_int_base(F i, typename boost::enable_if_c<is_floating_point<F>::value && (Checked == checked)>::type const* = 0) BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE cpp_int_base(F i, typename boost::enable_if_c<is_floating_point<F>::value && (Checked == checked)>::type const* = 0) : m_data(static_cast<local_limb_type>(std::fabs(i)) & limb_mask), m_sign(i < 0) { check_in_range(i); } #if defined(BOOST_MP_USER_DEFINED_LITERALS) - BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<>) + BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<>) BOOST_NOEXCEPT : m_data(static_cast<local_limb_type>(0u)), m_sign(false) {} template <limb_type a> - BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a>) + BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a>)BOOST_NOEXCEPT : m_data(static_cast<local_limb_type>(a)), m_sign(false) {} template <limb_type a, limb_type b> - BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a, b>) + BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a, b>)BOOST_NOEXCEPT : m_data(static_cast<local_limb_type>(a) | (static_cast<local_limb_type>(b) << bits_per_limb)), m_sign(false) {} - BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& a, const literals::detail::negate_tag&) + BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& a, const literals::detail::negate_tag&)BOOST_NOEXCEPT : m_data(a.m_data), m_sign(a.m_data ? !a.m_sign : false) {} #endif // @@ -806,7 +818,7 @@ public: m_data &= limb_mask; } - BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base() : m_data(0), m_sign(false) {} + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base() BOOST_NOEXCEPT : m_data(0), m_sign(false) {} BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT : m_data(o.m_data), m_sign(o.m_sign) {} //~cpp_int_base() BOOST_NOEXCEPT {} @@ -860,7 +872,7 @@ private: protected: template <class T> typename boost::disable_if_c<std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::digits <= (int)MinBits)>::type - check_in_range(T val, const mpl::int_<checked>&, const mpl::false_&) + check_in_range(T val, const mpl::int_<checked>&, const boost::false_type&) { typedef typename common_type<T, local_limb_type>::type common_type; @@ -868,7 +880,7 @@ protected: BOOST_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent.")); } template <class T> - void check_in_range(T val, const mpl::int_<checked>&, const mpl::true_&) + void check_in_range(T val, const mpl::int_<checked>&, const boost::true_type&) { typedef typename common_type<T, local_limb_type>::type common_type; @@ -878,10 +890,10 @@ protected: BOOST_THROW_EXCEPTION(std::range_error("The argument to an unsigned cpp_int constructor was negative.")); } template <class T, int C, bool B> - BOOST_MP_FORCEINLINE void check_in_range(T, const mpl::int_<C>&, const mpl::bool_<B>&){} + 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_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>()))) { check_in_range(val, checked_type(), is_signed<T>()); } @@ -891,16 +903,16 @@ 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((Checked == unchecked)) + 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((Checked == unchecked)) + 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>()))) : 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_IF((Checked == unchecked)) + 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((Checked == unchecked)) + 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>()))) : 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)) @@ -911,13 +923,13 @@ public: negate(); } #if defined(BOOST_MP_USER_DEFINED_LITERALS) - BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<>) + BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<>) BOOST_NOEXCEPT : m_data(static_cast<local_limb_type>(0u)) {} template <limb_type a> - BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a>) + BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a>) BOOST_NOEXCEPT : m_data(static_cast<local_limb_type>(a)) {} template <limb_type a, limb_type b> - BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a, b>) + BOOST_CONSTEXPR cpp_int_base(literals::detail::value_pack<a, b>) BOOST_NOEXCEPT : m_data(static_cast<local_limb_type>(a) | (static_cast<local_limb_type>(b) << bits_per_limb)) {} #endif // @@ -942,7 +954,7 @@ public: m_data &= limb_mask; } - BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base() : m_data(0) {} + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base() BOOST_NOEXCEPT : m_data(0) {} BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT : m_data(o.m_data) {} //~cpp_int_base() BOOST_NOEXCEPT {} @@ -1039,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((Checked == unchecked) && boost::is_void<Allocator>::value) + 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>()))) : base_type(i) {} private: @@ -1128,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((Checked == unchecked) && boost::is_void<Allocator>::value) + 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&>()))) { 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(boost::is_void<Allocator>::value) + BOOST_MP_FORCEINLINE cpp_int_backend& operator = (cpp_int_backend&& o) BOOST_NOEXCEPT_IF(noexcept(std::declval<base_type&>() = std::declval<base_type>())) { *static_cast<base_type*>(this) = static_cast<base_type&&>(o); return *this; @@ -1142,14 +1154,16 @@ public: #endif private: template <class A> - typename boost::enable_if<is_unsigned<A> >::type do_assign_arithmetic(A val, const mpl::true_&) + 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>()))) { this->check_in_range(val); *this->limbs() = static_cast<typename self_type::local_limb_type>(val); this->normalize(); } 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_&) + 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))) { 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); @@ -1170,13 +1184,13 @@ private: *this->limbs() = i; this->sign(false); } - BOOST_MP_FORCEINLINE void do_assign_arithmetic(signed_limb_type i, const mpl::false_&) BOOST_NOEXCEPT_IF((Checked == unchecked)) + 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))) { this->resize(1, 1); *this->limbs() = static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(i)); this->sign(i < 0); } - void do_assign_arithmetic(double_limb_type i, const mpl::false_&) + void do_assign_arithmetic(double_limb_type i, const mpl::false_&) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT(sizeof(i) == 2 * sizeof(limb_type)); BOOST_STATIC_ASSERT(base_type::internal_limb_count >= 2); @@ -1186,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_&) + void do_assign_arithmetic(signed_double_limb_type i, const mpl::false_&) BOOST_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); @@ -1249,7 +1263,7 @@ private: } public: template <class Arithmetic> - BOOST_MP_FORCEINLINE cpp_int_backend& operator = (Arithmetic val) + 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()))) { do_assign_arithmetic(val, trivial_tag()); return *this; @@ -1477,7 +1491,7 @@ private: if(f & std::ios_base::showbase) { const char* pp = base == 8 ? "0" : "0x"; - result.insert(0, pp); + result.insert(static_cast<std::string::size_type>(0), pp); } } else @@ -1501,9 +1515,9 @@ private: if(result.empty()) result = "0"; if(neg) - result.insert(0, 1, '-'); + result.insert(static_cast<std::string::size_type>(0), 1, '-'); else if(f & std::ios_base::showpos) - result.insert(0, 1, '+'); + result.insert(static_cast<std::string::size_type>(0), 1, '+'); } return result; } @@ -1562,7 +1576,7 @@ private: if(f & std::ios_base::showbase) { const char* pp = base == 8 ? "0" : "0x"; - result.insert(0, pp); + result.insert(static_cast<std::string::size_type>(0), pp); } } else @@ -1606,9 +1620,9 @@ private: if(result.empty()) result = "0"; if(neg) - result.insert(0, 1, '-'); + result.insert(static_cast<std::string::size_type>(0), 1, '-'); else if(f & std::ios_base::showpos) - result.insert(0, 1, '+'); + result.insert(static_cast<std::string::size_type>(0), 1, '+'); } return result; } |