Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r80408 - sandbox/big_number/boost/multiprecision
From: john_at_[hidden]
Date: 2012-09-05 12:46:55


Author: johnmaddock
Date: 2012-09-05 12:46:54 EDT (Wed, 05 Sep 2012)
New Revision: 80408
URL: http://svn.boost.org/trac/boost/changeset/80408

Log:
Allow mixed precision arithmetic in the cpp_int backend.
Text files modified:
   sandbox/big_number/boost/multiprecision/cpp_int.hpp | 340 ++++++++++++++++++++++------------------
   1 files changed, 187 insertions(+), 153 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-09-05 12:46:54 EDT (Wed, 05 Sep 2012)
@@ -1063,7 +1063,8 @@
       }
       return result;
    }
- int compare(const cpp_int_backend& o)const BOOST_NOEXCEPT
+ 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;
@@ -1075,7 +1076,8 @@
          result = -result;
       return result;
    }
- int compare_unsigned(const cpp_int_backend& o)const BOOST_NOEXCEPT
+ 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())
       {
@@ -1090,8 +1092,8 @@
       }
       return 0;
    }
- template <class Arithmatic>
- BOOST_FORCEINLINE typename enable_if<is_arithmetic<Arithmatic>, int>::type compare(Arithmatic i)const BOOST_NOEXCEPT
+ 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;
@@ -1377,8 +1379,8 @@
          result = -result;
       return result;
    }
- template <class Arithmatic>
- BOOST_FORCEINLINE typename enable_if<is_arithmetic<Arithmatic>, int>::type compare(Arithmatic i)const BOOST_NOEXCEPT
+ 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;
@@ -1394,6 +1396,13 @@
       && (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
 {
@@ -1504,13 +1513,13 @@
    return (b < 0) ? a.compare(b) > 0 : eval_gt(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison.
 }
 
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_add(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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 MinBits, bool Signed, class Allocator>
-inline void add_unsigned(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const cpp_int_backend<MinBits, Signed, Allocator, false>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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;
 
@@ -1528,10 +1537,10 @@
       return;
    }
    result.resize(x);
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::const_limb_pointer pa = a.limbs();
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::const_limb_pointer pb = b.limbs();
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pr = result.limbs();
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pr_end = pr + m;
+ 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);
@@ -1541,7 +1550,7 @@
    {
       carry += static_cast<double_limb_type>(*pa) + static_cast<double_limb_type>(*pb);
       *pr = static_cast<limb_type>(carry);
- carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+ carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
       ++pr, ++pa, ++pb;
    }
    pr_end += x - m;
@@ -1556,21 +1565,21 @@
       }
       carry += static_cast<double_limb_type>(*pa);
       *pr = static_cast<limb_type>(carry);
- carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+ 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<MinBits, Signed, Allocator, false>::variable || (result.size() > x))
+ 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>
-inline void eval_add(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const cpp_int_backend<MinBits, Signed, Allocator, false>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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())
    {
@@ -1580,22 +1589,22 @@
    add_unsigned(result, a, b);
 }
 
-template <unsigned MinBits, bool Signed, class Allocator>
-inline void add_unsigned(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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<MinBits, Signed, Allocator, false>::limb_pointer pr = result.limbs();
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::const_limb_pointer pa = a.limbs();
+ 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<MinBits, Signed, Allocator, false>::limb_bits;
+ carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
    }
    if(&a != &result)
    {
@@ -1607,7 +1616,7 @@
       unsigned x = result.size();
       result.resize(x + 1);
       // We overflowed, need to add one more limb:
- if(cpp_int_backend<MinBits, Signed, Allocator, false>::variable || (result.size() > x))
+ if(cpp_int_backend<MinBits1, Signed1, Allocator1, false>::variable || (result.size() > x))
          result.limbs()[x] = static_cast<limb_type>(carry);
    }
    result.normalize();
