Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81054 - in sandbox/big_number: boost/multiprecision boost/multiprecision/cpp_int boost/multiprecision/detail libs/multiprecision/test libs/multiprecision/test/include_test
From: john_at_[hidden]
Date: 2012-10-24 12:00:09


Author: johnmaddock
Date: 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
New Revision: 81054
URL: http://svn.boost.org/trac/boost/changeset/81054

Log:
Big "blow it away and start again" refactoring of cpp_int.
Adds support for runtime checking, enumerated template params, fixed precision with allocator, and no "hidden" template parameters.
Added:
   sandbox/big_number/boost/multiprecision/cpp_int/
   sandbox/big_number/boost/multiprecision/cpp_int/add.hpp (contents, props changed)
   sandbox/big_number/boost/multiprecision/cpp_int/bitwise.hpp (contents, props changed)
   sandbox/big_number/boost/multiprecision/cpp_int/checked.hpp (contents, props changed)
   sandbox/big_number/boost/multiprecision/cpp_int/comparison.hpp (contents, props changed)
   sandbox/big_number/boost/multiprecision/cpp_int/cpp_int_config.hpp (contents, props changed)
   sandbox/big_number/boost/multiprecision/cpp_int/divide.hpp (contents, props changed)
   sandbox/big_number/boost/multiprecision/cpp_int/limits.hpp (contents, props changed)
   sandbox/big_number/boost/multiprecision/cpp_int/misc.hpp (contents, props changed)
   sandbox/big_number/boost/multiprecision/cpp_int/multiply.hpp (contents, props changed)
Text files modified:
   sandbox/big_number/boost/multiprecision/cpp_int.hpp | 3334 +++++++++------------------------------
   sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp | 2
   sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp | 98
   sandbox/big_number/boost/multiprecision/detail/default_ops.hpp | 12
   sandbox/big_number/boost/multiprecision/detail/integer_ops.hpp | 8
   sandbox/big_number/boost/multiprecision/detail/no_et_ops.hpp | 4
   sandbox/big_number/boost/multiprecision/detail/number_base.hpp | 27
   sandbox/big_number/libs/multiprecision/test/Jamfile.v2 | 43
   sandbox/big_number/libs/multiprecision/test/include_test/cpp_int_include_test.cpp | 6
   sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp | 108
   sandbox/big_number/libs/multiprecision/test/test_cpp_int.cpp | 22
   sandbox/big_number/libs/multiprecision/test/test_cpp_int_conv.cpp | 10
   sandbox/big_number/libs/multiprecision/test/test_int_io.cpp | 29
   sandbox/big_number/libs/multiprecision/test/test_numeric_limits.cpp | 4
   14 files changed, 1076 insertions(+), 2631 deletions(-)

Modified: sandbox/big_number/boost/multiprecision/cpp_int.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/cpp_int.hpp (original)
+++ sandbox/big_number/boost/multiprecision/cpp_int.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -14,40 +14,148 @@
 #include <boost/array.hpp>
 #include <boost/type_traits/is_integral.hpp>
 #include <boost/type_traits/is_floating_point.hpp>
-#include <boost/multiprecision/detail/cpp_int_core.hpp>
+#include <boost/multiprecision/cpp_int/cpp_int_config.hpp>
 #include <boost/multiprecision/rational_adapter.hpp>
 #include <boost/detail/endian.hpp>
+#include <boost/integer/static_min_max.hpp>
+#include <boost/type_traits/common_type.hpp>
+#include <boost/multiprecision/cpp_int/checked.hpp>
 
 namespace boost{
 namespace multiprecision{
+
 namespace backends{
 
 #ifdef BOOST_MSVC
 // warning C4127: conditional expression is constant
 #pragma warning(push)
-#pragma warning(disable:4127 4351)
+#pragma warning(disable:4127 4351 4293)
 #endif
 
-template <unsigned MinBits = 0, bool Signed = true, class Allocator = std::allocator<limb_type>, bool trivial = is_void<Allocator>::value && (MinBits <= sizeof(double_limb_type) * CHAR_BIT) >
+template <unsigned MinBits = 0, unsigned MaxBits = 0, cpp_integer_type SignType = signed_magnitude, cpp_int_check_type Checked = unchecked, class Allocator = std::allocator<limb_type> >
 struct cpp_int_backend;
 
-template <unsigned MinBits = 0, bool Signed = true, class Allocator = std::allocator<limb_type>, bool trivial = false>
+template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, bool trivial = false>
 struct cpp_int_base;
+//
+// Traits class determines the maximum and minimum precision values:
+//
+template <class T> struct max_precision;
+
+template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
+struct max_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
+{
+ static const unsigned value = is_void<Allocator>::value ?
+ static_unsigned_max<MinBits, MaxBits>::value
+ : (((MaxBits >= MinBits) && MaxBits) ? MaxBits : UINT_MAX);
+};
 
+template <class T> struct min_precision;
+
+template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
+struct min_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
+{
+ static const unsigned value = (is_void<Allocator>::value ? static_unsigned_max<MinBits, MaxBits>::value : MinBits);
+};
+//
+// Traits class determines whether the number of bits precision requested could fit in a native type,
+// we call this a "trivial" cpp_int:
+//
 template <class T>
-struct is_trivial_cpp_int;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial>
-struct is_trivial_cpp_int<cpp_int_backend<MinBits, Signed, Allocator, trivial> >
+struct is_trivial_cpp_int
+{
+ static const bool value = false;
+};
+
+template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
+struct is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
+{
+ typedef cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> self;
+ static const bool value = is_void<Allocator>::value && (max_precision<self>::value <= (sizeof(double_limb_type) * CHAR_BIT) - (SignType == signed_packed ? 1 : 0));
+};
+
+template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
+struct is_trivial_cpp_int<cpp_int_base<MinBits, MaxBits, SignType, Checked, Allocator, true> >
+{
+ static const bool value = true;
+};
+
+} // namespace backends
+//
+// Traits class to determine whether a cpp_int_backend is signed or not:
+//
+template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
+struct is_unsigned_number<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
+ : public mpl::bool_<(SignType == unsigned_magnitude) || (SignType == unsigned_packed)>{};
+
+namespace backends{
+//
+// Traits class determines whether T should be implicitly convertible to U, or
+// whether the constructor should be made explicit. The latter happens if we
+// are losing the sign, or have fewer digits precision in the target type:
+//
+template <class T, class U>
+struct is_implicit_cpp_int_conversion;
+
+template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+struct is_implicit_cpp_int_conversion<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >
 {
- typedef mpl::bool_<trivial> type;
+ typedef cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> t1;
+ typedef cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> t2;
+ static const bool value =
+ (is_signed_number<t2>::value || !is_signed_number<t1>::value)
+ && (max_precision<t1>::value <= max_precision<t2>::value);
 };
 
-template <unsigned MinBits, bool Signed, class Allocator>
-struct cpp_int_base<MinBits, Signed, Allocator> : private Allocator::template rebind<limb_type>::other
+//
+// Traits class to determine whether operations on a cpp_int may throw:
+//
+template <class T>
+struct is_non_throwing_cpp_int : public mpl::false_{};
+template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType>
+struct is_non_throwing_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, unchecked, void> > : public mpl::true_ {};
+
+//
+// Traits class, determines whether the cpp_int is fixed precision or not:
+//
+template <class T>
+struct is_fixed_precision;
+template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
+struct is_fixed_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >
+ : public mpl::bool_<max_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value != UINT_MAX> {};
+
+namespace detail{
+
+inline void verify_new_size(unsigned new_size, unsigned min_size, const mpl::int_<checked>&)
+{
+ if(new_size < min_size)
+ BOOST_THROW_EXCEPTION(std::overflow_error("Unable to allocate sufficient storage for the value of the result: value overflows the maximum allowable magnitude."));
+}
+inline void verify_new_size(unsigned /*new_size*/, unsigned /*min_size*/, const mpl::int_<unchecked>&){}
+
+template <class U>
+inline void verify_limb_mask(bool b, U limb, U mask, const mpl::int_<checked>&)
+{
+ // When we mask out "limb" with "mask", do we loose bits? If so it's an overflow error:
+ if(b && (limb & ~mask))
+ BOOST_THROW_EXCEPTION(std::overflow_error("Overflow in cpp_int arithmetic: there is insufficient precision in the target type to hold all of the bits of the result."));
+}
+template <class U>
+inline void verify_limb_mask(bool /*b*/, U /*limb*/, U /*mask*/, const mpl::int_<unchecked>&){}
+
+}
+
+//
+// Now define the various data layouts that are possible as partial specializations of the base class,
+// starting with the default arbitrary precision signed integer type:
+//
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+struct cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false> : private Allocator::template rebind<limb_type>::other
 {
    typedef typename Allocator::template rebind<limb_type>::other allocator_type;
    typedef typename allocator_type::pointer limb_pointer;
    typedef typename allocator_type::const_pointer const_limb_pointer;
+ typedef mpl::int_<Checked> checked_type;
 
    //
    // Interface invariants:
@@ -65,14 +173,12 @@
    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
- ? MinBits / limb_bits + (MinBits % limb_bits ? 1 : 0)
+ BOOST_STATIC_CONSTANT(unsigned, internal_limb_count =
+ MinBits
+ ? MinBits / limb_bits + (MinBits % limb_bits ? 1 : 0)
          : sizeof(limb_data) / sizeof(limb_type));
    BOOST_STATIC_CONSTANT(bool, variable = true);
 
- BOOST_STATIC_ASSERT_MSG(Signed, "There is curently no support for unsigned arbitrary precision integers.");
-
 private:
    union data_type
    {
@@ -98,14 +204,14 @@
    //
    // Direct construction:
    //
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT
       : m_data(i), m_limbs(1), m_sign(false), m_internal(true) { }
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT
       : m_data(i), m_limbs(1), m_sign(i < 0), m_internal(true) { }
 #if defined(BOOST_LITTLE_ENDIAN)
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT
       : m_data(i), m_limbs(i > max_limb_value ? 2 : 1), m_sign(false), m_internal(true) { }
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT
       : m_data(i), m_limbs(i < 0 ? (-i > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)), m_sign(i < 0), m_internal(true) { }
 #endif
    //
@@ -118,9 +224,9 @@
    BOOST_FORCEINLINE const_limb_pointer limbs()const BOOST_NOEXCEPT { return m_internal ? m_data.la : m_data.ld.data; }
    BOOST_FORCEINLINE unsigned capacity()const BOOST_NOEXCEPT { return m_internal ? internal_limb_count : m_data.ld.capacity; }
    BOOST_FORCEINLINE bool sign()const BOOST_NOEXCEPT { return m_sign; }
- void sign(bool b) BOOST_NOEXCEPT
- {
- m_sign = b;
+ void sign(bool b) BOOST_NOEXCEPT
+ {
+ m_sign = b;
       // Check for zero value:
       if(m_sign && (m_limbs == 1))
       {
@@ -128,12 +234,19 @@
             m_sign = false;
       }
    }
- void resize(unsigned new_size)
+ 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);
+ // We never resize beyond MaxSize:
+ if(new_size > max_limbs)
+ new_size = max_limbs;
+ detail::verify_new_size(new_size, min_size, checked_type());
+ // See if we have enough capacity already:
       unsigned cap = capacity();
       if(new_size > cap)
       {
- cap = (std::max)(cap * 4, new_size);
+ // Allocate a new buffer and copy everything over:
+ cap = (std::min)((std::max)(cap * 4, new_size), max_limbs);
          limb_pointer pl = allocator().allocate(cap);
          std::copy(limbs(), limbs() + size(), pl);
          if(!m_internal)
@@ -157,12 +270,13 @@
    BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base() BOOST_NOEXCEPT : m_data(), m_limbs(1), m_sign(false), m_internal(true) {}
    BOOST_FORCEINLINE cpp_int_base(const cpp_int_base& o) : allocator_type(o), m_limbs(0), m_internal(true)
    {
- resize(o.size());
+ resize(o.size(), o.size());
       std::copy(o.limbs(), o.limbs() + o.size(), limbs());
       m_sign = o.m_sign;
    }
 #ifndef BOOST_NO_RVALUE_REFERENCES
- cpp_int_base(cpp_int_base&& o) BOOST_NOEXCEPT : allocator_type(static_cast<Allocator&&>(o)), m_limbs(o.m_limbs), m_sign(o.m_sign), m_internal(o.m_internal)
+ cpp_int_base(cpp_int_base&& o) BOOST_NOEXCEPT
+ : allocator_type(static_cast<Allocator&&>(o)), m_limbs(o.m_limbs), m_sign(o.m_sign), m_internal(o.m_internal)
    {
       if(m_internal)
       {
@@ -207,7 +321,7 @@
       {
          static_cast<allocator_type&>(*this) = static_cast<const allocator_type&>(o);
          m_limbs = 0;
- resize(o.size());
+ resize(o.size(), o.size());
          std::copy(o.limbs(), o.limbs() + o.size(), limbs());
          m_sign = o.m_sign;
       }
@@ -224,7 +338,7 @@
    }
    BOOST_FORCEINLINE bool isneg()const BOOST_NOEXCEPT
    {
- return m_sign;
+ return m_sign;
    }
    BOOST_FORCEINLINE void do_swap(cpp_int_base& o) BOOST_NOEXCEPT
    {
@@ -235,11 +349,39 @@
    }
 };
 
-template <unsigned MinBits>
-struct cpp_int_base<MinBits, true, void, false>
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+const unsigned cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::limb_bits;
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+const limb_type cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::max_limb_value;
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+const limb_type cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::sign_bit_mask;
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+const unsigned cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::internal_limb_count;
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+const bool cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false>::variable;
+
+#endif
+
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+struct cpp_int_base<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator, false> : private Allocator::template rebind<limb_type>::other
+{
+ //
+ // There is currently no support for unsigned arbitrary precision arithmetic, largely
+ // because it's not clear what subtraction should do:
+ //
+ BOOST_STATIC_ASSERT_MSG(((sizeof(Allocator) == 0) && !is_void<Allocator>::value), "There is curently no support for unsigned arbitrary precision integers.");
+};
+//
+// Fixed precision (i.e. no allocator), signed-magnitude type with limb-usage count:
+//
+template <unsigned MinBits, cpp_int_check_type Checked>
+struct cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>
 {
    typedef limb_type* limb_pointer;
    typedef const limb_type* const_limb_pointer;
+ typedef mpl::int_<Checked> checked_type;
 
    //
    // Interface invariants:
@@ -272,14 +414,14 @@
    //
    // Direct construction:
    //
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT
       : m_wrapper(i), m_limbs(1), m_sign(false) {}
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT
       : m_wrapper(limb_type(i < 0 ? -i : i)), m_limbs(1), m_sign(i < 0) {}
 #if defined(BOOST_LITTLE_ENDIAN)
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT
       : m_wrapper(i), m_limbs(i > max_limb_value ? 2 : 1), m_sign(false) {}
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT
       : m_wrapper(double_limb_type(i < 0 ? -i : i)), m_limbs(i < 0 ? (-i > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)), m_sign(i < 0) {}
 #endif
    //
@@ -290,8 +432,8 @@
    BOOST_FORCEINLINE const_limb_pointer limbs()const BOOST_NOEXCEPT { return m_wrapper.m_data; }
    BOOST_FORCEINLINE bool sign()const BOOST_NOEXCEPT { return m_sign; }
    BOOST_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT
- {
- m_sign = b;
+ {
+ m_sign = b;
       // Check for zero value:
       if(m_sign && (m_limbs == 1))
       {
@@ -299,13 +441,15 @@
             m_sign = false;
       }
    }
- BOOST_FORCEINLINE void resize(unsigned new_size) BOOST_NOEXCEPT
+ BOOST_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_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_FORCEINLINE void normalize() BOOST_NOEXCEPT
+ BOOST_FORCEINLINE void normalize() BOOST_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());
       p[internal_limb_count-1] &= upper_limb_mask;
       while((m_limbs-1) && !p[m_limbs - 1])--m_limbs;
       if((m_limbs == 1) && (!*p)) m_sign = false; // zero is always unsigned
@@ -321,7 +465,7 @@
    {
       if(this != &o)
       {
- resize(o.size());
+ resize(o.size(), o.size());
          std::copy(o.limbs(), o.limbs() + o.size(), limbs());
          m_sign = o.m_sign;
       }
@@ -338,7 +482,7 @@
    }
    BOOST_FORCEINLINE bool isneg()const BOOST_NOEXCEPT
    {
- return m_sign;
+ return m_sign;
    }
    BOOST_FORCEINLINE void do_swap(cpp_int_base& o) BOOST_NOEXCEPT
    {
@@ -348,12 +492,29 @@
       std::swap(m_limbs, o.m_limbs);
    }
 };
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+
+template <unsigned MinBits, cpp_int_check_type Checked>
+const unsigned cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::limb_bits;
+template <unsigned MinBits, cpp_int_check_type Checked>
+const limb_type cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::max_limb_value;
+template <unsigned MinBits, cpp_int_check_type Checked>
+const limb_type cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::sign_bit_mask;
+template <unsigned MinBits, cpp_int_check_type Checked>
+const unsigned cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::internal_limb_count;
+template <unsigned MinBits, cpp_int_check_type Checked>
+const bool cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, false>::variable;
 
-template <unsigned MinBits>
-struct cpp_int_base<MinBits, false, void, false>
+#endif
+//
+// Fixed precision (i.e. no allocator), unsigned type with limb-usage count:
+//
+template <unsigned MinBits, cpp_int_check_type Checked>
+struct cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>
 {
    typedef limb_type* limb_pointer;
    typedef const limb_type* const_limb_pointer;
+ typedef mpl::int_<Checked> checked_type;
 
    //
    // Interface invariants:
@@ -385,14 +546,14 @@
    //
    // Direct construction:
    //
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT
       : m_wrapper(i), m_limbs(1) {}
- BOOST_FORCEINLINE cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT
+ BOOST_FORCEINLINE cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT
       : m_wrapper(limb_type(i < 0 ? -i : i)), m_limbs(1) { if(i < 0) negate(); }
 #ifdef BOOST_LITTLE_ENDIAN
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT
       : m_wrapper(i), m_limbs(i > max_limb_value ? 2 : 1) {}
- BOOST_FORCEINLINE cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT
+ BOOST_FORCEINLINE cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT
       : m_wrapper(double_limb_type(i < 0 ? -i : i)), m_limbs(i < 0 ? (-i > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)) { if(i < 0) negate(); }
 #endif
    //
@@ -403,13 +564,15 @@
    BOOST_FORCEINLINE const_limb_pointer limbs()const BOOST_NOEXCEPT { return m_wrapper.m_data; }
    BOOST_FORCEINLINE BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return false; }
    BOOST_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT { if(b) negate(); }
- BOOST_FORCEINLINE void resize(unsigned new_size) BOOST_NOEXCEPT
+ BOOST_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_NOEXCEPT_IF((Checked == unchecked))
    {
       m_limbs = (std::min)(new_size, internal_limb_count);
+ detail::verify_new_size(m_limbs, min_size, checked_type());
    }
- BOOST_FORCEINLINE void normalize() BOOST_NOEXCEPT
+ BOOST_FORCEINLINE void normalize() BOOST_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());
       p[internal_limb_count-1] &= upper_limb_mask;
       while((m_limbs-1) && !p[m_limbs - 1])--m_limbs;
    }
@@ -424,26 +587,36 @@
    {
       if(this != &o)
       {
- resize(o.size());
+ resize(o.size(), o.size());
          std::copy(o.limbs(), o.limbs() + o.size(), limbs());
       }
    }
- void negate() BOOST_NOEXCEPT
+private:
+ void check_negate(const mpl::int_<checked>&)
+ {
+ BOOST_THROW_EXCEPTION(std::range_error("Attempt to negate an unsigned number."));
+ }
+ void check_negate(const mpl::int_<unchecked>&){}
+public:
+ void negate() BOOST_NOEXCEPT_IF((Checked == unchecked))
    {
       // Not so much a negate as a complement - this gets called when subtraction
       // would result in a "negative" number:
       unsigned i;
+ if((m_limbs == 1) && (m_wrapper.m_data[0] == 0))
+ return; // negating zero is always zero, and always OK.
+ check_negate(checked_type());
       for(i = m_limbs; i < internal_limb_count; ++i)
          m_wrapper.m_data[i] = 0;
       m_limbs = internal_limb_count;
       for(i = 0; i < internal_limb_count; ++i)
          m_wrapper.m_data[i] = ~m_wrapper.m_data[i];
       normalize();
- eval_increment(static_cast<cpp_int_backend<MinBits, false, void>& >(*this));
+ eval_increment(static_cast<cpp_int_backend<MinBits, MinBits, unsigned_magnitude, Checked, void>& >(*this));
    }
    BOOST_FORCEINLINE BOOST_CONSTEXPR bool isneg()const BOOST_NOEXCEPT
    {
- return false;
+ return false;
    }
    BOOST_FORCEINLINE void do_swap(cpp_int_base& o) BOOST_NOEXCEPT
    {
@@ -452,7 +625,24 @@
       std::swap(m_limbs, o.m_limbs);
    }
 };
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
 
+template <unsigned MinBits, cpp_int_check_type Checked>
+const unsigned cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::limb_bits;
+template <unsigned MinBits, cpp_int_check_type Checked>
+const limb_type cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::max_limb_value;
+template <unsigned MinBits, cpp_int_check_type Checked>
+const limb_type cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::sign_bit_mask;
+template <unsigned MinBits, cpp_int_check_type Checked>
+const unsigned cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::internal_limb_count;
+template <unsigned MinBits, cpp_int_check_type Checked>
+const bool cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, false>::variable;
+
+#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??
+//
 template <unsigned N, bool s>
 struct trivial_limb_type_imp
 {
@@ -467,18 +657,16 @@
 
 template <unsigned N>
 struct trivial_limb_type : public trivial_limb_type_imp<N, N <= sizeof(long long) * CHAR_BIT> {};
-
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4244 4293) // loss of data in initialization, shift count too large
-#endif
-
-template <unsigned MinBits>
-struct cpp_int_base<MinBits, true, void, true>
+//
+// Backend for fixed precision signed-magnitude type which will fit entirely inside a "double_limb_type":
+//
+template <unsigned MinBits, cpp_int_check_type Checked>
+struct cpp_int_base<MinBits, MinBits, signed_magnitude, Checked, void, true>
 {
    typedef typename trivial_limb_type<MinBits>::type local_limb_type;
    typedef local_limb_type* limb_pointer;
    typedef const local_limb_type* const_limb_pointer;
+ typedef mpl::int_<Checked> checked_type;
 protected:
    BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(local_limb_type) * CHAR_BIT);
    BOOST_STATIC_CONSTANT(local_limb_type, limb_mask = MinBits < limb_bits ? (local_limb_type(1) << MinBits) -1 : (~local_limb_type(0)));
@@ -490,20 +678,42 @@
    // Interface invariants:
    //
    BOOST_STATIC_ASSERT_MSG(MinBits <= sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
+protected:
+ template <class T>
+ typename disable_if_c<is_integral<T>::value && (sizeof(T) <= sizeof(local_limb_type)), T>::type check_in_range(T val, const mpl::int_<checked>&)
+ {
+ BOOST_MP_USING_ABS
+ typedef typename common_type<T, local_limb_type>::type common_type;
+
+ if(static_cast<common_type>(abs(val)) > static_cast<common_type>(limb_mask))
+ BOOST_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent."));
+ return val;
+ }
+ template <class T, int C>
+ BOOST_CONSTEXPR T check_in_range(T val, const mpl::int_<C>&)
+ {
+ return val;
+ }
+
+ template <class T>
+ BOOST_CONSTEXPR T check_in_range(T val)
+ {
+ return check_in_range(val, checked_type());
+ }
 
 public:
    //
    // Direct construction:
    //
    template <class SI>
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename enable_if<is_signed<SI> >::type const* = 0) BOOST_NOEXCEPT
- : m_data(i < 0 ? -i : i), m_sign(i < 0) {}
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename enable_if<is_signed<SI> >::type const* = 0) BOOST_NOEXCEPT_IF((Checked == unchecked))
+ : m_data(check_in_range(i) < 0 ? static_cast<local_limb_type>(-i) : static_cast<local_limb_type>(i)), m_sign(i < 0) {}
    template <class UI>
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename enable_if<is_unsigned<UI> >::type const* = 0) BOOST_NOEXCEPT
- : m_data(i), m_sign(false) {}
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename enable_if<is_unsigned<UI> >::type const* = 0) BOOST_NOEXCEPT_IF((Checked == unchecked))
+ : m_data(static_cast<local_limb_type>(check_in_range(i))), m_sign(false) {}
    template <class F>
- BOOST_FORCEINLINE cpp_int_base(F i, typename enable_if<is_floating_point<F> >::type const* = 0) BOOST_NOEXCEPT
- : m_data(std::fabs(i)), m_sign(i < 0) {}
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(F i, typename enable_if<is_floating_point<F> >::type const* = 0) BOOST_NOEXCEPT_IF((Checked == unchecked))
+ : m_data(static_cast<local_limb_type>(std::fabs(check_in_range(i)))), m_sign(i < 0) {}
    //
    // Helper functions for getting at our internal data, and manipulating storage:
    //
@@ -512,19 +722,23 @@
    BOOST_FORCEINLINE const_limb_pointer limbs()const BOOST_NOEXCEPT { return &m_data; }
    BOOST_FORCEINLINE bool sign()const BOOST_NOEXCEPT { return m_sign; }
    BOOST_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT
- {
- m_sign = b;
+ {
+ m_sign = b;
       // Check for zero value:
       if(m_sign && !m_data)
       {
          m_sign = false;
       }
    }
- BOOST_FORCEINLINE void resize(unsigned new_size) BOOST_NOEXCEPT {}
- BOOST_FORCEINLINE void normalize() BOOST_NOEXCEPT
+ BOOST_FORCEINLINE void resize(unsigned new_size, unsigned min_size)
+ {
+ detail::verify_new_size(2, min_size, checked_type());
+ }
+ BOOST_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked))
    {
- if(!m_data)
+ if(!m_data)
          m_sign = false; // zero is always unsigned
+ detail::verify_limb_mask(true, m_data, limb_mask, checked_type());
       m_data &= limb_mask;
    }
 
@@ -547,7 +761,7 @@
    }
    BOOST_FORCEINLINE bool isneg()const BOOST_NOEXCEPT
    {
- return m_sign;
+ return m_sign;
    }
    BOOST_FORCEINLINE void do_swap(cpp_int_base& o) BOOST_NOEXCEPT
    {
@@ -555,38 +769,74 @@
       std::swap(m_data, o.m_data);
    }
 };
-
-template <unsigned MinBits>
-struct cpp_int_base<MinBits, false, void, true>
+//
+// Backend for unsigned fixed precision (i.e. no allocator) type which will fit entirely inside a "double_limb_type":
+//
+template <unsigned MinBits, cpp_int_check_type Checked>
+struct cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, true>
 {
    typedef typename trivial_limb_type<MinBits>::type local_limb_type;
    typedef local_limb_type* limb_pointer;
    typedef const local_limb_type* const_limb_pointer;
 private:
    BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(local_limb_type) * CHAR_BIT);
- BOOST_STATIC_CONSTANT(local_limb_type, limb_mask = MinBits < limb_bits ? (local_limb_type(1) << MinBits) -1 : (~local_limb_type(0)));
+ BOOST_STATIC_CONSTANT(local_limb_type, limb_mask = (~local_limb_type(0)) >> (limb_bits - MinBits));
 
    local_limb_type m_data;
 
+ typedef mpl::int_<Checked> checked_type;
+
    //
    // Interface invariants:
    //
    BOOST_STATIC_ASSERT_MSG(MinBits <= sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
+protected:
+ template <class T>
+ typename disable_if_c<is_integral<T>::value && (sizeof(T) <= sizeof(local_limb_type)), T>::type check_in_range(T val, const mpl::int_<checked>&, const mpl::true_&)
+ {
+ typedef typename common_type<T, local_limb_type>::type common_type;
+
+ if(static_cast<common_type>(val) > limb_mask)
+ BOOST_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent."));
+ }
+ template <class T>
+ typename disable_if_c<is_integral<T>::value && (sizeof(T) <= sizeof(local_limb_type)), T>::type check_in_range(T val, const mpl::int_<checked>&, const mpl::false_&)
+ {
+ typedef typename common_type<T, local_limb_type>::type common_type;
+
+ if(static_cast<common_type>(val) > limb_mask)
+ BOOST_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent."));
+ if(val < 0)
+ BOOST_THROW_EXCEPTION(std::range_error("The argument to an unsigned cpp_int constructor was negative."));
+ return val;
+ }
+ template <class T, int C, class U>
+ BOOST_FORCEINLINE BOOST_CONSTEXPR T check_in_range(T val, const mpl::int_<C>&, const U&)
+ {
+ return val;
+ }
+
+ template <class T>
+ BOOST_FORCEINLINE BOOST_CONSTEXPR T check_in_range(T val)
+ {
+ return check_in_range(val, checked_type(), is_unsigned<T>());
+ }
 
 public:
    //
    // Direct construction:
    //
    template <class SI>
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename enable_if<is_signed<SI> >::type const* = 0) BOOST_NOEXCEPT
- : m_data(i < 0 ? 1 + ~static_cast<local_limb_type>(-i) : static_cast<local_limb_type>(i)) {}
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename enable_if<is_signed<SI> >::type const* = 0) BOOST_NOEXCEPT_IF((Checked == unchecked))
+ : m_data(check_in_range(i) < 0 ? 1 + ~static_cast<local_limb_type>(-i) : static_cast<local_limb_type>(i)) {}
    template <class UI>
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename enable_if<is_unsigned<UI> >::type const* = 0) BOOST_NOEXCEPT
- : m_data(i) {}
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename enable_if<is_unsigned<UI> >::type const* = 0) BOOST_NOEXCEPT_IF((Checked == unchecked))
+ : m_data(static_cast<local_limb_type>(check_in_range(i))) {}
    template <class F>
- BOOST_FORCEINLINE cpp_int_base(F i, typename enable_if<is_floating_point<F> >::type const* = 0) BOOST_NOEXCEPT
- : m_data(std::fabs(i))
+ BOOST_FORCEINLINE cpp_int_base(F i, typename enable_if<is_floating_point<F> >::type const* = 0) BOOST_NOEXCEPT_IF((Checked == unchecked))
+ : m_data(static_cast<local_limb_type>(std::fabs(i)))
    {
+ check_in_range(i);
       if(i < 0)
          negate();
    }
@@ -602,9 +852,13 @@
       if(b)
          negate();
    }
- BOOST_FORCEINLINE void resize(unsigned new_size) BOOST_NOEXCEPT {}
- BOOST_FORCEINLINE void normalize() BOOST_NOEXCEPT
+ BOOST_FORCEINLINE void resize(unsigned new_size, unsigned min_size)
+ {
+ detail::verify_new_size(2, min_size, checked_type());
+ }
+ BOOST_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked))
    {
+ detail::verify_limb_mask(true, m_data, limb_mask, checked_type());
       m_data &= limb_mask;
    }
 
@@ -622,61 +876,70 @@
    }
    BOOST_FORCEINLINE BOOST_CONSTEXPR bool isneg()const BOOST_NOEXCEPT
    {
- return false;
+ return false;
    }
    BOOST_FORCEINLINE void do_swap(cpp_int_base& o) BOOST_NOEXCEPT
    {
       std::swap(m_data, o.m_data);
    }
 };
