Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81070 - in sandbox/big_number: boost/multiprecision boost/multiprecision/cpp_int boost/multiprecision/detail libs/multiprecision/test libs/multiprecision/test/compile_fail
From: john_at_[hidden]
Date: 2012-10-27 13:48:35


Author: johnmaddock
Date: 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
New Revision: 81070
URL: http://svn.boost.org/trac/boost/changeset/81070

Log:
Add tests for checked ints and fix failures.
Make negating an unsigned int an error, and fix resulting test failures.
Change allocator defaults to be void when the allocator is not actually required.
Added:
   sandbox/big_number/libs/multiprecision/test/compile_fail/cpp_int_complement.cpp (contents, props changed)
   sandbox/big_number/libs/multiprecision/test/compile_fail/cpp_int_negate_1.cpp (contents, props changed)
   sandbox/big_number/libs/multiprecision/test/compile_fail/cpp_int_negate_2.cpp (contents, props changed)
   sandbox/big_number/libs/multiprecision/test/test_checked_cpp_int.cpp (contents, props changed)
Text files modified:
   sandbox/big_number/boost/multiprecision/cpp_int.hpp | 24 +-
   sandbox/big_number/boost/multiprecision/cpp_int/bitwise.hpp | 125 +++++++-------
   sandbox/big_number/boost/multiprecision/cpp_int/checked.hpp | 2
   sandbox/big_number/boost/multiprecision/cpp_int/cpp_int_config.hpp | 12
   sandbox/big_number/boost/multiprecision/cpp_int/limits.hpp | 7
   sandbox/big_number/boost/multiprecision/detail/et_ops.hpp | 12 +
   sandbox/big_number/boost/multiprecision/detail/no_et_ops.hpp | 2
   sandbox/big_number/libs/multiprecision/test/Jamfile.v2 | 2
   sandbox/big_number/libs/multiprecision/test/test.hpp | 7
   sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp | 331 +++++++++++++++++++--------------------
   sandbox/big_number/libs/multiprecision/test/test_cpp_int.cpp | 71 +++++---
   sandbox/big_number/libs/multiprecision/test/test_int_io.cpp | 38 +++-
   12 files changed, 346 insertions(+), 287 deletions(-)

Modified: sandbox/big_number/boost/multiprecision/cpp_int.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/cpp_int.hpp (original)
+++ sandbox/big_number/boost/multiprecision/cpp_int.hpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -32,7 +32,7 @@
 #pragma warning(disable:4127 4351 4293)
 #endif
 
-template <unsigned MinBits = 0, unsigned MaxBits = 0, cpp_integer_type SignType = signed_magnitude, cpp_int_check_type Checked = unchecked, class Allocator = std::allocator<limb_type> >
+template <unsigned MinBits = 0, unsigned MaxBits = 0, cpp_integer_type SignType = signed_magnitude, cpp_int_check_type Checked = unchecked, class Allocator = mpl::if_c<MinBits && (MinBits == MaxBits), void, std::allocator<limb_type> >::type >
 struct cpp_int_backend;
 
 template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator, bool trivial = false>
@@ -680,7 +680,8 @@
    BOOST_STATIC_ASSERT_MSG(MinBits <= sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
 protected:
    template <class T>
- typename disable_if_c<is_integral<T>::value && (sizeof(T) <= sizeof(local_limb_type)), void>::type check_in_range(T val, const mpl::int_<checked>&)
+ typename disable_if_c<std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::digits <= MinBits)>::type
+ check_in_range(T val, const mpl::int_<checked>&)
    {
       BOOST_MP_USING_ABS
       typedef typename common_type<T, local_limb_type>::type common_type;
@@ -797,7 +798,8 @@
    BOOST_STATIC_ASSERT_MSG(MinBits <= sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
 protected:
    template <class T>
- typename disable_if_c<is_integral<T>::value && (sizeof(T) <= sizeof(local_limb_type))>::type check_in_range(T val, const mpl::int_<checked>&, const mpl::true_&)
+ typename disable_if_c<std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::digits <= MinBits)>::type
+ check_in_range(T val, const mpl::int_<checked>&, const mpl::false_&)
    {
       typedef typename common_type<T, local_limb_type>::type common_type;
 
@@ -805,7 +807,7 @@
          BOOST_THROW_EXCEPTION(std::range_error("The argument to a cpp_int constructor exceeded the largest value it can represent."));
    }
    template <class T>
- typename disable_if_c<is_integral<T>::value && (sizeof(T) <= sizeof(local_limb_type))>::type check_in_range(T val, const mpl::int_<checked>&, const mpl::false_&)
+ void check_in_range(T val, const mpl::int_<checked>&, const mpl::true_&)
    {
       typedef typename common_type<T, local_limb_type>::type common_type;
 
@@ -814,13 +816,13 @@
       if(val < 0)
          BOOST_THROW_EXCEPTION(std::range_error("The argument to an unsigned cpp_int constructor was negative."));
    }
- template <class T, int C, class U>
- BOOST_FORCEINLINE void check_in_range(T val, const mpl::int_<C>&, const U&){}
+ template <class T, int C, bool B>
+ BOOST_FORCEINLINE void check_in_range(T val, const mpl::int_<C>&, const mpl::bool_<B>&){}
 
    template <class T>
    BOOST_FORCEINLINE void check_in_range(T val)
    {
- check_in_range(val, checked_type(), is_unsigned<T>());
+ check_in_range(val, checked_type(), is_signed<T>());
    }
 
 public:
@@ -878,6 +880,10 @@
    }
    BOOST_FORCEINLINE void negate() BOOST_NOEXCEPT
    {
+ if(Checked == checked)
+ {
+ BOOST_THROW_EXCEPTION(std::range_error("Attempt to negate an unsigned type."));
+ }
       m_data = ~m_data;
       ++m_data;
    }
@@ -1316,7 +1322,7 @@
                val = 10 + *s - 'A';
             else
                val = radix + 1;
- if(val > radix)
+ if(val >= radix)
             {
                BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string."));
             }
@@ -1377,7 +1383,7 @@
                      val = 10 + *s - 'A';
                   else
                      val = base_type::max_limb_value;
- if(val > radix)
+ if(val >= radix)
                   {
                      BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected content found while parsing character string."));
                   }