@@ -1623,8 +1632,8 @@
    else
       add_unsigned(result, result, o);
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_add(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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())
    {
@@ -1642,8 +1651,8 @@
    else if(o > 0)
       eval_add(result, static_cast<limb_type>(o));
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_add(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const signed_limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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));
@@ -1692,8 +1701,8 @@
    else
       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 cpp_int_backend<MinBits, Signed, Allocator, false>& a, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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<Allocator>::value)
 {
    if(a.sign())
    {
@@ -1716,8 +1725,8 @@
          eval_subtract(result, static_cast<limb_type>(o));
    }
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_subtract(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const signed_limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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)
    {
@@ -1751,13 +1760,13 @@
    else
       eval_subtract(result, one);
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_subtract(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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 MinBits, bool Signed, class Allocator>
-inline void subtract_unsigned(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const cpp_int_backend<MinBits, Signed, Allocator, false>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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;
 
@@ -1788,9 +1797,9 @@
    // 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<MinBits, Signed, Allocator, false>::const_limb_pointer pa = a.limbs();
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::const_limb_pointer pb = b.limbs();
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pr = result.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)
    {
@@ -1809,7 +1818,7 @@
    {
       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<MinBits, Signed, Allocator, false>::limb_bits) & 1u;
+ 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:
@@ -1817,7 +1826,7 @@
    {
       borrow = static_cast<double_limb_type>(pa[i]) - borrow;
       pr[i] = static_cast<limb_type>(borrow);
- borrow = (borrow >> cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits) & 1u;
+ borrow = (borrow >> cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits) & 1u;
       ++i;
    }
    // Any remaining digits are the same as those in pa:
@@ -1833,8 +1842,8 @@
    if(swapped)
       result.negate();
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_subtract(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const cpp_int_backend<MinBits, Signed, Allocator, false>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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())
    {
@@ -1843,8 +1852,8 @@
    }
    subtract_unsigned(result, a, b);
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const cpp_int_backend<MinBits, Signed, Allocator, false>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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:
@@ -1853,8 +1862,8 @@
    //
    unsigned as = a.size();
    unsigned bs = b.size();
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::const_limb_pointer pa = a.limbs();
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::const_limb_pointer pb = b.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();
    if(as == 1)
    {
       bool s = b.sign() != a.sign();
@@ -1879,21 +1888,21 @@
       return;
    }
 
- if(&result == &a)
+ if((void*)&result == (void*)&a)
    {
- cpp_int_backend<MinBits, Signed, Allocator, false> t(a);
+ cpp_int_backend<MinBits1, Signed1, Allocator1, false> t(a);
       eval_multiply(result, t, b);
       return;
    }
- if(&result == &b)
+ if((void*)&result == (void*)&b)
    {
- cpp_int_backend<MinBits, Signed, Allocator, false> t(b);
+ cpp_int_backend<MinBits1, Signed1, Allocator1, false> t(b);
       eval_multiply(result, a, t);
       return;
    }
 
    result.resize(as + bs);
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pr = result.limbs();
+ 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);
@@ -1903,19 +1912,22 @@
    std::memset(pr, 0, result.size() * sizeof(limb_type));
    for(unsigned i = 0; i < as; ++i)
    {
- unsigned inner_limit = cpp_int_backend<MinBits, Signed, Allocator, false>::variable ? bs : (std::min)(result.size() - i, bs);
+ 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<MinBits, Signed, Allocator, false>::max_limb_value) * static_cast<double_limb_type>(cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value)));
+ 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<MinBits, Signed, Allocator, false>::limb_bits;
- BOOST_ASSERT(carry <= (cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value));
+ 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<MinBits, Signed, Allocator, false>::variable || (i + bs < result.size()))
+ if(cpp_int_backend<MinBits1, Signed1, Allocator1, false>::variable || (i + bs < result.size()))
          pr[i + bs] = static_cast<limb_type>(carry);
       carry = 0;
    }
@@ -1925,41 +1937,41 @@
    //
    result.sign(a.sign() != b.sign());
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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 MinBits, bool Signed, class Allocator>
-inline void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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(&a != &result)
+ if((void*)&a != (void*)&result)
       result.resize(a.size());
    double_limb_type carry = 0;
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer p = result.limbs();
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pe = result.limbs() + result.size();
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::const_limb_pointer pa = a.limbs();
+ 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<MinBits, Signed, Allocator, false>::limb_bits;
+ 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<MinBits, Signed, Allocator, false>::variable || (result.size() > i))
+ 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<MinBits, Signed, Allocator, false>::variable)
+ if(!cpp_int_backend<MinBits1, Signed1, Allocator1, false>::variable)
       result.normalize();
 }
 template <unsigned MinBits, bool Signed, class Allocator>
@@ -1967,8 +1979,8 @@
 {
    eval_multiply(result, result, val);
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const double_limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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)())
    {
@@ -1976,7 +1988,7 @@
    }
    else
    {
- cpp_int_backend<MinBits, Signed, Allocator, false> t(val);
+ cpp_int_backend<MinBits1, Signed1, Allocator1, false> t(val);
       eval_multiply(result, a, t);
    }
 }
@@ -1985,8 +1997,8 @@
 {
    eval_multiply(result, result, val);
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const signed_limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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));
@@ -2001,8 +2013,8 @@
 {
    eval_multiply(result, result, val);
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const signed_double_limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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)
    {
@@ -2018,7 +2030,7 @@
       result.negate();
       return;
    }
- cpp_int_backend<MinBits, Signed, Allocator, false> t(val);
+ cpp_int_backend<MinBits1, Signed1, Allocator1, false> t(val);
    eval_multiply(result, a, t);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
@@ -2027,18 +2039,21 @@
    eval_multiply(result, result, val);
 }
 
-template <unsigned MinBits, bool Signed, class Allocator>
-void divide_unsigned_helper(cpp_int_backend<MinBits, Signed, Allocator, false>* result, 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>& r)
+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((result == &x) || (&r == &x))
+ if(((void*)result == (void*)&x) || ((void*)&r == (void*)&x))
    {
- cpp_int_backend<MinBits, Signed, Allocator, false> t(x);
+ cpp_int_backend<MinBits2, Signed2, Allocator2, false> t(x);
       divide_unsigned_helper(result, t, y, r);
       return;
    }
- if((result == &y) || (&r == &y))
+ if(((void*)result == (void*)&y) || ((void*)&r == (void*)&y))
    {
- cpp_int_backend<MinBits, Signed, Allocator, false> t(y);
+ cpp_int_backend<MinBits3, Signed3, Allocator3, false> t(y);
       divide_unsigned_helper(result, x, t, r);
       return;
    }
@@ -2066,7 +2081,7 @@
 
    if(result == &r)
    {
- cpp_int_backend<MinBits, Signed, Allocator, false> rem;
+ cpp_int_backend<MinBits1, Signed1, Allocator1, false> rem;
       divide_unsigned_helper(result, x, y, rem);
       r = rem;
       return;
@@ -2088,8 +2103,8 @@
       return;
    }
 
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::const_limb_pointer px = x.limbs();
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::const_limb_pointer py = y.limbs();
+ 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))
@@ -2118,7 +2133,7 @@
       }
    }
 
- cpp_int_backend<MinBits, Signed, Allocator, false> t;
+ cpp_int_backend<MinBits1, Signed1, Allocator1, false> t;
    bool r_neg = false;
 
    //
@@ -2134,9 +2149,9 @@
    else if(r_order == 1)
    {
       double_limb_type a, b;
- a = (static_cast<double_limb_type>(px[1]) << cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits) | px[0];
+ 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<MinBits, Signed, Allocator, false>::limb_bits) | py[0]
+ (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;
@@ -2148,9 +2163,10 @@
    //
    if(result)
       result->resize(1 + r_order - y_order);
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::const_limb_pointer prem = r.limbs();
+ 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<MinBits, Signed, Allocator, false>::limb_pointer pr = typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer();
+ 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();
@@ -2168,10 +2184,10 @@
       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<MinBits, Signed, Allocator, false>::limb_bits) | prem[r_order - 1];