-
-#ifdef BOOST_MSVC
-#pragma warning(pop)
+//
+// Traits class, lets us know whether type T can be directly converted to the base type,
+// used to enable/disable constructors etc:
+//
+template <class Arg, class Base>
+struct is_allowed_cpp_int_base_conversion : public mpl::if_c<
+ is_same<Arg, limb_type>::value || is_same<Arg, signed_limb_type>::value
+#ifdef BOOST_LITTLE_ENDIAN
+ || is_same<Arg, double_limb_type>::value || is_same<Arg, signed_double_limb_type>::value
 #endif
-
-template <unsigned MinBits, bool Signed, class Allocator>
-const unsigned cpp_int_base<MinBits, Signed, Allocator, false>::limb_bits;
-template <unsigned MinBits, bool Signed, class Allocator>
-const limb_type cpp_int_base<MinBits, Signed, Allocator, false>::max_limb_value;
-template <unsigned MinBits, bool Signed, class Allocator>
-const limb_type cpp_int_base<MinBits, Signed, Allocator, false>::sign_bit_mask;
-template <unsigned MinBits, bool Signed, class Allocator>
-const unsigned cpp_int_base<MinBits, Signed, Allocator, false>::internal_limb_count;
-template <unsigned MinBits, bool Signed, class Allocator>
-const bool cpp_int_base<MinBits, Signed, Allocator, false>::variable;
-
-template <unsigned MinBits>
-const unsigned cpp_int_base<MinBits, true, void, false>::limb_bits;
-template <unsigned MinBits>
-const limb_type cpp_int_base<MinBits, true, void, false>::max_limb_value;
-template <unsigned MinBits>
-const limb_type cpp_int_base<MinBits, true, void, false>::sign_bit_mask;
-template <unsigned MinBits>
-const unsigned cpp_int_base<MinBits, true, void, false>::internal_limb_count;
-template <unsigned MinBits>
-const bool cpp_int_base<MinBits, true, void, false>::variable;
-
-template <unsigned MinBits>
-const unsigned cpp_int_base<MinBits, false, void, false>::limb_bits;
-template <unsigned MinBits>
-const limb_type cpp_int_base<MinBits, false, void, false>::max_limb_value;
-template <unsigned MinBits>
-const limb_type cpp_int_base<MinBits, false, void, false>::sign_bit_mask;
-template <unsigned MinBits>
-const unsigned cpp_int_base<MinBits, false, void, false>::internal_limb_count;
-template <unsigned MinBits>
-const bool cpp_int_base<MinBits, false, void, false>::variable;
-
-template <unsigned MinBits, bool Signed, class Allocator>
-struct cpp_int_backend<MinBits, Signed, Allocator, false> : public cpp_int_base<MinBits, Signed, Allocator, false>
-{
- typedef cpp_int_backend<MinBits, Signed, Allocator> self_type;
- typedef cpp_int_base<MinBits, Signed, Allocator> base_type;
- typedef typename is_trivial_cpp_int<self_type>::type trivial_tag;
+ || (is_trivial_cpp_int<Base>::value && is_arithmetic<Arg>::value),
+ mpl::true_,
+ mpl::false_
+ >::type
+{};
+//
+// Now the actual backend, normalising parameters passed to the base class:
+//
+template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
+struct cpp_int_backend
+ : public cpp_int_base<
+ min_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
+ max_precision<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
+ SignType,
+ Checked,
+ Allocator,
+ is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value>
+{
+ typedef cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> self_type;
+ typedef cpp_int_base<
+ min_precision<self_type>::value,
+ max_precision<self_type>::value,
+ SignType,
+ Checked,
+ Allocator,
+ is_trivial_cpp_int<self_type>::value> base_type;
+ typedef mpl::bool_<is_trivial_cpp_int<self_type>::value> trivial_tag;
 public:
- typedef mpl::list<signed_limb_type, signed_double_limb_type> signed_types;
- typedef mpl::list<limb_type, double_limb_type> unsigned_types;
- typedef mpl::list<long double> float_types;
+ typedef typename mpl::if_<
+ trivial_tag,
+ mpl::list<
+ signed char, short, int, long,
+ long long, 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 long, double_limb_type>,
+ mpl::list<limb_type, double_limb_type>
+ >::type unsigned_types;
+ typedef typename mpl::if_<
+ trivial_tag,
+ mpl::list<float, double, long double>,
+ mpl::list<long double>
+ >::type float_types;
+ typedef mpl::int_<Checked> checked_type;
 
    BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend() BOOST_NOEXCEPT{}
    BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(const cpp_int_backend& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value) : base_type(o) {}
@@ -684,84 +947,207 @@
    BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(cpp_int_backend&& o) BOOST_NOEXCEPT : base_type(static_cast<base_type&&>(o)) {}
 #endif
    //
- // These are templates, so that only args that are *exactly* the types specified are allowed, and conversions
- // are not considered. Without this, conversions may be ambiguous.
+ // Direct construction from arithmetic type:
    //
- template <class LT>
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(LT i, typename enable_if<is_same<LT, limb_type> >::type const* = 0)BOOST_NOEXCEPT
- : base_type(i) {}
- template <class SLT>
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(SLT i, typename enable_if<is_same<SLT, signed_limb_type> >::type const* = 0)BOOST_NOEXCEPT
- : base_type(i) {}
-#if defined(BOOST_LITTLE_ENDIAN)
- template <class LT>
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(LT i, typename enable_if<is_same<LT, double_limb_type> >::type const* = 0)BOOST_NOEXCEPT
- : base_type(i) {}
- template <class SLT>
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(SLT i, typename enable_if<is_same<SLT, signed_double_limb_type> >::type const* = 0)BOOST_NOEXCEPT
+ template <class Arg>
+ BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(Arg i, typename enable_if_c<is_allowed_cpp_int_base_conversion<Arg, base_type>::value >::type const* = 0)BOOST_NOEXCEPT_IF((Checked == unchecked))
       : base_type(i) {}
-#endif
-
- template <unsigned MinBits2, bool Signed2, class Allocator2>
- cpp_int_backend(const cpp_int_backend<MinBits2, Signed2, Allocator2, true>& other)
+
+private:
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+ void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, mpl::true_ const&, mpl::true_ const &)
+ {
+ // Assigning trivial type to trivial type:
+ this->check_in_range(*other.limbs());
+ *this->limbs() = static_cast<typename self_type::local_limb_type>(*other.limbs());
+ this->sign(other.sign());
+ this->normalize();
+ }
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+ void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, mpl::true_ const&, mpl::false_ const &)
+ {
+ // non-trivial to trivial narrowing conversion:
+ double_limb_type v = *other.limbs();
+ if(other.size() > 1)
+ {
+ v |= static_cast<double_limb_type>(other.limbs()[1]) << bits_per_limb;
+ if((Checked == checked) && (other.size() > 2))
+ {
+ BOOST_THROW_EXCEPTION(std::range_error("Assignment of a cpp_int that is out of range for the target type."));
+ }
+ }
+ *this = v;
+ this->sign(other.sign());
+ this->normalize();
+ }
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+ void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, mpl::false_ const&, mpl::true_ const &)
+ {
+ // trivial to non-trivial, treat the trivial argument as if it were an unsigned arithmetic type, then set the sign afterwards:
+ *this = static_cast<
+ typename boost::multiprecision::detail::canonical<
+ typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::local_limb_type,
+ cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>
+ >::type
+ >(*other.limbs());
+ this->sign(other.sign());
+ }
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+ void do_assign(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other, mpl::false_ const&, mpl::false_ const &)
+ {
+ // regular non-trivial to non-trivial assign:
+ this->resize(other.size(), other.size());
+ std::copy(other.limbs(), other.limbs() + (std::min)(other.size(), this->size()), this->limbs());
+ this->sign(other.sign());
+ this->normalize();
+ }
+public:
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+ cpp_int_backend(
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other,
+ typename enable_if_c<is_implicit_cpp_int_conversion<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>, self_type>::value>::type* = 0)
+ : base_type()
+ {
+ do_assign(
+ other,
+ mpl::bool_<is_trivial_cpp_int<self_type>::value>(),
+ mpl::bool_<is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>());
+ }
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+ explicit cpp_int_backend(
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other,
+ typename disable_if_c<is_implicit_cpp_int_conversion<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>, self_type>::value>::type* = 0)
+ : base_type()
+ {
+ do_assign(
+ other,
+ mpl::bool_<is_trivial_cpp_int<self_type>::value>(),
+ mpl::bool_<is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>());
+ }
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+ cpp_int_backend& operator=(
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& other)
+ {
+ do_assign(
+ other,
+ mpl::bool_<is_trivial_cpp_int<self_type>::value>(),
+ mpl::bool_<is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>());
+ return *this;
+ }
+#if 0
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, class Allocator2>
+ cpp_int_backend(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other, typename enable_if_c<is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value >::type* = 0)
       : base_type()
    {
        *this = static_cast<
             typename boost::multiprecision::detail::canonical<
- typename cpp_int_backend<MinBits2, Signed2, Allocator2, true>::local_limb_type,
- cpp_int_backend<MinBits, Signed, Allocator, false>
+ typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>::local_limb_type,
+ cpp_int_backend<MinBits, MaxBits, SignType, Allocator>
>::type
>(*other.limbs());
       this->sign(other.sign());
    }
- template <unsigned MinBits2, bool Signed2, class Allocator2>
- cpp_int_backend& operator=(const cpp_int_backend<MinBits2, Signed2, Allocator2, true>& other)
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, class Allocator2>
+ typename enable_if_c<is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value, cpp_int_backend&>::type
+ operator=(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other)
    {
        *this = static_cast<
             typename boost::multiprecision::detail::canonical<
- typename cpp_int_backend<MinBits2, Signed2, Allocator2, true>::local_limb_type,
- cpp_int_backend<MinBits, Signed, Allocator, false>
+ typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>::local_limb_type,
+ cpp_int_backend<MinBits, MaxBits, SignType, Allocator>
>::type
>(*other.limbs());
       this->sign(other.sign());
       return *this;
    }
 
- template <unsigned MinBits2, bool Signed2, class Allocator2>
- cpp_int_backend(const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& other,
+ template <unsigned MinBits2, unsigned MaxBits2, bool SignType2, class Allocator2>
+ cpp_int_backend(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other,
       typename enable_if_c<
- (Signed || !Signed2)
+ ((is_signed_number<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value || !is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value)
          && (!is_void<Allocator>::value || (is_void<Allocator2>::value && (MinBits >= MinBits2)))
- >::type* = 0)
+ && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value
+ && !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value)
+ >::type* = 0)
       : base_type()
    {
- this->resize(other.size());
+ this->resize(other.size(), other_size());
       std::copy(other.limbs(), other.limbs() + (std::min)(other.size(), this->size()), this->limbs());
       this->sign(other.sign());
    }
 
- template <unsigned MinBits2, bool Signed2, class Allocator2>
- explicit cpp_int_backend(const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& other,
- typename disable_if_c<
- (Signed || !Signed2)
+ template <unsigned MinBits2, unsigned MaxBits2, bool SignType2, class Allocator2>
+ explicit cpp_int_backend(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other,
+ typename enable_if_c<
+ (!((is_signed_number<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value || !is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value)
+ && (!is_void<Allocator>::value || (is_void<Allocator2>::value && (MinBits >= MinBits2))))
+ && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value
+ && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value)
+ >::type* = 0)
+ : base_type()
+ {
+ double_limb_type v = *other.limbs();
+ if(other.size() > 1)
+ v |= static_cast<double_limb_type>(other.limbs()[1]) << bits_per_limb;
+ *this = v;
+ this->sign(other.sign());
+ }
+
+ template <unsigned MinBits2, unsigned MaxBits2, bool SignType2, class Allocator2>
+ explicit cpp_int_backend(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other,
+ typename enable_if_c<
+ (!((is_signed_number<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value || !is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value))
          && (!is_void<Allocator>::value || (is_void<Allocator2>::value && (MinBits >= MinBits2)))
- >::type* = 0)
+ && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value
+ && !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value)
+ >::type* = 0)
       : base_type()
    {
- this->resize(other.size());
+ this->resize(other.size(), other.size());
       std::copy(other.limbs(), other.limbs() + (std::min)(other.size(), this->size()), this->limbs());
       this->sign(other.sign());
    }
 
- template <unsigned MinBits2, bool Signed2, class Allocator2>
- cpp_int_backend& operator=(const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& other)
+ template <unsigned MinBits2, unsigned MaxBits2, bool SignType2, class Allocator2>
+ explicit cpp_int_backend(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other,
+ typename enable_if_c<
+ (!((is_signed_number<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value || !is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value))
+ && (!is_void<Allocator>::value || (is_void<Allocator2>::value && (MinBits >= MinBits2)))
+ && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value
+ && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value)
+ >::type* = 0)
+ : base_type()
+ {
+ double_limb_type v = *other.limbs();
+ if(other.size() > 1)
+ v |= static_cast<double_limb_type>(other.limbs()[1]) << bits_per_limb;
+ *this = v;
+ this->sign(other.sign());
+ }
+
+ template <unsigned MinBits2, unsigned MaxBits2, bool SignType2, class Allocator2>
+ typename enable_if_c<(!is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value
+ && !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value), cpp_int_backend&>::type
+ operator=(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other)
    {
- this->resize(other.size());
+ this->resize(other.size(), other.size());
       std::copy(other.limbs(), other.limbs() + (std::min)(other.size(), this->size()), this->limbs());
       this->sign(other.sign());
       return *this;
    }
 
+ template <unsigned MinBits2, unsigned MaxBits2, bool SignType2, class Allocator2>
+ typename enable_if_c<(!is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2> >::value
+ && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Allocator> >::value), cpp_int_backend&>::type
+ operator=(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Allocator2>& other)
+ {
+ double_limb_type v = *other.limbs();
+ if(other.size() > 1)
+ v |= static_cast<double_limb_type>(other.limbs()[1]) << bits_per_limb;
+ *this = v;
+ this->sign(other.sign());
+ }
+#endif
    BOOST_FORCEINLINE cpp_int_backend& operator = (const cpp_int_backend& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
    {
       this->assign(o);
@@ -774,32 +1160,45 @@
       return *this;
    }
 #endif
- BOOST_FORCEINLINE cpp_int_backend& operator = (limb_type i) BOOST_NOEXCEPT
+private:
+ template <class A>
+ typename enable_if<is_unsigned<A> >::type do_assign_arithmetic(A val, const mpl::true_&)
+ {
+ this->check_in_range(val);
+ *this->limbs() = static_cast<typename self_type::local_limb_type>(val);
+ this->normalize();
+ }
+ template <class A>
+ typename disable_if<is_unsigned<A> >::type do_assign_arithmetic(A val, const mpl::true_&)
    {
- this->resize(1);
+ this->check_in_range(val);
+ *this->limbs() = (val < 0) ? static_cast<typename self_type::local_limb_type>(-val) : static_cast<typename self_type::local_limb_type>(val);
+ this->sign(val < 0);
+ this->normalize();
+ }
+ BOOST_FORCEINLINE void do_assign_arithmetic(limb_type i, const mpl::false_&) BOOST_NOEXCEPT
+ {
+ this->resize(1, 1);
       *this->limbs() = i;
       this->sign(false);
- return *this;
    }
- BOOST_FORCEINLINE cpp_int_backend& operator = (signed_limb_type i) BOOST_NOEXCEPT
+ BOOST_FORCEINLINE void do_assign_arithmetic(signed_limb_type i, const mpl::false_&) BOOST_NOEXCEPT
    {
- this->resize(1);
+ this->resize(1, 1);
       *this->limbs() = static_cast<limb_type>(std::abs(i));
       this->sign(i < 0);
- return *this;
    }
- cpp_int_backend& operator = (double_limb_type i) BOOST_NOEXCEPT_IF(MinBits <= sizeof(double_limb_type) * CHAR_BIT)
+ void do_assign_arithmetic(double_limb_type i, const mpl::false_&)
    {
       BOOST_STATIC_ASSERT(sizeof(i) == 2 * sizeof(limb_type));
       BOOST_STATIC_ASSERT(base_type::internal_limb_count >= 2);
       typename base_type::limb_pointer p = this->limbs();
       *p = static_cast<limb_type>(i);
       p[1] = static_cast<limb_type>(i >> base_type::limb_bits);
- this->resize(p[1] ? 2 : 1);
+ this->resize(p[1] ? 2 : 1, p[1] ? 2 : 1);
       this->sign(false);
- return *this;
    }
- cpp_int_backend& operator = (signed_double_limb_type i) BOOST_NOEXCEPT_IF(MinBits <= sizeof(signed_double_limb_type) * CHAR_BIT)
+ void do_assign_arithmetic(signed_double_limb_type i, const mpl::false_&)
    {
       BOOST_STATIC_ASSERT(sizeof(i) == 2 * sizeof(limb_type));
       BOOST_STATIC_ASSERT(base_type::internal_limb_count >= 2);
@@ -814,12 +1213,11 @@
       typename base_type::limb_pointer p = this->limbs();
       *p = static_cast<limb_type>(i);
       p[1] = static_cast<limb_type>(i >> base_type::limb_bits);
- this->resize(p[1] ? 2 : 1);
+ this->resize(p[1] ? 2 : 1, p[1] ? 2 : 1);
       this->sign(s);
- return *this;
    }
 
- cpp_int_backend& operator = (long double a) BOOST_NOEXCEPT_IF(MinBits <= sizeof(long double) * CHAR_BIT)
+ void do_assign_arithmetic(long double a, const mpl::false_&)
    {
       using default_ops::eval_add;
       using default_ops::eval_subtract;
@@ -828,11 +1226,11 @@
       using std::floor;
 
       if (a == 0) {
- return *this = static_cast<limb_type>(0u);
+ *this = static_cast<limb_type>(0u);
       }
 
       if (a == 1) {
- return *this = static_cast<limb_type>(1u);
+ *this = static_cast<limb_type>(1u);
       }
 
       BOOST_ASSERT(!(boost::math::isinf)(a));
@@ -863,9 +1261,67 @@
          eval_left_shift(*this, e);
       else if(e < 0)
          eval_right_shift(*this, -e);
+ }
+public:
+ template <class Arithmetic>
+ BOOST_FORCEINLINE cpp_int_backend& operator = (Arithmetic val)
+ {
+ do_assign_arithmetic(val, trivial_tag());
       return *this;
    }
- cpp_int_backend& operator = (const char* s)
+private:
+ void do_assign_string(const char* s, const mpl::true_&)
+ {
+ std::size_t n = s ? std::strlen(s) : 0;
+ *this->limbs() = 0;
+ unsigned radix = 10;
+ bool isneg = false;
+ if(n && (*s == '-'))
+ {
+ --n;
+ ++s;
+ isneg = true;
+ }
+ if(n && (*s == '0'))
+ {
+ if((n > 1) && ((s[1] == 'x') || (s[1] == 'X')))
+ {
+ radix = 16;
+ s +=2;
+ n -= 2;
+ }
+ else
+ {
+ radix = 8;
+ n -= 1;
+ }
+ }
+ if(n)
+ {
+ unsigned val;
+ while(*s)
+ {
+ if(*s >= '0' && *s <= '9')
+ val = *s - '0';
+ else if(*s >= 'a' && *s <= 'f')
+ val = 10 + *s - 'a';
+ else if(*s >= 'A' && *s <= 'F')
+ val = 10 + *s - 'A';
+ else
+ val = radix + 1;
+ if(val > radix)
+ {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string."));
+ }
+ *this->limbs() = detail::checked_multiply(*this->limbs(), static_cast<typename base_type::local_limb_type>(radix), checked_type());
+ *this->limbs() = detail::checked_add(*this->limbs(), static_cast<typename base_type::local_limb_type>(val), checked_type());
+ ++s;
+ }
+ }
+ if(isneg)
+ this->negate();
+ }
+ void do_assign_string(const char* s, const mpl::false_&)
    {
       using default_ops::eval_multiply;
       using default_ops::eval_add;
@@ -961,22 +1417,44 @@
       }
       if(isneg)
          this->negate();
+ }
+public:
+ cpp_int_backend& operator = (const char* s)
+ {
+ do_assign_string(s, trivial_tag());
       return *this;
    }
    BOOST_FORCEINLINE void swap(cpp_int_backend& o) BOOST_NOEXCEPT
    {
       this->do_swap(o);
    }