Modified: sandbox/big_number/boost/multiprecision/cpp_int/bitwise.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/cpp_int/bitwise.hpp (original)
+++ sandbox/big_number/boost/multiprecision/cpp_int/bitwise.hpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -10,10 +10,24 @@
 
 namespace boost{ namespace multiprecision{ namespace backends{
 
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+void is_valid_bitwise_op(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const mpl::int_<checked>&)
+{
+ if(result.sign() || o.sign())
+ BOOST_THROW_EXCEPTION(std::range_error("Bitwise operations on negative values results in undefined behavior."));
+}
+
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
+void is_valid_bitwise_op(
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&,
+ const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& , const mpl::int_<unchecked>&){}
+
 template <class CppInt1, class CppInt2, class Op>
 void bitwise_op(
- CppInt1& result,
- const CppInt2& o,
+ CppInt1& result,
+ const CppInt2& o,
    Op op) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<CppInt1>::value))
 {
    //
@@ -26,6 +40,11 @@
    // When one arg is negative we convert to 2's complement form "on the fly",
    // and then convert back to signed-magnitude form at the end.
    //
+ // Note however, that if the type is checked, then bitwise ops on negative values
+ // are not permitted and an exception will result.
+ //
+ is_valid_bitwise_op(result, o, typename CppInt1::checked_type());
+ //
    // First figure out how big the result needs to be and set up some data:
    //
    unsigned rs = result.size();
@@ -144,36 +163,36 @@
 struct bit_xor{ limb_type operator()(limb_type a, limb_type b)const BOOST_NOEXCEPT { return a ^ b; } };
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
-BOOST_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
+BOOST_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
    eval_bitwise_and(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    bitwise_op(result, o, bit_and());
 }
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
-BOOST_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
+BOOST_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
    eval_bitwise_or(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    bitwise_op(result, o, bit_or());
 }
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
-BOOST_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
+BOOST_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
    eval_bitwise_xor(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    bitwise_op(result, o, bit_xor());
 }
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
-BOOST_FORCEINLINE typename enable_if_c<is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
+BOOST_FORCEINLINE typename enable_if_c<is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
    eval_complement(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    BOOST_STATIC_ASSERT_MSG(((Checked1 != checked) || (Checked2 != checked)), "Attempt to take the complement of a signed type results in undefined behavior.");
@@ -184,9 +203,9 @@
 }
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
-BOOST_FORCEINLINE typename enable_if_c<is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value >::type
+BOOST_FORCEINLINE typename enable_if_c<is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value >::type
    eval_complement(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    unsigned os = o.size();
@@ -195,12 +214,13 @@
       result.limbs()[i] = ~o.limbs()[i];
    for(unsigned i = os; i < result.size(); ++i)
       result.limbs()[i] = ~static_cast<limb_type>(0);
+ result.normalize();
 }
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
-inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
+inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
    eval_left_shift(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       double_limb_type s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    if(!s)
@@ -287,7 +307,7 @@
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
 inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
    eval_right_shift(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       double_limb_type s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    if(!s)
@@ -334,7 +354,7 @@
 // Over agin for trivial cpp_int's:
 //
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class T>
-BOOST_FORCEINLINE typename enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::type
+BOOST_FORCEINLINE typename enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::type
    eval_left_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, T s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    *result.limbs() = detail::checked_left_shift(*result.limbs(), s, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
@@ -342,7 +362,7 @@
 }
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, class T>
-BOOST_FORCEINLINE typename enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::type
+BOOST_FORCEINLINE typename enable_if<is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> > >::type
    eval_right_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, T s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    // Nothing to check here... just make sure we don't invoke undefined behavior:
@@ -350,27 +370,13 @@
 }
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
-void is_valid_bitwise_op(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o, const mpl::int_<checked>&)
-{
- if(result.sign() || o.sign())
- BOOST_THROW_EXCEPTION(std::range_error("Bitwise operations on negative values results in undefined behavior."));
-}
-
-template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
-void is_valid_bitwise_op(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>&,
- const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& , const mpl::int_<unchecked>&){}
-
-template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
 inline typename enable_if_c<
- is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
          && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
          && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value)
- >::type
+ >::type
    eval_bitwise_and(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
@@ -401,13 +407,13 @@
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
 inline typename enable_if_c<
- is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
          && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
- && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
          && is_unsigned_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
- >::type
+ >::type
    eval_bitwise_and(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    *result.limbs() &= *o.limbs();
@@ -415,12 +421,12 @@
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
 inline typename enable_if_c<
- is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
          && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
          && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value)
- >::type
+ >::type
    eval_bitwise_or(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
@@ -452,13 +458,13 @@
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
 inline typename enable_if_c<
- is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
          && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
- && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
          && is_unsigned_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
- >::type
+ >::type
    eval_bitwise_or(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    *result.limbs() |= *o.limbs();
@@ -466,12 +472,12 @@
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
 inline typename enable_if_c<
- is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
          && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
          && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value)
- >::type
+ >::type
    eval_bitwise_xor(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    is_valid_bitwise_op(result, o, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
@@ -502,13 +508,13 @@
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
 inline typename enable_if_c<
- is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
          && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
- && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
          && is_unsigned_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
- >::type
+ >::type
    eval_bitwise_xor(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    *result.limbs() ^= *o.limbs();
@@ -516,12 +522,12 @@
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
 inline typename enable_if_c<
- is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
          && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
          && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value)
- >::type
+ >::type
    eval_complement(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    BOOST_STATIC_ASSERT_MSG(((Checked1 != checked) || (Checked2 != checked)), "Attempt to take the complement of a signed type results in undefined behavior.");
@@ -543,16 +549,17 @@
 
 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
 inline typename enable_if_c<
- is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
          && is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
- && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
+ && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
          && is_unsigned_number<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value
- >::type
+ >::type
    eval_complement(
- cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
+ cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
       const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
 {
    *result.limbs() = ~*o.limbs();
+ result.normalize();
 }
 
 }}} // namespaces

Modified: sandbox/big_number/boost/multiprecision/cpp_int/checked.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/cpp_int/checked.hpp (original)
+++ sandbox/big_number/boost/multiprecision/cpp_int/checked.hpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -23,7 +23,7 @@
 }
 inline void raise_subtract_overflow()
 {
- raise_overflow("subtraction");
+ BOOST_THROW_EXCEPTION(std::range_error("Subtraction resulted in a negative value, but the type is unsigned"));
 }
 inline void raise_mul_overflow()
 {

Modified: sandbox/big_number/boost/multiprecision/cpp_int/cpp_int_config.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/cpp_int/cpp_int_config.hpp (original)
+++ sandbox/big_number/boost/multiprecision/cpp_int/cpp_int_config.hpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -137,16 +137,16 @@
 
 enum cpp_integer_type
 {
- signed_magnitude,
- unsigned_magnitude,
- signed_packed,
- unsigned_packed
+ signed_magnitude = 1,
+ unsigned_magnitude = 0,
+ signed_packed = 3,
+ unsigned_packed = 2
 };
 
 enum cpp_int_check_type
 {
- checked,
- unchecked
+ checked = 1,
+ unchecked = 0
 };
 
 }}

Modified: sandbox/big_number/boost/multiprecision/cpp_int/limits.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/cpp_int/limits.hpp (original)
+++ sandbox/big_number/boost/multiprecision/cpp_int/limits.hpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -18,7 +18,7 @@
 {
    // Bounded and signed.
    typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> result_type;
- typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, boost::multiprecision::unsigned_magnitude, Checked, Allocator>, ExpressionTemplates> ui_type;
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, Allocator>, ExpressionTemplates> ui_type;
    static const result_type val = -result_type(~ui_type(0));
    return val;
 }
@@ -57,7 +57,7 @@
 {
    // Bounded and signed.
    typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> result_type;
- typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, boost::multiprecision::unsigned_magnitude, Checked, Allocator>, ExpressionTemplates> ui_type;
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, Allocator>, ExpressionTemplates> ui_type;
    static const result_type val = ~ui_type(0);
    return val;
 }
@@ -68,7 +68,8 @@
 {
    // Bound and unsigned:
    typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> result_type;
- static const result_type val = ~result_type(0);
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, Allocator>, ExpressionTemplates> ui_type;
+ static const result_type val = ~ui_type(0);
    return val;
 }
 

Modified: sandbox/big_number/boost/multiprecision/detail/et_ops.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/et_ops.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/et_ops.hpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -18,9 +18,17 @@
 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
 inline const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& operator + (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) { return v; }
 template <class B>
-inline detail::expression<detail::negate, number<B, et_on> > operator - (const number<B, et_on>& v) { return detail::expression<detail::negate, number<B, et_on> >(v); }
+inline detail::expression<detail::negate, number<B, et_on> > operator - (const number<B, et_on>& v)
+{
+ BOOST_STATIC_ASSERT_MSG(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
+ return detail::expression<detail::negate, number<B, et_on> >(v);
+}
 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
-inline detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > operator - (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v) { return detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v); }
+inline detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > operator - (const detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& v)
+{
+ BOOST_STATIC_ASSERT_MSG((is_signed_number<typename detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::value), "Negating an unsigned type results in ill-defined behavior.");
+ return detail::expression<detail::negate, detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >(v);
+}
 template <class B>
 inline detail::expression<detail::complement_immediates, number<B, et_on> > operator ~ (const number<B, et_on>& v) { return detail::expression<detail::complement_immediates, number<B, et_on> >(v); }
 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>

Modified: sandbox/big_number/boost/multiprecision/detail/no_et_ops.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/no_et_ops.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/no_et_ops.hpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -17,6 +17,7 @@
 template <class B>
 inline number<B, et_off> operator - (const number<B, et_off>& v)
 {
+ BOOST_STATIC_ASSERT_MSG(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
    number<B, et_off> result(v);
    result.backend().negate();
    return BOOST_MP_MOVE(result);
@@ -299,6 +300,7 @@
 template <class B>
 inline number<B, et_off> operator - (number<B, et_off>&& v)
 {
+ BOOST_STATIC_ASSERT_MSG(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
    v.backend().negate();
    return static_cast<number<B, et_off>&&>(v);
 }

Modified: sandbox/big_number/libs/multiprecision/test/Jamfile.v2
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/Jamfile.v2 (original)
+++ sandbox/big_number/libs/multiprecision/test/Jamfile.v2 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -752,6 +752,8 @@
          : test_cpp_int_3
          ;
 
+run test_checked_cpp_int.cpp ;
+
 run test_miller_rabin.cpp gmp
         : # command line
         : # input files

Added: sandbox/big_number/libs/multiprecision/test/compile_fail/cpp_int_complement.cpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/libs/multiprecision/test/compile_fail/cpp_int_complement.cpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -0,0 +1,14 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2012 John Maddock. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/multiprecision/cpp_int.hpp>
+
+using namespace boost::multiprecision;
+
+int main()
+{
+ checked_int256_t i;
+ i = ~i;
+}

Added: sandbox/big_number/libs/multiprecision/test/compile_fail/cpp_int_negate_1.cpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/libs/multiprecision/test/compile_fail/cpp_int_negate_1.cpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -0,0 +1,14 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2012 John Maddock. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/multiprecision/cpp_int.hpp>
+
+using namespace boost::multiprecision;
+
+int main()
+{
+ checked_uint256_t i;
+ i = -i;
+}

Added: sandbox/big_number/libs/multiprecision/test/compile_fail/cpp_int_negate_2.cpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/libs/multiprecision/test/compile_fail/cpp_int_negate_2.cpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -0,0 +1,14 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2012 John Maddock. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/multiprecision/cpp_int.hpp>
+
+using namespace boost::multiprecision;
+
+int main()
+{
+ number<cpp_int_backend<32, 32, unsigned_magnitude>, et_on> i;
+ i = -i;
+}

Modified: sandbox/big_number/libs/multiprecision/test/test.hpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test.hpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test.hpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -16,17 +16,20 @@
 #include <boost/static_assert.hpp>
 #include <boost/utility/enable_if.hpp>
 #include <boost/type_traits/is_unsigned.hpp>
+#include <boost/multiprecision/number.hpp>
 
 namespace detail{
 
 template <class T>
-inline typename boost::disable_if<boost::is_unsigned<T>, T>::type abs(const T& a)
+inline typename boost::disable_if_c<boost::is_unsigned<T>::value || boost::multiprecision::is_unsigned_number<T>::value, T>::type
+ abs(const T& a)
 {
    return a < 0 ? -a : a;
 }
 
 template <class T>
-inline typename boost::enable_if<boost::is_unsigned<T>, T>::type abs(const T& a)
+inline typename boost::enable_if_c<boost::is_unsigned<T>::value || boost::multiprecision::is_unsigned_number<T>::value, T>::type
+ abs(const T& a)
 {
    return a;
 }

Modified: sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -396,8 +396,117 @@
 }
 
 template <class Real>
+void test_signed_integer_ops(const boost::mpl::true_&)
+{
+ Real a(20);
+ Real b(7);
+ Real c(5);
+ BOOST_TEST(-a % c == 0);
+ BOOST_TEST(-a % b == -20 % 7);
+ BOOST_TEST(-a % -b == -20 % -7);
+ BOOST_TEST(a % -b == 20 % -7);
+ BOOST_TEST(-a % 7 == -20 % 7);
+ BOOST_TEST(-a % -7 == -20 % -7);
+ BOOST_TEST(a % -7 == 20 % -7);
+ BOOST_TEST(-a % 7u == -20 % 7);
+ BOOST_TEST(-a % a == 0);
+ BOOST_TEST(-a % 5 == 0);
+ BOOST_TEST(-a % -5 == 0);
+ BOOST_TEST(a % -5 == 0);
+
+ b = -b;
+ BOOST_TEST(a % b == 20 % -7);
+ a = -a;
+ BOOST_TEST(a % b == -20 % -7);
+ BOOST_TEST(a % -7 == -20 % -7);
+ b = 7;
+ BOOST_TEST(a % b == -20 % 7);
+ BOOST_TEST(a % 7 == -20 % 7);
+ BOOST_TEST(a % 7u == -20 % 7);
+
+ a = 20;
+ a %= b;
+ BOOST_TEST(a == 20 % 7);
+ a = -20;
+ a %= b;
+ BOOST_TEST(a == -20 % 7);
+ a = 20;
+ a %= -b;
+ BOOST_TEST(a == 20 % -7);
+ a = -20;
+ a %= -b;
+ BOOST_TEST(a == -20 % -7);
+ a = 5;
+ a %= b - a;
+ BOOST_TEST(a == 5 % (7-5));
+ a = -20;
+ a %= 7;
+ BOOST_TEST(a == -20 % 7);
+ a = 20;
+ a %= -7;
+ BOOST_TEST(a == 20 % -7);
+ a = -20;
+ a %= -7;
+ BOOST_TEST(a == -20 % -7);
+#ifndef BOOST_NO_LONG_LONG
+ a = -20;
+ a %= 7uLL;
+ BOOST_TEST(a == -20 % 7);
+ a = 20;
+ a %= -7LL;
+ BOOST_TEST(a == 20 % -7);
+ a = -20;
+ a %= -7LL;
+ BOOST_TEST(a == -20 % -7);
+#endif
+ a = 400;
+ b = 45;
+ BOOST_TEST(gcd(a, -45) == boost::math::gcd(400, 45));
+ BOOST_TEST(lcm(a, -45) == boost::math::lcm(400, 45));
+ BOOST_TEST(gcd(-400, b) == boost::math::gcd(400, 45));
+ BOOST_TEST(lcm(-400, b) == boost::math::lcm(400, 45));
+ a = -20;
+ BOOST_TEST(abs(a) == 20);
+ BOOST_TEST(abs(-a) == 20);
+ BOOST_TEST(abs(+a) == 20);
+ a = 20;
+ BOOST_TEST(abs(a) == 20);
+ BOOST_TEST(abs(-a) == 20);
+ BOOST_TEST(abs(+a) == 20);
+ a = -400;
+ b = 45;
+ BOOST_TEST(gcd(a, b) == boost::math::gcd(-400, 45));
+ BOOST_TEST(lcm(a, b) == boost::math::lcm(-400, 45));
+ BOOST_TEST(gcd(a, 45) == boost::math::gcd(-400, 45));
+ BOOST_TEST(lcm(a, 45) == boost::math::lcm(-400, 45));
+ BOOST_TEST(gcd(-400, b) == boost::math::gcd(-400, 45));
+ BOOST_TEST(lcm(-400, b) == boost::math::lcm(-400, 45));
+ Real r;
+ divide_qr(a, b, c, r);
+ BOOST_TEST(c == a / b);
+ BOOST_TEST(r == a % b);
+ BOOST_TEST(integer_modulus(a, 57) == abs(a % 57));
+ b = -57;
+ divide_qr(a, b, c, r);
+ BOOST_TEST(c == a / b);
+ BOOST_TEST(r == a % b);
+ BOOST_TEST(integer_modulus(a, -57) == abs(a % -57));
+ a = 458;
+ divide_qr(a, b, c, r);
+ BOOST_TEST(c == a / b);
+ BOOST_TEST(r == a % b);
+ BOOST_TEST(integer_modulus(a, -57) == abs(a % -57));
+}
+template <class Real>
+void test_signed_integer_ops(const boost::mpl::false_&)
+{
+}
+
+template <class Real>
 void test_integer_ops(const boost::mpl::int_<boost::multiprecision::number_kind_integer>&)
 {
+ test_signed_integer_ops<Real>(boost::mpl::bool_<std::numeric_limits<Real>::is_signed>());
+
    Real a(20);
    Real b(7);
    Real c(5);
@@ -416,79 +525,14 @@
    a = b % (a - 15);
    BOOST_TEST(a == 7 % 5);
    a = 20;
- if(std::numeric_limits<Real>::is_signed)
- {
- BOOST_TEST(-a % c == 0);
- BOOST_TEST(-a % b == -20 % 7);
- BOOST_TEST(-a % -b == -20 % -7);
- BOOST_TEST(a % -b == 20 % -7);
- BOOST_TEST(-a % 7 == -20 % 7);
- BOOST_TEST(-a % -7 == -20 % -7);
- BOOST_TEST(a % -7 == 20 % -7);
- BOOST_TEST(-a % 7u == -20 % 7);
- BOOST_TEST(-a % a == 0);
- BOOST_TEST(-a % 5 == 0);
- BOOST_TEST(-a % -5 == 0);
- BOOST_TEST(a % -5 == 0);
-
- b = -b;
- BOOST_TEST(a % b == 20 % -7);
- a = -a;
- BOOST_TEST(a % b == -20 % -7);
- BOOST_TEST(a % -7 == -20 % -7);
- b = 7;
- BOOST_TEST(a % b == -20 % 7);
- BOOST_TEST(a % 7 == -20 % 7);
- BOOST_TEST(a % 7u == -20 % 7);
-
- a = 20;
- a %= b;
- BOOST_TEST(a == 20 % 7);
- a = -20;
- a %= b;
- BOOST_TEST(a == -20 % 7);
- a = 20;
- a %= -b;
- BOOST_TEST(a == 20 % -7);
- a = -20;
- a %= -b;
- BOOST_TEST(a == -20 % -7);
- a = 5;
- a %= b - a;
- BOOST_TEST(a == 5 % (7-5));
- }
 
    a = 20;
    a %= 7;
    BOOST_TEST(a == 20 % 7);
- if(std::numeric_limits<Real>::is_signed)
- {
- a = -20;
- a %= 7;
- BOOST_TEST(a == -20 % 7);
- a = 20;
- a %= -7;
- BOOST_TEST(a == 20 % -7);
- a = -20;
- a %= -7;
- BOOST_TEST(a == -20 % -7);
- }
 #ifndef BOOST_NO_LONG_LONG
    a = 20;
    a %= 7uLL;
    BOOST_TEST(a == 20 % 7);
- if(std::numeric_limits<Real>::is_signed)
- {
- a = -20;
- a %= 7uLL;
- BOOST_TEST(a == -20 % 7);
- a = 20;
- a %= -7LL;
- BOOST_TEST(a == 20 % -7);
- a = -20;
- a %= -7LL;
- BOOST_TEST(a == -20 % -7);
- }
 #endif
    a = 20;
    BOOST_TEST(++a == 21);
@@ -649,20 +693,10 @@
    BOOST_TEST(lcm(a, b) == boost::math::lcm(400, 45));
    BOOST_TEST(gcd(a, 45) == boost::math::gcd(400, 45));
    BOOST_TEST(lcm(a, 45) == boost::math::lcm(400, 45));
- if(std::numeric_limits<Real>::is_signed)
- {
- BOOST_TEST(gcd(a, -45) == boost::math::gcd(400, 45));
- BOOST_TEST(lcm(a, -45) == boost::math::lcm(400, 45));
- }
    BOOST_TEST(gcd(a, 45u) == boost::math::gcd(400, 45));
    BOOST_TEST(lcm(a, 45u) == boost::math::lcm(400, 45));
    BOOST_TEST(gcd(400, b) == boost::math::gcd(400, 45));
    BOOST_TEST(lcm(400, b) == boost::math::lcm(400, 45));
- if(std::numeric_limits<Real>::is_signed)
- {
- BOOST_TEST(gcd(-400, b) == boost::math::gcd(400, 45));
- BOOST_TEST(lcm(-400, b) == boost::math::lcm(400, 45));
- }
    BOOST_TEST(gcd(400u, b) == boost::math::gcd(400, 45));
    BOOST_TEST(lcm(400u, b) == boost::math::lcm(400, 45));
 
@@ -685,39 +719,6 @@
    BOOST_TEST(c == a / b);
    BOOST_TEST(r == a % b);
    BOOST_TEST(integer_modulus(a, 57) == a % 57);
- if(std::numeric_limits<Real>::is_signed)
- {
- a = -20;
- BOOST_TEST(abs(a) == 20);
- BOOST_TEST(abs(-a) == 20);
- BOOST_TEST(abs(+a) == 20);
- a = 20;
- BOOST_TEST(abs(a) == 20);
- BOOST_TEST(abs(-a) == 20);
- BOOST_TEST(abs(+a) == 20);
- a = -400;
- b = 45;
- BOOST_TEST(gcd(a, b) == boost::math::gcd(-400, 45));
- BOOST_TEST(lcm(a, b) == boost::math::lcm(-400, 45));
- BOOST_TEST(gcd(a, 45) == boost::math::gcd(-400, 45));
- BOOST_TEST(lcm(a, 45) == boost::math::lcm(-400, 45));
- BOOST_TEST(gcd(-400, b) == boost::math::gcd(-400, 45));
- BOOST_TEST(lcm(-400, b) == boost::math::lcm(-400, 45));
- divide_qr(a, b, c, r);
- BOOST_TEST(c == a / b);
- BOOST_TEST(r == a % b);
- BOOST_TEST(integer_modulus(a, 57) == abs(a % 57));
- b = -57;
- divide_qr(a, b, c, r);
- BOOST_TEST(c == a / b);
- BOOST_TEST(r == a % b);
- BOOST_TEST(integer_modulus(a, -57) == abs(a % -57));
- a = 458;
- divide_qr(a, b, c, r);
- BOOST_TEST(c == a / b);
- BOOST_TEST(r == a % b);
- BOOST_TEST(integer_modulus(a, -57) == abs(a % -57));
- }
    for(unsigned i = 0; i < 20; ++i)
    {
       if(std::numeric_limits<Real>::is_specialized && (!std::numeric_limits<Real>::is_bounded || ((int)i * 17 < std::numeric_limits<Real>::digits)))
@@ -904,8 +905,6 @@
 template <class Real, class Num>
 void test_negative_mixed(boost::mpl::true_ const&)
 {
- if(std::numeric_limits<Real>::is_specialized && !std::numeric_limits<Real>::is_signed)
- return;
    typedef typename lexical_cast_target_type<Num>::type target_type;
    typedef typename boost::mpl::if_<
          boost::is_convertible<Num, Real>,
@@ -1299,7 +1298,12 @@
    BOOST_TEST(r == static_cast<cast_type>(n4 * n5));
    r = static_cast<cast_type>(4 * n4) / Real(4);
    BOOST_TEST(r == static_cast<cast_type>(n4));
- test_negative_mixed<Real, Num>(boost::mpl::bool_<std::numeric_limits<Num>::is_signed>());
+
+ typedef boost::mpl::bool_<
+ (!std::numeric_limits<Num>::is_specialized || std::numeric_limits<Num>::is_signed)
+ && (!std::numeric_limits<Real>::is_specialized || std::numeric_limits<Real>::is_signed)> signed_tag;
+
+ test_negative_mixed<Real, Num>(signed_tag());
 
    n1 = 2;
    n2 = 3;
@@ -1406,6 +1410,53 @@
 }
 
 template <class Real>
+void test_signed_ops(const boost::mpl::true_&)
+{
+ Real a(8);
+ Real b(64);
+ Real c(500);
+ Real d(1024);
+ Real ac;
+ BOOST_TEST(-a == -8);
+ ac = a;
+ ac = ac - b;
+ BOOST_TEST(ac == 8 - 64);
+ ac = a;
+ ac -= a + b;
+ BOOST_TEST(ac == -64);
+ ac = a;
+ ac -= b - a;
+ BOOST_TEST(ac == 16 - 64);
+ ac = -a;
+ BOOST_TEST(ac == -8);
+ ac = a;
+ ac -= -a;
+ BOOST_TEST(ac == 16);
+ ac = a;
+ ac += -a;
+ BOOST_TEST(ac == 0);
+ ac = b;
+ ac /= -a;
+ BOOST_TEST(ac == -8);
+ ac = a;
+ ac *= -a;
+ BOOST_TEST(ac == -64);
+ ac = a + -b;
+ BOOST_TEST(ac == 8 - 64);
+ ac = -a + b;
+ BOOST_TEST(ac == -8+64);
+ ac = -a + -b;
+ BOOST_TEST(ac == -72);
+ ac = a + - + -b; // lots of unary operators!!
+ BOOST_TEST(ac == 72);
+ test_conditional(Real(-a), -a);
+}
+template <class Real>
+void test_signed_ops(const boost::mpl::false_&)
+{
+}
+
+template <class Real>
 void test()
 {
 #ifndef NO_MIXED_OPS
@@ -1462,10 +1513,6 @@
    BOOST_TEST(a == 8);
    Real ac(a);
    BOOST_TEST(ac == a);
- if(std::numeric_limits<Real>::is_signed)
- {
- BOOST_TEST(-a == -8);
- }
    ac = a * c;
    BOOST_TEST(ac == 8*500L);
    ac = 8*500L;
@@ -1509,12 +1556,6 @@
    ac = a;
    ac = a + ac;
    BOOST_TEST(ac == 16);
- if(std::numeric_limits<Real>::is_signed)
- {
- ac = a;
- ac = ac - b;
- BOOST_TEST(ac == 8 - 64);
- }
    ac = a;
    ac = a - ac;
    BOOST_TEST(ac == 0);
@@ -1524,22 +1565,8 @@
    ac = a;
    ac += b + a;
    BOOST_TEST(ac == 80);
- if(std::numeric_limits<Real>::is_signed)
- {
- ac = a;
- ac -= a + b;
- BOOST_TEST(ac == -64);
- ac = a;
- ac -= b - a;
- BOOST_TEST(ac == 16 - 64);
- }
    ac = +a;
    BOOST_TEST(ac == 8);
- if(std::numeric_limits<Real>::is_signed)
- {
- ac = -a;
- BOOST_TEST(ac == -8);
- }
    ac = 8;
    ac = a * ac;
    BOOST_TEST(ac == 8*8);
@@ -1558,14 +1585,6 @@
    ac -= +a;
    BOOST_TEST(ac == 0);
    ac = a;
- if(std::numeric_limits<Real>::is_signed)
- {
- ac -= -a;
- BOOST_TEST(ac == 16);
- ac = a;
- ac += -a;
- BOOST_TEST(ac == 0);
- }
    if(std::numeric_limits<Real>::is_signed || is_twos_complement_integer<Real>::value)
    {
       ac = a;
@@ -1599,15 +1618,6 @@
    ac = b;
    ac /= +a;
    BOOST_TEST(ac == 8);
- if(std::numeric_limits<Real>::is_signed)
- {
- ac = b;
- ac /= -a;
- BOOST_TEST(ac == -8);
- ac = a;
- ac *= -a;
- BOOST_TEST(ac == -64);
- }
    ac = b;
    ac /= b / a;
    BOOST_TEST(ac == 64 / (64/8));
@@ -1625,17 +1635,6 @@
    BOOST_TEST(ac == 72);
    ac = +a + +b;
    BOOST_TEST(ac == 72);
- if(std::numeric_limits<Real>::is_signed)
- {
- ac = a + -b;
- BOOST_TEST(ac == 8 - 64);
- ac = -a + b;
- BOOST_TEST(ac == -8+64);
- ac = -a + -b;
- BOOST_TEST(ac == -72);
- ac = a + - + -b; // lots of unary operators!!
- BOOST_TEST(ac == 72);
- }
    ac = a;
    ac = b / ac;
    BOOST_TEST(ac == b / a);
@@ -1799,11 +1798,9 @@
    //
    a = 20;
    test_conditional(a, +a);
- if(std::numeric_limits<Real>::is_signed || is_twos_complement_integer<Real>::value)
- {
- test_conditional(Real(-a), -a);
- }
    test_conditional(a, (a + 0));
+
+ test_signed_ops<Real>(boost::mpl::bool_<std::numeric_limits<Real>::is_signed>());
 }
 
 

Added: sandbox/big_number/libs/multiprecision/test/test_checked_cpp_int.cpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/libs/multiprecision/test/test_checked_cpp_int.cpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -0,0 +1,116 @@
+///////////////////////////////////////////////////////////////
+// Copyright 2012 John Maddock. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
+
+//
+// Compare arithmetic results using fixed_int to GMP results.
+//
+
+#ifdef _MSC_VER
+# define _SCL_SECURE_NO_WARNINGS
+#endif
+
+#include <boost/multiprecision/cpp_int.hpp>
+#include "test.hpp"
+
+template <class Number>
+void test()
+{
+ using namespace boost::multiprecision;
+ typedef Number test_type;
+
+ if(std::numeric_limits<test_type>::is_bounded)
+ {
+ test_type val = (std::numeric_limits<test_type>::max)();
+ BOOST_CHECK_THROW(++val, std::overflow_error);
+ val = (std::numeric_limits<test_type>::max)();
+ BOOST_CHECK_THROW(test_type(1 + val), std::overflow_error);
+ BOOST_CHECK_THROW(test_type(val + 1), std::overflow_error);
+ BOOST_CHECK_THROW(test_type(2 * val), std::overflow_error);
+ val /= 2;
+ val += 1;
+ BOOST_CHECK_THROW(test_type(2 * val), std::overflow_error);
+
+ if(std::numeric_limits<test_type>::is_signed)
+ {
+ val = (std::numeric_limits<test_type>::min)();
+ BOOST_CHECK_THROW(--val, std::overflow_error);
+ val = (std::numeric_limits<test_type>::min)();
+ BOOST_CHECK_THROW(test_type(val - 1), std::overflow_error);
+ BOOST_CHECK_THROW(test_type(2 * val), std::overflow_error);
+ val /= 2;
+ val -= 1;
+ BOOST_CHECK_THROW(test_type(2 * val), std::overflow_error);
+ }
+ else
+ {
+ val = (std::numeric_limits<test_type>::min)();
+ BOOST_CHECK_THROW(--val, std::range_error);
+ val = (std::numeric_limits<test_type>::min)();
+ BOOST_CHECK_THROW(test_type(val - 1), std::range_error);
+ }
+ }
+
+ if(std::numeric_limits<test_type>::is_signed)
+ {
+ test_type a = -1;
+ test_type b = 1;
+ BOOST_CHECK_THROW(test_type(a | b), std::range_error);
+ BOOST_CHECK_THROW(test_type(a & b), std::range_error);
+ BOOST_CHECK_THROW(test_type(a ^ b), std::range_error);
+ }
+ else
+ {
+ // Constructing from a negative value is not allowed:
+ BOOST_CHECK_THROW(test_type(-2), std::range_error);
+ BOOST_CHECK_THROW(test_type("-2"), std::range_error);
+ }
+ if(std::numeric_limits<test_type>::digits < std::numeric_limits<long long>::digits)
+ {
+ long long llm = (std::numeric_limits<long long>::max)();
+ test_type t;
+ BOOST_CHECK_THROW(t = llm, std::range_error);
+ BOOST_CHECK_THROW(t = static_cast<test_type>(llm), std::range_error);
+ unsigned long long ullm = (std::numeric_limits<unsigned long long>::max)();
+ BOOST_CHECK_THROW(t = ullm, std::range_error);
+ BOOST_CHECK_THROW(t = static_cast<test_type>(ullm), std::range_error);
+
+ static const checked_uint512_t big = (std::numeric_limits<checked_uint512_t>::max)();
+ BOOST_CHECK_THROW(t = static_cast<test_type>(big), std::range_error);
+ }
+ //
+ // String errors:
+ //
+ BOOST_CHECK_THROW(test_type("12A"), std::runtime_error);
+ BOOST_CHECK_THROW(test_type("0658"), std::runtime_error);
+
+ if(std::numeric_limits<test_type>::is_signed)
+ {
+ BOOST_CHECK_THROW(test_type(-2).str(0, std::ios_base::hex), std::runtime_error);
+ BOOST_CHECK_THROW(test_type(-2).str(0, std::ios_base::oct), std::runtime_error);
+ }
+}
+
+int main()
+{
+ using namespace boost::multiprecision;
+
+ test<number<cpp_int_backend<0, 0, signed_magnitude, checked> > >();
+ test<checked_int512_t>();
+ test<checked_uint512_t>();
+ test<number<cpp_int_backend<32, 32, signed_magnitude, checked, void> > >();
+ test<number<cpp_int_backend<32, 32, unsigned_magnitude, checked, void> > >();
+
+ //
+ // We also need to test type with "odd" bit counts in order to ensure full code coverage:
+ //
+ test<number<cpp_int_backend<528, 528, signed_magnitude, checked, void> > >();
+ test<number<cpp_int_backend<528, 528, unsigned_magnitude, checked, void> > >();
+ test<number<cpp_int_backend<48, 48, signed_magnitude, checked, void> > >();
+ test<number<cpp_int_backend<48, 48, unsigned_magnitude, checked, void> > >();
+ return boost::report_errors();
+}
+
+
+

Modified: sandbox/big_number/libs/multiprecision/test/test_cpp_int.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_cpp_int.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_cpp_int.cpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -52,6 +52,11 @@
    return val;
 }
 
+template <class T>
+struct is_checked_cpp_int : public boost::mpl::false_ {};
+template <unsigned MinBits, unsigned MaxBits, boost::multiprecision::cpp_integer_type SignType, class Allocator, boost::multiprecision::expression_template_option ET>
+struct is_checked_cpp_int<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, boost::multiprecision::checked, Allocator>, ET> > : public boost::mpl::true_ {};
+
 template <class Number>
 void test()
 {
@@ -115,28 +120,37 @@
       // bitwise ops:
       BOOST_CHECK_EQUAL(mpz_int(a|b).str(), test_type(a1 | b1).str());
       BOOST_CHECK_EQUAL((mpz_int(a)|=b).str(), (test_type(a1) |= b1).str());
- BOOST_CHECK_EQUAL(mpz_int(-a|b).str(), test_type(-a1 | b1).str());
- BOOST_CHECK_EQUAL((mpz_int(-a)|=b).str(), (test_type(-a1) |= b1).str());
- BOOST_CHECK_EQUAL(mpz_int(a|-b).str(), test_type(a1 | -b1).str());
- BOOST_CHECK_EQUAL((mpz_int(a)|=-b).str(), (test_type(a1) |= -b1).str());
- BOOST_CHECK_EQUAL(mpz_int(-a|-b).str(), test_type(-a1 | -b1).str());
- BOOST_CHECK_EQUAL((mpz_int(-a)|=-b).str(), (test_type(-a1) |= -b1).str());
+ if(!is_checked_cpp_int<test_type>::value)
+ {
+ BOOST_CHECK_EQUAL(mpz_int(-a|b).str(), test_type(-a1 | b1).str());
+ BOOST_CHECK_EQUAL((mpz_int(-a)|=b).str(), (test_type(-a1) |= b1).str());
+ BOOST_CHECK_EQUAL(mpz_int(a|-b).str(), test_type(a1 | -b1).str());
+ BOOST_CHECK_EQUAL((mpz_int(a)|=-b).str(), (test_type(a1) |= -b1).str());
+ BOOST_CHECK_EQUAL(mpz_int(-a|-b).str(), test_type(-a1 | -b1).str());
+ BOOST_CHECK_EQUAL((mpz_int(-a)|=-b).str(), (test_type(-a1) |= -b1).str());
+ }
       BOOST_CHECK_EQUAL(mpz_int(a&b).str(), test_type(a1 & b1).str());
       BOOST_CHECK_EQUAL((mpz_int(a)&=b).str(), (test_type(a1) &= b1).str());
- BOOST_CHECK_EQUAL(mpz_int(-a&b).str(), test_type(-a1 & b1).str());
- BOOST_CHECK_EQUAL((mpz_int(-a)&=b).str(), (test_type(-a1) &= b1).str());
- BOOST_CHECK_EQUAL(mpz_int(a&-b).str(), test_type(a1 & -b1).str());
- BOOST_CHECK_EQUAL((mpz_int(a)&=-b).str(), (test_type(a1) &= -b1).str());
- BOOST_CHECK_EQUAL(mpz_int(-a&-b).str(), test_type(-a1 & -b1).str());
- BOOST_CHECK_EQUAL((mpz_int(-a)&=-b).str(), (test_type(-a1) &= -b1).str());
+ if(!is_checked_cpp_int<test_type>::value)
+ {
+ BOOST_CHECK_EQUAL(mpz_int(-a&b).str(), test_type(-a1 & b1).str());
+ BOOST_CHECK_EQUAL((mpz_int(-a)&=b).str(), (test_type(-a1) &= b1).str());
+ BOOST_CHECK_EQUAL(mpz_int(a&-b).str(), test_type(a1 & -b1).str());
+ BOOST_CHECK_EQUAL((mpz_int(a)&=-b).str(), (test_type(a1) &= -b1).str());
+ BOOST_CHECK_EQUAL(mpz_int(-a&-b).str(), test_type(-a1 & -b1).str());
+ BOOST_CHECK_EQUAL((mpz_int(-a)&=-b).str(), (test_type(-a1) &= -b1).str());
+ }
       BOOST_CHECK_EQUAL(mpz_int(a^b).str(), test_type(a1 ^ b1).str());
       BOOST_CHECK_EQUAL((mpz_int(a)^=b).str(), (test_type(a1) ^= b1).str());
- BOOST_CHECK_EQUAL(mpz_int(-a^b).str(), test_type(-a1 ^ b1).str());
- BOOST_CHECK_EQUAL((mpz_int(-a)^=b).str(), (test_type(-a1) ^= b1).str());
- BOOST_CHECK_EQUAL(mpz_int(a^-b).str(), test_type(a1 ^ -b1).str());
- BOOST_CHECK_EQUAL((mpz_int(a)^=-b).str(), (test_type(a1) ^= -b1).str());
- BOOST_CHECK_EQUAL(mpz_int(-a^-b).str(), test_type(-a1 ^ -b1).str());
- BOOST_CHECK_EQUAL((mpz_int(-a)^=-b).str(), (test_type(-a1) ^= -b1).str());
+ if(!is_checked_cpp_int<test_type>::value)
+ {
+ BOOST_CHECK_EQUAL(mpz_int(-a^b).str(), test_type(-a1 ^ b1).str());
+ BOOST_CHECK_EQUAL((mpz_int(-a)^=b).str(), (test_type(-a1) ^= b1).str());
+ BOOST_CHECK_EQUAL(mpz_int(a^-b).str(), test_type(a1 ^ -b1).str());
+ BOOST_CHECK_EQUAL((mpz_int(a)^=-b).str(), (test_type(a1) ^= -b1).str());
+ BOOST_CHECK_EQUAL(mpz_int(-a^-b).str(), test_type(-a1 ^ -b1).str());
+ BOOST_CHECK_EQUAL((mpz_int(-a)^=-b).str(), (test_type(-a1) ^= -b1).str());
+ }
       // Shift ops:
       for(unsigned i = 0; i < 128; ++i)
       {
@@ -185,15 +199,18 @@
       BOOST_CHECK_EQUAL((mpz_int(a)%=-si).str(), (test_type(a1) %= -si).str());
       BOOST_CHECK_EQUAL((mpz_int(-a)%=si).str(), (test_type(-a1) %= si).str());
       BOOST_CHECK_EQUAL((mpz_int(-a)%=-si).str(), (test_type(-a1) %= -si).str());
- BOOST_CHECK_EQUAL(mpz_int(a|si).str(), test_type(a1 | si).str());
- BOOST_CHECK_EQUAL((mpz_int(a)|=si).str(), (test_type(a1) |= si).str());
- BOOST_CHECK_EQUAL(mpz_int(a&si).str(), test_type(a1 & si).str());
- BOOST_CHECK_EQUAL((mpz_int(a)&=si).str(), (test_type(a1) &= si).str());
- BOOST_CHECK_EQUAL(mpz_int(a^si).str(), test_type(a1 ^ si).str());
- BOOST_CHECK_EQUAL((mpz_int(a)^=si).str(), (test_type(a1) ^= si).str());
- BOOST_CHECK_EQUAL(mpz_int(si|a).str(), test_type(si|a1).str());
- BOOST_CHECK_EQUAL(mpz_int(si&a).str(), test_type(si&a1).str());
- BOOST_CHECK_EQUAL(mpz_int(si^a).str(), test_type(si^a1).str());
+ if((si > 0) || !is_checked_cpp_int<test_type>::value)
+ {
+ BOOST_CHECK_EQUAL(mpz_int(a|si).str(), test_type(a1 | si).str());
+ BOOST_CHECK_EQUAL((mpz_int(a)|=si).str(), (test_type(a1) |= si).str());
+ BOOST_CHECK_EQUAL(mpz_int(a&si).str(), test_type(a1 & si).str());
+ BOOST_CHECK_EQUAL((mpz_int(a)&=si).str(), (test_type(a1) &= si).str());
+ BOOST_CHECK_EQUAL(mpz_int(a^si).str(), test_type(a1 ^ si).str());
+ BOOST_CHECK_EQUAL((mpz_int(a)^=si).str(), (test_type(a1) ^= si).str());
+ BOOST_CHECK_EQUAL(mpz_int(si|a).str(), test_type(si|a1).str());
+ BOOST_CHECK_EQUAL(mpz_int(si&a).str(), test_type(si&a1).str());
+ BOOST_CHECK_EQUAL(mpz_int(si^a).str(), test_type(si^a1).str());
+ }
       BOOST_CHECK_EQUAL(mpz_int(gcd(a, b)).str(), test_type(gcd(a1, b1)).str());
       BOOST_CHECK_EQUAL(mpz_int(lcm(c, d)).str(), test_type(lcm(c1, d1)).str());
       BOOST_CHECK_EQUAL(mpz_int(gcd(-a, b)).str(), test_type(gcd(-a1, b1)).str());

Modified: sandbox/big_number/libs/multiprecision/test/test_int_io.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_int_io.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_int_io.cpp 2012-10-27 13:48:33 EDT (Sat, 27 Oct 2012)
@@ -99,22 +99,42 @@
 }
 
 template <class T>
+void negative_round_trip(T val, const boost::mpl::true_&)
+{
+ do_round_trip(T(-val));
+}
+template <class T>
+void negative_round_trip(T, const boost::mpl::false_&)
+{
+}
+
+template <class T>
+void negative_spots(const boost::mpl::true_&)
+{
+ BOOST_CHECK_EQUAL(T(-1002).str(), "-1002");
+ if(!std::numeric_limits<T>::is_modulo)
+ {
+ BOOST_CHECK_THROW(T(-2).str(0, std::ios_base::oct), std::runtime_error);
+ BOOST_CHECK_THROW(T(-2).str(0, std::ios_base::hex), std::runtime_error);
+ }
+}
+template <class T>
+void negative_spots(const boost::mpl::false_&)
+{
+}
+
+template <class T>
 void test_round_trip()
 {
    for(unsigned i = 0; i < 1000; ++i)
    {
       T val = generate_random<T>();
       do_round_trip(val);
- if(std::numeric_limits<T>::is_signed)
- do_round_trip(T(-val));
+ negative_round_trip(val, boost::mpl::bool_<std::numeric_limits<T>::is_signed>());
    }
 
    BOOST_CHECK_EQUAL(T(1002).str(), "1002");
    BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::showpos), "+1002");
- if(std::numeric_limits<T>::is_signed)
- {
- BOOST_CHECK_EQUAL(T(-1002).str(), "-1002");
- }
    BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::oct), "1752");
    BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::oct|std::ios_base::showbase), "01752");
    BOOST_CHECK_EQUAL(boost::to_lower_copy(T(1002).str(0, std::ios_base::hex)), "3ea");
@@ -122,11 +142,7 @@
    BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::dec), "1002");
    BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::dec|std::ios_base::showbase), "1002");
 
- if(std::numeric_limits<T>::is_signed && !std::numeric_limits<T>::is_modulo)
- {
- BOOST_CHECK_THROW(T(-2).str(0, std::ios_base::oct), std::runtime_error);
- BOOST_CHECK_THROW(T(-2).str(0, std::ios_base::hex), std::runtime_error);
- }
+ negative_spots<T>(boost::mpl::bool_<std::numeric_limits<T>::is_signed>());
 }
 
 int main()


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