|
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