- std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
+private:
+ std::string do_get_trivial_string(std::ios_base::fmtflags f, const mpl::false_&)const
    {
- int base = 10;
- if((f & std::ios_base::oct) == std::ios_base::oct)
+ if(this->sign() && (((f & std::ios_base::hex) == std::ios_base::hex) || ((f & std::ios_base::oct) == std::ios_base::oct)))
+ BOOST_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported."));
+ std::stringstream ss;
+ ss.flags(f & ~std::ios_base::showpos);
+ ss << *this->limbs();
+ std::string result;
+ if(this->sign())
+ result += '-';
+ else if(f & std::ios_base::showpos)
+ result += '+';
+ result += ss.str();
+ return result;
+ }
+ std::string do_get_trivial_string(std::ios_base::fmtflags f, const mpl::true_&)const
+ {
+ // Even though we have only one limb, we can't do IO on it :-(
+ int base = 10;
+ if((f & std::ios_base::oct) == std::ios_base::oct)
          base = 8;
       else if((f & std::ios_base::hex) == std::ios_base::hex)
          base = 16;
       std::string result;
 
- unsigned Bits = this->size() * base_type::limb_bits;
+ unsigned Bits = base_type::limb_bits;
 
       if(base == 8 || base == 16)
       {
@@ -984,21 +1462,21 @@
             BOOST_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported."));
          limb_type shift = base == 8 ? 3 : 4;
          limb_type mask = static_cast<limb_type>((1u << shift) - 1);
- cpp_int_backend t(*this);
+ typename base_type::local_limb_type v = *this->limbs();
          result.assign(Bits / shift + (Bits % shift ? 1 : 0), '0');
          int pos = result.size() - 1;
          for(unsigned i = 0; i < Bits / shift; ++i)
          {
- char c = '0' + static_cast<char>(t.limbs()[0] & mask);
+ char c = '0' + static_cast<char>(v & mask);
             if(c > '9')
                c += 'A' - '9' - 1;
             result[pos--] = c;
- eval_right_shift(t, shift);
+ v >>= shift;
          }
          if(Bits % shift)
          {
             mask = static_cast<limb_type>((1u << (Bits % shift)) - 1);
- char c = '0' + static_cast<char>(t.limbs()[0] & mask);
+ char c = '0' + static_cast<char>(v & mask);
             if(c > '9')
                c += 'A' - '9';
             result[pos] = c;
@@ -1020,37 +1498,17 @@
       {
          result.assign(Bits / 3 + 1, '0');
          int pos = result.size() - 1;
- cpp_int_backend t(*this);
- cpp_int_backend r;
+ typename base_type::local_limb_type v(*this->limbs());
          bool neg = false;
- if(t.sign())
+ if(this->sign())
          {
- t.negate();
             neg = true;
          }
- if(this->size() == 1)
- {
- result = boost::lexical_cast<std::string>(t.limbs()[0]);
- }
- else
+ while(v)
          {
- cpp_int_backend block10;
- block10 = max_block_10;
- while(eval_get_sign(t) != 0)
- {
- cpp_int_backend t2;
- divide_unsigned_helper(&t2, t, block10, r);
- t = t2;
- limb_type v = r.limbs()[0];
- for(unsigned i = 0; i < digits_per_block_10; ++i)
- {
- char c = '0' + v % 10;
- v /= 10;
- result[pos] = c;
- if(pos-- == 0)
- break;
- }
- }
+ result[pos] = (v % 10) + '0';
+ --pos;
+ v /= 10;
          }
          unsigned n = result.find_first_not_of('0');
          result.erase(0, n);
@@ -1063,175 +1521,17 @@
       }
       return result;
    }
- template <unsigned MinBits2, bool Signed2, class Allocator2>
- int compare(const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& o)const BOOST_NOEXCEPT
- {
- if(this->sign() != o.sign())
- return this->sign() ? -1 : 1;
- int result = 0;
- // Only do the compare if the same sign:
- result = compare_unsigned(o);
-
- if(this->sign())
- result = -result;
- return result;
- }
- template <unsigned MinBits2, bool Signed2, class Allocator2>
- int compare_unsigned(const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& o)const BOOST_NOEXCEPT
- {
- if(this->size() != o.size())
- {
- return this->size() > o.size() ? 1 : -1;
- }
- typename base_type::const_limb_pointer pa = this->limbs();
- typename base_type::const_limb_pointer pb = o.limbs();
- for(int i = this->size() - 1; i >= 0; --i)
- {
- if(pa[i] != pb[i])
- return pa[i] > pb[i] ? 1 : -1;
- }
- return 0;
- }
- template <class Arithmetic>
- BOOST_FORCEINLINE typename enable_if<is_arithmetic<Arithmetic>, int>::type compare(Arithmetic i)const BOOST_NOEXCEPT
- {
- // braindead version:
- cpp_int_backend t;
- t = i;
- return compare(t);
- }
-};
-
-template <unsigned MinBits, bool Signed>
-struct cpp_int_backend<MinBits, Signed, void, true> : public cpp_int_base<MinBits, Signed, void, true>
-{
-public:
- typedef cpp_int_backend<MinBits, Signed, void, true> self_type;
- typedef cpp_int_base<MinBits, Signed, void, true> base_type;
- typedef typename is_trivial_cpp_int<self_type>::type trivial_tag;
- typedef mpl::list<
- signed char, short, int, long,
- long long, signed_double_limb_type> signed_types;
- typedef mpl::list<unsigned char, unsigned short, unsigned,
- unsigned long long, double_limb_type> unsigned_types;
- typedef mpl::list<float, double, long double> float_types;
-
- BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(typename base_type::local_limb_type) * CHAR_BIT);
-
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend() BOOST_NOEXCEPT{}
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(const cpp_int_backend& o) BOOST_NOEXCEPT : base_type(o) {}
- BOOST_FORCEINLINE cpp_int_backend& operator = (const cpp_int_backend& o) BOOST_NOEXCEPT
- {
- this->assign(o);
- return *this;
- }
-
- template <class A>
- BOOST_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(A i, typename enable_if<is_arithmetic<A> >::type const* = 0) BOOST_NOEXCEPT
- : base_type(i) {}
-
- template <class SI>
- BOOST_FORCEINLINE typename enable_if<is_signed<SI>, cpp_int_backend&>::type operator = (SI i) BOOST_NOEXCEPT
- {
- *this->limbs() = static_cast<typename base_type::local_limb_type>(std::abs(i));
- this->sign(i < 0);
- return *this;
- }
- template <class UI>
- BOOST_FORCEINLINE typename enable_if<is_unsigned<UI>, cpp_int_backend&>::type operator = (UI i) BOOST_NOEXCEPT
- {
- *this->limbs() = static_cast<typename base_type::local_limb_type>(i);
- return *this;
- }
- template <class F>
- BOOST_FORCEINLINE typename enable_if<is_floating_point<F>, cpp_int_backend&>::type operator = (F i) BOOST_NOEXCEPT
- {
- *this->limbs() = static_cast<typename base_type::local_limb_type>(std::abs(i));
- this->sign(i < 0);
- return *this;
- }
-
- template <unsigned MinBits2, bool Signed2, class Allocator2>
- cpp_int_backend(const cpp_int_backend<MinBits2, Signed2, Allocator2, true>& other,
- typename enable_if_c<
- (MinBits2 <= MinBits)
- && (Signed || !Signed2)
- >::type* = 0) BOOST_NOEXCEPT
- : base_type()
- {
- *this->limbs() = static_cast<typename cpp_int_backend<MinBits, Signed, void, true>::local_limb_type>(*other.limbs());
- this->sign(other.sign());
- }
- template <unsigned MinBits2, bool Signed2, class Allocator2>
- explicit cpp_int_backend(const cpp_int_backend<MinBits2, Signed2, Allocator2, true>& other,
- typename disable_if_c<
- (MinBits2 <= MinBits)
- && (Signed || !Signed2)
- >::type* = 0) BOOST_NOEXCEPT
- : base_type()
- {
- *this->limbs() = static_cast<typename cpp_int_backend<MinBits, Signed, void, true>::local_limb_type>(*other.limbs());
- this->sign(other.sign());
- }
- template <unsigned MinBits2, bool Signed2, class Allocator2>
- cpp_int_backend& operator = (const cpp_int_backend<MinBits2, Signed2, Allocator2, true>& other)BOOST_NOEXCEPT
- {
- *this->limbs() = static_cast<typename cpp_int_backend<MinBits, Signed, void, true>::local_limb_type>(*other.limbs());
- this->sign(other.sign());
- return *this;
- }
- template <unsigned MinBits2, bool Signed2, class Allocator2>
- explicit cpp_int_backend(const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& other)BOOST_NOEXCEPT
- : base_type()
- {
- // We can only ever copy two limbs from other:
- if(other.size() == 1)
- {
- *this->limbs() = *other.limbs();
- }
- else
- {
- *this->limbs() = static_cast<double_limb_type>(*other.limbs()) | (static_cast<double_limb_type>(other.limbs()[1]) << (sizeof(limb_type) * CHAR_BIT));
- }
- this->sign(other.sign());
- }
- template <unsigned MinBits2, bool Signed2, class Allocator2>
- cpp_int_backend& operator=(const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& other)BOOST_NOEXCEPT
- {
- // We can only ever copy two limbs from other:
- if(other.size() == 1)
- {
- *this->limbs() = *other.limbs();
- }
- else
- {
- *this->limbs() = static_cast<double_limb_type>(*other.limbs()) | (static_cast<double_limb_type>(other.limbs()[1]) << (sizeof(limb_type) * CHAR_BIT));
- }
- this->sign(other.sign());
- return *this;
- }
-
- BOOST_FORCEINLINE void swap(cpp_int_backend& o) BOOST_NOEXCEPT
- {
- this->do_swap(o);
- }
-private:
- std::string str(std::ios_base::fmtflags f, const mpl::false_&)const
+ std::string do_get_string(std::ios_base::fmtflags f, const mpl::true_&)const
    {
- std::stringstream ss;
- ss.flags(f & ~std::ios_base::showpos);
- ss << *this->limbs();
- std::string result;
- if(this->sign())
- result += '-';
- else if(f & std::ios_base::showpos)
- result += '+';
- result += ss.str();
- return result;
+#ifdef BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO
+ return do_get_trivial_string(f, mpl::bool_<is_same<typename base_type::local_limb_type, double_limb_type>::value>());
+#else
+ return do_get_trivial_string(f, mpl::bool_<false>());
+#endif
    }
- std::string str(std::ios_base::fmtflags f, const mpl::true_&)const
+ std::string do_get_string(std::ios_base::fmtflags f, const mpl::false_&)const
    {
- // Even though we have only one limb, we can't do IO on it :-(
+ using default_ops::eval_get_sign;
       int base = 10;
       if((f & std::ios_base::oct) == std::ios_base::oct)
          base = 8;
@@ -1239,7 +1539,7 @@
          base = 16;
       std::string result;
 
- unsigned Bits = base_type::limb_bits;
+ unsigned Bits = this->size() * base_type::limb_bits;
 
       if(base == 8 || base == 16)
       {
@@ -1247,21 +1547,21 @@
             BOOST_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported."));
          limb_type shift = base == 8 ? 3 : 4;
          limb_type mask = static_cast<limb_type>((1u << shift) - 1);
- typename base_type::local_limb_type v = *this->limbs();
+ cpp_int_backend t(*this);
          result.assign(Bits / shift + (Bits % shift ? 1 : 0), '0');
          int pos = result.size() - 1;
          for(unsigned i = 0; i < Bits / shift; ++i)
          {
- char c = '0' + static_cast<char>(v & mask);
+ char c = '0' + static_cast<char>(t.limbs()[0] & mask);
             if(c > '9')
                c += 'A' - '9' - 1;
             result[pos--] = c;
- v >>= shift;
+ eval_right_shift(t, shift);
          }
          if(Bits % shift)
          {
             mask = static_cast<limb_type>((1u << (Bits % shift)) - 1);
- char c = '0' + static_cast<char>(v & mask);
+ char c = '0' + static_cast<char>(t.limbs()[0] & mask);
             if(c > '9')
                c += 'A' - '9';
             result[pos] = c;
@@ -1283,17 +1583,37 @@
       {
          result.assign(Bits / 3 + 1, '0');
          int pos = result.size() - 1;
- typename base_type::local_limb_type v(*this->limbs());
+ cpp_int_backend t(*this);
+ cpp_int_backend r;
          bool neg = false;
- if(this->sign())
+ if(t.sign())
          {
+ t.negate();
             neg = true;
          }
- while(v)
+ if(this->size() == 1)
          {
- result[pos] = (v % 10) + '0';
- --pos;
- v /= 10;
+ result = boost::lexical_cast<std::string>(t.limbs()[0]);
+ }
+ else
+ {
+ cpp_int_backend block10;
+ block10 = max_block_10;
+ while(eval_get_sign(t) != 0)
+ {
+ cpp_int_backend t2;
+ divide_unsigned_helper(&t2, t, block10, r);
+ t = t2;
+ limb_type v = r.limbs()[0];
+ for(unsigned i = 0; i < digits_per_block_10; ++i)
+ {
+ char c = '0' + v % 10;
+ v /= 10;
+ result[pos] = c;
+ if(pos-- == 0)
+ break;
+ }
+ }
          }
          unsigned n = result.find_first_not_of('0');
          result.erase(0, n);
@@ -1307,2158 +1627,158 @@
       return result;
    }
 public:
- cpp_int_backend& operator = (const char* s)
+ std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
    {
- std::size_t n = s ? std::strlen(s) : 0;
- *this->limbs() = 0;
- unsigned radix = 10;
- bool isneg = false;
- if(n && (*s == '-'))
- {
- --n;
- ++s;
- isneg = true;
- }
- if(n && (*s == '0'))
+ return do_get_string(f, trivial_tag());
+ }
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+ typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value,
+ int
+ >::type compare(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o)const BOOST_NOEXCEPT
+ {
+ if(this->sign() != o.sign())
+ return this->sign() ? -1 : 1;
+
+ // Only do the compare if the same sign:
+ int result = compare_unsigned(o);
+
+ if(this->sign())
+ result = -result;
+ return result;
+ }
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+ typename enable_if_c<
+ is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value,
+ int
+ >::type compare(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o)const
+ {
+ cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> t(*this);
+ return t.compare(o);
+ }
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+ typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value,
+ int
+ >::type compare(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o)const
+ {
+ cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> t(o);
+ return compare(t);
+ }
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+ typename enable_if_c<
+ is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value,
+ int
+ >::type compare(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o)const BOOST_NOEXCEPT
+ {
+ if(this->sign())
       {
- if((n > 1) && ((s[1] == 'x') || (s[1] == 'X')))
+ if(o.sign())
          {
- radix = 16;
- s +=2;
- n -= 2;
+ return *this->limbs() < *o.limbs() ? 1 : (*this->limbs() > *o.limbs() ? -1 : 0);
          }
          else
- {
- radix = 8;
- n -= 1;
- }
+ return -1;
       }
- if(n)
+ else
       {
- unsigned val;
- while(*s)
- {
- if(*s >= '0' && *s <= '9')
- val = *s - '0';
- else if(*s >= 'a' && *s <= 'f')
- val = 10 + *s - 'a';
- else if(*s >= 'A' && *s <= 'F')
- val = 10 + *s - 'A';
- else
- val = radix + 1;
- if(val > radix)
- {
- BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string."));
- }
- *this->limbs() *= radix;
- *this->limbs() += val;
- ++s;
- }
- }
- if(isneg)
- this->negate();
- return *this;
- }
- std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
- {
-#ifdef BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO
- return str(f, mpl::bool_<is_same<typename base_type::local_limb_type, double_limb_type>::value>());
-#else
- return str(f, mpl::bool_<false>());
-#endif
- }
- int compare(const cpp_int_backend& o)const BOOST_NOEXCEPT
- {
- if(this->sign() != o.sign())
- return this->sign() ? -1 : 1;
- int result = 0;
- // Only do the compare if the same sign:
- result = *this->limbs() == *o.limbs() ? 0 : *this->limbs() < *o.limbs() ? -1 : 1;
-
- if(this->sign())
- result = -result;
- return result;
- }
- template <class Arithmetic>
- BOOST_FORCEINLINE typename enable_if<is_arithmetic<Arithmetic>, int>::type compare(Arithmetic i)const BOOST_NOEXCEPT
- {
- // braindead version:
- cpp_int_backend t;
- t = i;
- return compare(t);
- }
-};
-
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE bool eval_eq(const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const cpp_int_backend<MinBits, Signed, Allocator, false>& b) BOOST_NOEXCEPT
-{
- return (a.sign() == b.sign())
- && (a.size() == b.size())
- && std::equal(a.limbs(), a.limbs() + a.size(), b.limbs());
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE bool eval_eq(const cpp_int_backend<MinBits1, Signed1, Allocator1, false>& a, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& b) BOOST_NOEXCEPT
-{
- return (a.sign() == b.sign())
- && (a.size() == b.size())
- && std::equal(a.limbs(), a.limbs() + a.size(), b.limbs());
-}
-template <unsigned MinBits, class Allocator>
-BOOST_FORCEINLINE bool eval_eq(const cpp_int_backend<MinBits, true, Allocator, false>& a, limb_type b) BOOST_NOEXCEPT
-{
- return (a.sign() == false)
- && (a.size() == 1)
- && (*a.limbs() == b);
-}
-template <unsigned MinBits, class Allocator>
-BOOST_FORCEINLINE bool eval_eq(const cpp_int_backend<MinBits, true, Allocator, false>& a, signed_limb_type b) BOOST_NOEXCEPT
-{
- return (a.sign() == (b < 0))
- && (a.size() == 1)
- && (*a.limbs() == static_cast<limb_type>(std::abs(b)));
-}
-template <unsigned MinBits, class Allocator>
-BOOST_FORCEINLINE bool eval_eq(const cpp_int_backend<MinBits, false, Allocator, false>& a, limb_type b) BOOST_NOEXCEPT
-{
- return (a.size() == 1)
- && (*a.limbs() == b);
-}
-template <unsigned MinBits, class Allocator>
-BOOST_FORCEINLINE bool eval_eq(const cpp_int_backend<MinBits, false, Allocator, false>& a, signed_limb_type b) BOOST_NOEXCEPT
-{
- return (b < 0) ? eval_eq(a, cpp_int_backend<MinBits, false, Allocator, false>(b)) : eval_eq(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison
-}
-
-template <unsigned MinBits, class Allocator>
-BOOST_FORCEINLINE bool eval_lt(const cpp_int_backend<MinBits, true, Allocator, false>& a, limb_type b) BOOST_NOEXCEPT
-{
- if(a.sign())
- return true;
- if(a.size() > 1)
- return false;
- return *a.limbs() < b;
-}
-template <unsigned MinBits, class Allocator>
-inline bool eval_lt(const cpp_int_backend<MinBits, true, Allocator, false>& a, signed_limb_type b) BOOST_NOEXCEPT
-{
- if((b == 0) || (a.sign() != (b < 0)))
- return a.sign();
- if(a.sign())
- {
- if(a.size() > 1)
- return true;
- return *a.limbs() > static_cast<limb_type>(std::abs(b));
- }
- else
- {
- if(a.size() > 1)
- return false;
- return *a.limbs() < static_cast<limb_type>(b);
- }
-}
-
-template <unsigned MinBits, class Allocator>
-BOOST_FORCEINLINE bool eval_lt(const cpp_int_backend<MinBits, false, Allocator, false>& a, limb_type b) BOOST_NOEXCEPT
-{
- if(a.size() > 1)
- return false;
- return *a.limbs() < b;
-}
-template <unsigned MinBits, class Allocator>
-BOOST_FORCEINLINE bool eval_lt(const cpp_int_backend<MinBits, false, Allocator, false>& a, signed_limb_type b) BOOST_NOEXCEPT
-{
- return (b < 0) ? a.compare(b) < 0 : eval_lt(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison
-}
-
-template <unsigned MinBits, class Allocator>
-BOOST_FORCEINLINE bool eval_gt(const cpp_int_backend<MinBits, true, Allocator, false>& a, limb_type b) BOOST_NOEXCEPT
-{
- if(a.sign())
- return false;
- if(a.size() > 1)
- return true;
- return *a.limbs() > b;
-}
-template <unsigned MinBits, class Allocator>
-inline bool eval_gt(const cpp_int_backend<MinBits, true, Allocator, false>& a, signed_limb_type b) BOOST_NOEXCEPT
-{
- if(b == 0)
- return !a.sign() && ((a.size() > 1) || *a.limbs());
- if(a.sign() != (b < 0))
- return !a.sign();
- if(a.sign())
- {
- if(a.size() > 1)
- return false;
- return *a.limbs() < static_cast<limb_type>(std::abs(b));
- }
- else
- {
- if(a.size() > 1)
- return true;
- return *a.limbs() > static_cast<limb_type>(b);
- }
-}
-
-template <unsigned MinBits, class Allocator>
-BOOST_FORCEINLINE bool eval_gt(const cpp_int_backend<MinBits, false, Allocator, false>& a, limb_type b) BOOST_NOEXCEPT
-{
- if(a.size() > 1)
- return true;
- return *a.limbs() > b;
-}
-template <unsigned MinBits, class Allocator>
-BOOST_FORCEINLINE bool eval_gt(const cpp_int_backend<MinBits, false, Allocator, false>& a, signed_limb_type b) BOOST_NOEXCEPT
-{
- return (b < 0) ? a.compare(b) > 0 : eval_gt(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison.
-}
-
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_add(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- eval_add(result, result, o);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2, unsigned MinBits3, bool Signed3, class Allocator3>
-inline void add_unsigned(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const cpp_int_backend<MinBits3, Signed3, Allocator3, false>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- using std::swap;
-
- // Nothing fancy, just let uintmax_t take the strain:
- double_limb_type carry = 0;
- unsigned m, x;
- unsigned as = a.size();
- unsigned bs = b.size();
- minmax(as, bs, m, x);
- if(x == 1)
- {
- bool s = a.sign();
- result = static_cast<double_limb_type>(*a.limbs()) + static_cast<double_limb_type>(*b.limbs());
- result.sign(s);
- return;
- }
- result.resize(x);
- typename cpp_int_backend<MinBits2, Signed2, Allocator2, false>::const_limb_pointer pa = a.limbs();
- typename cpp_int_backend<MinBits3, Signed3, Allocator3, false>::const_limb_pointer pb = b.limbs();
- typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer pr = result.limbs();
- typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer pr_end = pr + m;
-
- if(as < bs)
- swap(pa, pb);
-
- // First where a and b overlap:
- while(pr != pr_end)
- {
- carry += static_cast<double_limb_type>(*pa) + static_cast<double_limb_type>(*pb);
- *pr = static_cast<limb_type>(carry);
- carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- ++pr, ++pa, ++pb;
- }
- pr_end += x - m;
- // Now where only a has digits:
- while(pr != pr_end)
- {
- if(!carry)
- {
- if(pa != pr)
- std::copy(pa, pa + (pr_end - pr), pr);
- break;
- }
- carry += static_cast<double_limb_type>(*pa);
- *pr = static_cast<limb_type>(carry);
- carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- ++pr, ++pa;
- }
- if(carry)
- {
- result.resize(x + 1);
- // We overflowed, need to add one more limb:
- if(cpp_int_backend<MinBits1, Signed1, Allocator1, false>::variable || (result.size() > x))
- result.limbs()[x] = static_cast<limb_type>(carry);
- }
- result.normalize();
- result.sign(a.sign());
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2, unsigned MinBits3, bool Signed3, class Allocator3>
-inline void eval_add(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const cpp_int_backend<MinBits3, Signed3, Allocator3, false>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- if(a.sign() != b.sign())
- {
- subtract_unsigned(result, a, b);
- return;
- }
- add_unsigned(result, a, b);
-}
-
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-inline void add_unsigned(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- // Addition using modular arithmatic.
- // Nothing fancy, just let uintmax_t take the strain:
- if(&result != &a)
- result.resize(a.size());
- double_limb_type carry = o;
- typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer pr = result.limbs();
- typename cpp_int_backend<MinBits2, Signed2, Allocator2, false>::const_limb_pointer pa = a.limbs();
- unsigned i = 0;
- for(; carry && (i < result.size()); ++i)
- {
- carry += static_cast<double_limb_type>(pa[i]);
- pr[i] = static_cast<limb_type>(carry);
- carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- }
- if(&a != &result)
- {
- for(; i < result.size(); ++i)
- pr[i] = pa[i];
- }
- if(carry)
- {
- unsigned x = result.size();
- result.resize(x + 1);
- // We overflowed, need to add one more limb:
- if(cpp_int_backend<MinBits1, Signed1, Allocator1, false>::variable || (result.size() > x))
- result.limbs()[x] = static_cast<limb_type>(carry);
- }
- result.normalize();
- result.sign(a.sign());
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_add(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- if(result.sign())
- {
- subtract_unsigned(result, o);
- }
- else
- add_unsigned(result, result, o);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_add(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- if(a.sign())
- {
- result = a;
- subtract_unsigned(result, o);
- }
- else
- add_unsigned(result, a, o);
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_add(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const signed_limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- if(o < 0)
- eval_subtract(result, static_cast<limb_type>(-o));
- else if(o > 0)
- eval_add(result, static_cast<limb_type>(o));
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_add(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const signed_limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- if(o < 0)
- eval_subtract(result, a, static_cast<limb_type>(-o));
- else if(o > 0)
- eval_add(result, a, static_cast<limb_type>(o));
- else if(&result != &a)
- result = a;
-}
-
-template <unsigned MinBits, bool Signed, class Allocator>
-inline void subtract_unsigned(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- // Subtract one limb.
- // Nothing fancy, just let uintmax_t take the strain:
- BOOST_STATIC_CONSTANT(double_limb_type, borrow = static_cast<double_limb_type>(cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value) + 1);
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer p = result.limbs();
- if(*p > o)
- {
- *p -= o;
- }
- else if(result.size() == 1)
- {
- *p = o - *p;
- result.negate();
- }
- else
- {
- *p = static_cast<limb_type>((borrow + *p) - o);
- ++p;
- while(!*p)
- {
- *p = cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value;
- ++p;
- }
- --*p;
- result.normalize();
- }
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_subtract(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- if(result.sign())
- {
- add_unsigned(result, result, o);
- }
- else
- subtract_unsigned(result, o);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_subtract(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- if(a.sign())
- {
- add_unsigned(result, a, o);
- }
- else
- {
- result = a;
- subtract_unsigned(result, o);
- }
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_subtract(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const signed_limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- if(o)
- {
- if(o < 0)
- eval_add(result, static_cast<limb_type>(-o));
- else
- eval_subtract(result, static_cast<limb_type>(o));
- }
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_subtract(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const signed_limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- if(o)
- {
- if(o < 0)
- eval_add(result, a, static_cast<limb_type>(-o));
- else
- eval_subtract(result, a, static_cast<limb_type>(o));
- }
- else if(&result != &a)
- result = a;
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_increment(cpp_int_backend<MinBits, Signed, Allocator, false>& result) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- static const limb_type one = 1;
- if(!result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value))
- ++result.limbs()[0];
- else if(result.sign() && result.limbs()[0])
- --result.limbs()[0];
- else
- eval_add(result, one);
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_decrement(cpp_int_backend<MinBits, Signed, Allocator, false>& result) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- static const limb_type one = 1;
- if(!result.sign() && result.limbs()[0])
- --result.limbs()[0];
- else if(result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value))
- ++result.limbs()[0];
- else
- eval_subtract(result, one);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_subtract(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- eval_subtract(result, result, o);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2, unsigned MinBits3, bool Signed3, class Allocator3>
-inline void subtract_unsigned(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const cpp_int_backend<MinBits3, Signed3, Allocator3, false>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- using std::swap;
-
- // Nothing fancy, just let uintmax_t take the strain:
- double_limb_type borrow = 0;
- unsigned m, x;
- minmax(a.size(), b.size(), m, x);
- //
- // special cases for small limb counts:
- //
- if(x == 1)
- {
- bool s = a.sign();
- limb_type al = *a.limbs();
- limb_type bl = *b.limbs();
- if(bl > al)
- {
- std::swap(al, bl);
- s = !s;
- }
- result = al - bl;
- result.sign(s);
- return;
- }
- // This isn't used till later, but comparison has to occur before we resize the result,
- // as that may also resize a or b if this is an inplace operation:
- int c = a.compare_unsigned(b);
- // Set up the result vector:
- result.resize(x);
- // Now that a, b, and result are stable, get pointers to their limbs:
- typename cpp_int_backend<MinBits2, Signed2, Allocator2, false>::const_limb_pointer pa = a.limbs();
- typename cpp_int_backend<MinBits3, Signed3, Allocator3, false>::const_limb_pointer pb = b.limbs();
- typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer pr = result.limbs();
- bool swapped = false;
- if(c < 0)
- {
- swap(pa, pb);
- swapped = true;
- }
- else if(c == 0)
- {
- result = static_cast<limb_type>(0);
- return;
- }
-
- unsigned i = 0;
- // First where a and b overlap:
- while(i < m)
- {
- borrow = static_cast<double_limb_type>(pa[i]) - static_cast<double_limb_type>(pb[i]) - borrow;
- pr[i] = static_cast<limb_type>(borrow);
- borrow = (borrow >> cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits) & 1u;
- ++i;
- }
- // Now where only a has digits, only as long as we've borrowed:
- while(borrow && (i < x))
- {
- borrow = static_cast<double_limb_type>(pa[i]) - borrow;
- pr[i] = static_cast<limb_type>(borrow);
- borrow = (borrow >> cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits) & 1u;
- ++i;
- }
- // Any remaining digits are the same as those in pa:
- if((x != i) && (pa != pr))
- std::copy(pa + i, pa + x, pr + i);
- BOOST_ASSERT(0 == borrow);
-
- //
- // We may have lost digits, if so update limb usage count:
- //
- result.normalize();
- result.sign(a.sign());
- if(swapped)
- result.negate();
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2, unsigned MinBits3, bool Signed3, class Allocator3>
-BOOST_FORCEINLINE void eval_subtract(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const cpp_int_backend<MinBits3, Signed3, Allocator3, false>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- if(a.sign() != b.sign())
- {
- add_unsigned(result, a, b);
- return;
- }
- subtract_unsigned(result, a, b);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2, unsigned MinBits3, bool Signed3, class Allocator3>
-inline void eval_multiply(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const cpp_int_backend<MinBits3, Signed3, Allocator3, false>& b) BOOST_NOEXCEPT_IF(boost::is_void<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:
- //
- // Special cases first:
- //
- unsigned as = a.size();
- unsigned bs = b.size();
- typename cpp_int_backend<MinBits2, Signed2, Allocator2, false>::const_limb_pointer pa = a.limbs();
- typename cpp_int_backend<MinBits3, Signed3, Allocator3, false>::const_limb_pointer pb = b.limbs();
- if(as == 1)
- {
- bool s = b.sign() != a.sign();
- if(bs == 1)
- {
- result = static_cast<double_limb_type>(*pa) * static_cast<double_limb_type>(*pb);
- }
- else
- {
- limb_type l = *pa;
- eval_multiply(result, b, l);
- }
- result.sign(s);
- return;
- }
- if(bs == 1)
- {
- bool s = b.sign() != a.sign();
- limb_type l = *pb;
- eval_multiply(result, a, l);
- result.sign(s);
- return;
- }
-
- if((void*)&result == (void*)&a)
- {
- cpp_int_backend<MinBits1, Signed1, Allocator1, false> t(a);
- eval_multiply(result, t, b);
- return;
- }
- if((void*)&result == (void*)&b)
- {
- cpp_int_backend<MinBits1, Signed1, Allocator1, false> t(b);
- eval_multiply(result, a, t);
- return;
- }
-
- result.resize(as + bs);
- typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer pr = result.limbs();
-
- static const double_limb_type limb_max = ~static_cast<limb_type>(0u);
- static const double_limb_type double_limb_max = ~static_cast<double_limb_type>(0u);
- BOOST_STATIC_ASSERT(double_limb_max - 2 * limb_max >= limb_max * limb_max);
-
- double_limb_type carry = 0;
- std::memset(pr, 0, result.size() * sizeof(limb_type));
- for(unsigned i = 0; i < as; ++i)
- {
- unsigned inner_limit = cpp_int_backend<MinBits1, Signed1, Allocator1, false>::variable ? bs : (std::min)(result.size() - i, bs);
- for(unsigned j = 0; j < inner_limit; ++j)
- {
- BOOST_ASSERT(i+j < result.size());
- 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, Signed1, Allocator1, false>::max_limb_value) * static_cast<double_limb_type>(cpp_int_backend<MinBits1, Signed1, Allocator1, false>::max_limb_value)));
- 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];
- pr[i + j] = static_cast<limb_type>(carry);
- carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- BOOST_ASSERT(carry <= (cpp_int_backend<MinBits1, Signed1, Allocator1, false>::max_limb_value));
- }
- if(cpp_int_backend<MinBits1, Signed1, Allocator1, false>::variable || (i + bs < result.size()))
- pr[i + bs] = static_cast<limb_type>(carry);
- carry = 0;
- }
- result.normalize();
- //
- // Set the sign of the result:
- //
- result.sign(a.sign() != b.sign());
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_multiply(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- eval_multiply(result, result, a);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-inline void eval_multiply(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- if(!val)
- {
- result = static_cast<limb_type>(0);
- return;
- }
- if((void*)&a != (void*)&result)
- result.resize(a.size());
- double_limb_type carry = 0;
- typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer p = result.limbs();
- typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer pe = result.limbs() + result.size();
- typename cpp_int_backend<MinBits2, Signed2, Allocator2, false>::const_limb_pointer pa = a.limbs();
- while(p != pe)
- {
- carry += static_cast<double_limb_type>(*pa) * static_cast<double_limb_type>(val);
- *p = static_cast<limb_type>(carry);
- carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- ++p, ++pa;
- }
- if(carry)
- {
- unsigned i = result.size();
- result.resize(i + 1);
- if(cpp_int_backend<MinBits1, Signed1, Allocator1, false>::variable || (result.size() > i))
- result.limbs()[i] = static_cast<limb_type>(carry);
- }
- result.sign(a.sign());
- if(!cpp_int_backend<MinBits1, Signed1, Allocator1, false>::variable)
- result.normalize();
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- eval_multiply(result, result, val);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_multiply(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const double_limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- if(val <= (std::numeric_limits<limb_type>::max)())
- {
- eval_multiply(result, a, static_cast<limb_type>(val));
- }
- else
- {
- cpp_int_backend<MinBits1, Signed1, Allocator1, false> t(val);
- eval_multiply(result, a, t);
- }
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const double_limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- eval_multiply(result, result, val);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_multiply(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const signed_limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- if(val > 0)
- eval_multiply(result, a, static_cast<limb_type>(val));
- else
- {
- eval_multiply(result, a, static_cast<limb_type>(-val));
- result.negate();
- }
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const signed_limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- eval_multiply(result, result, val);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-inline void eval_multiply(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const signed_double_limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- if(val > 0)
- {
- if(val <= (std::numeric_limits<limb_type>::max)())
- {
- eval_multiply(result, a, static_cast<limb_type>(val));
- return;
- }
- }
- else if(val >= -static_cast<signed_double_limb_type>((std::numeric_limits<limb_type>::max)()))
- {
- eval_multiply(result, a, static_cast<limb_type>(-val));
- result.negate();
- return;
- }
- cpp_int_backend<MinBits1, Signed1, Allocator1, false> t(val);
- eval_multiply(result, a, t);
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const signed_double_limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- eval_multiply(result, result, val);
-}
-
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2, unsigned MinBits3, bool Signed3, class Allocator3>
-void divide_unsigned_helper(cpp_int_backend<MinBits1, Signed1, Allocator1, false>* result,
- const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& x,
- const cpp_int_backend<MinBits3, Signed3, Allocator3, false>& y,
- cpp_int_backend<MinBits1, Signed1, Allocator1, false>& r)
-{
- if(((void*)result == (void*)&x) || ((void*)&r == (void*)&x))
- {
- cpp_int_backend<MinBits2, Signed2, Allocator2, false> t(x);
- divide_unsigned_helper(result, t, y, r);
- return;
- }
- if(((void*)result == (void*)&y) || ((void*)&r == (void*)&y))
- {
- cpp_int_backend<MinBits3, Signed3, Allocator3, false> t(y);
- divide_unsigned_helper(result, x, t, r);
- return;
- }
-
- /*
- Very simple, fairly braindead long division.
- Start by setting the remainder equal to x, and the
- result equal to 0. Then in each loop we calculate our
- "best guess" for how many times y divides into r,
- add our guess to the result, and subtract guess*y
- from the remainder r. One wrinkle is that the remainder
- may go negative, in which case we subtract the current guess
- from the result rather than adding. The value of the guess
- is determined by dividing the most-significant-limb of the
- current remainder by the most-significant-limb of y.
-
- Note that there are more efficient algorithms than this
- available, in particular see Knuth Vol 2. However for small
- numbers of limbs this generally outperforms the alternatives
- and avoids the normalisation step which would require extra storage.
- */
-
-
- using default_ops::eval_subtract;
-
- if(result == &r)
- {
- cpp_int_backend<MinBits1, Signed1, Allocator1, false> rem;
- divide_unsigned_helper(result, x, y, rem);
- r = rem;
- return;
- }
-
- //
- // Find the most significant words of numerator and denominator.
- //
- limb_type y_order = y.size() - 1;
-
- if(y_order == 0)
- {
- //
- // Only a single non-zero limb in the denominator, in this case
- // we can use a specialized divide-by-single-limb routine which is
- // much faster. This also handles division by zero:
- //
- divide_unsigned_helper(result, x, y.limbs()[y_order], r);
- return;
- }
-
- typename cpp_int_backend<MinBits2, Signed2, Allocator2, false>::const_limb_pointer px = x.limbs();
- typename cpp_int_backend<MinBits3, Signed3, Allocator3, false>::const_limb_pointer py = y.limbs();
-
- limb_type r_order = x.size() - 1;
- if((r_order == 0) && (*px == 0))
- {
- // x is zero, so is the result:
- r = y;
- if(result)
- *result = x;
- return;
- }
-
- r = x;
- r.sign(false);
- if(result)
- *result = static_cast<limb_type>(0u);
- //
- // Check if the remainder is already less than the divisor, if so
- // we already have the result. Note we try and avoid a full compare
- // if we can:
- //
- if(r_order <= y_order)
- {
- if((r_order < y_order) || (r.compare_unsigned(y) < 0))
- {
- return;
- }
- }
-
- cpp_int_backend<MinBits1, Signed1, Allocator1, false> t;
- bool r_neg = false;
-
- //
- // See if we can short-circuit long division, and use basic arithmetic instead:
- //
- if(r_order == 0)
- {
- if(result)
- *result = px[0] / py[0];
- r = px[0] % py[0];
- return;
- }
- else if(r_order == 1)
- {
- double_limb_type a, b;
- a = (static_cast<double_limb_type>(px[1]) << cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits) | px[0];
- b = y_order ?
- (static_cast<double_limb_type>(py[1]) << cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits) | py[0]
- : py[0];
- if(result)
- *result = a / b;
- r = a % b;
- return;
- }
- //
- // prepare result:
- //
- if(result)
- result->resize(1 + r_order - y_order);
- typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::const_limb_pointer prem = r.limbs();
- // This is initialised just to keep the compiler from emitting useless warnings later on:
- typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer pr
- = typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer();
- if(result)
- {
- pr = result->limbs();
- for(unsigned i = 1; i < 1 + r_order - y_order; ++i)
- pr[i] = 0;
- }
- bool first_pass = true;
-
- do
- {
- //
- // Calculate our best guess for how many times y divides into r:
- //
- limb_type guess;
- if((prem[r_order] <= py[y_order]) && (r_order > 0))
- {
- double_limb_type a, b, v;
- a = (static_cast<double_limb_type>(prem[r_order]) << cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits) | prem[r_order - 1];
- b = py[y_order];
- v = a / b;
- if(v > cpp_int_backend<MinBits1, Signed1, Allocator1, false>::max_limb_value)
- guess = 1;
- else
- {
- guess = static_cast<limb_type>(v);
- --r_order;
- }
- }
- else if(r_order == 0)
- {
- guess = prem[0] / py[y_order];
- }
- else
- {
- double_limb_type a, b, v;
- a = (static_cast<double_limb_type>(prem[r_order]) << cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits) | prem[r_order - 1];
- b = (y_order > 0) ? (static_cast<double_limb_type>(py[y_order]) << cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits) | py[y_order - 1] : (static_cast<double_limb_type>(py[y_order]) << cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits);
- v = a / b;
- guess = static_cast<limb_type>(v);
- }
- BOOST_ASSERT(guess); // If the guess ever gets to zero we go on forever....
- //
- // Update result:
- //
- limb_type shift = r_order - y_order;
- if(result)
- {
- if(r_neg)
- {
- if(pr[shift] > guess)
- pr[shift] -= guess;
- else
- {
- t.resize(shift + 1);
- t.limbs()[shift] = guess;
- for(unsigned i = 0; i < shift; ++i)
- t.limbs()[i] = 0;
- eval_subtract(*result, t);
- }
- }
- else if(cpp_int_backend<MinBits1, Signed1, Allocator1, false>::max_limb_value - pr[shift] > guess)
- pr[shift] += guess;
- else
- {
- t.resize(shift + 1);
- t.limbs()[shift] = guess;
- for(unsigned i = 0; i < shift; ++i)
- t.limbs()[i] = 0;
- eval_add(*result, t);
- }
- }
- //
- // Calculate guess * y, we use a fused mutiply-shift O(N) for this
- // rather than a full O(N^2) multiply:
- //
- double_limb_type carry = 0;
- t.resize(y.size() + shift + 1);
- bool truncated_t = !cpp_int_backend<MinBits1, Signed1, Allocator1, false>::variable && (t.size() != y.size() + shift + 1);
- typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer pt = t.limbs();
- for(unsigned i = 0; i < shift; ++i)
- pt[i] = 0;
- for(unsigned i = 0; i < y.size(); ++i)
- {
- carry += static_cast<double_limb_type>(py[i]) * static_cast<double_limb_type>(guess);
- pt[i + shift] = static_cast<limb_type>(carry);
- carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- }
- if(carry && !truncated_t)
- {
- pt[t.size() - 1] = static_cast<limb_type>(carry);
- }
- else if(!truncated_t)
- {
- t.resize(t.size() - 1);
- }
- //
- // Update r:
- //
- eval_subtract(r, t);
- if(r.isneg())
- {
- r.negate();
- r_neg = !r_neg;
- }
- //
- // First time through we need to strip any leading zero, otherwise
- // the termination condition goes belly-up:
- //
- if(result && first_pass)
- {
- first_pass = false;
- while(pr[result->size() - 1] == 0)
- result->resize(result->size() - 1);
- }
- //
- // Update r_order:
- //
- r_order = r.size() - 1;
- if(r_order < y_order)
- break;
- }
- // Termination condition is really just a check that r > y, but with a common
- // short-circuit case handled first:
- while((r_order > y_order) || (r.compare_unsigned(y) >= 0));
-
- //
- // We now just have to normalise the result:
- //
- if(r_neg && eval_get_sign(r))
- {
- // We have one too many in the result:
- if(result)
- eval_decrement(*result);
- r.negate();
- if(y.sign())
- eval_subtract(r, y);
- else
- eval_add(r, y);
- }
-
- BOOST_ASSERT(r.compare_unsigned(y) < 0); // remainder must be less than the divisor or our code has failed
-}
-
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-void divide_unsigned_helper(
- cpp_int_backend<MinBits1, Signed1, Allocator1, false>* result,
- const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& x,
- limb_type y,
- cpp_int_backend<MinBits1, Signed1, Allocator1, false>& r)
-{
- if(((void*)result == (void*)&x) || ((void*)&r == (void*)&x))
- {
- cpp_int_backend<MinBits2, Signed2, Allocator2, false> t(x);
- divide_unsigned_helper(result, t, y, r);
- return;
- }
-
- if(result == &r)
- {
- cpp_int_backend<MinBits1, Signed1, Allocator1, false> rem;
- divide_unsigned_helper(result, x, y, rem);
- r = rem;
- return;
- }
-
- // As above, but simplified for integer divisor:
-
- using default_ops::eval_subtract;
-
- if(y == 0)
- {
- BOOST_THROW_EXCEPTION(std::overflow_error("Integer Division by zero."));
- }
- //
- // Find the most significant word of numerator.
- //
- limb_type r_order = x.size() - 1;
-
- //
- // Set remainder and result to their initial values:
- //
- r = x;
- r.sign(false);
- typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer pr = r.limbs();
-
- if((r_order == 0) && (*pr == 0))
- {
- // All the limbs in x are zero, so is the result:
- return;
- }
- //
- // check for x < y, try to do this without actually having to
- // do a full comparison:
- //
- if((r_order == 0) && (*pr < y))
- {
- if(result)
- *result = static_cast<limb_type>(0u);
- return;
- }
-
- //
- // See if we can short-circuit long division, and use basic arithmetic instead:
- //
- if(r_order == 0)
- {
- if(result)
- {
- *result = *pr / y;
- result->sign(x.sign());
- }
- *pr %= y;
- r.sign(x.sign());
- return;
- }
- else if(r_order == 1)
- {
- double_limb_type a;
- a = (static_cast<double_limb_type>(pr[r_order]) << cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits) | pr[0];
- if(result)
- {
- *result = a / y;
- result->sign(x.sign());
- }
- r = a % y;
- r.sign(x.sign());
- return;
- }
-
- // This is initialised just to keep the compiler from emitting useless warnings later on:
- typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer pres = typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer();
- if(result)
- {
- result->resize(r_order + 1);
- pres = result->limbs();
- if(result->size() > r_order)
- pres[r_order] = 0; // just in case we don't set the most significant limb below.
- }
-
- do
- {
- //
- // Calculate our best guess for how many times y divides into r:
- //
- if((pr[r_order] < y) && r_order)
- {
- double_limb_type a, b;
- a = (static_cast<double_limb_type>(pr[r_order]) << cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits) | pr[r_order - 1];
- b = a % y;
- r.resize(r.size() - 1);
- --r_order;
- pr[r_order] = static_cast<limb_type>(b);
- if(result)
- pres[r_order] = static_cast<limb_type>(a / y);
- if(r_order && pr[r_order] == 0)
- {
- --r_order; // No remainder, division was exact.
- r.resize(r.size() - 1);
- if(result)
- pres[r_order] = static_cast<limb_type>(0u);
- }
- }
- else
- {
- if(result)
- pres[r_order] = pr[r_order] / y;
- pr[r_order] %= y;
- if(r_order && pr[r_order] == 0)
- {
- --r_order; // No remainder, division was exact.
- r.resize(r.size() - 1);
- if(result)
- pres[r_order] = static_cast<limb_type>(0u);
- }
- }
- }
- // Termination condition is really just a check that r > y, but with two common
- // short-circuit cases handled first:
- while(r_order || (pr[r_order] > y));
-
- if(result)
- {
- result->normalize();
- result->sign(x.sign());
- }
- r.normalize();
- r.sign(x.sign());
-
- BOOST_ASSERT(r.compare(y) < 0); // remainder must be less than the divisor or our code has failed
-}
-
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2, unsigned MinBits3, bool Signed3, class Allocator3>
-BOOST_FORCEINLINE void eval_divide(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result,
- const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, const cpp_int_backend<MinBits3, Signed3, Allocator3, false>& b)
-{
- cpp_int_backend<MinBits1, Signed1, Allocator1, false> r;
- divide_unsigned_helper(&result, a, b, r);
- result.sign(a.sign() != b.sign());
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_divide(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result,
- const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, limb_type& b)
-{
- cpp_int_backend<MinBits1, Signed1, Allocator1, false> r;
- divide_unsigned_helper(&result, a, b, r);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_divide(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result,
- const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, signed_limb_type& b)
-{
- cpp_int_backend<MinBits1, Signed1, Allocator1, false> r;
- divide_unsigned_helper(&result, a, std::abs(b), r);
- if(b < 0)
- result.negate();
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_divide(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result,
- const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& b)
-{
- // There is no in place divide:
- cpp_int_backend<MinBits1, Signed1, Allocator1, false> a(result);
- eval_divide(result, a, b);
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_divide(cpp_int_backend<MinBits, Signed, Allocator, false>& result, limb_type b)
-{
- // There is no in place divide:
- cpp_int_backend<MinBits, Signed, Allocator, false> a(result);
- eval_divide(result, a, b);
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_divide(cpp_int_backend<MinBits, Signed, Allocator, false>& result, signed_limb_type b)
-{
- // There is no in place divide:
- cpp_int_backend<MinBits, Signed, Allocator, false> a(result);
- eval_divide(result, a, b);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2, unsigned MinBits3, bool Signed3, class Allocator3>
-BOOST_FORCEINLINE void eval_modulus(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result,
- const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a,
- const cpp_int_backend<MinBits3, Signed3, Allocator3, false>& b)
-{
- divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, Signed1, Allocator1, false>* >(0), a, b, result);
- result.sign(a.sign());
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_modulus(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result,
- const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, limb_type b)
-{
- divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, Signed1, Allocator1, false>* >(0), a, b, result);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_modulus(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result,
- const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& a, signed_limb_type b)
-{
- divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, Signed1, Allocator1, false>* >(0), a, static_cast<limb_type>(std::abs(b)), result);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_modulus(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result,
- const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& b)
-{
- // There is no in place divide:
- cpp_int_backend<MinBits1, Signed1, Allocator1, false> a(result);
- eval_modulus(result, a, b);
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator, false>& result, limb_type b)
-{
- // There is no in place divide:
- cpp_int_backend<MinBits, Signed, Allocator, false> a(result);
- eval_modulus(result, a, b);
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator, false>& result, signed_limb_type b)
-{
- // There is no in place divide:
- cpp_int_backend<MinBits, Signed, Allocator, false> a(result);
- eval_modulus(result, a, b);
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2, class Op>
-void bitwise_op(
- cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result,
- const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& o,
- Op op) BOOST_NOEXCEPT
-{
- //
- // There are 4 cases:
- // * Both positive.
- // * result negative, o positive.
- // * o negative, result positive.
- // * Both negative.
- //
- // When one arg is negative we convert to 2's complement form "on the fly",
- // and then convert back to signed-magnitude form at the end.
- //
- // First figure out how big the result needs to be and set up some data:
- //
- unsigned rs = result.size();
- unsigned os = o.size();
- unsigned m, x;
- minmax(rs, os, m, x);
- result.resize(x);
- typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer pr = result.limbs();
- typename cpp_int_backend<MinBits2, Signed2, Allocator2, false>::const_limb_pointer po = o.limbs();
- for(unsigned i = rs; i < x; ++i)
- pr[i] = 0;
-
- limb_type next_limb = 0;
-
- if(!result.sign())
- {
- if(!o.sign())
- {
- for(unsigned i = 0; i < os; ++i)
- pr[i] = op(pr[i], po[i]);
- for(unsigned i = os; i < x; ++i)
- pr[i] = op(pr[i], limb_type(0));
- }
- else
- {
- // "o" is negative:
- double_limb_type carry = 1;
- for(unsigned i = 0; i < os; ++i)
- {
- carry += static_cast<double_limb_type>(~po[i]);
- pr[i] = op(pr[i], static_cast<limb_type>(carry));
- carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- }
- for(unsigned i = os; i < x; ++i)
- {
- carry += static_cast<double_limb_type>(~limb_type(0));
- pr[i] = op(pr[i], static_cast<limb_type>(carry));
- carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- }
- // Set the overflow into the "extra" limb:
- carry += static_cast<double_limb_type>(~limb_type(0));
- next_limb = op(limb_type(0), static_cast<limb_type>(carry));
- }
- }
- else
- {
- if(!o.sign())
- {
- // "result" is negative:
- double_limb_type carry = 1;
- for(unsigned i = 0; i < os; ++i)
- {
- carry += static_cast<double_limb_type>(~pr[i]);
- pr[i] = op(static_cast<limb_type>(carry), po[i]);
- carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- }
- for(unsigned i = os; i < x; ++i)
- {
- carry += static_cast<double_limb_type>(~pr[i]);
- pr[i] = op(static_cast<limb_type>(carry), limb_type(0));
- carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- }
- // Set the overflow into the "extra" limb:
- carry += static_cast<double_limb_type>(~limb_type(0));
- next_limb = op(static_cast<limb_type>(carry), limb_type(0));
- }
- else
- {
- // both are negative:
- double_limb_type r_carry = 1;
- double_limb_type o_carry = 1;
- for(unsigned i = 0; i < os; ++i)
- {
- r_carry += static_cast<double_limb_type>(~pr[i]);
- o_carry += static_cast<double_limb_type>(~po[i]);
- pr[i] = op(static_cast<limb_type>(r_carry), static_cast<limb_type>(o_carry));
- r_carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- o_carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- }
- for(unsigned i = os; i < x; ++i)
- {
- r_carry += static_cast<double_limb_type>(~pr[i]);
- o_carry += static_cast<double_limb_type>(~limb_type(0));
- pr[i] = op(static_cast<limb_type>(r_carry), static_cast<limb_type>(o_carry));
- r_carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- o_carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- }
- // Set the overflow into the "extra" limb:
- r_carry += static_cast<double_limb_type>(~limb_type(0));
- o_carry += static_cast<double_limb_type>(~limb_type(0));
- next_limb = op(static_cast<limb_type>(r_carry), static_cast<limb_type>(o_carry));
- }
- }
- //
- // See if the result is negative or not:
- //
- if(static_cast<signed_limb_type>(next_limb) < 0)
- {
- result.sign(true);
- double_limb_type carry = 1;
- for(unsigned i = 0; i < x; ++i)
- {
- carry += static_cast<double_limb_type>(~pr[i]);
- pr[i] = static_cast<limb_type>(carry);
- carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
- }
- }
- else
- result.sign(false);
-
- result.normalize();
-}
-
-struct bit_and{ limb_type operator()(limb_type a, limb_type b)const BOOST_NOEXCEPT { return a & b; } };
-struct bit_or { limb_type operator()(limb_type a, limb_type b)const BOOST_NOEXCEPT { return a | b; } };
-struct bit_xor{ limb_type operator()(limb_type a, limb_type b)const BOOST_NOEXCEPT { return a ^ b; } };
-
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_bitwise_and(
- cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result,
- const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& o)BOOST_NOEXCEPT_IF(is_void<Allocator1>::value)
-{
- bitwise_op(result, o, bit_and());
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_bitwise_or(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& o) BOOST_NOEXCEPT_IF(is_void<Allocator1>::value)
-{
- bitwise_op(result, o, bit_or());
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_bitwise_xor(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& o) BOOST_NOEXCEPT_IF(is_void<Allocator1>::value)
-{
- bitwise_op(result, o, bit_xor());
-}
-template <unsigned MinBits1, bool Signed1, class Allocator1, unsigned MinBits2, bool Signed2, class Allocator2>
-BOOST_FORCEINLINE void eval_complement(cpp_int_backend<MinBits1, Signed1, Allocator1, false>& result, const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator1>::value)
-{
- // Increment and negate:
- result = o;
- eval_increment(result);
- result.negate();
-}
-template <unsigned MinBits, bool Signed>
-inline void eval_left_shift(cpp_int_backend<MinBits, Signed, void, false>& result, double_limb_type s) BOOST_NOEXCEPT
-{
- if(!s)
- return;
-
- limb_type offset = static_cast<limb_type>(s / cpp_int_backend<MinBits, Signed, void>::limb_bits);
- limb_type shift = static_cast<limb_type>(s % cpp_int_backend<MinBits, Signed, void>::limb_bits);
-
- if(offset > cpp_int_backend<MinBits, Signed, void>::internal_limb_count)
- {
- result = static_cast<limb_type>(0);
- return;
- }
-
- unsigned ors = result.size();
- if((ors == 1) && (!*result.limbs()))
- return; // shifting zero yields zero.
- unsigned rs = ors;
- if(shift && (result.limbs()[ors - 1] >> (cpp_int_backend<MinBits, Signed, void>::limb_bits - shift)))
- ++rs; // Most significant limb will overflow when shifted
- rs += offset;
- result.resize(rs);
- bool truncated = result.size() != rs;
- if(truncated)
- rs = result.size();
- typename cpp_int_backend<MinBits, Signed, void>::limb_pointer pr = result.limbs();
-
- unsigned i = 0;
- if(shift)
- {
- // This code only works when shift is non-zero, otherwise we invoke undefined behaviour!
- i = 0;
- if(!truncated)
- {
- if(rs > ors + offset)
- {
- pr[rs - 1 - i] = pr[ors - 1 - i] >> (cpp_int_backend<MinBits, Signed, void>::limb_bits - shift);
- --rs;
- }
- else
- {
- pr[rs - 1 - i] = pr[ors - 1 - i] << shift;
- if(ors > 1)
- pr[rs - 1 - i] |= pr[ors - 2 - i] >> (cpp_int_backend<MinBits, Signed, void>::limb_bits - shift);
- ++i;
- }
- }
- for(; ors > 1 + i; ++i)
- {
- pr[rs - 1 - i] = pr[ors - 1 - i] << shift;
- pr[rs - 1 - i] |= pr[ors - 2 - i] >> (cpp_int_backend<MinBits, Signed, void>::limb_bits - shift);
- }
- if(ors >= 1 + i)
- {
- pr[rs - 1 - i] = pr[ors - 1 - i] << shift;
- ++i;
+ if(o.sign())
+ return 1;
+ return *this->limbs() < *o.limbs() ? -1 : (*this->limbs() > *o.limbs() ? 1 : 0);
       }
- for(; i < rs; ++i)
- pr[rs - 1 - i] = 0;
    }
- else
+ template <unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+ int compare_unsigned(const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o)const BOOST_NOEXCEPT
    {
- for(; i < ors; ++i)
- pr[rs - 1 - i] = pr[ors - 1 - i];
- for(; i < rs; ++i)
- pr[rs - 1 - i] = 0;
- }
- //
- // We may have shifted off the end and have leading zeros:
- //
- if(truncated)
- {
- result.normalize();
- }
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_left_shift(cpp_int_backend<MinBits, Signed, Allocator, false>& result, double_limb_type s) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- if(!s)
- return;
-
- limb_type offset = static_cast<limb_type>(s / cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits);
- limb_type shift = static_cast<limb_type>(s % cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits);
-
- unsigned ors = result.size();
- if((ors == 1) && (!*result.limbs()))
- return; // shifting zero yields zero.
- unsigned rs = ors;
- if(shift && (result.limbs()[rs - 1] >> (cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits - shift)))
- ++rs; // Most significant limb will overflow when shifted
- rs += offset;
- result.resize(rs);
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pr = result.limbs();
-
- unsigned i = 0;
- if(shift)
- {
- // This code only works when shift is non-zero, otherwise we invoke undefined behaviour!
- i = 0;
- if(rs > ors + offset)
- {
- pr[rs - 1 - i] = pr[ors - 1 - i] >> (cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits - shift);
- --rs;
- }
- else
- {
- pr[rs - 1 - i] = pr[ors - 1 - i] << shift;
- if(ors > 1)
- pr[rs - 1 - i] |= pr[ors - 2 - i] >> (cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits - shift);
- ++i;
- }
- for(; ors > 1 + i; ++i)
- {
- pr[rs - 1 - i] = pr[ors - 1 - i] << shift;
- pr[rs - 1 - i] |= pr[ors - 2 - i] >> (cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits - shift);
- }
- if(ors >= 1 + i)
+ if(this->size() != o.size())
       {
- pr[rs - 1 - i] = pr[ors - 1 - i] << shift;
- ++i;
+ return this->size() > o.size() ? 1 : -1;
       }
- for(; i < rs; ++i)
- pr[rs - 1 - i] = 0;
- }
- else
- {
- for(; i < ors; ++i)
- pr[rs - 1 - i] = pr[ors - 1 - i];
- for(; i < rs; ++i)
- pr[rs - 1 - i] = 0;
- }
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_right_shift(cpp_int_backend<MinBits, Signed, Allocator, false>& result, double_limb_type s) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- if(!s)
- return;
-
- limb_type offset = static_cast<limb_type>(s / cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits);
- limb_type shift = static_cast<limb_type>(s % cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits);
- unsigned ors = result.size();
- unsigned rs = ors;
- if(offset >= rs)
- {
- result = limb_type(0);
- return;
- }
- rs -= offset;
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pr = result.limbs();
- if((pr[ors - 1] >> shift) == 0)
- --rs;
- if(rs == 0)
- {
- result = limb_type(0);
- return;
- }
- unsigned i = 0;
- if(shift)
- {
- // This code only works for non-zero shift, otherwise we invoke undefined behaviour!
- for(; i + offset + 1 < ors; ++i)
+ typename base_type::const_limb_pointer pa = this->limbs();
+ typename base_type::const_limb_pointer pb = o.limbs();
+ for(int i = this->size() - 1; i >= 0; --i)
       {
- pr[i] = pr[i + offset] >> shift;
- pr[i] |= pr[i + offset + 1] << (cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits - shift);
+ if(pa[i] != pb[i])
+ return pa[i] > pb[i] ? 1 : -1;
       }
- pr[i] = pr[i + offset] >> shift;
- }
- else
- {
- for(; i < rs; ++i)
- pr[i] = pr[i + offset];
- }
- result.resize(rs);
-}
-
-template <class Integer>
-inline Integer negate_integer(Integer i, const mpl::true_&) BOOST_NOEXCEPT
-{
- return -i;
-}
-template <class Integer>
-inline Integer negate_integer(Integer i, const mpl::false_&) BOOST_NOEXCEPT
-{
- return ~(i-1);
-}
-
-template <class R, unsigned MinBits, bool Signed, class Allocator>
-inline typename enable_if<is_integral<R>, void>::type eval_convert_to(R* result, const cpp_int_backend<MinBits, Signed, Allocator, false>& backend) BOOST_NOEXCEPT
-{
- *result = static_cast<R>(backend.limbs()[0]);
- unsigned shift = cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
- for(unsigned i = 1; (i < backend.size()) && (shift < static_cast<unsigned>(std::numeric_limits<R>::digits)); ++i)
- {
- *result += static_cast<R>(backend.limbs()[i]) << shift;
- shift += cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
- }
- if(backend.sign())
- {
- *result = negate_integer(*result, mpl::bool_<std::numeric_limits<R>::is_signed>());
- }
-}
-
-template <class R, unsigned MinBits, bool Signed, class Allocator>
-inline typename enable_if<is_floating_point<R>, void>::type eval_convert_to(R* result, const cpp_int_backend<MinBits, Signed, Allocator, false>& backend) BOOST_NOEXCEPT
-{
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::const_limb_pointer p = backend.limbs();
- unsigned shift = cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
- *result = static_cast<R>(*p);
- for(unsigned i = 1; i < backend.size(); ++i)
- {
- *result += static_cast<R>(std::ldexp(static_cast<long double>(p[i]), shift));
- shift += cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
- }
- if(backend.sign())
- *result = -*result;
-}
-
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE bool eval_is_zero(const cpp_int_backend<MinBits, Signed, Allocator, false>& val) BOOST_NOEXCEPT
-{
- return (val.size() == 1) && (val.limbs()[0] == 0);
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE int eval_get_sign(const cpp_int_backend<MinBits, Signed, Allocator, false>& val) BOOST_NOEXCEPT
-{
- return eval_is_zero(val) ? 0 : val.sign() ? -1 : 1;
-}
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_abs(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- result = val;
- result.sign(false);
-}
-
-//
-// Get the location of the least-significant-bit:
-//
-template <unsigned MinBits, bool Signed, class Allocator>
-inline unsigned eval_lsb(const cpp_int_backend<MinBits, Signed, Allocator, false>& a) BOOST_NOEXCEPT
-{
- BOOST_ASSERT(eval_get_sign(a) != 0);
-
- unsigned result = 0;
- //
- // Find the index of the least significant limb that is non-zero:
- //
- unsigned index = 0;
- while(!a.limbs()[index] && (index < a.size()))
- ++index;
- //
- // Find the index of the least significant bit within that limb:
- //
- limb_type l = a.limbs()[index];
- while(!(l & 1u))
- {
- l >>= 1;
- ++result;
- }
-
- return result + index * cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
-}
-
-template <unsigned MinBits, bool Signed, class Allocator>
-inline bool eval_bit_test(const cpp_int_backend<MinBits, Signed, Allocator, false>& val, unsigned index) BOOST_NOEXCEPT
-{
- unsigned offset = index / cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
- unsigned shift = index % cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
- limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u);
- if(offset >= val.size())
- return false;
- return val.limbs()[offset] & mask ? true : false;
-}
-
-template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_bit_set(cpp_int_backend<MinBits, Signed, Allocator, false>& val, unsigned index) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- unsigned offset = index / cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
- unsigned shift = index % cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
- limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u);
- if(offset >= val.size())
- {
- unsigned os = val.size();
- val.resize(offset + 1);
- if(offset >= val.size())
- return; // fixed precision overflow
- for(unsigned i = os; i <= offset; ++i)
- val.limbs()[i] = 0;
- }
- val.limbs()[offset] |= mask;
-}
-
-template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_bit_unset(cpp_int_backend<MinBits, Signed, Allocator, false>& val, unsigned index) BOOST_NOEXCEPT
-{
- unsigned offset = index / cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
- unsigned shift = index % cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
- limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u);
- if(offset >= val.size())
- return;
- val.limbs()[offset] &= ~mask;
- val.normalize();
-}
-
-template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_bit_flip(cpp_int_backend<MinBits, Signed, Allocator, false>& val, unsigned index) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- unsigned offset = index / cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
- unsigned shift = index % cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
- limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u);
- if(offset >= val.size())
- {
- unsigned os = val.size();
- val.resize(offset + 1);
- if(offset >= val.size())
- return; // fixed precision overflow
- for(unsigned i = os; i <= offset; ++i)
- val.limbs()[i] = 0;
- }
- val.limbs()[offset] ^= mask;
- val.normalize();
-}
-
-template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_qr(const cpp_int_backend<MinBits, Signed, Allocator, false>& x, const cpp_int_backend<MinBits, Signed, Allocator, false>& y,
- cpp_int_backend<MinBits, Signed, Allocator, false>& q, cpp_int_backend<MinBits, Signed, Allocator, false>& r) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- divide_unsigned_helper(&q, x, y, r);
- q.sign(x.sign() != y.sign());
- r.sign(x.sign());
-}
-
-template <unsigned MinBits, bool Signed, class Allocator, class Integer>
-inline typename enable_if<is_unsigned<Integer>, Integer>::type eval_integer_modulus(const cpp_int_backend<MinBits, Signed, Allocator, false>& x, Integer val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- if((sizeof(Integer) <= sizeof(limb_type)) || (val <= (std::numeric_limits<limb_type>::max)()))
- {
- cpp_int_backend<MinBits, Signed, Allocator, false> d;
- divide_unsigned_helper(static_cast<cpp_int_backend<MinBits, Signed, Allocator, false>*>(0), x, val, d);
- return d.limbs()[0];
+ return 0;
    }
- else
+ template <class Arithmetic>
+ BOOST_FORCEINLINE typename enable_if<is_arithmetic<Arithmetic>, int>::type compare(Arithmetic i)const
    {
- return default_ops::eval_integer_modulus(x, val);
+ // braindead version:
+ cpp_int_backend t;
+ t = i;
+ return compare(t);
    }
-}
-template <unsigned MinBits, bool Signed, class Allocator, class Integer>
-BOOST_FORCEINLINE typename enable_if<is_signed<Integer>, Integer>::type eval_integer_modulus(const cpp_int_backend<MinBits, Signed, Allocator, false>& x, Integer val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
-{
- typedef typename make_unsigned<Integer>::type unsigned_type;
- return eval_integer_modulus(x, static_cast<unsigned_type>(std::abs(val)));
-}
+};
 
-} // namespace backends;
+} // namespace backends
 
-template <unsigned MinBits, bool Signed, bool trivial>
-struct expression_template_default<backends::cpp_int_backend<MinBits, Signed, void, trivial> >
+template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked>
+struct expression_template_default<backends::cpp_int_backend<MinBits, MaxBits, SignType, Checked, void> >
 {
    static const expression_template_option value = et_off;
 };
 
 using boost::multiprecision::backends::cpp_int_backend;
 
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial>
-struct number_category<cpp_int_backend<MinBits, Signed, Allocator, trivial> > : public mpl::int_<number_kind_integer>{};
+template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
+struct number_category<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> > : public mpl::int_<number_kind_integer>{};
 
-typedef number<cpp_int_backend<> > cpp_int;
-typedef rational_adapter<cpp_int_backend<> > cpp_rational_backend;
-typedef number<cpp_rational_backend> cpp_rational;
+typedef number<cpp_int_backend<> > cpp_int;
+typedef rational_adapter<cpp_int_backend<> > cpp_rational_backend;
+typedef number<cpp_rational_backend> cpp_rational;
 
 // Fixed precision unsigned types:
-typedef number<cpp_int_backend<128, false, void> > uint128_t;
-typedef number<cpp_int_backend<256, false, void> > uint256_t;
-typedef number<cpp_int_backend<512, false, void> > uint512_t;
-typedef number<cpp_int_backend<1024, false, void> > uint1024_t;
+typedef number<cpp_int_backend<128, 128, unsigned_magnitude, unchecked, void> > uint128_t;
+typedef number<cpp_int_backend<256, 256, unsigned_magnitude, unchecked, void> > uint256_t;
+typedef number<cpp_int_backend<512, 512, unsigned_magnitude, unchecked, void> > uint512_t;
+typedef number<cpp_int_backend<1024, 1024, unsigned_magnitude, unchecked, void> > uint1024_t;
 
 // Fixed precision signed types:
-typedef number<cpp_int_backend<128, true, void> > int128_t;
-typedef number<cpp_int_backend<256, true, void> > int256_t;
-typedef number<cpp_int_backend<512, true, void> > int512_t;
-typedef number<cpp_int_backend<1024, true, void> > int1024_t;
+typedef number<cpp_int_backend<128, 128, signed_magnitude, unchecked, void> > int128_t;
+typedef number<cpp_int_backend<256, 256, signed_magnitude, unchecked, void> > int256_t;
+typedef number<cpp_int_backend<512, 512, signed_magnitude, unchecked, void> > int512_t;
+typedef number<cpp_int_backend<1024, 1024, signed_magnitude, unchecked, void> > int1024_t;
+
+// Over again, but with checking enabled this time:
+typedef number<cpp_int_backend<0, 0, signed_magnitude, checked> > checked_cpp_int;
+typedef rational_adapter<cpp_int_backend<0, 0, signed_magnitude, checked> > checked_cpp_rational_backend;
+typedef number<cpp_rational_backend> checked_cpp_rational;
+// Fixed precision unsigned types:
+typedef number<cpp_int_backend<128, 128, unsigned_magnitude, checked, void> > checked_uint128_t;
+typedef number<cpp_int_backend<256, 256, unsigned_magnitude, checked, void> > checked_uint256_t;
+typedef number<cpp_int_backend<512, 512, unsigned_magnitude, checked, void> > checked_uint512_t;
+typedef number<cpp_int_backend<1024, 1024, unsigned_magnitude, checked, void> > checked_uint1024_t;
 
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+// Fixed precision signed types:
+typedef number<cpp_int_backend<128, 128, signed_magnitude, checked, void> > checked_int128_t;
+typedef number<cpp_int_backend<256, 256, signed_magnitude, checked, void> > checked_int256_t;
+typedef number<cpp_int_backend<512, 512, signed_magnitude, checked, void> > checked_int512_t;
+typedef number<cpp_int_backend<1024, 1024, signed_magnitude, checked, void> > checked_int1024_t;
 
 #ifdef BOOST_NO_SFINAE_EXPR
 
 namespace detail{
 
-template<unsigned MinBits, bool Signed, class Allocator, bool trivial, unsigned MinBits2, bool Signed2, class Allocator2, bool trivial2>
-struct is_explicitly_convertible<cpp_int_backend<MinBits, Signed, Allocator, trivial>, cpp_int_backend<MinBits2, Signed2, Allocator2, trivial2> > : public mpl::true_ {};
+template<unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+struct is_explicitly_convertible<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> > : public mpl::true_ {};
 
 }
-
 #endif
 
 }} // namespaces
 
-#include <boost/multiprecision/detail/cpp_int_trivial_ops.hpp>
-
-
-namespace std{
-
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >
-{
- typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> number_type;
-
-public:
- BOOST_STATIC_CONSTEXPR bool is_specialized = true;
- //
- // Largest and smallest numbers are bounded only by available memory, set
- // to zero:
- //
- static number_type (min)() BOOST_NOEXCEPT
- {
- return number_type(0);
- }
- static number_type (max)() BOOST_NOEXCEPT
- {
- return number_type(0);
- }
- static number_type lowest() BOOST_NOEXCEPT { return (min)(); }
- BOOST_STATIC_CONSTEXPR int digits = INT_MAX;
- BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L;
- BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2;
- BOOST_STATIC_CONSTEXPR bool is_signed = true;
- BOOST_STATIC_CONSTEXPR bool is_integer = true;
- BOOST_STATIC_CONSTEXPR bool is_exact = true;
- BOOST_STATIC_CONSTEXPR int radix = 2;
- static number_type epsilon() BOOST_NOEXCEPT { return 0; }
- static number_type round_error() BOOST_NOEXCEPT { return 0; }
- BOOST_STATIC_CONSTEXPR int min_exponent = 0;
- BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
- BOOST_STATIC_CONSTEXPR int max_exponent = 0;
- BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
- BOOST_STATIC_CONSTEXPR bool has_infinity = false;
- BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
- BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
- BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
- BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
- static number_type infinity() BOOST_NOEXCEPT { return 0; }
- static number_type quiet_NaN() BOOST_NOEXCEPT { return 0; }
- static number_type signaling_NaN() BOOST_NOEXCEPT { return 0; }
- static number_type denorm_min() BOOST_NOEXCEPT { return 0; }
- BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
- BOOST_STATIC_CONSTEXPR bool is_bounded = false;
- BOOST_STATIC_CONSTEXPR bool is_modulo = false;
- BOOST_STATIC_CONSTEXPR bool traps = false;
- BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
- BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
-};
-
-#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
-
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::digits;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::digits10;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::max_digits10;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::is_signed;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::is_integer;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::is_exact;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::radix;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::min_exponent;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::min_exponent10;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::max_exponent;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::max_exponent10;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::has_infinity;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::has_quiet_NaN;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::has_signaling_NaN;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::has_denorm;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::has_denorm_loss;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::is_iec559;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::is_bounded;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::is_modulo;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::traps;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::tinyness_before;
-template <unsigned MinBits, bool Signed, class Allocator, bool trivial, boost::multiprecision::expression_template_option ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::round_style;
-
-#endif
-
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >
-{
- typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> number_type;
-
- struct inititializer
- {
- inititializer()
- {
- (std::numeric_limits<number_type>::max)();
- (std::numeric_limits<number_type>::min)();
- }
- void do_nothing()const{}
- };
-
- static const inititializer init;
-
-public:
- BOOST_STATIC_CONSTEXPR bool is_specialized = true;
- //
- // Largest and smallest numbers are bounded only by available memory, set
- // to zero:
- //
- static number_type (min)() BOOST_NOEXCEPT
- {
- return -(max)();
- }
- static number_type (max)() BOOST_NOEXCEPT
- {
- typedef typename number_type::backend_type backend_type;
- init.do_nothing();
- static bool init = false;
- static number_type val;
- if(!init)
- {
- boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> t(0);
- val = ~t;
- init = true;
- }
- return val;
- }
- static number_type lowest() BOOST_NOEXCEPT { return (min)(); }
- BOOST_STATIC_CONSTEXPR int digits = MinBits;
- BOOST_STATIC_CONSTEXPR int digits10 = static_cast<int>(MinBits * 301L / 1000L);
- BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2;
- BOOST_STATIC_CONSTEXPR bool is_signed = true;
- BOOST_STATIC_CONSTEXPR bool is_integer = true;
- BOOST_STATIC_CONSTEXPR bool is_exact = true;
- BOOST_STATIC_CONSTEXPR int radix = 2;
- static number_type epsilon() BOOST_NOEXCEPT { return 0; }
- static number_type round_error() BOOST_NOEXCEPT { return 0; }
- BOOST_STATIC_CONSTEXPR int min_exponent = 0;
- BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
- BOOST_STATIC_CONSTEXPR int max_exponent = 0;
- BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
- BOOST_STATIC_CONSTEXPR bool has_infinity = false;
- BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
- BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
- BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
- BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
- static number_type infinity() BOOST_NOEXCEPT { return 0; }
- static number_type quiet_NaN() BOOST_NOEXCEPT { return 0; }
- static number_type signaling_NaN() BOOST_NOEXCEPT { return 0; }
- static number_type denorm_min() BOOST_NOEXCEPT { return 0; }
- BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
- BOOST_STATIC_CONSTEXPR bool is_bounded = true;
- BOOST_STATIC_CONSTEXPR bool is_modulo = true;
- BOOST_STATIC_CONSTEXPR bool traps = false;
- BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
- BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
-};
-
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::inititializer numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::init;
-
-#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
-
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::digits;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::digits10;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::max_digits10;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::is_signed;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::is_integer;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::is_exact;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::radix;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::min_exponent;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::min_exponent10;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::max_exponent;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::max_exponent10;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::has_infinity;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::has_quiet_NaN;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::has_signaling_NaN;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::has_denorm;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::has_denorm_loss;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::is_iec559;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::is_bounded;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::is_modulo;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::traps;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::tinyness_before;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::round_style;
-
-#endif
-
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >
-{
- typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> number_type;
-
- struct inititializer
- {
- inititializer()
- {
- (std::numeric_limits<number_type>::max)();
- }
- void do_nothing()const{}
- };
-
- static const inititializer init;
-
-public:
- BOOST_STATIC_CONSTEXPR bool is_specialized = true;
- //
- // Largest and smallest numbers are bounded only by available memory, set
- // to zero:
- //
- static number_type (min)() BOOST_NOEXCEPT
- {
- return number_type(0);
- }
- static number_type (max)() BOOST_NOEXCEPT
- {
- typedef typename number_type::backend_type backend_type;
- init.do_nothing();
- static bool init = false;
- static number_type val(0);
- if(!init)
- {
- boost::multiprecision::limb_type l = ~static_cast<boost::multiprecision::limb_type>(0);
- unsigned c = MinBits / backend_type::limb_bits + (MinBits % backend_type::limb_bits ? 1 : 0);
- for(unsigned i = 0; i < c; ++i)
- {
- val <<= backend_type::limb_bits;
- val |= l;
- }
- init = true;
- }
- return val;
- }
- static number_type lowest() BOOST_NOEXCEPT { return (min)(); }
- BOOST_STATIC_CONSTEXPR int digits = MinBits;
- BOOST_STATIC_CONSTEXPR int digits10 = static_cast<int>(MinBits * 301L / 1000L);
- BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2;
- BOOST_STATIC_CONSTEXPR bool is_signed = false;
- BOOST_STATIC_CONSTEXPR bool is_integer = true;
- BOOST_STATIC_CONSTEXPR bool is_exact = true;
- BOOST_STATIC_CONSTEXPR int radix = 2;
- static number_type epsilon() BOOST_NOEXCEPT { return 0; }
- static number_type round_error() BOOST_NOEXCEPT { return 0; }
- BOOST_STATIC_CONSTEXPR int min_exponent = 0;
- BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
- BOOST_STATIC_CONSTEXPR int max_exponent = 0;
- BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
- BOOST_STATIC_CONSTEXPR bool has_infinity = false;
- BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
- BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
- BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
- BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
- static number_type infinity() BOOST_NOEXCEPT { return 0; }
- static number_type quiet_NaN() BOOST_NOEXCEPT { return 0; }
- static number_type signaling_NaN() BOOST_NOEXCEPT { return 0; }
- static number_type denorm_min() BOOST_NOEXCEPT { return 0; }
- BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
- BOOST_STATIC_CONSTEXPR bool is_bounded = true;
- BOOST_STATIC_CONSTEXPR bool is_modulo = true;
- BOOST_STATIC_CONSTEXPR bool traps = false;
- BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
- BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
-};
-
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::inititializer numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::init;
-
-#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
-
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::digits;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::digits10;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::max_digits10;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::is_signed;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::is_integer;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::is_exact;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::radix;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::min_exponent;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::min_exponent10;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::max_exponent;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::max_exponent10;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::has_infinity;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::has_quiet_NaN;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::has_signaling_NaN;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::has_denorm;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::has_denorm_loss;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::is_iec559;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::is_bounded;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::is_modulo;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::traps;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::tinyness_before;
-template <unsigned MinBits, boost::multiprecision::expression_template_option ExpressionTemplates, bool trivial>
-BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::round_style;
-
-#endif
-
-}
+//
+// Last of all we include the implementations of all the eval_* non member functions:
+//
+#include <boost/multiprecision/cpp_int/comparison.hpp>
+#include <boost/multiprecision/cpp_int/add.hpp>
+#include <boost/multiprecision/cpp_int/multiply.hpp>
+#include <boost/multiprecision/cpp_int/divide.hpp>
+#include <boost/multiprecision/cpp_int/bitwise.hpp>
+#include <boost/multiprecision/cpp_int/misc.hpp>
+#include <boost/multiprecision/cpp_int/limits.hpp>
 
 #endif

Added: sandbox/big_number/boost/multiprecision/cpp_int/add.hpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/boost/multiprecision/cpp_int/add.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -0,0 +1,509 @@
+///////////////////////////////////////////////////////////////
+// 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_
+//
+// Comparison operators for cpp_int_backend:
+//
+#ifndef BOOST_MP_CPP_INT_ADD_HPP
+#define BOOST_MP_CPP_INT_ADD_HPP
+
+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)
+{
+ using std::swap;
+
+ // Nothing fancy, just let uintmax_t take the strain:
+ double_limb_type carry = 0;
+ unsigned m, x;
+ unsigned as = a.size();
+ unsigned bs = b.size();
+ minmax(as, bs, m, x);
+ if(x == 1)
+ {
+ bool s = a.sign();
+ result = static_cast<double_limb_type>(*a.limbs()) + static_cast<double_limb_type>(*b.limbs());
+ result.sign(s);
+ return;
+ }
+ result.resize(x, x);
+ typename CppInt2::const_limb_pointer pa = a.limbs();
+ typename CppInt3::const_limb_pointer pb = b.limbs();
+ typename CppInt1::limb_pointer pr = result.limbs();
+ typename CppInt1::limb_pointer pr_end = pr + m;
+
+ if(as < bs)
+ swap(pa, pb);
+
+ // First where a and b overlap:
+ while(pr != pr_end)
+ {
+ carry += static_cast<double_limb_type>(*pa) + static_cast<double_limb_type>(*pb);
+ *pr = static_cast<limb_type>(carry);
+ carry >>= CppInt1::limb_bits;
+ ++pr, ++pa, ++pb;
+ }
+ pr_end += x - m;
+ // Now where only a has digits:
+ while(pr != pr_end)
+ {
+ if(!carry)
+ {
+ if(pa != pr)
+ std::copy(pa, pa + (pr_end - pr), pr);
+ break;
+ }
+ carry += static_cast<double_limb_type>(*pa);
+ *pr = static_cast<limb_type>(carry);
+ carry >>= CppInt1::limb_bits;
+ ++pr, ++pa;
+ }
+ if(carry)
+ {
+ // We overflowed, need to add one more limb:
+ result.resize(x + 1, x + 1);
+ if(CppInt1::variable || (result.size() > x))
+ result.limbs()[x] = static_cast<limb_type>(carry);
+ }
+ result.normalize();
+ result.sign(a.sign());
+}
+//
+// 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)
+{
+ // Addition using modular arithmatic.
+ // Nothing fancy, just let uintmax_t take the strain:
+ if(&result != &a)
+ result.resize(a.size(), a.size());
+ double_limb_type carry = o;
+ typename CppInt1::limb_pointer pr = result.limbs();
+ typename CppInt2::const_limb_pointer pa = a.limbs();
+ unsigned i = 0;
+ // Addition with carry until we either run out of digits or carry is zero:
+ for(; carry && (i < result.size()); ++i)
+ {
+ carry += static_cast<double_limb_type>(pa[i]);
+ pr[i] = static_cast<limb_type>(carry);
+ carry >>= CppInt1::limb_bits;
+ }
+ // Just copy any remaining digits:
+ if(&a != &result)
+ {
+ for(; i < result.size(); ++i)
+ pr[i] = pa[i];
+ }
+ if(carry)
+ {
+ // We overflowed, need to add one more limb:
+ unsigned x = result.size();
+ result.resize(x + 1, x + 1);
+ if(CppInt1::variable || (result.size() > x))
+ result.limbs()[x] = static_cast<limb_type>(carry);
+ }
+ result.normalize();
+ result.sign(a.sign());
+}
+//
+// 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)
+{
+ using std::swap;
+
+ // Nothing fancy, just let uintmax_t take the strain:
+ double_limb_type borrow = 0;
+ unsigned m, x;
+ minmax(a.size(), b.size(), m, x);
+ //
+ // special cases for small limb counts:
+ //
+ if(x == 1)
+ {
+ bool s = a.sign();
+ limb_type al = *a.limbs();
+ limb_type bl = *b.limbs();
+ if(bl > al)
+ {
+ std::swap(al, bl);
+ s = !s;
+ }
+ result = al - bl;
+ result.sign(s);
+ return;
+ }
+ // This isn't used till later, but comparison has to occur before we resize the result,
+ // as that may also resize a or b if this is an inplace operation:
+ int c = a.compare_unsigned(b);
+ // Set up the result vector:
+ result.resize(x, x);
+ // Now that a, b, and result are stable, get pointers to their limbs:
+ typename CppInt2::const_limb_pointer pa = a.limbs();
+ typename CppInt3::const_limb_pointer pb = b.limbs();
+ typename CppInt1::limb_pointer pr = result.limbs();
+ bool swapped = false;
+ if(c < 0)
+ {
+ swap(pa, pb);
+ swapped = true;
+ }
+ else if(c == 0)
+ {
+ result = static_cast<limb_type>(0);
+ return;
+ }
+
+ unsigned i = 0;
+ // First where a and b overlap:
+ while(i < m)
+ {
+ borrow = static_cast<double_limb_type>(pa[i]) - static_cast<double_limb_type>(pb[i]) - borrow;
+ pr[i] = static_cast<limb_type>(borrow);
+ borrow = (borrow >> CppInt1::limb_bits) & 1u;
+ ++i;
+ }
+ // Now where only a has digits, only as long as we've borrowed:
+ while(borrow && (i < x))
+ {
+ borrow = static_cast<double_limb_type>(pa[i]) - borrow;
+ pr[i] = static_cast<limb_type>(borrow);
+ borrow = (borrow >> CppInt1::limb_bits) & 1u;
+ ++i;
+ }
+ // Any remaining digits are the same as those in pa:
+ if((x != i) && (pa != pr))
+ std::copy(pa + i, pa + x, pr + i);
+ BOOST_ASSERT(0 == borrow);
+
+ //
+ // We may have lost digits, if so update limb usage count:
+ //
+ result.normalize();
+ result.sign(a.sign());
+ if(swapped)
+ result.negate();
+}
+//
+// 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)
+{
+ // Subtract one limb.
+ // Nothing fancy, just let uintmax_t take the strain:
+ BOOST_STATIC_CONSTANT(double_limb_type, borrow = static_cast<double_limb_type>(CppInt1::max_limb_value) + 1);
+ result.resize(a.size(), a.size());
+ typename CppInt1::limb_pointer pr = result.limbs();
+ typename CppInt2::const_limb_pointer pa = a.limbs();
+ if(*pa > b)
+ {
+ *pr = *pa - b;
+ if(&result != &a)
+ {
+ std::copy(pa + 1, pa + a.size(), pr + 1);
+ result.sign(a.sign());
+ }
+ }
+ else if(result.size() == 1)
+ {
+ *pr = b - *pa;
+ result.sign(!a.sign());
+ }
+ else
+ {
+ *pr = static_cast<limb_type>((borrow + *pa) - b);
+ unsigned i = 1;
+ while(!pa[i])
+ {
+ pr[i] = CppInt1::max_limb_value;
+ ++i;
+ }
+ pr[i] = pa[i] - 1;
+ if(&result != &a)
+ {
+ ++i;
+ std::copy(pa + i, pa + a.size(), pr + i);
+ }
+ result.normalize();
+ result.sign(a.sign());
+ }
+}
+
+//
+// Now the actual functions called by the front end, all of which forward to one of the above:
+//
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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))
+{
+ eval_add(result, result, o);
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, unsigned MinBits3, unsigned MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
+inline 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 && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value >::type
+ 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))
+{
+ if(a.sign() != b.sign())
+ {
+ subtract_unsigned(result, a, b);
+ return;
+ }
+ add_unsigned(result, a, b);
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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))
+{
+ if(result.sign())
+ {
+ subtract_unsigned(result, result, o);
+ }
+ else
+ add_unsigned(result, result, o);
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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>& a,
+ const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+{
+ if(a.sign())
+ {
+ subtract_unsigned(result, a, o);
+ }
+ else
+ add_unsigned(result, a, o);
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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))
+{
+ if(o < 0)
+ eval_subtract(result, static_cast<limb_type>(-o));
+ else if(o > 0)
+ eval_add(result, static_cast<limb_type>(o));
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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>& a,
+ const signed_limb_type& o) BOOST_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>(-o));
+ else if(o > 0)
+ eval_add(result, a, static_cast<limb_type>(o));
+ else if(&result != &a)
+ result = a;
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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))
+{
+ if(result.sign())
+ {
+ add_unsigned(result, result, o);
+ }
+ else
+ subtract_unsigned(result, result, o);
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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>& a,
+ const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+{
+ if(a.sign())
+ {
+ add_unsigned(result, a, o);
+ }
+ else
+ {
+ subtract_unsigned(result, a, o);
+ }
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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))
+{
+ if(o)
+ {
+ if(o < 0)
+ eval_add(result, static_cast<limb_type>(-o));
+ else
+ eval_subtract(result, static_cast<limb_type>(o));
+ }
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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>& a,
+ const signed_limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+{
+ if(o)
+ {
+ if(o < 0)
+ eval_add(result, a, static_cast<limb_type>(-o));
+ else
+ eval_subtract(result, a, static_cast<limb_type>(o));
+ }
+ else if(&result != &a)
+ result = a;
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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))
+{
+ static const limb_type one = 1;
+ if(!result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value))
+ ++result.limbs()[0];
+ else if(result.sign() && result.limbs()[0])
+ --result.limbs()[0];
+ else
+ eval_add(result, one);
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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))
+{
+ static const limb_type one = 1;
+ if(!result.sign() && result.limbs()[0])
+ --result.limbs()[0];
+ else if(result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value))
+ ++result.limbs()[0];
+ else
+ eval_subtract(result, one);
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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))
+{
+ eval_subtract(result, result, o);
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, unsigned MinBits3, unsigned MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
+BOOST_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 && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value >::type
+ 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))
+{
+ if(a.sign() != b.sign())
+ {
+ add_unsigned(result, a, b);
+ return;
+ }
+ subtract_unsigned(result, a, b);
+}
+
+//
+// Simple addition and subtraction routine for trivial cpp_int's come last:
+//
+// One of the arguments is signed:
+//
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+inline typename enable_if_c<
+ 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
+ && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_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))
+{
+ if(result.sign() != o.sign())
+ {
+ if(*o.limbs() > *result.limbs())
+ {
+ *result.limbs() = detail::checked_subtract(*o.limbs(), *result.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
+ result.negate();
+ }
+ else
+ *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
+ }
+ else
+ *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
+ result.normalize();
+}
+// Simple version for two unsigned arguments:
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && 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))
+{
+ *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
+ result.normalize();
+}
+
+// signed subtraction:
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+inline typename enable_if_c<
+ 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
+ && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)
+ >::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))
+{
+ if(result.sign() != o.sign())
+ {
+ *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
+ }
+ else if(*result.limbs() < *o.limbs())
+ {
+ *result.limbs() = detail::checked_subtract(*o.limbs(), *result.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
+ result.negate();
+ }
+ else
+ *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), 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>
+BOOST_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<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ >::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))
+{
+ *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
+ result.normalize();
+}
+
+}}} // namespaces
+
+#endif