+ 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<MinBits, Signed, Allocator, false>::max_limb_value)
+ if(v > cpp_int_backend<MinBits1, Signed1, Allocator1, false>::max_limb_value)
             guess = 1;
          else
          {
@@ -2186,8 +2202,8 @@
       else
       {
          double_limb_type a, b, v;
- a = (static_cast<double_limb_type>(prem[r_order]) << cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits) | prem[r_order - 1];
- b = (y_order > 0) ? (static_cast<double_limb_type>(py[y_order]) << cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits) | py[y_order - 1] : (static_cast<double_limb_type>(py[y_order]) << cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits);
+ 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);
       }
@@ -2211,7 +2227,7 @@
                eval_subtract(*result, t);
             }
          }
- else if(cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value - pr[shift] > guess)
+ else if(cpp_int_backend<MinBits1, Signed1, Allocator1, false>::max_limb_value - pr[shift] > guess)
             pr[shift] += guess;
          else
          {
@@ -2228,15 +2244,15 @@
       //
       double_limb_type carry = 0;
       t.resize(y.size() + shift + 1);
- bool truncated_t = !cpp_int_backend<MinBits, Signed, Allocator, false>::variable && (t.size() != y.size() + shift + 1);
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pt = t.limbs();
+ 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<MinBits, Signed, Allocator, false>::limb_bits;
+ carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
       }
       if(carry && !truncated_t)
       {
@@ -2294,19 +2310,23 @@
    BOOST_ASSERT(r.compare_unsigned(y) < 0); // remainder must be less than the divisor or our code has failed
 }
 
-template <unsigned MinBits, bool Signed, class Allocator>
-void divide_unsigned_helper(cpp_int_backend<MinBits, Signed, Allocator, false>* result, const cpp_int_backend<MinBits, Signed, Allocator, false>& x, limb_type y, cpp_int_backend<MinBits, Signed, Allocator, false>& r)
+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((result == &x) || (&r == &x))
+ if(((void*)result == (void*)&x) || ((void*)&r == (void*)&x))
    {
- cpp_int_backend<MinBits, Signed, Allocator, false> t(x);
+ cpp_int_backend<MinBits2, Signed2, Allocator2, false> t(x);
       divide_unsigned_helper(result, t, y, r);
       return;
    }
 
    if(result == &r)
    {
- cpp_int_backend<MinBits, Signed, Allocator, false> rem;
+ cpp_int_backend<MinBits1, Signed1, Allocator1, false> rem;
       divide_unsigned_helper(result, x, y, rem);
       r = rem;
       return;
@@ -2330,7 +2350,7 @@
    //
    r = x;
    r.sign(false);
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pr = r.limbs();
+ typename cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_pointer pr = r.limbs();
 
    if((r_order == 0) && (*pr == 0))
    {
@@ -2365,7 +2385,7 @@
    else if(r_order == 1)
    {
       double_limb_type a;
- a = (static_cast<double_limb_type>(pr[r_order]) << cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits) | pr[0];
+ 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;
@@ -2377,7 +2397,7 @@
    }
 
    // This is initialised just to keep the compiler from emitting useless warnings later on:
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pres = typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer();
+ 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);
@@ -2394,7 +2414,7 @@
       if((pr[r_order] < y) && r_order)
       {
          double_limb_type a, b;
- a = (static_cast<double_limb_type>(pr[r_order]) << cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits) | pr[r_order - 1];
+ 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;
@@ -2438,32 +2458,36 @@
    BOOST_ASSERT(r.compare(y) < 0); // remainder must be less than the divisor or our code has failed
 }
 
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_divide(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const cpp_int_backend<MinBits, Signed, Allocator, false>& b)
+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<MinBits, Signed, Allocator, false> r;
+ cpp_int_backend<MinBits1, Signed1, Allocator1, false> r;
    divide_unsigned_helper(&result, a, b, r);
    result.sign(a.sign() != b.sign());
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_divide(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, limb_type& b)
+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<MinBits, Signed, Allocator, false> r;
+ cpp_int_backend<MinBits1, Signed1, Allocator1, false> r;
    divide_unsigned_helper(&result, a, b, r);
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_divide(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, signed_limb_type& b)
+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<MinBits, Signed, Allocator, false> r;
+ cpp_int_backend<MinBits1, Signed1, Allocator1, false> r;
    divide_unsigned_helper(&result, a, std::abs(b), r);
    if(b < 0)
       result.negate();
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_divide(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& b)
+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<MinBits, Signed, Allocator, false> a(result);
+ cpp_int_backend<MinBits1, Signed1, Allocator1, false> a(result);
    eval_divide(result, a, b);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
@@ -2480,27 +2504,32 @@
    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_modulus(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, const cpp_int_backend<MinBits, Signed, Allocator, false>& 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<MinBits, Signed, Allocator, false>* >(0), a, b, result);
+ divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, Signed1, Allocator1, false>* >(0), a, b, result);
    result.sign(a.sign());
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, limb_type b)
+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<MinBits, Signed, Allocator, false>* >(0), a, b, result);
+ divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, Signed1, Allocator1, false>* >(0), a, b, result);
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, signed_limb_type b)
+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<MinBits, Signed, Allocator, false>* >(0), a, static_cast<limb_type>(std::abs(b)), result);
+ divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, Signed1, Allocator1, false>* >(0), a, static_cast<limb_type>(std::abs(b)), result);
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& b)
+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<MinBits, Signed, Allocator, false> a(result);
+ cpp_int_backend<MinBits1, Signed1, Allocator1, false> a(result);
    eval_modulus(result, a, b);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