Added: sandbox/big_number/boost/multiprecision/cpp_int/bitwise.hpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/boost/multiprecision/cpp_int/bitwise.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -0,0 +1,560 @@
+///////////////////////////////////////////////////////////////
+// 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_
+//
+// Comparison operators for cpp_int_backend:
+//
+#ifndef BOOST_MP_CPP_INT_BIT_HPP
+#define BOOST_MP_CPP_INT_BIT_HPP
+
+namespace boost{ namespace multiprecision{ namespace backends{
+
+template <class CppInt1, class CppInt2, class Op>
+void bitwise_op(
+ CppInt1& result,
+ const CppInt2& o,
+ Op op) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<CppInt1>::value))
+{
+ //
+ // There are 4 cases:
+ // * Both positive.
+ // * result negative, o positive.
+ // * o negative, result positive.
+ // * Both negative.
+ //
+ // When one arg is negative we convert to 2's complement form "on the fly",
+ // and then convert back to signed-magnitude form at the end.
+ //
+ // First figure out how big the result needs to be and set up some data:
+ //
+ unsigned rs = result.size();
+ unsigned os = o.size();
+ unsigned m, x;
+ minmax(rs, os, m, x);
+ result.resize(x, x);
+ typename CppInt1::limb_pointer pr = result.limbs();
+ typename CppInt2::const_limb_pointer po = o.limbs();
+ for(unsigned i = rs; i < x; ++i)
+ pr[i] = 0;
+
+ limb_type next_limb = 0;
+
+ if(!result.sign())
+ {
+ if(!o.sign())
+ {
+ for(unsigned i = 0; i < os; ++i)
+ pr[i] = op(pr[i], po[i]);
+ for(unsigned i = os; i < x; ++i)
+ pr[i] = op(pr[i], limb_type(0));
+ }
+ else
+ {
+ // "o" is negative:
+ double_limb_type carry = 1;
+ for(unsigned i = 0; i < os; ++i)
+ {
+ carry += static_cast<double_limb_type>(~po[i]);
+ pr[i] = op(pr[i], static_cast<limb_type>(carry));
+ carry >>= CppInt1::limb_bits;
+ }
+ for(unsigned i = os; i < x; ++i)
+ {
+ carry += static_cast<double_limb_type>(~limb_type(0));
+ pr[i] = op(pr[i], static_cast<limb_type>(carry));
+ carry >>= CppInt1::limb_bits;
+ }
+ // Set the overflow into the "extra" limb:
+ carry += static_cast<double_limb_type>(~limb_type(0));
+ next_limb = op(limb_type(0), static_cast<limb_type>(carry));
+ }
+ }
+ else
+ {
+ if(!o.sign())
+ {
+ // "result" is negative:
+ double_limb_type carry = 1;
+ for(unsigned i = 0; i < os; ++i)
+ {
+ carry += static_cast<double_limb_type>(~pr[i]);
+ pr[i] = op(static_cast<limb_type>(carry), po[i]);
+ carry >>= CppInt1::limb_bits;
+ }
+ for(unsigned i = os; i < x; ++i)
+ {
+ carry += static_cast<double_limb_type>(~pr[i]);
+ pr[i] = op(static_cast<limb_type>(carry), limb_type(0));
+ carry >>= CppInt1::limb_bits;
+ }
+ // Set the overflow into the "extra" limb:
+ carry += static_cast<double_limb_type>(~limb_type(0));
+ next_limb = op(static_cast<limb_type>(carry), limb_type(0));
+ }
+ else
+ {
+ // both are negative:
+ double_limb_type r_carry = 1;
+ double_limb_type o_carry = 1;
+ for(unsigned i = 0; i < os; ++i)
+ {
+ r_carry += static_cast<double_limb_type>(~pr[i]);
+ o_carry += static_cast<double_limb_type>(~po[i]);
+ pr[i] = op(static_cast<limb_type>(r_carry), static_cast<limb_type>(o_carry));
+ r_carry >>= CppInt1::limb_bits;
+ o_carry >>= CppInt1::limb_bits;
+ }
+ for(unsigned i = os; i < x; ++i)
+ {
+ r_carry += static_cast<double_limb_type>(~pr[i]);
+ o_carry += static_cast<double_limb_type>(~limb_type(0));
+ pr[i] = op(static_cast<limb_type>(r_carry), static_cast<limb_type>(o_carry));
+ r_carry >>= CppInt1::limb_bits;
+ o_carry >>= CppInt1::limb_bits;
+ }
+ // Set the overflow into the "extra" limb:
+ r_carry += static_cast<double_limb_type>(~limb_type(0));
+ o_carry += static_cast<double_limb_type>(~limb_type(0));
+ next_limb = op(static_cast<limb_type>(r_carry), static_cast<limb_type>(o_carry));
+ }
+ }
+ //
+ // See if the result is negative or not:
+ //
+ if(static_cast<signed_limb_type>(next_limb) < 0)
+ {
+ result.sign(true);
+ double_limb_type carry = 1;
+ for(unsigned i = 0; i < x; ++i)
+ {
+ carry += static_cast<double_limb_type>(~pr[i]);
+ pr[i] = static_cast<limb_type>(carry);
+ carry >>= CppInt1::limb_bits;
+ }
+ }
+ else
+ result.sign(false);
+
+ result.normalize();
+}
+
+struct bit_and{ limb_type operator()(limb_type a, limb_type b)const BOOST_NOEXCEPT { return a & b; } };
+struct bit_or { limb_type operator()(limb_type a, limb_type b)const BOOST_NOEXCEPT { return a | b; } };
+struct bit_xor{ limb_type operator()(limb_type a, limb_type b)const BOOST_NOEXCEPT { return a ^ b; } };
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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))
+{
+ bitwise_op(result, o, bit_and());
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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))
+{
+ bitwise_op(result, o, bit_or());
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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))
+{
+ bitwise_op(result, o, bit_xor());
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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))
+{
+ BOOST_STATIC_ASSERT_MSG(((Checked1 != checked) || (Checked2 != checked)), "Attempt to take the complement of a signed type results in undefined behavior.");
+ // Increment and negate:
+ result = o;
+ eval_increment(result);
+ result.negate();
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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))
+{
+ unsigned os = o.size();
+ result.resize(UINT_MAX, os);
+ for(unsigned i = 0; i < os; ++i)
+ result.limbs()[i] = ~o.limbs()[i];
+ for(unsigned i = os; i < result.size(); ++i)
+ result.limbs()[i] = ~static_cast<limb_type>(0);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+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))
+{
+ if(!s)
+ return;
+
+ 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);
+
+ /*
+ static const unsigned max_bits = max_bits<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value;
+ static const unsigned max_limbs = max_bits / cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits
+ + (max_bits % cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits ? 1 : 0);
+ */
+
+ unsigned ors = result.size();
+ if((ors == 1) && (!*result.limbs()))
+ return; // shifting zero yields zero.
+ unsigned rs = ors;
+ if(shift && (result.limbs()[ors - 1] >> (cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits - shift)))
+ ++rs; // Most significant limb will overflow when shifted
+ rs += offset;
+ result.resize(rs, rs);
+ bool truncated = result.size() != rs;
+ if(truncated)
+ rs = result.size();
+ typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pr = result.limbs();
+
+ if(offset > rs)
+ {
+ // The result is shifted past the end of the result:
+ result = static_cast<limb_type>(0);
+ return;
+ }
+
+ unsigned i = 0;
+ if(shift)
+ {
+ // This code only works when shift is non-zero, otherwise we invoke undefined behaviour!
+ i = 0;
+ if(!truncated)
+ {
+ if(rs > ors + offset)
+ {
+ pr[rs - 1 - i] = pr[ors - 1 - i] >> (cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits - shift);
+ --rs;
+ }
+ else
+ {
+ pr[rs - 1 - i] = pr[ors - 1 - i] << shift;
+ if(ors > 1)
+ pr[rs - 1 - i] |= pr[ors - 2 - i] >> (cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits - shift);
+ ++i;
+ }
+ }
+ for(; ors > 1 + i; ++i)
+ {
+ pr[rs - 1 - i] = pr[ors - 1 - i] << shift;
+ pr[rs - 1 - i] |= pr[ors - 2 - i] >> (cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits - shift);
+ }
+ if(ors >= 1 + i)
+ {
+ pr[rs - 1 - i] = pr[ors - 1 - i] << shift;
+ ++i;
+ }
+ for(; i < rs; ++i)
+ pr[rs - 1 - i] = 0;
+ }
+ else
+ {
+ for(; i < ors; ++i)
+ pr[rs - 1 - i] = pr[ors - 1 - i];
+ for(; i < rs; ++i)
+ pr[rs - 1 - i] = 0;
+ }
+ //
+ // We may have shifted off the end and have leading zeros:
+ //
+ if(truncated)
+ {
+ result.normalize();
+ }
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+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))
+{
+ if(!s)
+ return;
+
+ 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);
+ return;
+ }
+ rs -= offset;
+ typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pr = result.limbs();
+ if((pr[ors - 1] >> shift) == 0)
+ --rs;
+ if(rs == 0)
+ {
+ result = limb_type(0);
+ return;
+ }
+ unsigned i = 0;
+ if(shift)
+ {
+ // This code only works for non-zero shift, otherwise we invoke undefined behaviour!
+ for(; i + offset + 1 < ors; ++i)
+ {
+ pr[i] = pr[i + offset] >> shift;
+ pr[i] |= pr[i + offset + 1] << (cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits - shift);
+ }
+ pr[i] = pr[i + offset] >> shift;
+ }
+ else
+ {
+ for(; i < rs; ++i)
+ pr[i] = pr[i + offset];
+ }
+ result.resize(rs, rs);
+}
+
+//
+// Over agin for trivial cpp_int's:
+//
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class T>
+BOOST_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))
+{
+ *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_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))
+{
+ // Nothing to check here... just make sure we don't invoke undefined behavior:
+ *result.limbs() = (static_cast<unsigned>(s) >= sizeof(*result.limbs()) * CHAR_BIT) ? 0 : *result.limbs() >>= s;
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+void is_valid_bitwise_op(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const mpl::int_<checked>&)
+{
+ if(result.sign() || o.sign())
+ BOOST_THROW_EXCEPTION(std::range_error("Bitwise operations on negative values results in undefined behavior."));
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+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_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+inline 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
+ && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<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))
+{
+ is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
+
+ using default_ops::eval_bit_test;
+ using default_ops::eval_increment;
+
+ if(result.sign() || o.sign())
+ {
+ static const unsigned m = static_unsigned_max<static_unsigned_max<MinBits1, MinBits2>::value, static_unsigned_max<MaxBits1, MaxBits2>::value>::value;
+ cpp_int_backend<m + 1, m + 1, unsigned_magnitude, unchecked, void> t1(result);
+ cpp_int_backend<m + 1, m + 1, unsigned_magnitude, unchecked, void> t2(o);
+ eval_bitwise_and(t1, t2);
+ bool s = eval_bit_test(t1, m + 1);
+ if(s)
+ {
+ eval_complement(t1, t1);
+ eval_increment(t1);
+ }
+ result = t1;
+ result.sign(s);
+ }
+ else
+ {
+ *result.limbs() &= *o.limbs();
+ }
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+inline 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
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<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))
+{
+ *result.limbs() &= *o.limbs();
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+inline 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
+ && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<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))
+{
+ is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
+
+ using default_ops::eval_bit_test;
+ using default_ops::eval_increment;
+
+ if(result.sign() || o.sign())
+ {
+ static const unsigned m = static_unsigned_max<static_unsigned_max<MinBits1, MinBits2>::value, static_unsigned_max<MaxBits1, MaxBits2>::value>::value;
+ cpp_int_backend<m + 1, m + 1, unsigned_magnitude, unchecked, void> t1(result);
+ cpp_int_backend<m + 1, m + 1, unsigned_magnitude, unchecked, void> t2(o);
+ eval_bitwise_or(t1, t2);
+ bool s = eval_bit_test(t1, m + 1);
+ if(s)
+ {
+ eval_complement(t1, t1);
+ eval_increment(t1);
+ }
+ result = t1;
+ result.sign(s);
+ }
+ else
+ {
+ *result.limbs() |= *o.limbs();
+ result.normalize();
+ }
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+inline 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
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<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))
+{
+ *result.limbs() |= *o.limbs();
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+inline 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
+ && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<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))
+{
+ is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
+
+ using default_ops::eval_bit_test;
+ using default_ops::eval_increment;
+
+ if(result.sign() || o.sign())
+ {
+ static const unsigned m = static_unsigned_max<static_unsigned_max<MinBits1, MinBits2>::value, static_unsigned_max<MaxBits1, MaxBits2>::value>::value;
+ cpp_int_backend<m + 1, m + 1, unsigned_magnitude, unchecked, void> t1(result);
+ cpp_int_backend<m + 1, m + 1, unsigned_magnitude, unchecked, void> t2(o);
+ eval_bitwise_xor(t1, t2);
+ bool s = eval_bit_test(t1, m + 1);
+ if(s)
+ {
+ eval_complement(t1, t1);
+ eval_increment(t1);
+ }
+ result = t1;
+ result.sign(s);
+ }
+ else
+ {
+ *result.limbs() ^= *o.limbs();
+ }
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+inline 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
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<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))
+{
+ *result.limbs() ^= *o.limbs();
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+inline 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
+ && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<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))
+{
+ BOOST_STATIC_ASSERT_MSG(((Checked1 != checked) || (Checked2 != checked)), "Attempt to take the complement of a signed type results in undefined behavior.");
+ //
+ // If we're not checked then emulate 2's complement behavior:
+ //
+ if(o.sign())
+ {
+ *result.limbs() = *o.limbs() - 1;
+ result.sign(false);
+ }
+ else
+ {
+ *result.limbs() = 1 + *o.limbs();
+ result.sign(true);
+ }
+ result.normalize();
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+inline 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
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<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))
+{
+ *result.limbs() = ~*o.limbs();
+}
+
+}}} // namespaces
+
+#endif

Added: sandbox/big_number/boost/multiprecision/cpp_int/checked.hpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/boost/multiprecision/cpp_int/checked.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -0,0 +1,149 @@
+
+// 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_
+
+#ifndef BOOST_MP_CPP_INT_CHECKED_HPP
+#define BOOST_MP_CPP_INT_CHECKED_HPP
+
+namespace boost{ namespace multiprecision{ namespace backends{ namespace detail{
+
+//
+// Simple routines for performing checked arithmetic with a builtin arithmetic type.
+// Note that is is not a complete header, it must be included as part of boost/multiprecision/cpp_int.hpp.
+//
+
+inline void raise_overflow(std::string op)
+{
+ BOOST_THROW_EXCEPTION(std::overflow_error("overflow in " + op));
+}
+inline void raise_add_overflow()
+{
+ raise_overflow("addition");
+}
+inline void raise_subtract_overflow()
+{
+ raise_overflow("subtraction");
+}
+inline void raise_mul_overflow()
+{
+ raise_overflow("multiplication");
+}
+inline void raise_div_overflow()
+{
+ raise_overflow("division");
+}
+
+template <class A>
+inline A checked_add_imp(A a, A b, const mpl::true_&)
+{
+ if(a > 0)
+ {
+ if((b > 0) && ((integer_traits<A>::const_max - b) < a))
+ raise_add_overflow();
+ }
+ else
+ {
+ if((b < 0) && ((integer_traits<A>::const_min - b) > a))
+ raise_add_overflow();
+ }
+ return a + b;
+}
+template <class A>
+inline A checked_add_imp(A a, A b, const mpl::false_&)
+{
+ if((integer_traits<A>::const_max - b) < a)
+ raise_add_overflow();
+ return a + b;
+}
+template <class A>
+inline A checked_add(A a, A b, const mpl::int_<checked>&)
+{
+ return checked_add_imp(a, b, boost::is_signed<A>());
+}
+template <class A>
+inline A checked_add(A a, A b, const mpl::int_<unchecked>&)
+{
+ return a + b;
+}
+
+template <class A>
+inline A checked_subtract_imp(A a, A b, const mpl::true_&)
+{
+ if(a > 0)
+ {
+ if((b < 0) && ((integer_traits<A>::const_max + b) < a))
+ raise_subtract_overflow();
+ }
+ else
+ {
+ if((b > 0) && ((integer_traits<A>::const_min + b) > a))
+ raise_subtract_overflow();
+ }
+ return a - b;
+}
+template <class A>
+inline A checked_subtract_imp(A a, A b, const mpl::false_&)
+{
+ if(a < b)
+ raise_subtract_overflow();
+ return a - b;
+}
+template <class A>
+inline A checked_subtract(A a, A b, const mpl::int_<checked>&)
+{
+ return checked_subtract_imp(a, b, boost::is_signed<A>());
+}
+template <class A>
+inline A checked_subtract(A a, A b, const mpl::int_<unchecked>&)
+{
+ return a - b;
+}
+
+template <class A>
+inline A checked_multiply(A a, A b, const mpl::int_<checked>&)
+{
+ BOOST_MP_USING_ABS
+ if(a && (integer_traits<A>::const_max / abs(a) < abs(b)))
+ raise_mul_overflow();
+ return a * b;
+}
+template <class A>
+inline A checked_multiply(A a, A b, const mpl::int_<unchecked>&)
+{
+ return a * b;
+}
+
+template <class A>
+inline A checked_divide(A a, A b, const mpl::int_<checked>&)
+{
+ if(b == 0)
+ raise_div_overflow();
+ return a / b;
+}
+template <class A>
+inline A checked_divide(A a, A b, const mpl::int_<unchecked>&)
+{
+ return a / b;
+}
+
+template <class A>
+inline A checked_left_shift(A a, unsigned long long shift, const mpl::int_<checked>&)
+{
+ if(a && shift)
+ {
+ if((shift > sizeof(A) * CHAR_BIT) || (a >> (sizeof(A) * CHAR_BIT - shift)))
+ BOOST_THROW_EXCEPTION(std::overflow_error("Shift out of range"));
+ }
+ return a << shift;
+}
+template <class A>
+inline A checked_left_shift(A a, unsigned long long shift, const mpl::int_<unchecked>&)
+{
+ return (shift >= sizeof(A) * CHAR_BIT) ? 0 : a << shift;
+}
+
+}}}} // namespaces
+
+#endif
+