@@ -2517,8 +2546,11 @@
    cpp_int_backend<MinBits, Signed, Allocator, false> a(result);
    eval_modulus(result, a, b);
 }
-template <unsigned MinBits, bool Signed, class Allocator, class Op>
-void bitwise_op(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& o, Op op) BOOST_NOEXCEPT
+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:
@@ -2537,8 +2569,8 @@
    unsigned m, x;
    minmax(rs, os, m, x);
    result.resize(x);
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pr = result.limbs();
- typename cpp_int_backend<MinBits, Signed, Allocator, false>::const_limb_pointer po = o.limbs();
+ 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;
 
@@ -2561,13 +2593,13 @@
          {
             carry += static_cast<double_limb_type>(~po[i]);
             pr[i] = op(pr[i], static_cast<limb_type>(carry));
- carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+ 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<MinBits, Signed, Allocator, false>::limb_bits;
+ 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));
@@ -2584,13 +2616,13 @@
          {
             carry += static_cast<double_limb_type>(~pr[i]);
             pr[i] = op(static_cast<limb_type>(carry), po[i]);
- carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+ 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<MinBits, Signed, Allocator, false>::limb_bits;
+ 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));
@@ -2606,16 +2638,16 @@
             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<MinBits, Signed, Allocator, false>::limb_bits;
- o_carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+ 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<MinBits, Signed, Allocator, false>::limb_bits;
- o_carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+ 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));
@@ -2634,7 +2666,7 @@
       {
          carry += static_cast<double_limb_type>(~pr[i]);
          pr[i] = static_cast<limb_type>(carry);
- carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+ carry >>= cpp_int_backend<MinBits1, Signed1, Allocator1, false>::limb_bits;
       }
    }
    else
@@ -2647,23 +2679,25 @@
 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 MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_bitwise_and(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& o)BOOST_NOEXCEPT_IF(is_void<Allocator>::value)
+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<Allocator>::value)
 {
    bitwise_op(result, o, bit_and());
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_bitwise_or(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& o) BOOST_NOEXCEPT_IF(is_void<Allocator>::value)
+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<Allocator>::value)
 {
    bitwise_op(result, o, bit_or());
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_bitwise_xor(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& o) BOOST_NOEXCEPT_IF(is_void<Allocator>::value)
+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<Allocator>::value)
 {
    bitwise_op(result, o, bit_xor());
 }
-template <unsigned MinBits, bool Signed, class Allocator>
-BOOST_FORCEINLINE void eval_complement(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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<Allocator>::value)
 {
    // Increment and negate:
    result = o;


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