Added: sandbox/big_number/boost/multiprecision/cpp_int/comparison.hpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/boost/multiprecision/cpp_int/comparison.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -0,0 +1,389 @@
+///////////////////////////////////////////////////////////////
+// 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_
+//
+// Comparison operators for cpp_int_backend:
+//
+#ifndef BOOST_MP_CPP_INT_COMPARISON_HPP
+#define BOOST_MP_CPP_INT_COMPARISON_HPP
+
+#include <boost/type_traits/make_unsigned.hpp>
+
+namespace boost{ namespace multiprecision{ namespace backends{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4018 4389)
+#endif
+
+//
+// Start with non-trivial cpp_int's:
+//
+template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
+BOOST_FORCEINLINE typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
+ bool
+ >::type
+ eval_eq(const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& a, const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& b) BOOST_NOEXCEPT
+{
+ return (a.sign() == b.sign())
+ && (a.size() == b.size())
+ && std::equal(a.limbs(), a.limbs() + a.size(), b.limbs());
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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,
+ bool
+ >::type
+ eval_eq(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& b) BOOST_NOEXCEPT
+{
+ return (a.sign() == b.sign())
+ && (a.size() == b.size())
+ && std::equal(a.limbs(), a.limbs() + a.size(), b.limbs());
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+BOOST_FORCEINLINE typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
+ bool
+ >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
+{
+ return (a.sign() == false)
+ && (a.size() == 1)
+ && (*a.limbs() == b);
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+BOOST_FORCEINLINE typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
+ bool
+ >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
+{
+ return (a.sign() == (b < 0))
+ && (a.size() == 1)
+ && (*a.limbs() == static_cast<limb_type>(std::abs(b)));
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+BOOST_FORCEINLINE typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
+ bool
+ >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
+{
+ return (a.size() == 1)
+ && (*a.limbs() == b);
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+BOOST_FORCEINLINE typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
+ bool
+ >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
+{
+ return (b < 0) ? eval_eq(a, cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>(b)) : eval_eq(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison
+}
+
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+BOOST_FORCEINLINE typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
+ bool
+ >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
+{
+ if(a.sign())
+ return true;
+ if(a.size() > 1)
+ return false;
+ return *a.limbs() < b;
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+inline typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
+ bool
+ >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
+{
+ if((b == 0) || (a.sign() != (b < 0)))
+ return a.sign();
+ if(a.sign())
+ {
+ if(a.size() > 1)
+ return true;
+ return *a.limbs() > static_cast<limb_type>(std::abs(b));
+ }
+ else
+ {
+ if(a.size() > 1)
+ return false;
+ return *a.limbs() < static_cast<limb_type>(b);
+ }
+}
+
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+BOOST_FORCEINLINE typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
+ bool
+ >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
+{
+ if(a.size() > 1)
+ return false;
+ return *a.limbs() < b;
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+BOOST_FORCEINLINE typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
+ bool
+ >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
+{
+ return (b < 0) ? a.compare(b) < 0 : eval_lt(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison
+}
+
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+BOOST_FORCEINLINE typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
+ bool
+ >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
+{
+ if(a.sign())
+ return false;
+ if(a.size() > 1)
+ return true;
+ return *a.limbs() > b;
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+inline typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
+ bool
+ >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
+{
+ if(b == 0)
+ return !a.sign() && ((a.size() > 1) || *a.limbs());
+ if(a.sign() != (b < 0))
+ return !a.sign();
+ if(a.sign())
+ {
+ if(a.size() > 1)
+ return false;
+ return *a.limbs() < static_cast<limb_type>(std::abs(b));
+ }
+ else
+ {
+ if(a.size() > 1)
+ return true;
+ return *a.limbs() > static_cast<limb_type>(b);
+ }
+}
+
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+BOOST_FORCEINLINE typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
+ bool
+ >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
+{
+ if(a.size() > 1)
+ return true;
+ return *a.limbs() > b;
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
+BOOST_FORCEINLINE typename enable_if_c<
+ !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
+ bool
+ >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
+{
+ return (b < 0) ? a.compare(b) > 0 : eval_gt(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison.
+}
+//
+// And again for trivial cpp_ints:
+//
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
+ bool
+ >::value eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& b) BOOST_NOEXCEPT
+{
+ return (a.sign() == b.sign()) && (*a.limbs() == *b.limbs());
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
+ bool
+ >::value eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT
+{
+ return *a.limbs() == *b.limbs();
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
+{
+ return !a.sign() && (*a.limbs() == b);
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
+{
+ typedef typename make_unsigned<S>::type ui_type;
+ return (a.sign() == (b < 0)) && (*a.limbs() == static_cast<ui_type>(std::abs(b)));
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
+{
+ return *a.limbs() == b;
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
+{
+ typedef typename make_unsigned<S>::type ui_type;
+ if(b < 0)
+ {
+ cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b);
+ return *a.limbs() == *t.limbs();
+ }
+ else
+ {
+ return *a.limbs() == static_cast<ui_type>(b);
+ }
+}
+
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT
+{
+ if(a.sign() != b.sign())
+ return a.sign();
+ return a.sign() ? *a.limbs() > *b.limbs() : *a.limbs() < *b.limbs();
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT
+{
+ return *a.limbs() < *b.limbs();
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
+{
+ if(a.sign())
+ return true;
+ return *a.limbs() < b;
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
+{
+ typedef typename make_unsigned<S>::type ui_type;
+ if(a.sign() != (b < 0))
+ return a.sign();
+ return a.sign() ? (*a.limbs() > static_cast<ui_type>(std::abs(b))) : (*a.limbs() < static_cast<ui_type>(std::abs(b)));
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
+{
+ return *a.limbs() < b;
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
+{
+ typedef typename make_unsigned<S>::type ui_type;
+ if(b < 0)
+ {
+ cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b);
+ return *a.limbs() < *t.limbs();
+ }
+ else
+ {
+ return *a.limbs() < static_cast<ui_type>(b);
+ }
+}
+
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& b) BOOST_NOEXCEPT
+{
+ if(a.sign() != b.sign())
+ return !a.sign();
+ return a.sign() ? *a.limbs() < *b.limbs() : *a.limbs() > *b.limbs();
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT
+{
+ return *a.limbs() > *b.limbs();
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
+{
+ if(a.sign())
+ return false;
+ return *a.limbs() > b;
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
+{
+ typedef typename make_unsigned<S>::type ui_type;
+ if(a.sign() != (b < 0))
+ return !a.sign();
+ return a.sign() ? (*a.limbs() < static_cast<ui_type>(std::abs(b))) : (*a.limbs() > static_cast<ui_type>(std::abs(b)));
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
+{
+ return *a.limbs() > b;
+}
+template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
+BOOST_FORCEINLINE typename enable_if_c<
+ is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
+ bool
+ >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
+{
+ typedef typename make_unsigned<S>::type ui_type;
+ if(b < 0)
+ {
+ cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b);
+ return *a.limbs() > *t.limbs();
+ }
+ else
+ {
+ return *a.limbs() > static_cast<ui_type>(b);
+ }
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+}}} // namespaces
+
+#endif

Added: sandbox/big_number/boost/multiprecision/cpp_int/cpp_int_config.hpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/boost/multiprecision/cpp_int/cpp_int_config.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -0,0 +1,156 @@
+///////////////////////////////////////////////////////////////
+// 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_
+
+#ifndef BOOST_MP_CPP_INT_CORE_HPP
+#define BOOST_MP_CPP_INT_CORE_HPP
+
+#include <boost/integer.hpp>
+#include <boost/integer_traits.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/assert.hpp>
+
+namespace boost{ namespace multiprecision{
+
+namespace detail{
+
+//
+// These traits calculate the largest type in the list
+// [unsigned] ong long, 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
+// as possible.
+//
+template <unsigned N>
+struct largest_signed_type
+{
+ typedef typename mpl::if_c<
+ 1 + std::numeric_limits<long long>::digits == N,
+ long long,
+ typename mpl::if_c<
+ 1 + std::numeric_limits<long>::digits == N,
+ long,
+ typename mpl::if_c<
+ 1 + std::numeric_limits<int>::digits == N,
+ int,
+ typename boost::int_t<N>::exact
+ >::type
+ >::type
+ >::type type;
+};
+
+template <unsigned N>
+struct largest_unsigned_type
+{
+ typedef typename mpl::if_c<
+ std::numeric_limits<unsigned long long>::digits == N,
+ unsigned long long,
+ typename mpl::if_c<
+ std::numeric_limits<unsigned long>::digits == N,
+ unsigned long,
+ typename mpl::if_c<
+ std::numeric_limits<unsigned int>::digits == N,
+ unsigned int,
+ typename boost::uint_t<N>::exact
+ >::type
+ >::type
+ >::type type;
+};
+
+} // namepsace detail
+
+#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))) \
+ && !defined(BOOST_INTEL) && defined(__WORDSIZE) && (__WORDSIZE == 64)
+
+typedef detail::largest_unsigned_type<64>::type limb_type;
+typedef detail::largest_signed_type<64>::type signed_limb_type;
+typedef unsigned __int128 double_limb_type;
+typedef __int128 signed_double_limb_type;
+static const limb_type max_block_10 = 1000000000000000000uLL;
+static const limb_type digits_per_block_10 = 18;
+
+inline limb_type block_multiplier(unsigned count)
+{
+ static const limb_type values[digits_per_block_10]
+ = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000 };
+ BOOST_ASSERT(count < digits_per_block_10);
+ return values[count];
+}
+
+// Can't do formatted IO on an __int128
+#define BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO
+
+// Need to specialise integer_traits for __int128 as it's not a normal native type:
+} // namespace multiprecision
+
+template<>
+class integer_traits<double_limb_type>
+ : public std::numeric_limits<double_limb_type>,
+ public detail::integer_traits_base<double_limb_type, 0, ~static_cast<double_limb_type>(0)>
+{ };
+template<>
+class integer_traits<signed_double_limb_type>
+ : public std::numeric_limits<signed_double_limb_type>,
+ public detail::integer_traits_base<signed_double_limb_type, static_cast<signed_double_limb_type>(static_cast<double_limb_type>(1) << 127), static_cast<signed_double_limb_type>((~static_cast<double_limb_type>(0)) >> 1)>
+{ };
+
+namespace multiprecision{
+
+#else
+
+typedef detail::largest_unsigned_type<32>::type limb_type;
+typedef detail::largest_signed_type<32>::type signed_limb_type;
+typedef boost::uint64_t double_limb_type;
+typedef boost::int64_t signed_double_limb_type;
+static const limb_type max_block_10 = 1000000000;
+static const limb_type digits_per_block_10 = 9;
+
+inline limb_type block_multiplier(unsigned count)
+{
+ static const limb_type values[digits_per_block_10]
+ = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
+ BOOST_ASSERT(count < digits_per_block_10);
+ return values[count];
+}
+
+#endif
+
+static const unsigned bits_per_limb = sizeof(limb_type) * CHAR_BIT;
+
+template <class T>
+inline void minmax(const T& a, const T& b, T& aa, T& bb)
+{
+ if(a < b)
+ {
+ aa = a;
+ bb = b;
+ }
+ else
+ {
+ aa = b;
+ bb = a;
+ }
+}
+
+enum cpp_integer_type
+{
+ signed_magnitude,
+ unsigned_magnitude,
+ signed_packed,
+ unsigned_packed
+};
+
+enum cpp_int_check_type
+{
+ checked,
+ unchecked
+};
+
+}}
+
+#endif // BOOST_MP_CPP_INT_CORE_HPP
+

Added: sandbox/big_number/boost/multiprecision/cpp_int/divide.hpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/boost/multiprecision/cpp_int/divide.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -0,0 +1,618 @@
+///////////////////////////////////////////////////////////////
+// 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_
+//
+// Comparison operators for cpp_int_backend:
+//
+#ifndef BOOST_MP_CPP_INT_DIV_HPP
+#define BOOST_MP_CPP_INT_DIV_HPP
+
+namespace boost{ namespace multiprecision{ namespace backends{
+
+template <class CppInt1, class CppInt2, class CppInt3>
+void divide_unsigned_helper(
+ CppInt1* result,
+ const CppInt2& x,
+ const CppInt3& y,
+ CppInt1& r)
+{
+ if(((void*)result == (void*)&x) || ((void*)&r == (void*)&x))
+ {
+ CppInt2 t(x);
+ divide_unsigned_helper(result, t, y, r);
+ return;
+ }
+ if(((void*)result == (void*)&y) || ((void*)&r == (void*)&y))
+ {
+ CppInt3 t(y);
+ divide_unsigned_helper(result, x, t, r);
+ return;
+ }
+
+ /*
+ Very simple, fairly braindead long division.
+ Start by setting the remainder equal to x, and the
+ result equal to 0. Then in each loop we calculate our
+ "best guess" for how many times y divides into r,
+ add our guess to the result, and subtract guess*y
+ from the remainder r. One wrinkle is that the remainder
+ may go negative, in which case we subtract the current guess
+ from the result rather than adding. The value of the guess
+ is determined by dividing the most-significant-limb of the
+ current remainder by the most-significant-limb of y.
+
+ Note that there are more efficient algorithms than this
+ available, in particular see Knuth Vol 2. However for small
+ numbers of limbs this generally outperforms the alternatives
+ and avoids the normalisation step which would require extra storage.
+ */
+
+
+ using default_ops::eval_subtract;
+
+ if(result == &r)
+ {
+ CppInt1 rem;
+ divide_unsigned_helper(result, x, y, rem);
+ r = rem;
+ return;
+ }
+
+ //
+ // Find the most significant words of numerator and denominator.
+ //
+ limb_type y_order = y.size() - 1;
+
+ if(y_order == 0)
+ {
+ //
+ // Only a single non-zero limb in the denominator, in this case
+ // we can use a specialized divide-by-single-limb routine which is
+ // much faster. This also handles division by zero:
+ //
+ divide_unsigned_helper(result, x, y.limbs()[y_order], r);
+ return;
+ }
+
+ typename CppInt2::const_limb_pointer px = x.limbs();
+ typename CppInt3::const_limb_pointer py = y.limbs();
+
+ limb_type r_order = x.size() - 1;
+ if((r_order == 0) && (*px == 0))
+ {
+ // x is zero, so is the result:
+ r = y;
+ if(result)
+ *result = x;
+ return;
+ }
+
+ r = x;
+ r.sign(false);
+ if(result)
+ *result = static_cast<limb_type>(0u);
+ //
+ // Check if the remainder is already less than the divisor, if so
+ // we already have the result. Note we try and avoid a full compare
+ // if we can:
+ //
+ if(r_order <= y_order)
+ {
+ if((r_order < y_order) || (r.compare_unsigned(y) < 0))
+ {
+ return;
+ }
+ }
+
+ CppInt1 t;
+ bool r_neg = false;
+
+ //
+ // See if we can short-circuit long division, and use basic arithmetic instead:
+ //
+ if(r_order == 0)
+ {
+ if(result)
+ *result = px[0] / py[0];
+ r = px[0] % py[0];
+ return;
+ }
+ else if(r_order == 1)
+ {
+ double_limb_type a, b;
+ a = (static_cast<double_limb_type>(px[1]) << CppInt1::limb_bits) | px[0];
+ b = y_order ?
+ (static_cast<double_limb_type>(py[1]) << CppInt1::limb_bits) | py[0]
+ : py[0];
+ if(result)
+ *result = a / b;
+ r = a % b;
+ return;
+ }
+ //
+ // prepare result:
+ //
+ if(result)
+ result->resize(1 + r_order - y_order, 1 + r_order - y_order);
+ typename CppInt1::const_limb_pointer prem = r.limbs();
+ // This is initialised just to keep the compiler from emitting useless warnings later on:
+ typename CppInt1::limb_pointer pr
+ = typename CppInt1::limb_pointer();
+ if(result)
+ {
+ pr = result->limbs();
+ for(unsigned i = 1; i < 1 + r_order - y_order; ++i)
+ pr[i] = 0;
+ }
+ bool first_pass = true;
+
+ do
+ {
+ //
+ // Calculate our best guess for how many times y divides into r:
+ //
+ limb_type guess;
+ if((prem[r_order] <= py[y_order]) && (r_order > 0))
+ {
+ double_limb_type a, b, v;
+ a = (static_cast<double_limb_type>(prem[r_order]) << CppInt1::limb_bits) | prem[r_order - 1];
+ b = py[y_order];
+ v = a / b;
+ if(v > CppInt1::max_limb_value)
+ guess = 1;
+ else
+ {
+ guess = static_cast<limb_type>(v);
+ --r_order;
+ }
+ }
+ else if(r_order == 0)
+ {
+ guess = prem[0] / py[y_order];
+ }
+ else
+ {
+ double_limb_type a, b, v;
+ a = (static_cast<double_limb_type>(prem[r_order]) << CppInt1::limb_bits) | prem[r_order - 1];
+ b = (y_order > 0) ? (static_cast<double_limb_type>(py[y_order]) << CppInt1::limb_bits) | py[y_order - 1] : (static_cast<double_limb_type>(py[y_order]) << CppInt1::limb_bits);
+ v = a / b;
+ guess = static_cast<limb_type>(v);
+ }
+ BOOST_ASSERT(guess); // If the guess ever gets to zero we go on forever....
+ //
+ // Update result:
+ //
+ limb_type shift = r_order - y_order;
+ if(result)
+ {
+ if(r_neg)
+ {
+ if(pr[shift] > guess)
+ pr[shift] -= guess;
+ else
+ {
+ t.resize(shift + 1, shift + 1);
+ t.limbs()[shift] = guess;
+ for(unsigned i = 0; i < shift; ++i)
+ t.limbs()[i] = 0;
+ eval_subtract(*result, t);
+ }
+ }
+ else if(CppInt1::max_limb_value - pr[shift] > guess)
+ pr[shift] += guess;
+ else
+ {
+ t.resize(shift + 1, shift + 1);
+ t.limbs()[shift] = guess;
+ for(unsigned i = 0; i < shift; ++i)
+ t.limbs()[i] = 0;
+ eval_add(*result, t);
+ }
+ }
+ //
+ // Calculate guess * y, we use a fused mutiply-shift O(N) for this
+ // rather than a full O(N^2) multiply:
+ //
+ double_limb_type carry = 0;
+ t.resize(y.size() + shift + 1, y.size() + shift + 1);
+ bool truncated_t = !CppInt1::variable && (t.size() != y.size() + shift + 1);
+ typename CppInt1::limb_pointer pt = t.limbs();
+ for(unsigned i = 0; i < shift; ++i)
+ pt[i] = 0;
+ for(unsigned i = 0; i < y.size(); ++i)
+ {
+ carry += static_cast<double_limb_type>(py[i]) * static_cast<double_limb_type>(guess);
+ pt[i + shift] = static_cast<limb_type>(carry);
+ carry >>= CppInt1::limb_bits;
+ }
+ if(carry && !truncated_t)
+ {
+ pt[t.size() - 1] = static_cast<limb_type>(carry);
+ }
+ else if(!truncated_t)
+ {
+ t.resize(t.size() - 1, t.size() - 1);
+ }
+ //
+ // Update r:
+ //
+ eval_subtract(r, t);
+ if(r.isneg())
+ {
+ r.negate();
+ r_neg = !r_neg;
+ }
+ //
+ // First time through we need to strip any leading zero, otherwise
+ // the termination condition goes belly-up:
+ //
+ if(result && first_pass)
+ {
+ first_pass = false;
+ while(pr[result->size() - 1] == 0)
+ result->resize(result->size() - 1, result->size() - 1);
+ }
+ //
+ // Update r_order:
+ //
+ r_order = r.size() - 1;
+ if(r_order < y_order)
+ break;
+ }
+ // Termination condition is really just a check that r > y, but with a common
+ // short-circuit case handled first:
+ while((r_order > y_order) || (r.compare_unsigned(y) >= 0));
+
+ //
+ // We now just have to normalise the result:
+ //
+ if(r_neg && eval_get_sign(r))
+ {
+ // We have one too many in the result:
+ if(result)
+ eval_decrement(*result);
+ r.negate();
+ if(y.sign())
+ eval_subtract(r, y);
+ else
+ eval_add(r, y);
+ }
+
+ BOOST_ASSERT(r.compare_unsigned(y) < 0); // remainder must be less than the divisor or our code has failed
+}
+
+template <class CppInt1, class CppInt2>
+void divide_unsigned_helper(
+ CppInt1* result,
+ const CppInt2& x,
+ limb_type y,
+ CppInt1& r)
+{
+ if(((void*)result == (void*)&x) || ((void*)&r == (void*)&x))
+ {
+ CppInt2 t(x);
+ divide_unsigned_helper(result, t, y, r);
+ return;
+ }
+
+ if(result == &r)
+ {
+ CppInt1 rem;
+ divide_unsigned_helper(result, x, y, rem);
+ r = rem;
+ return;
+ }
+
+ // As above, but simplified for integer divisor:
+
+ using default_ops::eval_subtract;
+
+ if(y == 0)
+ {
+ BOOST_THROW_EXCEPTION(std::overflow_error("Integer Division by zero."));
+ }
+ //
+ // Find the most significant word of numerator.
+ //
+ limb_type r_order = x.size() - 1;
+
+ //
+ // Set remainder and result to their initial values:
+ //
+ r = x;
+ r.sign(false);
+ typename CppInt1::limb_pointer pr = r.limbs();
+
+ if((r_order == 0) && (*pr == 0))
+ {
+ // All the limbs in x are zero, so is the result:
+ return;
+ }
+ //
+ // check for x < y, try to do this without actually having to
+ // do a full comparison:
+ //
+ if((r_order == 0) && (*pr < y))
+ {
+ if(result)
+ *result = static_cast<limb_type>(0u);
+ return;
+ }
+
+ //
+ // See if we can short-circuit long division, and use basic arithmetic instead:
+ //
+ if(r_order == 0)
+ {
+ if(result)
+ {
+ *result = *pr / y;
+ result->sign(x.sign());
+ }
+ *pr %= y;
+ r.sign(x.sign());
+ return;
+ }
+ else if(r_order == 1)
+ {
+ double_limb_type a;
+ a = (static_cast<double_limb_type>(pr[r_order]) << CppInt1::limb_bits) | pr[0];
+ if(result)
+ {
+ *result = a / y;
+ result->sign(x.sign());
+ }
+ r = a % y;
+ r.sign(x.sign());
+ return;
+ }
+
+ // This is initialised just to keep the compiler from emitting useless warnings later on:
+ typename CppInt1::limb_pointer pres = typename CppInt1::limb_pointer();
+ if(result)
+ {
+ result->resize(r_order + 1, r_order + 1);
+ pres = result->limbs();
+ if(result->size() > r_order)
+ pres[r_order] = 0; // just in case we don't set the most significant limb below.
+ }
+
+ do
+ {
+ //
+ // Calculate our best guess for how many times y divides into r:
+ //
+ if((pr[r_order] < y) && r_order)
+ {
+ double_limb_type a, b;
+ a = (static_cast<double_limb_type>(pr[r_order]) << CppInt1::limb_bits) | pr[r_order - 1];
+ b = a % y;
+ r.resize(r.size() - 1, r.size() - 1);
+ --r_order;
+ pr[r_order] = static_cast<limb_type>(b);
+ if(result)
+ pres[r_order] = static_cast<limb_type>(a / y);
+ if(r_order && pr[r_order] == 0)
+ {
+ --r_order; // No remainder, division was exact.
+ r.resize(r.size() - 1, r.size() - 1);
+ if(result)
+ pres[r_order] = static_cast<limb_type>(0u);
+ }
+ }
+ else
+ {
+ if(result)
+ pres[r_order] = pr[r_order] / y;
+ pr[r_order] %= y;
+ if(r_order && pr[r_order] == 0)
+ {
+ --r_order; // No remainder, division was exact.
+ r.resize(r.size() - 1, r.size() - 1);
+ if(result)
+ pres[r_order] = static_cast<limb_type>(0u);
+ }
+ }
+ }
+ // Termination condition is really just a check that r > y, but with two common
+ // short-circuit cases handled first:
+ while(r_order || (pr[r_order] > y));
+
+ if(result)
+ {
+ result->normalize();
+ result->sign(x.sign());
+ }
+ r.normalize();
+ r.sign(x.sign());
+
+ BOOST_ASSERT(r.compare(y) < 0); // remainder must be less than the divisor or our code has failed
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, unsigned MinBits3, unsigned MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
+BOOST_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 && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value >::type
+ eval_divide(
+ 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)
+{
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> r;
+ divide_unsigned_helper(&result, a, b, r);
+ result.sign(a.sign() != b.sign());
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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_divide(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
+ limb_type& b)
+{
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> r;
+ divide_unsigned_helper(&result, a, b, r);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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_divide(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
+ signed_limb_type& b)
+{
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> r;
+ divide_unsigned_helper(&result, a, static_cast<limb_type>(std::abs(b)), r);
+ if(b < 0)
+ result.negate();
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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_divide(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& b)
+{
+ // There is no in place divide:
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result);
+ eval_divide(result, a, b);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
+ eval_divide(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ limb_type b)
+{
+ // There is no in place divide:
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result);
+ eval_divide(result, a, b);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
+ eval_divide(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ signed_limb_type b)
+{
+ // There is no in place divide:
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result);
+ eval_divide(result, a, b);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, unsigned MinBits3, unsigned MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
+BOOST_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 && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value >::type
+ eval_modulus(
+ 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)
+{
+ divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>* >(0), a, b, result);
+ result.sign(a.sign());
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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_modulus(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, limb_type b)
+{
+ divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>* >(0), a, b, result);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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_modulus(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
+ signed_limb_type b)
+{
+ divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>* >(0), a, static_cast<limb_type>(std::abs(b)), result);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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_modulus(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& b)
+{
+ // There is no in place divide:
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result);
+ eval_modulus(result, a, b);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
+ eval_modulus(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ limb_type b)
+{
+ // There is no in place divide:
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result);
+ eval_modulus(result, a, b);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
+ eval_modulus(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ signed_limb_type b)
+{
+ // There is no in place divide:
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result);
+ eval_modulus(result, a, b);
+}
+
+//
+// Over again for trivial cpp_int's:
+//
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)
+ >::type
+ eval_divide(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o)
+{
+ if(!*o.limbs())
+ BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
+ *result.limbs() /= *o.limbs();
+ result.sign(result.sign() != o.sign());
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ >::type
+ eval_divide(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o)
+{
+ if(!*o.limbs())
+ BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
+ *result.limbs() /= *o.limbs();
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ >::type
+ eval_modulus(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o)
+{
+ if(!*o.limbs())
+ BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
+ *result.limbs() %= *o.limbs();
+ result.sign(result.sign());
+}
+
+}}} // namespaces
+
+#endif

Added: sandbox/big_number/boost/multiprecision/cpp_int/limits.hpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/boost/multiprecision/cpp_int/limits.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -0,0 +1,215 @@
+///////////////////////////////////////////////////////////////
+// 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_
+//
+// Comparison operators for cpp_int_backend:
+//
+#ifndef BOOST_MP_CPP_INT_LIM_HPP
+#define BOOST_MP_CPP_INT_LIM_HPP
+
+namespace std{
+
+namespace detail{
+
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>
+ get_min(const boost::mpl::true_&, const boost::mpl::true_&)
+{
+ // Bounded and signed.
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> result_type;
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, boost::multiprecision::unsigned_magnitude, Checked, Allocator>, ExpressionTemplates> ui_type;
+ static const result_type val = -result_type(~ui_type(0));
+ return val;
+}
+
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>
+ get_min(const boost::mpl::true_&, const boost::mpl::false_&)
+{
+ // Bounded and unsigned:
+ static const boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> val(0u);
+ return val;
+}
+
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>
+ get_min(const boost::mpl::false_&, const boost::mpl::true_&)
+{
+ // Unbounded and signed.
+ // There is no minimum value, just return 0:
+ static const boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> val(0u);
+ return val;
+}
+
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>
+ get_min(const boost::mpl::false_&, const boost::mpl::false_&)
+{
+ // Unbound and unsigned:
+ static const boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> val(0u);
+ return val;
+}
+
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>
+ get_max(const boost::mpl::true_&, const boost::mpl::true_&)
+{
+ // Bounded and signed.
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> result_type;
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, boost::multiprecision::unsigned_magnitude, Checked, Allocator>, ExpressionTemplates> ui_type;
+ static const result_type val = ~ui_type(0);
+ return val;
+}
+
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>
+ get_max(const boost::mpl::true_&, const boost::mpl::false_&)
+{
+ // Bound and unsigned:
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> result_type;
+ static const result_type val = ~result_type(0);
+ return val;
+}
+
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>
+ get_max(const boost::mpl::false_&, const boost::mpl::true_&)
+{
+ // Unbounded and signed.
+ // There is no maximum value, just return 0:
+ static const boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> val(0u);
+ return val;
+}
+
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>
+ get_max(const boost::mpl::false_&, const boost::mpl::false_&)
+{
+ // Unbound and unsigned:
+ static const boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> val(0u);
+ return val;
+}
+
+}
+
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >
+{
+ typedef boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> backend_type;
+ typedef boost::multiprecision::number<backend_type, ExpressionTemplates> number_type;
+
+ struct inititializer
+ {
+ inititializer()
+ {
+ (std::numeric_limits<number_type>::max)();
+ (std::numeric_limits<number_type>::min)();
+ }
+ void do_nothing()const{}
+ };
+
+ static const inititializer init;
+
+public:
+ BOOST_STATIC_CONSTEXPR bool is_specialized = true;
+ //
+ // Largest and smallest numbers are bounded only by available memory, set
+ // to zero:
+ //
+ static number_type (min)() BOOST_NOEXCEPT
+ {
+ init.do_nothing();
+ return detail::get_min<MinBits, MaxBits, SignType, Checked, Allocator, ExpressionTemplates>(boost::multiprecision::backends::is_fixed_precision<backend_type>(), boost::multiprecision::is_signed_number<backend_type>());
+ }
+ static number_type (max)() BOOST_NOEXCEPT
+ {
+ init.do_nothing();
+ return detail::get_max<MinBits, MaxBits, SignType, Checked, Allocator, ExpressionTemplates>(boost::multiprecision::backends::is_fixed_precision<backend_type>(), boost::multiprecision::is_signed_number<backend_type>());
+ }
+ static number_type lowest() BOOST_NOEXCEPT { return (min)(); }
+ BOOST_STATIC_CONSTEXPR int digits = boost::multiprecision::backends::max_precision<backend_type>::value == UINT_MAX ? INT_MAX : boost::multiprecision::backends::max_precision<backend_type>::value;
+ BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L;
+ BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2;
+ BOOST_STATIC_CONSTEXPR bool is_signed = boost::multiprecision::is_signed_number<backend_type>::value;
+ BOOST_STATIC_CONSTEXPR bool is_integer = true;
+ BOOST_STATIC_CONSTEXPR bool is_exact = true;
+ BOOST_STATIC_CONSTEXPR int radix = 2;
+ static number_type epsilon() BOOST_NOEXCEPT { return 0; }
+ static number_type round_error() BOOST_NOEXCEPT { return 0; }
+ BOOST_STATIC_CONSTEXPR int min_exponent = 0;
+ BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
+ BOOST_STATIC_CONSTEXPR int max_exponent = 0;
+ BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
+ BOOST_STATIC_CONSTEXPR bool has_infinity = false;
+ BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
+ BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
+ BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
+ BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
+ static number_type infinity() BOOST_NOEXCEPT { return 0; }
+ static number_type quiet_NaN() BOOST_NOEXCEPT { return 0; }
+ static number_type signaling_NaN() BOOST_NOEXCEPT { return 0; }
+ static number_type denorm_min() BOOST_NOEXCEPT { return 0; }
+ BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
+ BOOST_STATIC_CONSTEXPR bool is_bounded = boost::multiprecision::backends::is_fixed_precision<backend_type>::value;
+ BOOST_STATIC_CONSTEXPR bool is_modulo = (boost::multiprecision::backends::is_fixed_precision<backend_type>::value && (Checked == boost::multiprecision::unchecked));
+ BOOST_STATIC_CONSTEXPR bool traps = false;
+ BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
+ BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
+};
+
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::inititializer numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::init;
+
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::digits;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::digits10;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::max_digits10;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::is_signed;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::is_integer;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::is_exact;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::radix;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::min_exponent;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::min_exponent10;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::max_exponent;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::max_exponent10;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::has_infinity;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::has_quiet_NaN;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::has_signaling_NaN;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::has_denorm;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::has_denorm_loss;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::is_iec559;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::is_bounded;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::is_modulo;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::traps;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::tinyness_before;
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >::round_style;
+
+#endif
+
+} // namespace std
+
+#endif

Added: sandbox/big_number/boost/multiprecision/cpp_int/misc.hpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/boost/multiprecision/cpp_int/misc.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -0,0 +1,301 @@
+///////////////////////////////////////////////////////////////
+// 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_
+//
+// Comparison operators for cpp_int_backend:
+//
+#ifndef BOOST_MP_CPP_INT_MISC_HPP
+#define BOOST_MP_CPP_INT_MISC_HPP
+
+namespace boost{ namespace multiprecision{ namespace backends{
+
+template <class R, class CppInt>
+void check_in_range(const CppInt& val, const mpl::int_<checked>&)
+{
+ typedef typename boost::multiprecision::detail::canonical<R, CppInt>::type cast_type;
+ if(val.sign())
+ {
+ if(val.compare(static_cast<cast_type>((std::numeric_limits<R>::min)())) < 0)
+ BOOST_THROW_EXCEPTION(std::overflow_error("Could not convert to the target type - -value is out of range."));
+ }
+ else
+ {
+ if(val.compare(static_cast<cast_type>((std::numeric_limits<R>::max)())) > 0)
+ BOOST_THROW_EXCEPTION(std::overflow_error("Could not convert to the target type - -value is out of range."));
+ }
+}
+template <class R, class CppInt>
+void check_in_range(const CppInt& /*val*/, const mpl::int_<unchecked>&) BOOST_NOEXCEPT {}
+
+void check_is_negative(const mpl::true_&) BOOST_NOEXCEPT {}
+void check_is_negative(const mpl::false_&)
+{
+ BOOST_THROW_EXCEPTION(std::domain_error("Attempt to assign a negative value to an unsigned type."));
+}
+
+template <class Integer>
+inline Integer negate_integer(Integer i, const mpl::true_&) BOOST_NOEXCEPT
+{
+ return -i;
+}
+template <class Integer>
+inline Integer negate_integer(Integer i, const mpl::false_&) BOOST_NOEXCEPT
+{
+ return ~(i-1);
+}
+
+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))
+{
+ typedef mpl::int_<Checked1> checked_type;
+ check_in_range<R>(backend, checked_type());
+
+ *result = static_cast<R>(backend.limbs()[0]);
+ unsigned shift = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+ for(unsigned i = 1; (i < backend.size()) && (shift < static_cast<unsigned>(std::numeric_limits<R>::digits)); ++i)
+ {
+ *result += static_cast<R>(backend.limbs()[i]) << shift;
+ shift += cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+ }
+ if(backend.sign())
+ {
+ check_is_negative(boost::is_signed<R>());
+ *result = negate_integer(*result, boost::is_signed<R>());
+ }
+}
+
+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
+{
+ 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;
+ *result = static_cast<R>(*p);
+ for(unsigned i = 1; i < backend.size(); ++i)
+ {
+ *result += static_cast<R>(std::ldexp(static_cast<long double>(p[i]), shift));
+ shift += cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+ }
+ if(backend.sign())
+ *result = -*result;
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, bool>::type
+ eval_is_zero(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) BOOST_NOEXCEPT
+{
+ return (val.size() == 1) && (val.limbs()[0] == 0);
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, int>::type
+ eval_get_sign(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val) BOOST_NOEXCEPT
+{
+ return eval_is_zero(val) ? 0 : val.sign() ? -1 : 1;
+}
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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))
+{
+ result = val;
+ result.sign(false);
+}
+
+//
+// Get the location of the least-significant-bit:
+//
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, unsigned>::type
+ eval_lsb(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a) BOOST_NOEXCEPT
+{
+ using default_ops::eval_get_sign;
+ BOOST_ASSERT(eval_get_sign(a) != 0);
+
+ unsigned result = 0;
+ //
+ // Find the index of the least significant limb that is non-zero:
+ //
+ unsigned index = 0;
+ while(!a.limbs()[index] && (index < a.size()))
+ ++index;
+ //
+ // Find the index of the least significant bit within that limb:
+ //
+ limb_type l = a.limbs()[index];
+ while(!(l & 1u))
+ {
+ l >>= 1;
+ ++result;
+ }
+
+ return result + index * cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, bool>::type
+ eval_bit_test(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val, unsigned index) BOOST_NOEXCEPT
+{
+ unsigned offset = index / cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+ unsigned shift = index % cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+ limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u);
+ if(offset >= val.size())
+ return false;
+ return val.limbs()[offset] & mask ? true : false;
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
+ eval_bit_set(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val, unsigned index)
+{
+ unsigned offset = index / cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+ unsigned shift = index % cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+ limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u);
+ if(offset >= val.size())
+ {
+ unsigned os = val.size();
+ val.resize(offset + 1, offset + 1);
+ if(offset >= val.size())
+ return; // fixed precision overflow
+ for(unsigned i = os; i <= offset; ++i)
+ val.limbs()[i] = 0;
+ }
+ val.limbs()[offset] |= mask;
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
+ eval_bit_unset(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val, unsigned index) BOOST_NOEXCEPT
+{
+ unsigned offset = index / cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+ unsigned shift = index % cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+ limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u);
+ if(offset >= val.size())
+ return;
+ val.limbs()[offset] &= ~mask;
+ val.normalize();
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
+ eval_bit_flip(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val, unsigned index)
+{
+ unsigned offset = index / cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+ unsigned shift = index % cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+ limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u);
+ if(offset >= val.size())
+ {
+ unsigned os = val.size();
+ val.resize(offset + 1, offset + 1);
+ if(offset >= val.size())
+ return; // fixed precision overflow
+ for(unsigned i = os; i <= offset; ++i)
+ val.limbs()[i] = 0;
+ }
+ val.limbs()[offset] ^= mask;
+ val.normalize();
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
+ eval_qr(
+ 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))
+{
+ divide_unsigned_helper(&q, x, y, r);
+ q.sign(x.sign() != y.sign());
+ r.sign(x.sign());
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class Integer>
+inline typename enable_if_c<is_unsigned<Integer>::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, Integer>::type
+ eval_integer_modulus(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& x, Integer val)
+{
+ if((sizeof(Integer) <= sizeof(limb_type)) || (val <= (std::numeric_limits<limb_type>::max)()))
+ {
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> d;
+ divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>*>(0), x, static_cast<limb_type>(val), d);
+ return d.limbs()[0];
+ }
+ else
+ {
+ return default_ops::eval_integer_modulus(x, val);
+ }
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class Integer>
+BOOST_FORCEINLINE typename enable_if_c<is_signed<Integer>::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, Integer>::type
+ eval_integer_modulus(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& x, Integer val)
+{
+ typedef typename make_unsigned<Integer>::type unsigned_type;
+ return eval_integer_modulus(x, static_cast<unsigned_type>(std::abs(val)));
+}
+
+//
+// Now again for trivial backends:
+//
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_FORCEINLINE typename enable_if_c<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
+ eval_gcd(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
+{
+ *result.limbs() = boost::math::gcd(*a.limbs(), *b.limbs());
+}
+// 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_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))
+{
+ *result.limbs() = boost::math::lcm(*a.limbs(), *b.limbs());
+ result.normalize(); // result may overflow the specified number of bits
+}
+
+inline void conversion_overflow(const mpl::int_<checked>&)
+{
+ BOOST_THROW_EXCEPTION(std::overflow_error("Overflow in conversion to narrower type"));
+}
+inline void conversion_overflow(const mpl::int_<unchecked>&){}
+
+template <class R, unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+inline typename enable_if_c<
+ is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ >::type
+ eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val)
+{
+ typedef typename common_type<R, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::local_limb_type>::type common_type;
+ if(std::numeric_limits<R>::is_specialized && (static_cast<common_type>(*val.limbs()) > static_cast<common_type>((std::numeric_limits<R>::max)())))
+ {
+ conversion_overflow(typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
+ *result = (std::numeric_limits<R>::max)();
+ }
+ else
+ *result = static_cast<R>(*val.limbs());
+ if(val.isneg())
+ {
+ check_is_negative(mpl::bool_<boost::is_signed<R>::value || boost::is_floating_point<R>::value>());
+ *result = negate_integer(*result, mpl::bool_<boost::is_signed<R>::value || boost::is_floating_point<R>::value>());
+ }
+}
+
+template <class R, unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+inline typename enable_if_c<
+ is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ >::type
+ eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& val)
+{
+ typedef typename common_type<R, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::local_limb_type>::type common_type;
+ if(std::numeric_limits<R>::is_specialized && (static_cast<common_type>(*val.limbs()) > static_cast<common_type>((std::numeric_limits<R>::max)())))
+ {
+ conversion_overflow(typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
+ *result = (std::numeric_limits<R>::max)();
+ }
+ else
+ *result = static_cast<R>(*val.limbs());
+}
+
+}}} // namespaces
+
+#endif

Added: sandbox/big_number/boost/multiprecision/cpp_int/multiply.hpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/boost/multiprecision/cpp_int/multiply.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -0,0 +1,288 @@
+///////////////////////////////////////////////////////////////
+// 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_
+//
+// Comparison operators for cpp_int_backend:
+//
+#ifndef BOOST_MP_CPP_INT_MUL_HPP
+#define BOOST_MP_CPP_INT_MUL_HPP
+
+namespace boost{ namespace multiprecision{ namespace backends{
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+inline 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,
+ const limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+{
+ if(!val)
+ {
+ result = static_cast<limb_type>(0);
+ return;
+ }
+ if((void*)&a != (void*)&result)
+ result.resize(a.size(), a.size());
+ double_limb_type carry = 0;
+ typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer p = result.limbs();
+ typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pe = result.limbs() + result.size();
+ typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer pa = a.limbs();
+ while(p != pe)
+ {
+ carry += static_cast<double_limb_type>(*pa) * static_cast<double_limb_type>(val);
+ *p = static_cast<limb_type>(carry);
+ carry >>= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+ ++p, ++pa;
+ }
+ if(carry)
+ {
+ unsigned i = result.size();
+ result.resize(i + 1, i + 1);
+ if(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::variable || (result.size() > i))
+ result.limbs()[i] = static_cast<limb_type>(carry);
+ }
+ result.sign(a.sign());
+ if(!cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::variable)
+ result.normalize();
+}
+
+//
+// resize_for_carry forces a resize of the underlying buffer only if a previous request
+// for "required" elements could possibly have failed, *and* we have checking enabled.
+// This will cause an overflow error inside resize():
+//
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+inline void resize_for_carry(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& /*result*/, unsigned /*required*/){}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+inline void resize_for_carry(cpp_int_backend<MinBits1, MaxBits1, SignType1, checked, void>& result, unsigned required)
+{
+ if(result.size() != required)
+ result.resize(required, required);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, unsigned MinBits3, unsigned MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
+inline 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 && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value >::type
+ 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))
+{
+ // Very simple long multiplication, only usable for small numbers of limb_type's
+ // but that's the typical use case for this type anyway:
+ //
+ // Special cases first:
+ //
+ unsigned as = a.size();
+ unsigned bs = b.size();
+ typename cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer pa = a.limbs();
+ typename cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>::const_limb_pointer pb = b.limbs();
+ if(as == 1)
+ {
+ bool s = b.sign() != a.sign();
+ if(bs == 1)
+ {
+ result = static_cast<double_limb_type>(*pa) * static_cast<double_limb_type>(*pb);
+ }
+ else
+ {
+ limb_type l = *pa;
+ eval_multiply(result, b, l);
+ }
+ result.sign(s);
+ return;
+ }
+ if(bs == 1)
+ {
+ bool s = b.sign() != a.sign();
+ limb_type l = *pb;
+ eval_multiply(result, a, l);
+ result.sign(s);
+ return;
+ }
+
+ if((void*)&result == (void*)&a)
+ {
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(a);
+ eval_multiply(result, t, b);
+ return;
+ }
+ if((void*)&result == (void*)&b)
+ {
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(b);
+ eval_multiply(result, a, t);
+ return;
+ }
+
+ result.resize(as + bs, as + bs - 1);
+ typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_pointer pr = result.limbs();
+
+ static const double_limb_type limb_max = ~static_cast<limb_type>(0u);
+ static const double_limb_type double_limb_max = ~static_cast<double_limb_type>(0u);
+ BOOST_STATIC_ASSERT(double_limb_max - 2 * limb_max >= limb_max * limb_max);
+
+ double_limb_type carry = 0;
+ std::memset(pr, 0, result.size() * sizeof(limb_type));
+ for(unsigned i = 0; i < as; ++i)
+ {
+ unsigned inner_limit = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::variable ? bs : (std::min)(result.size() - i, bs);
+ for(unsigned j = 0; j < inner_limit; ++j)
+ {
+ BOOST_ASSERT(i+j < result.size());
+ 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)));
+ 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];
+ pr[i + j] = static_cast<limb_type>(carry);
+ carry >>= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
+ BOOST_ASSERT(carry <= (cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value));
+ }
+ resize_for_carry(result, as + bs); // May throw if checking is enabled
+ if(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::variable || (i + bs < result.size()))
+ pr[i + bs] = static_cast<limb_type>(carry);
+ carry = 0;
+ }
+ result.normalize();
+ //
+ // Set the sign of the result:
+ //
+ result.sign(a.sign() != b.sign());
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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))
+{
+ eval_multiply(result, result, a);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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(result, result, val);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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,
+ const double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+{
+ if(val <= (std::numeric_limits<limb_type>::max)())
+ {
+ eval_multiply(result, a, static_cast<limb_type>(val));
+ }
+ else
+ {
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(val);
+ eval_multiply(result, a, t);
+ }
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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(result, result, val);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+BOOST_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,
+ const signed_limb_type& val) BOOST_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));
+ else
+ {
+ eval_multiply(result, a, static_cast<limb_type>(-val));
+ result.negate();
+ }
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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(result, result, val);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+inline 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,
+ const signed_double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
+{
+ if(val > 0)
+ {
+ if(val <= (std::numeric_limits<limb_type>::max)())
+ {
+ eval_multiply(result, a, static_cast<limb_type>(val));
+ return;
+ }
+ }
+ else if(val >= -static_cast<signed_double_limb_type>((std::numeric_limits<limb_type>::max)()))
+ {
+ eval_multiply(result, a, static_cast<limb_type>(-val));
+ result.negate();
+ return;
+ }
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> t(val);
+ eval_multiply(result, a, t);
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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(result, result, val);
+}
+
+//
+// Now over again for trivial cpp_int's:
+//
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)
+ >::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))
+{
+ *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());
+ result.normalize();
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
+BOOST_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<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ >::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))
+{
+ *result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
+ result.normalize();
+}
+
+}}} // namespaces
+
+#endif

Modified: sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -98,6 +98,8 @@
 
 #endif
 
+static const unsigned bits_per_limb = sizeof(limb_type) * CHAR_BIT;
+
 template <class T>
 inline void minmax(const T& a, const T& b, T& aa, T& bb)
 {

Modified: sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -19,112 +19,112 @@
 #endif
 
 template <unsigned MinBits>
-BOOST_FORCEINLINE bool eval_eq(const cpp_int_backend<MinBits, true, void, true>& a, const cpp_int_backend<MinBits, true, void, true>& b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE bool eval_eq(const old_cpp_int_backend<MinBits, true, void, true>& a, const old_cpp_int_backend<MinBits, true, void, true>& b) BOOST_NOEXCEPT
 {
    return (a.sign() == b.sign()) && (*a.limbs() == *b.limbs());
 }
 template <unsigned MinBits>
-BOOST_FORCEINLINE bool eval_eq(const cpp_int_backend<MinBits, false, void, true>& a, const cpp_int_backend<MinBits, false, void, true>& b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE bool eval_eq(const old_cpp_int_backend<MinBits, false, void, true>& a, const old_cpp_int_backend<MinBits, false, void, true>& b) BOOST_NOEXCEPT
 {
    return *a.limbs() == *b.limbs();
 }
 template <unsigned MinBits, class U>
-BOOST_FORCEINLINE typename enable_if<is_unsigned<U>, bool>::type eval_eq(const cpp_int_backend<MinBits, true, void, true>& a, U b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE typename enable_if<is_unsigned<U>, bool>::type eval_eq(const old_cpp_int_backend<MinBits, true, void, true>& a, U b) BOOST_NOEXCEPT
 {
    return !a.sign() && (*a.limbs() == b);
 }
 template <unsigned MinBits, class S>
-BOOST_FORCEINLINE typename enable_if<is_signed<S>, bool>::type eval_eq(const cpp_int_backend<MinBits, true, void, true>& a, S b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE typename enable_if<is_signed<S>, bool>::type eval_eq(const old_cpp_int_backend<MinBits, true, void, true>& a, S b) BOOST_NOEXCEPT
 {
    return (a.sign() == (b < 0)) && (*a.limbs() == std::abs(b));
 }
 template <unsigned MinBits, class U>
-BOOST_FORCEINLINE typename enable_if<is_unsigned<U>, bool>::type eval_eq(const cpp_int_backend<MinBits, false, void, true>& a, U b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE typename enable_if<is_unsigned<U>, bool>::type eval_eq(const old_cpp_int_backend<MinBits, false, void, true>& a, U b) BOOST_NOEXCEPT
 {
    return *a.limbs() == b;
 }
 template <unsigned MinBits, class S>
-BOOST_FORCEINLINE typename enable_if<is_signed<S>, bool>::type eval_eq(const cpp_int_backend<MinBits, false, void, true>& a, S b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE typename enable_if<is_signed<S>, bool>::type eval_eq(const old_cpp_int_backend<MinBits, false, void, true>& a, S b) BOOST_NOEXCEPT
 {
    return *a.limbs() == b;
 }
 
 template <unsigned MinBits>
-BOOST_FORCEINLINE bool eval_lt(const cpp_int_backend<MinBits, true, void, true>& a, const cpp_int_backend<MinBits, true, void, true>& b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE bool eval_lt(const old_cpp_int_backend<MinBits, true, void, true>& a, const old_cpp_int_backend<MinBits, true, void, true>& b) BOOST_NOEXCEPT
 {
    if(a.sign() != b.sign())
       return a.sign();
    return a.sign() ? *a.limbs() > *b.limbs() : *a.limbs() < *b.limbs();
 }
 template <unsigned MinBits>
-BOOST_FORCEINLINE bool eval_lt(const cpp_int_backend<MinBits, false, void, true>& a, const cpp_int_backend<MinBits, false, void, true>& b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE bool eval_lt(const old_cpp_int_backend<MinBits, false, void, true>& a, const old_cpp_int_backend<MinBits, false, void, true>& b) BOOST_NOEXCEPT
 {
    return *a.limbs() < *b.limbs();
 }
 template <unsigned MinBits, class U>
-BOOST_FORCEINLINE typename enable_if<is_unsigned<U>, bool>::type eval_lt(const cpp_int_backend<MinBits, true, void, true>& a, U b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE typename enable_if<is_unsigned<U>, bool>::type eval_lt(const old_cpp_int_backend<MinBits, true, void, true>& a, U b) BOOST_NOEXCEPT
 {
    if(a.sign())
       return true;
    return *a.limbs() < b;
 }
 template <unsigned MinBits, class S>
-BOOST_FORCEINLINE typename enable_if<is_signed<S>, bool>::type eval_lt(const cpp_int_backend<MinBits, true, void, true>& a, S b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE typename enable_if<is_signed<S>, bool>::type eval_lt(const old_cpp_int_backend<MinBits, true, void, true>& a, S b) BOOST_NOEXCEPT
 {
    if(a.sign() != (b < 0))
       return a.sign();
    return a.sign() ? (*a.limbs() > std::abs(b)) : (*a.limbs() < std::abs(b));
 }
 template <unsigned MinBits, class U>
-BOOST_FORCEINLINE typename enable_if<is_unsigned<U>, bool>::type eval_lt(const cpp_int_backend<MinBits, false, void, true>& a, U b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE typename enable_if<is_unsigned<U>, bool>::type eval_lt(const old_cpp_int_backend<MinBits, false, void, true>& a, U b) BOOST_NOEXCEPT
 {
    return *a.limbs() < b;
 }
 template <unsigned MinBits, class S>
-BOOST_FORCEINLINE typename enable_if<is_signed<S>, bool>::type eval_lt(const cpp_int_backend<MinBits, false, void, true>& a, S b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE typename enable_if<is_signed<S>, bool>::type eval_lt(const old_cpp_int_backend<MinBits, false, void, true>& a, S b) BOOST_NOEXCEPT
 {
    return *a.limbs() < b;
 }
 
 template <unsigned MinBits>
-BOOST_FORCEINLINE bool eval_gt(const cpp_int_backend<MinBits, true, void, true>& a, const cpp_int_backend<MinBits, true, void, true>& b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE bool eval_gt(const old_cpp_int_backend<MinBits, true, void, true>& a, const old_cpp_int_backend<MinBits, true, void, true>& b) BOOST_NOEXCEPT
 {
    if(a.sign() != b.sign())
       return !a.sign();
    return a.sign() ? *a.limbs() < *b.limbs() : *a.limbs() > *b.limbs();
 }
 template <unsigned MinBits>
-BOOST_FORCEINLINE bool eval_gt(const cpp_int_backend<MinBits, false, void, true>& a, const cpp_int_backend<MinBits, false, void, true>& b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE bool eval_gt(const old_cpp_int_backend<MinBits, false, void, true>& a, const old_cpp_int_backend<MinBits, false, void, true>& b) BOOST_NOEXCEPT
 {
    return *a.limbs() > *b.limbs();
 }
 template <unsigned MinBits, class U>
-BOOST_FORCEINLINE typename enable_if<is_unsigned<U>, bool>::type eval_gt(const cpp_int_backend<MinBits, true, void, true>& a, U b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE typename enable_if<is_unsigned<U>, bool>::type eval_gt(const old_cpp_int_backend<MinBits, true, void, true>& a, U b) BOOST_NOEXCEPT
 {
    if(a.sign())
       return false;
    return *a.limbs() > b;
 }
 template <unsigned MinBits, class S>
-BOOST_FORCEINLINE typename enable_if<is_signed<S>, bool>::type eval_gt(const cpp_int_backend<MinBits, true, void, true>& a, S b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE typename enable_if<is_signed<S>, bool>::type eval_gt(const old_cpp_int_backend<MinBits, true, void, true>& a, S b) BOOST_NOEXCEPT
 {
    if(a.sign() != (b < 0))
       return !a.sign();
    return a.sign() ? (*a.limbs() < std::abs(b)) : (*a.limbs() > std::abs(b));
 }
 template <unsigned MinBits, class U>
-BOOST_FORCEINLINE typename enable_if<is_unsigned<U>, bool>::type eval_gt(const cpp_int_backend<MinBits, false, void, true>& a, U b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE typename enable_if<is_unsigned<U>, bool>::type eval_gt(const old_cpp_int_backend<MinBits, false, void, true>& a, U b) BOOST_NOEXCEPT
 {
    return *a.limbs() > b;
 }
 template <unsigned MinBits, class S>
-BOOST_FORCEINLINE typename enable_if<is_signed<S>, bool>::type eval_gt(const cpp_int_backend<MinBits, false, void, true>& a, S b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE typename enable_if<is_signed<S>, bool>::type eval_gt(const old_cpp_int_backend<MinBits, false, void, true>& a, S b) BOOST_NOEXCEPT
 {
    return *a.limbs() > b;
 }
 
 template <unsigned MinBits>
-inline void eval_add(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+inline void eval_add(old_cpp_int_backend<MinBits, true, void, true>& result, const old_cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
 {
    if(result.sign() != o.sign())
    {
@@ -141,13 +141,13 @@
 }
 
 template <unsigned MinBits>
-BOOST_FORCEINLINE void eval_add(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+BOOST_FORCEINLINE void eval_add(old_cpp_int_backend<MinBits, false, void, true>& result, const old_cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
 {
    *result.limbs() += *o.limbs();
 }
 
 template <unsigned MinBits>
-inline void eval_subtract(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+inline void eval_subtract(old_cpp_int_backend<MinBits, true, void, true>& result, const old_cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
 {
    if(result.sign() != o.sign())
    {
@@ -163,26 +163,26 @@
 }
 
 template <unsigned MinBits>
-BOOST_FORCEINLINE void eval_subtract(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+BOOST_FORCEINLINE void eval_subtract(old_cpp_int_backend<MinBits, false, void, true>& result, const old_cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
 {
    *result.limbs() -= *o.limbs();
 }
 
 template <unsigned MinBits>
-BOOST_FORCEINLINE void eval_multiply(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+BOOST_FORCEINLINE void eval_multiply(old_cpp_int_backend<MinBits, true, void, true>& result, const old_cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
 {
    *result.limbs() *= *o.limbs();
    result.sign(result.sign() != o.sign());
 }
 
 template <unsigned MinBits>
-BOOST_FORCEINLINE void eval_multiply(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+BOOST_FORCEINLINE void eval_multiply(old_cpp_int_backend<MinBits, false, void, true>& result, const old_cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
 {
    *result.limbs() *= *o.limbs();
 }
 
 template <unsigned MinBits>
-BOOST_FORCEINLINE void eval_divide(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o)
+BOOST_FORCEINLINE void eval_divide(old_cpp_int_backend<MinBits, true, void, true>& result, const old_cpp_int_backend<MinBits, true, void, true>& o)
 {
    if(!*o.limbs())
       BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
@@ -191,7 +191,7 @@
 }
 
 template <unsigned MinBits>
-BOOST_FORCEINLINE void eval_divide(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o)
+BOOST_FORCEINLINE void eval_divide(old_cpp_int_backend<MinBits, false, void, true>& result, const old_cpp_int_backend<MinBits, false, void, true>& o)
 {
    if(!*o.limbs())
       BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
@@ -199,7 +199,7 @@
 }
 
 template <unsigned MinBits, bool Signed>
-BOOST_FORCEINLINE void eval_modulus(cpp_int_backend<MinBits, Signed, void, true>& result, const cpp_int_backend<MinBits, Signed, void, true>& o)
+BOOST_FORCEINLINE void eval_modulus(old_cpp_int_backend<MinBits, Signed, void, true>& result, const old_cpp_int_backend<MinBits, Signed, void, true>& o)
 {
    if(!*o.limbs())
       BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
@@ -208,21 +208,21 @@
 }
 
 template <unsigned MinBits, bool Signed, class T>
-BOOST_FORCEINLINE void eval_left_shift(cpp_int_backend<MinBits, Signed, void, true>& result, T s) BOOST_NOEXCEPT
+BOOST_FORCEINLINE void eval_left_shift(old_cpp_int_backend<MinBits, Signed, void, true>& result, T s) BOOST_NOEXCEPT
 {
    *result.limbs() <<= s;
 }
 
 template <unsigned MinBits, bool Signed, class T>
-BOOST_FORCEINLINE void eval_right_shift(cpp_int_backend<MinBits, Signed, void, true>& result, T s) BOOST_NOEXCEPT
+BOOST_FORCEINLINE void eval_right_shift(old_cpp_int_backend<MinBits, Signed, void, true>& result, T s) BOOST_NOEXCEPT
 {
    *result.limbs() >>= s;
 }
 
 template <unsigned MinBits>
-inline void eval_bitwise_and(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+inline void eval_bitwise_and(old_cpp_int_backend<MinBits, true, void, true>& result, const old_cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
 {
- typename cpp_int_backend<MinBits, true, void, true>::local_limb_type a, b;
+ typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type a, b;
    a = *result.limbs();
    if(result.isneg())
    {
@@ -237,7 +237,7 @@
    }
    a &= b;
    bool isneg = false;
- static const typename cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (std::numeric_limits<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>::digits - 1);
+ static const typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (std::numeric_limits<typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type>::digits - 1);
    if(a & mask)
    {
       a = ~a;
@@ -249,15 +249,15 @@
 }
 
 template <unsigned MinBits>
-BOOST_FORCEINLINE void eval_bitwise_and(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+BOOST_FORCEINLINE void eval_bitwise_and(old_cpp_int_backend<MinBits, false, void, true>& result, const old_cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
 {
    *result.limbs() &= *o.limbs();
 }
 
 template <unsigned MinBits>
-inline void eval_bitwise_or(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+inline void eval_bitwise_or(old_cpp_int_backend<MinBits, true, void, true>& result, const old_cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
 {
- typename cpp_int_backend<MinBits, true, void, true>::local_limb_type a, b;
+ typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type a, b;
    a = *result.limbs();
    if(result.isneg())
    {
@@ -272,7 +272,7 @@
    }
    a |= b;
    bool isneg = false;
- static const typename cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (sizeof(typename cpp_int_backend<MinBits, true, void, true>::local_limb_type) * CHAR_BIT - 1);
+ static const typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (sizeof(typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type) * CHAR_BIT - 1);
    if(a & mask)
    {
       a = ~a;
@@ -284,15 +284,15 @@
 }
 
 template <unsigned MinBits>
-BOOST_FORCEINLINE void eval_bitwise_or(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+BOOST_FORCEINLINE void eval_bitwise_or(old_cpp_int_backend<MinBits, false, void, true>& result, const old_cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
 {
    *result.limbs() |= *o.limbs();
 }
 
 template <unsigned MinBits>
-inline void eval_bitwise_xor(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+inline void eval_bitwise_xor(old_cpp_int_backend<MinBits, true, void, true>& result, const old_cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
 {
- typename cpp_int_backend<MinBits, true, void, true>::local_limb_type a, b;
+ typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type a, b;
    a = *result.limbs();
    if(result.isneg())
    {
@@ -307,7 +307,7 @@
    }
    a ^= b;
    bool isneg = false;
- static const typename cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (std::numeric_limits<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>::digits - 1);
+ static const typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (std::numeric_limits<typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type>::digits - 1);
    if(a & mask)
    {
       a = ~a;
@@ -319,15 +319,15 @@
 }
 
 template <unsigned MinBits>
-BOOST_FORCEINLINE void eval_bitwise_xor(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+BOOST_FORCEINLINE void eval_bitwise_xor(old_cpp_int_backend<MinBits, false, void, true>& result, const old_cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
 {
    *result.limbs() ^= *o.limbs();
 }
 
 template <unsigned MinBits>
-inline void eval_complement(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+inline void eval_complement(old_cpp_int_backend<MinBits, true, void, true>& result, const old_cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
 {
- typename cpp_int_backend<MinBits, true, void, true>::local_limb_type a;
+ typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type a;
    a = *o.limbs();
    if(o.isneg())
    {
@@ -336,7 +336,7 @@
    }
    a = ~a;
    bool isneg = false;
- static const typename cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (std::numeric_limits<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>::digits - 1);
+ static const typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (std::numeric_limits<typename old_cpp_int_backend<MinBits, true, void, true>::local_limb_type>::digits - 1);
    if(a & mask)
    {
       a = ~a;
@@ -348,25 +348,25 @@
 }
 
 template <unsigned MinBits>
-BOOST_FORCEINLINE void eval_complement(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+BOOST_FORCEINLINE void eval_complement(old_cpp_int_backend<MinBits, false, void, true>& result, const old_cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
 {
    *result.limbs() = ~*o.limbs();
 }
 
 template <unsigned MinBits, bool Signed>
-BOOST_FORCEINLINE void eval_gcd(cpp_int_backend<MinBits, Signed, void, true>& result, const cpp_int_backend<MinBits, Signed, void, true>& a, const cpp_int_backend<MinBits, Signed, void, true>& b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE void eval_gcd(old_cpp_int_backend<MinBits, Signed, void, true>& result, const old_cpp_int_backend<MinBits, Signed, void, true>& a, const old_cpp_int_backend<MinBits, Signed, void, true>& b) BOOST_NOEXCEPT
 {
    *result.limbs() = boost::math::gcd(*a.limbs(), *b.limbs());
 }
 
 template <unsigned MinBits, bool Signed>
-BOOST_FORCEINLINE void eval_lcm(cpp_int_backend<MinBits, Signed, void, true>& result, const cpp_int_backend<MinBits, Signed, void, true>& a, const cpp_int_backend<MinBits, Signed, void, true>& b) BOOST_NOEXCEPT
+BOOST_FORCEINLINE void eval_lcm(old_cpp_int_backend<MinBits, Signed, void, true>& result, const old_cpp_int_backend<MinBits, Signed, void, true>& a, const old_cpp_int_backend<MinBits, Signed, void, true>& b) BOOST_NOEXCEPT
 {
    *result.limbs() = boost::math::lcm(*a.limbs(), *b.limbs());
 }
 
 template <class R, unsigned MinBits>
-inline void eval_convert_to(R* result, const cpp_int_backend<MinBits, true, void, true>& val)
+inline void eval_convert_to(R* result, const old_cpp_int_backend<MinBits, true, void, true>& val)
 {
    if(std::numeric_limits<R>::is_specialized && (*val.limbs() > (std::numeric_limits<R>::max)()))
       *result = (std::numeric_limits<R>::max)();
@@ -377,7 +377,7 @@
 }
 
 template <class R, unsigned MinBits>
-inline void eval_convert_to(R* result, const cpp_int_backend<MinBits, false, void, true>& val)
+inline void eval_convert_to(R* result, const old_cpp_int_backend<MinBits, false, void, true>& val)
 {
    if(std::numeric_limits<R>::is_specialized && (*val.limbs() > (std::numeric_limits<R>::max)()))
       *result = (std::numeric_limits<R>::max)();

Modified: sandbox/big_number/boost/multiprecision/detail/default_ops.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/default_ops.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/default_ops.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -267,7 +267,7 @@
 template <class T>
 inline void eval_subtract_default(T& t, const T& u, const T& v)
 {
- if(&t == &v)
+ if((&t == &v) && is_signed_number<T>::value)
    {
       eval_subtract(t, u);
       t.negate();
@@ -296,16 +296,22 @@
    eval_subtract(t, u, vv);
 }
 template <class T, class U>
-inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value>::type eval_subtract_default(T& t, const U& u, const T& v)
+inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_signed_number<T>::value>::type eval_subtract_default(T& t, const U& u, const T& v)
 {
    eval_subtract(t, v, u);
    t.negate();
 }
+template <class T, class U>
+inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_unsigned_number<T>::value>::type eval_subtract_default(T& t, const U& u, const T& v)
+{
+ T temp(u);
+ eval_subtract(t, temp, v);
+}
 template <class T, class U, class V>
 inline void eval_subtract_default(T& t, const U& u, const V& v)
 {
    t = u;
- eval_subtract(t, u);
+ eval_subtract(t, v);
 }
 template <class T, class U, class V>
 inline void eval_subtract(T& t, const U& u, const V& v)

Modified: sandbox/big_number/boost/multiprecision/detail/integer_ops.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/integer_ops.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/integer_ops.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -20,14 +20,10 @@
    eval_modulus(r, x, y);
 }
 
-template <class Integer>
-inline typename enable_if<is_signed<Integer>, Integer>::type maybe_abs(Integer i) { return std::abs(i); }
-template <class Integer>
-inline typename enable_if<is_unsigned<Integer>, Integer>::type maybe_abs(Integer i) { return i; }
-
 template <class Backend, class Integer>
 inline Integer eval_integer_modulus(const Backend& x, Integer val)
 {
+ BOOST_MP_USING_ABS
    using default_ops::eval_modulus;
    using default_ops::eval_convert_to;
    typedef typename boost::multiprecision::detail::canonical<Integer, Backend>::type int_type;
@@ -35,7 +31,7 @@
    eval_modulus(t, x, static_cast<int_type>(val));
    Integer result;
    eval_convert_to(&result, t);
- return maybe_abs(result);
+ return abs(result);
 }
 
 #ifdef BOOST_MSVC

Modified: sandbox/big_number/boost/multiprecision/detail/no_et_ops.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/no_et_ops.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/no_et_ops.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -359,7 +359,7 @@
    return static_cast<number<B, et_off>&&>(a);
 }
 template <class B>
-inline number<B, et_off> operator - (const number<B, et_off>& a, number<B, et_off>&& b)
+inline typename enable_if<is_signed_number<B>, number<B, et_off> >::type operator - (const number<B, et_off>& a, number<B, et_off>&& b)
 {
    using default_ops::eval_subtract;
    eval_subtract(b.backend(), a.backend());
@@ -382,7 +382,7 @@
    return static_cast<number<B, et_off>&&>(a);
 }
 template <class V, class B>
-inline typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
+inline typename enable_if_c<(is_compatible_arithmetic_type<V, number<B, et_off> >::value && is_signed_number<B>::value), number<B, et_off> >::type
    operator - (const V& a, number<B, et_off>&& b)
 {
    using default_ops::eval_subtract;

Modified: sandbox/big_number/boost/multiprecision/detail/number_base.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/number_base.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/number_base.hpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -59,15 +59,20 @@
 
 namespace detail{
 //
-// Workaround for missing abs(long long) on some compilers:
+// Workaround for missing abs(long long) and abs(__int128) on some compilers:
 //
 template <class T>
-typename boost::enable_if<is_arithmetic<T>, T>::type abs(const T& t) BOOST_NOEXCEPT
+typename enable_if_c<(is_signed<T>::value || is_floating_point<T>::value), T>::type abs(T t) BOOST_NOEXCEPT
 {
    return t < 0 ? -t : t;
 }
+template <class T>
+typename enable_if_c<(is_unsigned<T>::value), T>::type abs(T t) BOOST_NOEXCEPT
+{
+ return t;
+}
 
-#define BOOST_MP_USING_ABS using std::abs; using boost::multiprecision::detail::abs;
+#define BOOST_MP_USING_ABS using boost::multiprecision::detail::abs;
 
 //
 // Move support:
@@ -205,15 +210,6 @@
 };
 
 
-template <class T>
-struct is_number : public mpl::false_{};
-template <class T, expression_template_option ExpressionTemplates>
-struct is_number<boost::multiprecision::number<T, ExpressionTemplates> > : public mpl::true_{};
-template <class T>
-struct is_mp_number_exp : public mpl::false_{};
-template <class Tag, class Arg1, class Arg2, class Arg3, class Arg4>
-struct is_mp_number_exp<boost::multiprecision::detail::expression<Tag, Arg1, Arg2, Arg3, Arg4> > : public mpl::true_{};
-
 template <class T1, class T2>
 struct combine_expression
 {
@@ -676,6 +672,13 @@
 template <class tag, class A1, class A2, class A3, class A4>
 struct component_type<detail::expression<tag, A1, A2, A3, A4> > : public component_type<typename detail::expression<tag, A1, A2, A3, A4>::result_type>{};
 
+template <class T>
+struct is_unsigned_number : public mpl::false_{};
+template <class Backend, expression_template_option ExpressionTemplates>
+struct is_unsigned_number<number<Backend, ExpressionTemplates> > : public is_unsigned_number<Backend> {};
+template <class T>
+struct is_signed_number : public mpl::bool_<!is_unsigned_number<T>::value> {};
+
 }} // namespaces
 
 namespace boost{ namespace math{ namespace tools{

Modified: sandbox/big_number/libs/multiprecision/test/Jamfile.v2
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/Jamfile.v2 (original)
+++ sandbox/big_number/libs/multiprecision/test/Jamfile.v2 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -156,6 +156,27 @@
         : # command line
         : # input files
         : # requirements
+ <define>TEST_CPP_INT_1A
+ : test_arithmetic_cpp_int_1a ;
+
+run test_arithmetic.cpp
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_CPP_INT_2A
+ : test_arithmetic_cpp_int_2a ;
+
+run test_arithmetic.cpp
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_CPP_INT_3A
+ : test_arithmetic_cpp_int_3a ;
+
+run test_arithmetic.cpp
+ : # command line
+ : # input files
+ : # requirements
               <define>TEST_CPP_INT_BR
         : test_arithmetic_cpp_int_br ;
 
@@ -707,6 +728,28 @@
         : # requirements
          [ check-target-builds ../config//has_gmp : : <build>no ]
          release # otherwise runtime is too slow!!
+ <define>TEST1
+ : test_cpp_int_1
+ ;
+
+run test_cpp_int.cpp gmp
+ : # command line
+ : # input files
+ : # requirements
+ [ check-target-builds ../config//has_gmp : : <build>no ]
+ release # otherwise runtime is too slow!!
+ <define>TEST2
+ : test_cpp_int_2
+ ;
+
+run test_cpp_int.cpp gmp
+ : # command line
+ : # input files
+ : # requirements
+ [ check-target-builds ../config//has_gmp : : <build>no ]
+ release # otherwise runtime is too slow!!
+ <define>TEST3
+ : test_cpp_int_3
          ;
 
 run test_miller_rabin.cpp gmp

Modified: sandbox/big_number/libs/multiprecision/test/include_test/cpp_int_include_test.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/include_test/cpp_int_include_test.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/include_test/cpp_int_include_test.cpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -9,8 +9,8 @@
 
 number<cpp_int_backend<> > a;
 number<cpp_int_backend<>, et_off> b;
-number<cpp_int_backend<64, true, void>, et_off> c;
-number<cpp_int_backend<128, false, void>, et_off> d;
-number<cpp_int_backend<500, true, void>, et_off> e;
+number<cpp_int_backend<64, 64, signed_magnitude, checked, void>, et_off> c;
+number<cpp_int_backend<128, 128, signed_magnitude, checked, void>, et_off> d;
+number<cpp_int_backend<500, 500, signed_magnitude, checked, void>, et_off> e;
 
 

Modified: sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -19,6 +19,7 @@
    !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) \
    && !defined(TEST_TOMMATH) && !defined(TEST_TOMMATH_BOOST_RATIONAL) && !defined(TEST_MPZ_BOOST_RATIONAL)\
    && !defined(TEST_CPP_INT_1) && !defined(TEST_CPP_INT_2) && !defined(TEST_CPP_INT_3) \
+ && !defined(TEST_CPP_INT_1A) && !defined(TEST_CPP_INT_2A) && !defined(TEST_CPP_INT_3A) \
    && !defined(TEST_CPP_INT_BR) && !defined(TEST_ARITHMETIC_BACKEND)
 # define TEST_MPF_50
 # define TEST_MPF
@@ -32,6 +33,9 @@
 # define TEST_CPP_INT_1
 # define TEST_CPP_INT_2
 # define TEST_CPP_INT_3
+# define TEST_CPP_INT_1A
+# define TEST_CPP_INT_2A
+# define TEST_CPP_INT_3A
 # define TEST_CPP_INT_BR
 # define TEST_ARITHMETIC_BACKEND
 
@@ -64,7 +68,7 @@
 #include <boost/multiprecision/tommath.hpp>
 #include <boost/multiprecision/rational_adapter.hpp>
 #endif
-#if defined(TEST_CPP_INT_1) || defined(TEST_CPP_INT_2) || defined(TEST_CPP_INT_3) || defined(TEST_CPP_INT_BR)
+#if defined(TEST_CPP_INT_1) || defined(TEST_CPP_INT_2) || defined(TEST_CPP_INT_3) || defined(TEST_CPP_INT_BR) || defined(TEST_CPP_INT_1A) || defined(TEST_CPP_INT_2A) || defined(TEST_CPP_INT_3A)
 #include <boost/multiprecision/cpp_int.hpp>
 #endif
 
@@ -150,6 +154,10 @@
 template <>
 struct is_twos_complement_integer<boost::multiprecision::tom_int> : public boost::mpl::false_ {};
 #endif
+#if defined(TEST_CPP_INT_1) || defined(TEST_CPP_INT_2) || defined(TEST_CPP_INT_3) || defined(TEST_CPP_INT_BR) || defined(TEST_CPP_INT_1A) || defined(TEST_CPP_INT_2A) || defined(TEST_CPP_INT_3A)
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+struct is_twos_complement_integer<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, boost::multiprecision::checked, Allocator>, ExpressionTemplates> > : public boost::mpl::false_ {};
+#endif
 
 #define BOOST_TEST_EQUAL(a, b) BOOST_TEST((a) == (b))
 
@@ -193,16 +201,16 @@
    typedef boost::multiprecision::number< boost::multiprecision::mpfr_float_backend<D/2> > type;
 };
 #endif
-#if defined(TEST_CPP_INT_1) || defined(TEST_CPP_INT_2) || defined(TEST_CPP_INT_3) || defined(TEST_CPP_INT_BR)
+#if defined(TEST_CPP_INT_1) || defined(TEST_CPP_INT_2) || defined(TEST_CPP_INT_3) || defined(TEST_CPP_INT_BR) || defined(TEST_CPP_INT_1A) || defined(TEST_CPP_INT_2A) || defined(TEST_CPP_INT_3A)
 template <>
 struct related_type<boost::multiprecision::cpp_int>
 {
    typedef boost::multiprecision::int256_t type;
 };
-template <unsigned D, bool S, boost::multiprecision::expression_template_option ET>
-struct related_type<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<D, S, void>, ET> >
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ET>
+struct related_type<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ET> >
 {
- typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<D/2, S, void>, ET> type;
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits/2, MaxBits/2, SignType, Checked, Allocator>, ET> type;
 };
 #endif
 template <class Real, class Val>
@@ -315,11 +323,18 @@
    int i = 1020304;
    int j = 56789123;
    int sign_mask = ~0;
- BOOST_TEST(~a == (~i & sign_mask));
- c = a & ~b;
- BOOST_TEST(c == (i & (~j & sign_mask)));
- c = ~(a | b);
- BOOST_TEST(c == (~(i | j) & sign_mask));
+ if(std::numeric_limits<Real>::is_signed)
+ {
+ BOOST_TEST(~a == (~i & sign_mask));
+ c = a & ~b;
+ BOOST_TEST(c == (i & (~j & sign_mask)));
+ c = ~(a | b);
+ BOOST_TEST(c == (~(i | j) & sign_mask));
+ }
+ else
+ {
+ BOOST_TEST((~a & a) == 0);
+ }
 }
 
 template <class Real>
@@ -710,7 +725,10 @@
          BOOST_TEST(lsb(Real(1) << (i * 17)) == i * 17);
          BOOST_TEST(bit_test(Real(1) << (i * 17), i * 17));
          BOOST_TEST(!bit_test(Real(1) << (i * 17), i * 17 + 1));
- BOOST_TEST(!bit_test(Real(1) << (i * 17), i * 17 - 1));
+ if(i)
+ {
+ BOOST_TEST(!bit_test(Real(1) << (i * 17), i * 17 - 1));
+ }
          Real zero(0);
          BOOST_TEST(bit_test(bit_set(zero, i * 17), i * 17));
          zero = 0;
@@ -1530,9 +1548,6 @@
    ac += +a;
    BOOST_TEST(ac == 16);
    ac = a;
- ac += -a;
- BOOST_TEST(ac == 0);
- ac = a;
    ac += b - a;
    BOOST_TEST(ac == 8 + 64-8);
    ac = a;
@@ -1547,26 +1562,32 @@
    {
       ac -= -a;
       BOOST_TEST(ac == 16);
+ ac = a;
+ ac += -a;
+ BOOST_TEST(ac == 0);
+ }
+ if(std::numeric_limits<Real>::is_signed || is_twos_complement_integer<Real>::value)
+ {
+ ac = a;
+ ac -= c - b;
+ BOOST_TEST(ac == 8 - (500-64));
+ ac = a;
+ ac -= b*c;
+ BOOST_TEST(ac == 8 - 500*64);
    }
- ac = a;
- ac -= c - b;
- BOOST_TEST(ac == 8 - (500-64));
- ac = a;
- ac -= b*c;
- BOOST_TEST(ac == 8 - 500*64);
    ac = a;
    ac += ac * b;
    BOOST_TEST(ac == 8 + 8 * 64);
- ac = a;
- ac -= ac * b;
- BOOST_TEST(ac == 8 - 8 * 64);
+ if(std::numeric_limits<Real>::is_signed || is_twos_complement_integer<Real>::value)
+ {
+ ac = a;
+ ac -= ac * b;
+ BOOST_TEST(ac == 8 - 8 * 64);
+ }
    ac = a * 8;
    ac *= +a;
    BOOST_TEST(ac == 64 * 8);
    ac = a;
- ac *= -a;
- BOOST_TEST(ac == -64);
- ac = a;
    ac *= b * c;
    BOOST_TEST(ac == 8 * 64 * 500);
    ac = a;
@@ -1583,6 +1604,9 @@
       ac = b;
       ac /= -a;
       BOOST_TEST(ac == -8);
+ ac = a;
+ ac *= -a;
+ BOOST_TEST(ac == -64);
    }
    ac = b;
    ac /= b / a;
@@ -1775,7 +1799,10 @@
    //
    a = 20;
    test_conditional(a, +a);
- test_conditional(Real(-a), -a);
+ if(std::numeric_limits<Real>::is_signed || is_twos_complement_integer<Real>::value)
+ {
+ test_conditional(Real(-a), -a);
+ }
    test_conditional(a, (a + 0));
 }
 
@@ -1828,18 +1855,35 @@
 #endif
 #ifdef TEST_CPP_INT_1
    test<boost::multiprecision::cpp_int>();
- test<boost::multiprecision::int256_t >();
- test<boost::multiprecision::uint512_t >();
+ test<boost::multiprecision::int512_t >();
+ test<boost::multiprecision::uint1024_t >();
+#endif
+#ifdef TEST_CPP_INT_1A
+ test<boost::multiprecision::checked_cpp_int>();
+ test<boost::multiprecision::checked_int512_t >();
+ test<boost::multiprecision::checked_uint1024_t >();
 #endif
 #ifdef TEST_CPP_INT_2
    test<boost::multiprecision::cpp_rational>();
    test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>, boost::multiprecision::et_off> >();
- test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<500, true, void> > >();
+ test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<500, 500, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > >();
+#endif
+#ifdef TEST_CPP_INT_2A
+ test<boost::multiprecision::checked_cpp_rational>();
+ test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<0, 0, boost::multiprecision::signed_magnitude, boost::multiprecision::checked>, boost::multiprecision::et_off> >();
+ test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<500, 500, boost::multiprecision::signed_magnitude, boost::multiprecision::checked, void> > >();
 #endif
 #ifdef TEST_CPP_INT_3
    // Again with "trivial" backends:
- test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64, true, void> > >();
- test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64, false, void> > >();
+ test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64, 64, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > >();
+ test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64, 64, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void> > >();
+ test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<31, 31, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > >();
+#endif
+#ifdef TEST_CPP_INT_3A
+ // Again with "trivial" checked backends:
+ test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64, 64, boost::multiprecision::signed_magnitude, boost::multiprecision::checked, void> > >();
+ test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64, 64, boost::multiprecision::unsigned_magnitude, boost::multiprecision::checked, void> > >();
+ test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<31, 31, boost::multiprecision::signed_magnitude, boost::multiprecision::checked, void> > >();
 #endif
 #ifdef TEST_CPP_INT_BR
    test<boost::rational<boost::multiprecision::cpp_int> >();

Modified: sandbox/big_number/libs/multiprecision/test/test_cpp_int.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_cpp_int.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_cpp_int.cpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -57,6 +57,8 @@
 {
    using namespace boost::multiprecision;
    typedef Number test_type;
+ typedef typename test_type::backend_type::checked_type checked;
+
    unsigned last_error_count = 0;
    boost::timer tim;
 
@@ -242,7 +244,7 @@
       BOOST_CHECK_EQUAL(mpz_int(gcd(a, -b)).str(), test_type(gcd(a1, -b1)).str());
       BOOST_CHECK_EQUAL(mpz_int(lcm(c, -d)).str(), test_type(lcm(c1, -d1)).str());
 
- if(std::numeric_limits<test_type>::is_modulo)
+ if(std::numeric_limits<test_type>::is_modulo && checked::value)
       {
          static mpz_int m = mpz_int(1) << std::numeric_limits<test_type>::digits;
          mpz_int t(a);
@@ -327,7 +329,7 @@
       // Tests run on the compiler farm time out after 300 seconds,
       // so don't get too close to that:
       //
- if(tim.elapsed() > 100)
+ if(tim.elapsed() > 200)
       {
          std::cout << "Timeout reached, aborting tests now....\n";
          break;
@@ -336,11 +338,25 @@
    }
 }
 
+#if !defined(TEST1) && !defined(TEST2) && !defined(TEST3)
+#define TEST1
+#define TEST2
+#define TEST3
+#endif
+
 int main()
 {
    using namespace boost::multiprecision;
+#ifdef TEST1
    test<cpp_int>();
- test<number<cpp_int_backend<2048, true, void> > >();
+#endif
+#ifdef TEST2
+ test<number<cpp_int_backend<2048, 2048, signed_magnitude, checked, void> > >();
+#endif
+#ifdef TEST3
+ // Unchecked test verifies modulo arithmetic:
+ test<number<cpp_int_backend<2048, 2048, signed_magnitude, unchecked, void> > >();
+#endif
    return boost::report_errors();
 }
 

Modified: sandbox/big_number/libs/multiprecision/test/test_cpp_int_conv.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_cpp_int_conv.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_cpp_int_conv.cpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -23,7 +23,7 @@
    cpp_int i1(2);
    int128_t i2(3);
    int256_t i3(4);
- number<cpp_int_backend<32, true, void> > i4(5);
+ number<cpp_int_backend<32, 32, signed_magnitude, checked, void> > i4(5);
 
    i1 = i3;
    BOOST_TEST(i1 == 4);
@@ -48,7 +48,7 @@
    int128_t i6(i4);
    BOOST_TEST(i6 == -5677334);
 
- number<cpp_int_backend<32, true, void>, et_off> i7(i3);
+ number<cpp_int_backend<32, 32, signed_magnitude, unchecked, void>, et_off> i7(i3);
    BOOST_TEST(i7 == -1234567);
 
    int256_t i8(i6);
@@ -57,13 +57,13 @@
    i7.assign(4.0);
    BOOST_TEST(i7 == 4);
 
- number<cpp_int_backend<30, true, void>, et_off> i9(-5677334);
+ number<cpp_int_backend<30, 30, signed_magnitude, checked, void>, et_off> i9(-5677334);
    i7 = i9;
    BOOST_TEST(i7 == -5677334);
- i7 = number<cpp_int_backend<32, true, void>, et_off>(i9);
+ i7 = number<cpp_int_backend<32, 32, signed_magnitude, checked, void>, et_off>(i9);
    BOOST_TEST(i7 == -5677334);
 
- i9 = static_cast<number<cpp_int_backend<30, true, void>, et_off> >(i7);
+ i9 = static_cast<number<cpp_int_backend<30, 30, signed_magnitude, checked, void>, et_off> >(i7);
    BOOST_TEST(i9 == -5677334);
 
    ++i9;

Modified: sandbox/big_number/libs/multiprecision/test/test_int_io.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_int_io.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_int_io.cpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -41,11 +41,26 @@
 #include <iomanip>
 
 template <class T>
+struct unchecked_type{ typedef T type; };
+
+#ifdef TEST_CPP_INT
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, boost::multiprecision::cpp_int_check_type Checked, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
+struct unchecked_type<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> >
+{
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, boost::multiprecision::unchecked, Allocator>, ExpressionTemplates> type;
+};
+#endif
+
+template <class T>
 T generate_random()
 {
- static boost::random::uniform_int_distribution<unsigned> ui(0, 20);
+ typedef typename unchecked_type<T>::type unchecked_T;
+
+ static const unsigned limbs = std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::is_bounded ? std::numeric_limits<T>::digits / std::numeric_limits<unsigned>::digits + 3 : 20;
+
+ static boost::random::uniform_int_distribution<unsigned> ui(0, limbs);
    static boost::random::mt19937 gen;
- T val = gen();
+ unchecked_T val = gen();
    unsigned lim = ui(gen);
    for(unsigned i = 0; i < lim; ++i)
    {
@@ -123,11 +138,11 @@
    test_round_trip<boost::multiprecision::tom_int>();
 #endif
 #ifdef TEST_CPP_INT
- test_round_trip<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<> > >();
- test_round_trip<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<1024, true, void> > >();
- test_round_trip<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, false, void> > >();
- test_round_trip<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<32, true, void> > >();
- test_round_trip<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<32, false, void> > >();
+ test_round_trip<boost::multiprecision::cpp_int>();
+ test_round_trip<boost::multiprecision::checked_int1024_t>();
+ test_round_trip<boost::multiprecision::checked_uint512_t >();
+ test_round_trip<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<32, 32, boost::multiprecision::signed_magnitude, boost::multiprecision::checked, void> > >();
+ test_round_trip<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<32, 32, boost::multiprecision::unsigned_magnitude, boost::multiprecision::checked, void> > >();
 #endif
    return boost::report_errors();
 }

Modified: sandbox/big_number/libs/multiprecision/test/test_numeric_limits.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_numeric_limits.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_numeric_limits.cpp 2012-10-24 12:00:05 EDT (Wed, 24 Oct 2012)
@@ -239,8 +239,8 @@
    test<boost::multiprecision::cpp_int>();
    test<boost::multiprecision::int256_t>();
    test<boost::multiprecision::uint512_t>();
- test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<200, false, void> > >();
- test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<70, true, void> > >();
+ test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<200, 200, boost::multiprecision::unsigned_magnitude, boost::multiprecision::checked, void> > >();
+ test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<70, 70, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > >();
 #endif
    return boost::report_errors();
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk