$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r79692 - in sandbox/big_number: boost/multiprecision boost/multiprecision/detail libs/multiprecision/doc libs/multiprecision/performance libs/multiprecision/test
From: john_at_[hidden]
Date: 2012-07-23 04:57:46
Author: johnmaddock
Date: 2012-07-23 04:57:44 EDT (Mon, 23 Jul 2012)
New Revision: 79692
URL: http://svn.boost.org/trac/boost/changeset/79692
Log:
Update frontend to allow direct construction of backend.
Improve construction times for cpp_int from integers.
Allow constexpr construction.
Allow fixed precision cpp_int's with small bit counts.
Added:
   sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp   (contents, props changed)
Text files modified: 
   sandbox/big_number/boost/multiprecision/cpp_int.hpp                     |  1099 ++++++++++++++++++++++++++------------- 
   sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp         |    58 +                                       
   sandbox/big_number/boost/multiprecision/gmp.hpp                         |     4                                         
   sandbox/big_number/boost/multiprecision/mp_number.hpp                   |    19                                         
   sandbox/big_number/boost/multiprecision/mpfr.hpp                        |     4                                         
   sandbox/big_number/libs/multiprecision/doc/multiprecision.qbk           |     6                                         
   sandbox/big_number/libs/multiprecision/performance/performance_test.cpp |    87 ++                                      
   sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp         |     4                                         
   8 files changed, 886 insertions(+), 395 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-07-23 04:57:44 EDT (Mon, 23 Jul 2012)
@@ -16,6 +16,7 @@
 #include <boost/type_traits/is_floating_point.hpp>
 #include <boost/multiprecision/detail/cpp_int_core.hpp>
 #include <boost/multiprecision/rational_adapter.hpp>
+#include <boost/detail/endian.hpp>
 
 namespace boost{
 namespace multiprecision{
@@ -27,16 +28,32 @@
 #pragma warning(disable:4127 4351)
 #endif
 
-template <unsigned MinBits = 0, bool Signed = true, class Allocator = std::allocator<limb_type> >
+template <unsigned MinBits = 0, bool Signed = true, class Allocator = std::allocator<limb_type>, bool trivial = is_void<Allocator>::value && (MinBits <= sizeof(double_limb_type) * CHAR_BIT) >
 struct cpp_int_backend;
 
-template <unsigned MinBits = 0, bool Signed = true, class Allocator = std::allocator<limb_type> >
-struct cpp_int_base : private Allocator::template rebind<limb_type>::other
+template <unsigned MinBits = 0, bool Signed = true, class Allocator = std::allocator<limb_type>, bool trivial = false>
+struct cpp_int_base;
+
+template <class T>
+struct is_trivial_cpp_int;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial>
+struct is_trivial_cpp_int<cpp_int_backend<MinBits, Signed, Allocator, trivial> >
+{
+   typedef mpl::bool_<trivial> type;
+};
+
+template <unsigned MinBits, bool Signed, class Allocator>
+struct cpp_int_base<MinBits, Signed, Allocator> : private Allocator::template rebind<limb_type>::other
 {
    typedef typename Allocator::template rebind<limb_type>::other allocator_type;
    typedef typename allocator_type::pointer                      limb_pointer;
    typedef typename allocator_type::const_pointer                const_limb_pointer;
 
+   //
+   // Interface invariants:
+   //
+   BOOST_STATIC_ASSERT(!is_void<Allocator>::value);
+
 private:
    struct limb_data
    {
@@ -61,6 +78,16 @@
    {
       limb_data ld;
       limb_type la[internal_limb_count];
+      limb_type first;
+      double_limb_type double_first;
+
+      BOOST_CONSTEXPR data_type() : first(0) {}
+      BOOST_CONSTEXPR data_type(limb_type i) : first(i) {}
+      BOOST_CONSTEXPR data_type(signed_limb_type i) : first(i < 0 ? -i : i) {}
+#ifdef BOOST_LITTLE_ENDIAN
+      BOOST_CONSTEXPR data_type(double_limb_type i) : double_first(i) {}
+      BOOST_CONSTEXPR data_type(signed_double_limb_type i) : double_first(i < 0 ? -i : i) {}
+#endif
    };
 
    data_type   m_data;
@@ -69,6 +96,19 @@
 
 public:
    //
+   // Direct construction:
+   //
+   BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT 
+      : m_data(i), m_limbs(1), m_sign(false), m_internal(true) { }
+   BOOST_CONSTEXPR cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT 
+      : m_data(i), m_limbs(1), m_sign(i < 0), m_internal(true) { }
+#if defined(BOOST_LITTLE_ENDIAN)
+   BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT 
+      : m_data(i), m_limbs(i > max_limb_value ? 2 : 1), m_sign(false), m_internal(true) { }
+   BOOST_CONSTEXPR cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT 
+      : m_data(i), m_limbs(i < 0 ? (-i > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)), m_sign(i < 0), m_internal(true) { }
+#endif
+   //
    // Helper functions for getting at our internal data, and manipulating storage:
    //
    allocator_type& allocator() BOOST_NOEXCEPT { return *this; }
@@ -114,13 +154,11 @@
       limb_pointer p = limbs();
       while((m_limbs-1) && !p[m_limbs - 1])--m_limbs;
    }
-   BOOST_CONSTEXPR cpp_int_base() BOOST_NOEXCEPT : m_data(), m_limbs(1), m_sign(false), m_internal(true) 
-   {
-   }
+   BOOST_CONSTEXPR cpp_int_base() BOOST_NOEXCEPT : m_data(), m_limbs(1), m_sign(false), m_internal(true) {}
    cpp_int_base(const cpp_int_base& o) : allocator_type(o), m_limbs(0), m_internal(true)
    {
       resize(o.size());
-      std::memcpy(limbs(), o.limbs(), size() * sizeof(limb_type));
+      std::copy(o.limbs(), o.limbs() + o.size(), limbs());
       m_sign = o.m_sign;
    }
 #ifndef BOOST_NO_RVALUE_REFERENCES
@@ -128,7 +166,7 @@
    {
       if(m_internal)
       {
-         std::memcpy(limbs(), o.limbs(), size() * sizeof(limb_type));
+         std::copy(o.limbs(), o.limbs() + o.size(), limbs());
       }
       else
       {
@@ -178,11 +216,16 @@
 };
 
 template <unsigned MinBits>
-struct cpp_int_base<MinBits, true, void>
+struct cpp_int_base<MinBits, true, void, false>
 {
    typedef limb_type*                      limb_pointer;
    typedef const limb_type*                const_limb_pointer;
 
+   //
+   // Interface invariants:
+   //
+   BOOST_STATIC_ASSERT_MSG(MinBits > sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
+
 public:
    BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(limb_type) * CHAR_BIT);
    BOOST_STATIC_CONSTANT(limb_type, max_limb_value = ~static_cast<limb_type>(0u));
@@ -193,12 +236,29 @@
    BOOST_STATIC_ASSERT_MSG(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs");
 
 private:
-   limb_type          m_data[internal_limb_count];
+   union{
+      limb_type          m_data[internal_limb_count];
+      limb_type          m_first_limb;
+      double_limb_type   m_double_first_limb;
+   };
    boost::uint16_t    m_limbs;
    bool               m_sign;
 
 public:
    //
+   // Direct construction:
+   //
+   BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT 
+      : m_first_limb(i), m_limbs(1), m_sign(false) {}
+   BOOST_CONSTEXPR cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT 
+      : m_first_limb(std::abs(i)), m_limbs(1), m_sign(i < 0) {}
+#if defined(BOOST_LITTLE_ENDIAN)
+   BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT 
+      : m_double_first_limb(i), m_limbs(i > max_limb_value ? 2 : 1), m_sign(false) {}
+   BOOST_CONSTEXPR cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT 
+      : m_double_first_limb(i < 0 ? -i : i), m_limbs(i < 0 ? (-i > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)), m_sign(i < 0) {}
+#endif
+   //
    // Helper functions for getting at our internal data, and manipulating storage:
    //
    unsigned size()const BOOST_NOEXCEPT { return m_limbs; }
@@ -227,20 +287,12 @@
       if((m_limbs == 1) && (!*p)) m_sign = false; // zero is always unsigned
    }
 
-   BOOST_CONSTEXPR cpp_int_base() : m_data(), m_limbs(1), m_sign(false) {}
-   cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT : m_limbs(0)
-   {
-      resize(o.size());
-      std::memcpy(limbs(), o.limbs(), size() * sizeof(limb_type));
-      m_sign = o.m_sign;
-   }
-#ifndef BOOST_NO_RVALUE_REFERENCES
-   cpp_int_base(cpp_int_base&& o) BOOST_NOEXCEPT : m_limbs(o.m_limbs), m_sign(o.m_sign)
+   BOOST_CONSTEXPR cpp_int_base() : m_first_limb(0), m_limbs(1), m_sign(false) {}
+   cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT : m_limbs(o.m_limbs), m_sign(o.m_sign)
    {
-      std::memcpy(limbs(), o.limbs(), size() * sizeof(limb_type));
+      std::copy(o.limbs(), o.limbs() + o.size(), limbs());
    }
-#endif
-   ~cpp_int_base() BOOST_NOEXCEPT {}
+   //~cpp_int_base() BOOST_NOEXCEPT {}
    void assign(const cpp_int_base& o) BOOST_NOEXCEPT
    {
       if(this != &o)
@@ -274,11 +326,16 @@
 };
 
 template <unsigned MinBits>
-struct cpp_int_base<MinBits, false, void>
+struct cpp_int_base<MinBits, false, void, false>
 {
    typedef limb_type*                      limb_pointer;
    typedef const limb_type*                const_limb_pointer;
 
+   //
+   // Interface invariants:
+   //
+   BOOST_STATIC_ASSERT_MSG(MinBits > sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
+
 public:
    BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(limb_type) * CHAR_BIT);
    BOOST_STATIC_CONSTANT(limb_type, max_limb_value = ~static_cast<limb_type>(0u));
@@ -289,11 +346,28 @@
    BOOST_STATIC_ASSERT_MSG(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs");
 
 private:
-   limb_type          m_data[internal_limb_count];
+   union{
+      limb_type          m_data[internal_limb_count];
+      limb_type          m_first_limb;
+      double_limb_type   m_double_first_limb;
+   };
    limb_type          m_limbs;
 
 public:
    //
+   // Direct construction:
+   //
+   BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT 
+      : m_first_limb(i), m_limbs(1) {}
+   cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT 
+      : m_first_limb(i < 0 ? -i : i), m_limbs(1) { if(i < 0) negate(); }
+#ifdef BOOST_LITTLE_ENDIAN
+   BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT 
+      : m_double_first_limb(i), m_limbs(i > max_limb_value ? 2 : 1) {}
+   cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT 
+      : m_double_first_limb(i < 0 ? -i : i), m_limbs(i < 0 ? (-i > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)) { if(i < 0) negate(); }
+#endif
+   //
    // Helper functions for getting at our internal data, and manipulating storage:
    //
    unsigned size()const BOOST_NOEXCEPT { return m_limbs; }
@@ -312,19 +386,12 @@
       while((m_limbs-1) && !p[m_limbs - 1])--m_limbs;
    }
 
-   BOOST_CONSTEXPR cpp_int_base() BOOST_NOEXCEPT : m_data(), m_limbs(1) {}
-   cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT : m_limbs(0)
-   {
-      resize(o.size());
-      std::memcpy(limbs(), o.limbs(), size() * sizeof(limb_type));
-   }
-#ifndef BOOST_NO_RVALUE_REFERENCES
-   cpp_int_base(cpp_int_base&& o) BOOST_NOEXCEPT : m_limbs(o.m_limbs)
+   BOOST_CONSTEXPR cpp_int_base() BOOST_NOEXCEPT : m_first_limb(0), m_limbs(1) {}
+   cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT : m_limbs(o.m_limbs)
    {
-      std::memcpy(limbs(), o.limbs(), size() * sizeof(limb_type));
+      std::copy(o.limbs(), o.limbs() + o.size(), limbs());
    }
-#endif
-   ~cpp_int_base() BOOST_NOEXCEPT {}
+   //~cpp_int_base() BOOST_NOEXCEPT {}
    void assign(const cpp_int_base& o) BOOST_NOEXCEPT
    {
       if(this != &o)
@@ -358,52 +425,244 @@
    }
 };
 
+template <unsigned N>
+struct trivial_limb_type
+{
+   typedef typename mpl::if_c<
+      N <= sizeof(long long) * CHAR_BIT,
+      typename boost::uint_t<N>::least,
+      double_limb_type
+   >::type type;
+};
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4244) // loss of data in initialization
+#endif
+
+template <unsigned MinBits>
+struct cpp_int_base<MinBits, true, void, true>
+{
+   typedef typename trivial_limb_type<MinBits>::type  local_limb_type;
+   typedef local_limb_type*                           limb_pointer;
+   typedef const local_limb_type*                     const_limb_pointer;
+private:
+   BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(local_limb_type) * CHAR_BIT);
+   BOOST_STATIC_CONSTANT(local_limb_type, limb_mask = MinBits < limb_bits ? (local_limb_type(1) << MinBits) -1 : (~local_limb_type(0)));
+
+   local_limb_type    m_data;
+   bool               m_sign;
+
+   //
+   // Interface invariants:
+   //
+   BOOST_STATIC_ASSERT_MSG(MinBits <= sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
+
+public:
+   //
+   // Direct construction:
+   //
+   template <class SI>
+   BOOST_CONSTEXPR cpp_int_base(SI i, typename enable_if<is_signed<SI> >::type const* = 0) BOOST_NOEXCEPT
+      : m_data(i < 0 ? -i : i), m_sign(i < 0) {}
+   template <class UI>
+   BOOST_CONSTEXPR cpp_int_base(UI i, typename enable_if<is_unsigned<UI> >::type const* = 0) BOOST_NOEXCEPT
+      : m_data(i), m_sign(false) {}
+   template <class F>
+   cpp_int_base(F i, typename enable_if<is_floating_point<F> >::type const* = 0) BOOST_NOEXCEPT
+      : m_data(std::fabs(i)), m_sign(i < 0) {}
+   //
+   // Helper functions for getting at our internal data, and manipulating storage:
+   //
+   BOOST_CONSTEXPR unsigned size()const BOOST_NOEXCEPT { return 1; }
+   limb_pointer limbs() BOOST_NOEXCEPT { return &m_data; }
+   const_limb_pointer limbs()const BOOST_NOEXCEPT { return &m_data; }
+   bool sign()const BOOST_NOEXCEPT { return m_sign; }
+   void sign(bool b) BOOST_NOEXCEPT
+   { 
+      m_sign = b; 
+      // Check for zero value:
+      if(m_sign && !m_data)
+      {
+         m_sign = false;
+      }
+   }
+   void resize(unsigned new_size) BOOST_NOEXCEPT {}
+   void normalize() BOOST_NOEXCEPT
+   {
+      if(!m_data) 
+         m_sign = false; // zero is always unsigned
+      m_data &= limb_mask;
+   }
+
+   BOOST_CONSTEXPR cpp_int_base() : m_data(0), m_sign(false) {}
+   BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT : m_data(o.m_data), m_sign(o.m_sign) {}
+   //~cpp_int_base() BOOST_NOEXCEPT {}
+   void assign(const cpp_int_base& o) BOOST_NOEXCEPT
+   {
+      m_data = o.m_data;
+      m_sign = o.m_sign;
+   }
+   void negate() BOOST_NOEXCEPT
+   {
+      m_sign = !m_sign;
+      // Check for zero value:
+      if(m_data == 0)
+      {
+         m_sign = false;
+      }
+   }
+   bool isneg()const BOOST_NOEXCEPT
+   {
+      return m_sign; 
+   }
+   void do_swap(cpp_int_base& o) BOOST_NOEXCEPT
+   {
+      std::swap(m_sign, o.m_sign);
+      std::swap(m_data, o.m_data);
+   }
+};
+
+template <unsigned MinBits>
+struct cpp_int_base<MinBits, false, void, true>
+{
+   typedef typename trivial_limb_type<MinBits>::type  local_limb_type;
+   typedef local_limb_type*                           limb_pointer;
+   typedef const local_limb_type*                     const_limb_pointer;
+private:
+   BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(local_limb_type) * CHAR_BIT);
+   BOOST_STATIC_CONSTANT(local_limb_type, limb_mask = MinBits < limb_bits ? (local_limb_type(1) << MinBits) -1 : (~local_limb_type(0)));
+
+   local_limb_type    m_data;
+
+   //
+   // Interface invariants:
+   //
+   BOOST_STATIC_ASSERT_MSG(MinBits <= sizeof(double_limb_type) * CHAR_BIT, "Template parameter MinBits is inconsistent with the parameter trivial - did you mistakingly try to override the trivial parameter?");
+
+public:
+   //
+   // Direct construction:
+   //
+   template <class SI>
+   BOOST_CONSTEXPR cpp_int_base(SI i, typename enable_if<is_signed<SI> >::type const* = 0) BOOST_NOEXCEPT
+      : m_data(i < 0 ? 1 + ~static_cast<local_limb_type>(-i) : static_cast<local_limb_type>(i)) {}
+   template <class UI>
+   BOOST_CONSTEXPR cpp_int_base(UI i, typename enable_if<is_unsigned<UI> >::type const* = 0) BOOST_NOEXCEPT
+      : m_data(i) {}
+   template <class F>
+   cpp_int_base(F i, typename enable_if<is_floating_point<F> >::type const* = 0) BOOST_NOEXCEPT
+      : m_data(std::fabs(i)) 
+   {
+      if(i < 0)
+         negate();
+   }
+   //
+   // Helper functions for getting at our internal data, and manipulating storage:
+   //
+   BOOST_CONSTEXPR unsigned size()const BOOST_NOEXCEPT { return 1; }
+   limb_pointer limbs() BOOST_NOEXCEPT { return &m_data; }
+   const_limb_pointer limbs()const BOOST_NOEXCEPT { return &m_data; }
+   BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return false; }
+   void sign(bool b) BOOST_NOEXCEPT
+   {
+      if(b)
+         negate();
+   }
+   void resize(unsigned new_size) BOOST_NOEXCEPT {}
+   void normalize() BOOST_NOEXCEPT 
+   {
+      m_data &= limb_mask;
+   }
+
+   BOOST_CONSTEXPR cpp_int_base() : m_data(0) {}
+   BOOST_CONSTEXPR cpp_int_base(const cpp_int_base& o) BOOST_NOEXCEPT : m_data(o.m_data) {}
+   //~cpp_int_base() BOOST_NOEXCEPT {}
+   void assign(const cpp_int_base& o) BOOST_NOEXCEPT
+   {
+      m_data = o.m_data;
+   }
+   void negate() BOOST_NOEXCEPT
+   {
+      m_data = ~m_data;
+      ++m_data;
+   }
+   BOOST_CONSTEXPR bool isneg()const BOOST_NOEXCEPT
+   {
+      return false; 
+   }
+   void do_swap(cpp_int_base& o) BOOST_NOEXCEPT
+   {
+      std::swap(m_data, o.m_data);
+   }
+};
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
 template <unsigned MinBits, bool Signed, class Allocator>
-const unsigned cpp_int_base<MinBits, Signed, Allocator>::limb_bits;
+const unsigned cpp_int_base<MinBits, Signed, Allocator, false>::limb_bits;
 template <unsigned MinBits, bool Signed, class Allocator>
-const limb_type cpp_int_base<MinBits, Signed, Allocator>::max_limb_value;
+const limb_type cpp_int_base<MinBits, Signed, Allocator, false>::max_limb_value;
 template <unsigned MinBits, bool Signed, class Allocator>
-const limb_type cpp_int_base<MinBits, Signed, Allocator>::sign_bit_mask;
+const limb_type cpp_int_base<MinBits, Signed, Allocator, false>::sign_bit_mask;
 template <unsigned MinBits, bool Signed, class Allocator>
-const unsigned cpp_int_base<MinBits, Signed, Allocator>::internal_limb_count;
+const unsigned cpp_int_base<MinBits, Signed, Allocator, false>::internal_limb_count;
 template <unsigned MinBits, bool Signed, class Allocator>
-const bool cpp_int_base<MinBits, Signed, Allocator>::variable;
+const bool cpp_int_base<MinBits, Signed, Allocator, false>::variable;
 
 template <unsigned MinBits>
-const unsigned cpp_int_base<MinBits, true, void>::limb_bits;
+const unsigned cpp_int_base<MinBits, true, void, false>::limb_bits;
 template <unsigned MinBits>
-const limb_type cpp_int_base<MinBits, true, void>::max_limb_value;
+const limb_type cpp_int_base<MinBits, true, void, false>::max_limb_value;
 template <unsigned MinBits>
-const limb_type cpp_int_base<MinBits, true, void>::sign_bit_mask;
+const limb_type cpp_int_base<MinBits, true, void, false>::sign_bit_mask;
 template <unsigned MinBits>
-const unsigned cpp_int_base<MinBits, true, void>::internal_limb_count;
+const unsigned cpp_int_base<MinBits, true, void, false>::internal_limb_count;
 template <unsigned MinBits>
-const bool cpp_int_base<MinBits, true, void>::variable;
+const bool cpp_int_base<MinBits, true, void, false>::variable;
 
 template <unsigned MinBits>
-const unsigned cpp_int_base<MinBits, false, void>::limb_bits;
+const unsigned cpp_int_base<MinBits, false, void, false>::limb_bits;
 template <unsigned MinBits>
-const limb_type cpp_int_base<MinBits, false, void>::max_limb_value;
+const limb_type cpp_int_base<MinBits, false, void, false>::max_limb_value;
 template <unsigned MinBits>
-const limb_type cpp_int_base<MinBits, false, void>::sign_bit_mask;
+const limb_type cpp_int_base<MinBits, false, void, false>::sign_bit_mask;
 template <unsigned MinBits>
-const unsigned cpp_int_base<MinBits, false, void>::internal_limb_count;
+const unsigned cpp_int_base<MinBits, false, void, false>::internal_limb_count;
 template <unsigned MinBits>
-const bool cpp_int_base<MinBits, false, void>::variable;
+const bool cpp_int_base<MinBits, false, void, false>::variable;
 
 template <unsigned MinBits, bool Signed, class Allocator>
-struct cpp_int_backend : public cpp_int_base<MinBits, Signed, Allocator>
+struct cpp_int_backend<MinBits, Signed, Allocator, false> : public cpp_int_base<MinBits, Signed, Allocator, false>
 {
-   typedef cpp_int_base<MinBits, Signed, Allocator> base_type;
+   typedef cpp_int_backend<MinBits, Signed, Allocator>               self_type;
+   typedef cpp_int_base<MinBits, Signed, Allocator>                  base_type;
+   typedef typename is_trivial_cpp_int<self_type>::type              trivial_tag;
 public:
    typedef mpl::list<signed_limb_type, signed_double_limb_type>      signed_types;
    typedef mpl::list<limb_type, double_limb_type>                    unsigned_types;
    typedef mpl::list<long double>                                    float_types;
 
    BOOST_CONSTEXPR cpp_int_backend() BOOST_NOEXCEPT{}
-   cpp_int_backend(const cpp_int_backend& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value) : base_type(o) {}
+   BOOST_CONSTEXPR cpp_int_backend(const cpp_int_backend& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value) : base_type(o) {}
 #ifndef BOOST_NO_RVALUE_REFERENCES
-   cpp_int_backend(cpp_int_backend&& o) BOOST_NOEXCEPT : base_type(static_cast<base_type&&>(o)) {}
+   BOOST_CONSTEXPR cpp_int_backend(cpp_int_backend&& o) BOOST_NOEXCEPT : base_type(static_cast<base_type&&>(o)) {}
+#endif
+   template <class LT>
+   BOOST_CONSTEXPR cpp_int_backend(LT i, typename enable_if<is_same<LT, limb_type> >::type const* = 0)BOOST_NOEXCEPT 
+      : base_type(i) {}
+   template <class SLT>
+   BOOST_CONSTEXPR cpp_int_backend(SLT i, typename enable_if<is_same<SLT, signed_limb_type> >::type const* = 0)BOOST_NOEXCEPT 
+      : base_type(i) {}
+#if defined(BOOST_LITTLE_ENDIAN)
+   template <class LT>
+   BOOST_CONSTEXPR cpp_int_backend(LT i, typename enable_if<is_same<LT, double_limb_type> >::type const* = 0)BOOST_NOEXCEPT 
+      : base_type(i) {}
+   template <class SLT>
+   BOOST_CONSTEXPR cpp_int_backend(SLT i, typename enable_if<is_same<SLT, signed_double_limb_type> >::type const* = 0)BOOST_NOEXCEPT 
+      : base_type(i) {}
 #endif
    cpp_int_backend& operator = (const cpp_int_backend& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
    {
@@ -736,14 +995,110 @@
    }
 };
 
+template <unsigned MinBits, bool Signed>
+struct cpp_int_backend<MinBits, Signed, void, true> : public cpp_int_base<MinBits, Signed, void, true>
+{
+public:
+   typedef cpp_int_backend<MinBits, Signed, void, true>              self_type;
+   typedef cpp_int_base<MinBits, Signed, void, true>                 base_type;
+   typedef typename is_trivial_cpp_int<self_type>::type              trivial_tag;
+   typedef mpl::list<
+      signed char, short, int, long, 
+      long long, signed_double_limb_type>                            signed_types;
+   typedef mpl::list<unsigned char, unsigned short, unsigned,
+      unsigned long long, double_limb_type>                          unsigned_types;
+   typedef mpl::list<float, double, long double>                     float_types;
+
+   BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(typename base_type::local_limb_type) * CHAR_BIT);
+
+   BOOST_CONSTEXPR cpp_int_backend() BOOST_NOEXCEPT{}
+   BOOST_CONSTEXPR cpp_int_backend(const cpp_int_backend& o) BOOST_NOEXCEPT : base_type(o) {}
+   cpp_int_backend& operator = (const cpp_int_backend& o) BOOST_NOEXCEPT
+   {
+      this->assign(o);
+      return *this;
+   }
+
+   template <class A>
+   BOOST_CONSTEXPR cpp_int_backend(A i, typename enable_if<is_arithmetic<A> >::type const* = 0) BOOST_NOEXCEPT
+      : base_type(i) {}
+
+   template <class SI>
+   typename enable_if<is_signed<SI>, cpp_int_backend&>::type operator = (SI i) BOOST_NOEXCEPT
+   {
+      *this->limbs() = static_cast<typename base_type::local_limb_type>(std::abs(i));
+      this->sign(i < 0);
+      return *this;
+   }
+   template <class UI>
+   typename enable_if<is_unsigned<UI>, cpp_int_backend&>::type operator = (UI i) BOOST_NOEXCEPT
+   {
+      *this->limbs() = static_cast<typename base_type::local_limb_type>(i);
+      return *this;
+   }
+   template <class F>
+   typename enable_if<is_floating_point<F>, cpp_int_backend&>::type operator = (F i) BOOST_NOEXCEPT
+   {
+      *this->limbs() = static_cast<typename base_type::local_limb_type>(std::abs(i));
+      this->sign(i < 0);
+      return *this;
+   }
+   cpp_int_backend& operator = (const char* s)
+   {
+      try{
+         *this->limbs() = boost::lexical_cast<limb_type>(s);
+      }
+      catch(const std::exception&)
+      {
+         BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Could not interpret the string \"") + s + std::string("\" as a valid integer value.")));
+      }
+      return *this;
+   }
+   void swap(cpp_int_backend& o) BOOST_NOEXCEPT
+   {
+      this->do_swap(o);
+   }
+   std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
+   {
+      std::stringstream ss;
+      ss.flags(f);
+      ss << *this->limbs();
+      std::string result;
+      if(this->sign())
+         result += '-';
+      result += ss.str();
+      return result;
+   }
+   int compare(const cpp_int_backend& o)const BOOST_NOEXCEPT
+   {
+      if(this->sign() != o.sign())
+         return this->sign() ? -1 : 1;
+      int result = 0;
+      // Only do the compare if the same sign:
+      result = *this->limbs() == *o.limbs() ? 0 : *this->limbs() < *o.limbs() ? -1 : 1;
+
+      if(this->sign())
+         result = -result;
+      return result;
+   }
+   template <class Arithmatic>
+   typename enable_if<is_arithmetic<Arithmatic>, int>::type compare(Arithmatic i)const BOOST_NOEXCEPT
+   {
+      // braindead version:
+      cpp_int_backend t;
+      t = i;
+      return compare(t);
+   }
+};
+
 
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_add(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline 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)
 {
    eval_add(result, result, o);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void add_unsigned(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a, const cpp_int_backend<MinBits, Signed, Allocator>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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)
 {
    using std::swap;
 
@@ -761,10 +1116,10 @@
       return;
    }
    result.resize(x);
-   typename cpp_int_backend<MinBits, Signed, Allocator>::const_limb_pointer pa = a.limbs();
-   typename cpp_int_backend<MinBits, Signed, Allocator>::const_limb_pointer pb = b.limbs();
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer pr = result.limbs();
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer pr_end = pr + m;
+   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;
 
    if(as < bs)
       swap(pa, pb);
@@ -774,7 +1129,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>::limb_bits;
+      carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
       ++pr, ++pa, ++pb;
    }
    pr_end += x - m;
@@ -789,21 +1144,21 @@
       }
       carry += static_cast<double_limb_type>(*pa);
       *pr = static_cast<limb_type>(carry);
-      carry >>= cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+      carry >>= cpp_int_backend<MinBits, Signed, Allocator, 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>::variable || (result.size() > x))
+      if(cpp_int_backend<MinBits, Signed, Allocator, 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>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a, const cpp_int_backend<MinBits, Signed, Allocator>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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)
 {
    if(a.sign() != b.sign())
    {
@@ -814,30 +1169,30 @@
 }
 
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void add_unsigned(cpp_int_backend<MinBits, Signed, Allocator>& result, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void add_unsigned(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    // Addition using modular arithmatic.
    // Nothing fancy, just let uintmax_t take the strain:
    double_limb_type carry = o;
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer pr = result.limbs();
+   typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pr = result.limbs();
    for(unsigned i = 0; carry && (i < result.size()); ++i)
    {
       carry += static_cast<double_limb_type>(pr[i]);
       pr[i] = static_cast<limb_type>(carry);
-      carry >>= cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+      carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
    }
    if(carry)
    {
       unsigned x = result.size();
       result.resize(x + 1);
       // We overflowed, need to add one more limb:
-      if(cpp_int_backend<MinBits, Signed, Allocator>::variable || (result.size() > x))
+      if(cpp_int_backend<MinBits, Signed, Allocator, false>::variable || (result.size() > x))
          result.limbs()[x] = static_cast<limb_type>(carry);
    }
    result.normalize();
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_add(cpp_int_backend<MinBits, Signed, Allocator>& result, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_add(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    if(result.sign())
    {
@@ -847,7 +1202,7 @@
       add_unsigned(result, o);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_add(cpp_int_backend<MinBits, Signed, Allocator>& result, const signed_limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_add(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const signed_limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    if(o < 0)
       eval_subtract(result, static_cast<limb_type>(-o));
@@ -856,12 +1211,12 @@
 }
 
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void subtract_unsigned(cpp_int_backend<MinBits, Signed, Allocator>& result, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void subtract_unsigned(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    // Subtract one limb.
    // Nothing fancy, just let uintmax_t take the strain:
-   BOOST_STATIC_CONSTANT(double_limb_type, borrow = static_cast<double_limb_type>(cpp_int_backend<MinBits, Signed, Allocator>::max_limb_value) + 1);
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer p = result.limbs();
+   BOOST_STATIC_CONSTANT(double_limb_type, borrow = static_cast<double_limb_type>(cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value) + 1);
+   typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer p = result.limbs();
    if(*p > o)
    {
       *p -= o;
@@ -877,7 +1232,7 @@
       ++p;
       while(!*p)
       {
-         *p = cpp_int_backend<MinBits, Signed, Allocator>::max_limb_value;
+         *p = cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value;
          ++p;
       }
       --*p;
@@ -885,7 +1240,7 @@
    }
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_subtract(cpp_int_backend<MinBits, Signed, Allocator>& result, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_subtract(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    if(result.sign())
       add_unsigned(result, o);
@@ -893,7 +1248,7 @@
       subtract_unsigned(result, o);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_subtract(cpp_int_backend<MinBits, Signed, Allocator>& result, const signed_limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_subtract(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const signed_limb_type& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    if(o)
    {
@@ -904,10 +1259,10 @@
    }
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_increment(cpp_int_backend<MinBits, Signed, Allocator>& result) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_increment(cpp_int_backend<MinBits, Signed, Allocator, false>& result) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    static const limb_type one = 1;
-   if(!result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits, Signed, Allocator>::max_limb_value))
+   if(!result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value))
       ++result.limbs()[0];
    else if(result.sign() && result.limbs()[0])
       --result.limbs()[0];
@@ -915,23 +1270,23 @@
       eval_add(result, one);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_decrement(cpp_int_backend<MinBits, Signed, Allocator>& result) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_decrement(cpp_int_backend<MinBits, Signed, Allocator, false>& result) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    static const limb_type one = 1;
    if(!result.sign() && result.limbs()[0])
       --result.limbs()[0];
-   else if(result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits, Signed, Allocator>::max_limb_value))
+   else if(result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value))
       ++result.limbs()[0];
    else
       eval_subtract(result, one);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_subtract(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline 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)
 {
    eval_subtract(result, result, o);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void subtract_unsigned(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a, const cpp_int_backend<MinBits, Signed, Allocator>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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)
 {
    using std::swap;
 
@@ -962,9 +1317,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>::const_limb_pointer pa = a.limbs();
-   typename cpp_int_backend<MinBits, Signed, Allocator>::const_limb_pointer pb = b.limbs();
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer pr = result.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();
    bool swapped = false;
    if(c < 0)
    {
@@ -983,7 +1338,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>::limb_bits) & 1u;
+      borrow = (borrow >> cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits) & 1u;
       ++i;
    }
    // Now where only a has digits, only as long as we've borrowed:
@@ -991,7 +1346,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>::limb_bits) & 1u;
+      borrow = (borrow >> cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits) & 1u;
       ++i;
    }
    // Any remaining digits are the same as those in pa:
@@ -1008,7 +1363,7 @@
       result.negate();
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_subtract(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a, const cpp_int_backend<MinBits, Signed, Allocator>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline 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)
 {
    if(a.sign() != b.sign())
    {
@@ -1018,7 +1373,7 @@
    subtract_unsigned(result, a, b);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a, const cpp_int_backend<MinBits, Signed, Allocator>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+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)
 {
    // Very simple long multiplication, only usable for small numbers of limb_type's
    // but that's the typical use case for this type anyway:
@@ -1027,8 +1382,8 @@
    //
    unsigned as = a.size();
    unsigned bs = b.size();
-   typename cpp_int_backend<MinBits, Signed, Allocator>::const_limb_pointer pa = a.limbs();
-   typename cpp_int_backend<MinBits, Signed, Allocator>::const_limb_pointer pb = b.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();
    if(as == 1)
    {
       bool s = b.sign() != a.sign();
@@ -1057,19 +1412,19 @@
 
    if(&result == &a)
    {
-      cpp_int_backend<MinBits, Signed, Allocator> t(a);
+      cpp_int_backend<MinBits, Signed, Allocator, false> t(a);
       eval_multiply(result, t, b);
       return;
    }
    if(&result == &b)
    {
-      cpp_int_backend<MinBits, Signed, Allocator> t(b);
+      cpp_int_backend<MinBits, Signed, Allocator, false> t(b);
       eval_multiply(result, a, t);
       return;
    }
 
    result.resize(as + bs);
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer pr = result.limbs();
+   typename cpp_int_backend<MinBits, Signed, Allocator, 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);
@@ -1079,19 +1434,19 @@
    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>::variable ? bs : (std::min)(result.size() - i, bs);
+      unsigned inner_limit = cpp_int_backend<MinBits, Signed, Allocator, 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>::max_limb_value) * static_cast<double_limb_type>(cpp_int_backend<MinBits, Signed, Allocator>::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<MinBits, Signed, Allocator, false>::max_limb_value) * static_cast<double_limb_type>(cpp_int_backend<MinBits, Signed, Allocator, 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>::limb_bits;
-         BOOST_ASSERT(carry <= (cpp_int_backend<MinBits, Signed, Allocator>::max_limb_value));
+         carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+         BOOST_ASSERT(carry <= (cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value));
       }
-      if(cpp_int_backend<MinBits, Signed, Allocator>::variable || (i + bs < result.size()))
+      if(cpp_int_backend<MinBits, Signed, Allocator, false>::variable || (i + bs < result.size()))
          pr[i + bs] = static_cast<limb_type>(carry);
       carry = 0;
    }
@@ -1102,12 +1457,12 @@
    result.sign(a.sign() != b.sign());
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline 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)
 {
     eval_multiply(result, result, a);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator>& result, cpp_int_backend<MinBits, Signed, Allocator>& a, const limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, cpp_int_backend<MinBits, Signed, Allocator, false>& a, const limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    if(!val)
    {
@@ -1115,33 +1470,33 @@
       return;
    }
    double_limb_type carry = 0;
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer p = result.limbs();
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer pe = result.limbs() + result.size();
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer pa = a.limbs();
+   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>::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>::limb_bits;
+      carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
       ++p, ++pa;
    }
    if(carry)
    {
       unsigned i = result.size();
       result.resize(i + 1);
-      if(cpp_int_backend<MinBits, Signed, Allocator>::variable || (result.size() > i))
+      if(cpp_int_backend<MinBits, Signed, Allocator, false>::variable || (result.size() > i))
          result.limbs()[i] = static_cast<limb_type>(carry);
    }
-   if(!cpp_int_backend<MinBits, Signed, Allocator>::variable)
+   if(!cpp_int_backend<MinBits, Signed, Allocator, false>::variable)
       result.normalize();
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator>& result, const limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    eval_multiply(result, result, val);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator>& result, cpp_int_backend<MinBits, Signed, Allocator>& a, const signed_limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, cpp_int_backend<MinBits, Signed, Allocator, false>& a, const signed_limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    if(val > 0)
       eval_multiply(result, a, static_cast<limb_type>(val));
@@ -1152,22 +1507,22 @@
    }
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator>& result, const signed_limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_multiply(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const signed_limb_type& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    eval_multiply(result, result, val);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-void divide_unsigned_helper(cpp_int_backend<MinBits, Signed, Allocator>* result, const cpp_int_backend<MinBits, Signed, Allocator>& x, const cpp_int_backend<MinBits, Signed, Allocator>& y, cpp_int_backend<MinBits, Signed, Allocator>& r)
+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)
 {
    if((result == &x) || (&r == &x))
    {
-      cpp_int_backend<MinBits, Signed, Allocator> t(x);
+      cpp_int_backend<MinBits, Signed, Allocator, false> t(x);
       divide_unsigned_helper(result, t, y, r);
       return;
    }
    if((result == &y) || (&r == &y))
    {
-      cpp_int_backend<MinBits, Signed, Allocator> t(y);
+      cpp_int_backend<MinBits, Signed, Allocator, false> t(y);
       divide_unsigned_helper(result, x, t, r);
       return;
    }
@@ -1195,7 +1550,7 @@
 
    if(result == &r)
    {
-      cpp_int_backend<MinBits, Signed, Allocator> rem;
+      cpp_int_backend<MinBits, Signed, Allocator, false> rem;
       divide_unsigned_helper(result, x, y, rem);
       r = rem;
       return;
@@ -1217,8 +1572,8 @@
       return;
    }
 
-   typename cpp_int_backend<MinBits, Signed, Allocator>::const_limb_pointer px = x.limbs();
-   typename cpp_int_backend<MinBits, Signed, Allocator>::const_limb_pointer py = y.limbs();
+   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();
 
    limb_type r_order = x.size() - 1;
    if((r_order == 0) && (*px == 0))
@@ -1247,7 +1602,7 @@
       }
    }
 
-   cpp_int_backend<MinBits, Signed, Allocator> t;
+   cpp_int_backend<MinBits, Signed, Allocator, false> t;
    bool r_neg = false;
 
    //
@@ -1263,9 +1618,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>::limb_bits) | px[0];
+      a = (static_cast<double_limb_type>(px[1]) << cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits) | px[0];
       b = y_order ? 
-         (static_cast<double_limb_type>(py[1]) << cpp_int_backend<MinBits, Signed, Allocator>::limb_bits) | py[0] 
+         (static_cast<double_limb_type>(py[1]) << cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits) | py[0] 
          : py[0];
       if(result)
          *result = a / b;
@@ -1277,9 +1632,9 @@
    //
    if(result)
       result->resize(1 + r_order - y_order);
-   typename cpp_int_backend<MinBits, Signed, Allocator>::const_limb_pointer prem = r.limbs();
+   typename cpp_int_backend<MinBits, Signed, Allocator, 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>::limb_pointer pr = typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer();
+   typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pr = typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer();
    if(result)
    {
       pr = result->limbs();
@@ -1297,10 +1652,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>::limb_bits) | prem[r_order - 1];
+         a = (static_cast<double_limb_type>(prem[r_order]) << cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits) | prem[r_order - 1];
          b = py[y_order];
          v = a / b;
-         if(v > cpp_int_backend<MinBits, Signed, Allocator>::max_limb_value)
+         if(v > cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value)
             guess = 1;
          else
          {
@@ -1315,8 +1670,8 @@
       else
       {
          double_limb_type a, b, v;
-         a = (static_cast<double_limb_type>(prem[r_order]) << cpp_int_backend<MinBits, Signed, Allocator>::limb_bits) | prem[r_order - 1];
-         b = (y_order > 0) ? (static_cast<double_limb_type>(py[y_order]) << cpp_int_backend<MinBits, Signed, Allocator>::limb_bits) | py[y_order - 1] : (static_cast<double_limb_type>(py[y_order])  << cpp_int_backend<MinBits, Signed, Allocator>::limb_bits);
+         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);
          v = a / b;
          guess = static_cast<limb_type>(v);
       }
@@ -1340,7 +1695,7 @@
                eval_subtract(*result, t);
             }
          }
-         else if(cpp_int_backend<MinBits, Signed, Allocator>::max_limb_value - pr[shift] > guess)
+         else if(cpp_int_backend<MinBits, Signed, Allocator, false>::max_limb_value - pr[shift] > guess)
             pr[shift] += guess;
          else
          {
@@ -1357,15 +1712,15 @@
       //
       double_limb_type carry = 0;
       t.resize(y.size() + shift + 1);
-      bool truncated_t = !cpp_int_backend<MinBits, Signed, Allocator>::variable && (t.size() != y.size() + shift + 1);
-      typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer pt = t.limbs();
+      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();
       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>::limb_bits;
+         carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
       }
       if(carry && !truncated_t)
       {
@@ -1424,18 +1779,18 @@
 }
 
 template <unsigned MinBits, bool Signed, class Allocator>
-void divide_unsigned_helper(cpp_int_backend<MinBits, Signed, Allocator>* result, const cpp_int_backend<MinBits, Signed, Allocator>& x, limb_type y, cpp_int_backend<MinBits, Signed, Allocator>& r)
+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)
 {
    if((result == &x) || (&r == &x))
    {
-      cpp_int_backend<MinBits, Signed, Allocator> t(x);
+      cpp_int_backend<MinBits, Signed, Allocator, false> t(x);
       divide_unsigned_helper(result, t, y, r);
       return;
    }
 
    if(result == &r)
    {
-      cpp_int_backend<MinBits, Signed, Allocator> rem;
+      cpp_int_backend<MinBits, Signed, Allocator, false> rem;
       divide_unsigned_helper(result, x, y, rem);
       r = rem;
       return;
@@ -1459,7 +1814,7 @@
    //
    r = x;
    r.sign(false);
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer pr = r.limbs();
+   typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pr = r.limbs();
 
    if((r_order == 0) && (*pr == 0))
    {
@@ -1494,7 +1849,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>::limb_bits) | pr[0];
+      a = (static_cast<double_limb_type>(pr[r_order]) << cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits) | pr[0];
       if(result)
       {
          *result = a / y;
@@ -1506,7 +1861,7 @@
    }
 
    // This is initialised just to keep the compiler from emitting useless warnings later on:
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer pres = typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer();
+   typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pres = typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer();
    if(result)
    {
       result->resize(r_order + 1);
@@ -1523,7 +1878,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>::limb_bits) | pr[r_order - 1];
+         a = (static_cast<double_limb_type>(pr[r_order]) << cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits) | pr[r_order - 1];
          b = a % y;
          r.resize(r.size() - 1);
          --r_order;
@@ -1568,86 +1923,86 @@
 }
 
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_divide(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a, const cpp_int_backend<MinBits, Signed, Allocator>& b)
+inline 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)
 {
-   cpp_int_backend<MinBits, Signed, Allocator> r;
+   cpp_int_backend<MinBits, Signed, Allocator, false> r;
    divide_unsigned_helper(&result, a, b, r);
    result.sign(a.sign() != b.sign());
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_divide(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a, limb_type& b)
+inline void eval_divide(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, limb_type& b)
 {
-   cpp_int_backend<MinBits, Signed, Allocator> r;
+   cpp_int_backend<MinBits, Signed, Allocator, false> r;
    divide_unsigned_helper(&result, a, b, r);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_divide(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a, signed_limb_type& b)
+inline void eval_divide(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, signed_limb_type& b)
 {
-   cpp_int_backend<MinBits, Signed, Allocator> r;
+   cpp_int_backend<MinBits, Signed, Allocator, false> r;
    divide_unsigned_helper(&result, a, std::abs(b), r);
    if(b < 0)
       result.negate();
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_divide(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& b)
+inline void eval_divide(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& b)
 {
    // There is no in place divide:
-   cpp_int_backend<MinBits, Signed, Allocator> a(result);
+   cpp_int_backend<MinBits, Signed, Allocator, false> a(result);
    eval_divide(result, a, b);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_divide(cpp_int_backend<MinBits, Signed, Allocator>& result, limb_type b)
+inline void eval_divide(cpp_int_backend<MinBits, Signed, Allocator, false>& result, limb_type b)
 {
    // There is no in place divide:
-   cpp_int_backend<MinBits, Signed, Allocator> a(result);
+   cpp_int_backend<MinBits, Signed, Allocator, false> a(result);
    eval_divide(result, a, b);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_divide(cpp_int_backend<MinBits, Signed, Allocator>& result, signed_limb_type b)
+inline void eval_divide(cpp_int_backend<MinBits, Signed, Allocator, false>& result, signed_limb_type b)
 {
    // There is no in place divide:
-   cpp_int_backend<MinBits, Signed, Allocator> a(result);
+   cpp_int_backend<MinBits, Signed, Allocator, false> a(result);
    eval_divide(result, a, b);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a, const cpp_int_backend<MinBits, Signed, Allocator>& b)
+inline 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)
 {
-   divide_unsigned_helper(static_cast<cpp_int_backend<MinBits, Signed, Allocator>* >(0), a, b, result);
+   divide_unsigned_helper(static_cast<cpp_int_backend<MinBits, Signed, Allocator, false>* >(0), a, b, result);
    result.sign(a.sign());
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a, limb_type b)
+inline void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, limb_type b)
 {
-   divide_unsigned_helper(static_cast<cpp_int_backend<MinBits, Signed, Allocator>* >(0), a, b, result);
+   divide_unsigned_helper(static_cast<cpp_int_backend<MinBits, Signed, Allocator, false>* >(0), a, b, result);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a, signed_limb_type b)
+inline void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& a, signed_limb_type b)
 {
-   divide_unsigned_helper(static_cast<cpp_int_backend<MinBits, Signed, Allocator>* >(0), a, static_cast<limb_type>(std::abs(b)), result);
+   divide_unsigned_helper(static_cast<cpp_int_backend<MinBits, Signed, Allocator, false>* >(0), a, static_cast<limb_type>(std::abs(b)), result);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& b)
+inline void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& b)
 {
    // There is no in place divide:
-   cpp_int_backend<MinBits, Signed, Allocator> a(result);
+   cpp_int_backend<MinBits, Signed, Allocator, false> a(result);
    eval_modulus(result, a, b);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator>& result, limb_type b)
+inline void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator, false>& result, limb_type b)
 {
    // There is no in place divide:
-   cpp_int_backend<MinBits, Signed, Allocator> a(result);
+   cpp_int_backend<MinBits, Signed, Allocator, false> a(result);
    eval_modulus(result, a, b);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator>& result, signed_limb_type b)
+inline void eval_modulus(cpp_int_backend<MinBits, Signed, Allocator, false>& result, signed_limb_type b)
 {
    // There is no in place divide:
-   cpp_int_backend<MinBits, Signed, Allocator> a(result);
+   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>& result, const cpp_int_backend<MinBits, Signed, Allocator>& o, Op op) BOOST_NOEXCEPT
+void bitwise_op(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& o, Op op) BOOST_NOEXCEPT
 {
    //
    // There are 4 cases:
@@ -1666,8 +2021,8 @@
    unsigned m, x;
    minmax(rs, os, m, x);
    result.resize(x);
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer pr = result.limbs();
-   typename cpp_int_backend<MinBits, Signed, Allocator>::const_limb_pointer po = o.limbs();
+   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();
    for(unsigned i = rs; i < x; ++i)
       pr[i] = 0;
 
@@ -1690,13 +2045,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>::limb_bits;
+            carry >>= cpp_int_backend<MinBits, Signed, Allocator, 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>::limb_bits;
+            carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
          }
          // Set the overflow into the "extra" limb:
          carry += static_cast<double_limb_type>(~limb_type(0));
@@ -1713,13 +2068,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>::limb_bits;
+            carry >>= cpp_int_backend<MinBits, Signed, Allocator, 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>::limb_bits;
+            carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
          }
          // Set the overflow into the "extra" limb:
          carry += static_cast<double_limb_type>(~limb_type(0));
@@ -1735,16 +2090,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>::limb_bits;
-            o_carry >>= cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+            r_carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+            o_carry >>= cpp_int_backend<MinBits, Signed, Allocator, 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>::limb_bits;
-            o_carry >>= cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+            r_carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+            o_carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
          }
          // Set the overflow into the "extra" limb:
          r_carry += static_cast<double_limb_type>(~limb_type(0));
@@ -1763,7 +2118,7 @@
       {
          carry += static_cast<double_limb_type>(~pr[i]);
          pr[i] = static_cast<limb_type>(carry);
-         carry >>= cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+         carry >>= cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
       }
    }
    else
@@ -1777,22 +2132,22 @@
 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>
-inline void eval_bitwise_and(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& o)BOOST_NOEXCEPT_IF(is_void<Allocator>::value)
+inline 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)
 {
    bitwise_op(result, o, bit_and());
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_bitwise_or(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& o) BOOST_NOEXCEPT_IF(is_void<Allocator>::value)
+inline 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)
 {
    bitwise_op(result, o, bit_or());
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_bitwise_xor(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& o) BOOST_NOEXCEPT_IF(is_void<Allocator>::value)
+inline 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)
 {
    bitwise_op(result, o, bit_xor());
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_complement(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& o) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline 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)
 {
    // Increment and negate:
    result = o;
@@ -1800,7 +2155,7 @@
    result.negate();
 }
 template <unsigned MinBits, bool Signed>
-inline void eval_left_shift(cpp_int_backend<MinBits, Signed, void>& result, double_limb_type s) BOOST_NOEXCEPT
+inline void eval_left_shift(cpp_int_backend<MinBits, Signed, void, false>& result, double_limb_type s) BOOST_NOEXCEPT
 {
    if(!s)
       return;
@@ -1876,23 +2231,23 @@
    }
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_left_shift(cpp_int_backend<MinBits, Signed, Allocator>& result, double_limb_type s) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_left_shift(cpp_int_backend<MinBits, Signed, Allocator, false>& result, double_limb_type s) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    if(!s)
       return;
 
-   limb_type offset = static_cast<limb_type>(s / cpp_int_backend<MinBits, Signed, Allocator>::limb_bits);
-   limb_type shift  = static_cast<limb_type>(s % cpp_int_backend<MinBits, Signed, Allocator>::limb_bits);
+   limb_type offset = static_cast<limb_type>(s / cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits);
+   limb_type shift  = static_cast<limb_type>(s % cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits);
 
    unsigned ors = result.size();
    if((ors == 1) && (!*result.limbs()))
       return; // shifting zero yields zero.
    unsigned rs = ors;
-   if(shift && (result.limbs()[rs - 1] >> (cpp_int_backend<MinBits, Signed, Allocator>::limb_bits - shift)))
+   if(shift && (result.limbs()[rs - 1] >> (cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits - shift)))
       ++rs; // Most significant limb will overflow when shifted
    rs += offset;
    result.resize(rs);
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer pr = result.limbs();
+   typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pr = result.limbs();
 
    unsigned i = 0;
    if(shift)
@@ -1901,20 +2256,20 @@
       i = 0;
       if(rs > ors + offset)
       {
-         pr[rs - 1 - i] = pr[ors - 1 - i] >> (cpp_int_backend<MinBits, Signed, Allocator>::limb_bits - shift);
+         pr[rs - 1 - i] = pr[ors - 1 - i] >> (cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits - shift);
          --rs;
       }
       else
       {
          pr[rs - 1 - i] = pr[ors - 1 - i] << shift;
          if(ors > 1)
-            pr[rs - 1 - i] |= pr[ors - 2 - i] >> (cpp_int_backend<MinBits, Signed, Allocator>::limb_bits - shift);
+            pr[rs - 1 - i] |= pr[ors - 2 - i] >> (cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits - shift);
          ++i;
       }
       for(; ors > 1 + i; ++i)
       {
          pr[rs - 1 - i] = pr[ors - 1 - i] << shift;
-         pr[rs - 1 - i] |= pr[ors - 2 - i] >> (cpp_int_backend<MinBits, Signed, Allocator>::limb_bits - shift);
+         pr[rs - 1 - i] |= pr[ors - 2 - i] >> (cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits - shift);
       }
       if(ors >= 1 + i)
       {
@@ -1933,13 +2288,13 @@
    }
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_right_shift(cpp_int_backend<MinBits, Signed, Allocator>& result, double_limb_type s) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_right_shift(cpp_int_backend<MinBits, Signed, Allocator, false>& result, double_limb_type s) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    if(!s)
       return;
 
-   limb_type offset = static_cast<limb_type>(s / cpp_int_backend<MinBits, Signed, Allocator>::limb_bits);
-   limb_type shift  = static_cast<limb_type>(s % cpp_int_backend<MinBits, Signed, Allocator>::limb_bits);
+   limb_type offset = static_cast<limb_type>(s / cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits);
+   limb_type shift  = static_cast<limb_type>(s % cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits);
    unsigned ors = result.size();
    unsigned rs = ors;
    if(offset >= rs)
@@ -1948,7 +2303,7 @@
       return;
    }
    rs -= offset;
-   typename cpp_int_backend<MinBits, Signed, Allocator>::limb_pointer pr = result.limbs();
+   typename cpp_int_backend<MinBits, Signed, Allocator, false>::limb_pointer pr = result.limbs();
    if((pr[ors - 1] >> shift) == 0)
       --rs;
    if(rs == 0)
@@ -1963,7 +2318,7 @@
       for(; i + offset + 1 < ors; ++i)
       {
          pr[i] = pr[i + offset] >> shift;
-         pr[i] |= pr[i + offset + 1] << (cpp_int_backend<MinBits, Signed, Allocator>::limb_bits - shift);
+         pr[i] |= pr[i + offset + 1] << (cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits - shift);
       }
       pr[i] = pr[i + offset] >> shift;
    }
@@ -1987,14 +2342,14 @@
 }
 
 template <class R, unsigned MinBits, bool Signed, class Allocator>
-inline typename enable_if<is_integral<R>, void>::type eval_convert_to(R* result, const cpp_int_backend<MinBits, Signed, Allocator>& backend) BOOST_NOEXCEPT
+inline typename enable_if<is_integral<R>, void>::type eval_convert_to(R* result, const cpp_int_backend<MinBits, Signed, Allocator, false>& backend) BOOST_NOEXCEPT
 {
    *result = static_cast<R>(backend.limbs()[0]);
-   unsigned shift = cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+   unsigned shift = cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
    for(unsigned i = 1; (i < backend.size()) && (shift < static_cast<unsigned>(std::numeric_limits<R>::digits)); ++i)
    {
       *result += static_cast<R>(backend.limbs()[i]) << shift;
-      shift += cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+      shift += cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
    }
    if(backend.sign())
    {
@@ -2003,32 +2358,32 @@
 }
 
 template <class R, unsigned MinBits, bool Signed, class Allocator>
-inline typename enable_if<is_floating_point<R>, void>::type eval_convert_to(R* result, const cpp_int_backend<MinBits, Signed, Allocator>& backend) BOOST_NOEXCEPT
+inline typename enable_if<is_floating_point<R>, void>::type eval_convert_to(R* result, const cpp_int_backend<MinBits, Signed, Allocator, false>& backend) BOOST_NOEXCEPT
 {
-   typename cpp_int_backend<MinBits, Signed, Allocator>::const_limb_pointer p = backend.limbs();
-   unsigned shift = cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+   typename cpp_int_backend<MinBits, Signed, Allocator, false>::const_limb_pointer p = backend.limbs();
+   unsigned shift = cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
    *result = static_cast<R>(*p);
    for(unsigned i = 1; i < backend.size(); ++i)
    {
       *result += static_cast<R>(std::ldexp(static_cast<long double>(p[i]), shift));
-      shift += cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+      shift += cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
    }
    if(backend.sign())
       *result = -*result;
 }
 
 template <unsigned MinBits, bool Signed, class Allocator>
-inline bool eval_is_zero(const cpp_int_backend<MinBits, Signed, Allocator>& val) BOOST_NOEXCEPT
+inline bool eval_is_zero(const cpp_int_backend<MinBits, Signed, Allocator, false>& val) BOOST_NOEXCEPT
 {
    return (val.size() == 1) && (val.limbs()[0] == 0);
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline int eval_get_sign(const cpp_int_backend<MinBits, Signed, Allocator>& val) BOOST_NOEXCEPT
+inline int eval_get_sign(const cpp_int_backend<MinBits, Signed, Allocator, false>& val) BOOST_NOEXCEPT
 {
    return eval_is_zero(val) ? 0 : val.sign() ? -1 : 1;
 }
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_abs(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_abs(cpp_int_backend<MinBits, Signed, Allocator, false>& result, const cpp_int_backend<MinBits, Signed, Allocator, false>& val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    result = val;
    result.sign(false);
@@ -2038,7 +2393,7 @@
 // Get the location of the least-significant-bit:
 //
 template <unsigned MinBits, bool Signed, class Allocator>
-inline unsigned eval_lsb(const cpp_int_backend<MinBits, Signed, Allocator>& a) BOOST_NOEXCEPT
+inline unsigned eval_lsb(const cpp_int_backend<MinBits, Signed, Allocator, false>& a) BOOST_NOEXCEPT
 {
    BOOST_ASSERT(eval_get_sign(a) != 0);
    
@@ -2059,15 +2414,15 @@
       ++result;
    }
 
-   return result + index * cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+   return result + index * cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
 }
 
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_gcd(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a, const cpp_int_backend<MinBits, Signed, Allocator>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_gcd(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)
 {
    int shift;
 
-   cpp_int_backend<MinBits, Signed, Allocator> u(a), v(b);
+   cpp_int_backend<MinBits, Signed, Allocator, false> u(a), v(b);
 
    int s = eval_get_sign(u);
 
@@ -2123,10 +2478,10 @@
 }
 
 template <unsigned MinBits, bool Signed, class Allocator>
-inline bool eval_bit_test(const cpp_int_backend<MinBits, Signed, Allocator>& val, unsigned index) BOOST_NOEXCEPT
+inline bool eval_bit_test(const cpp_int_backend<MinBits, Signed, Allocator, false>& val, unsigned index) BOOST_NOEXCEPT
 {
-   unsigned offset = index / cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
-   unsigned shift = index % cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+   unsigned offset = index / cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+   unsigned shift = index % cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
    limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u);
    if(offset >= val.size())
       return false;
@@ -2134,10 +2489,10 @@
 }
 
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_bit_set(cpp_int_backend<MinBits, Signed, Allocator>& val, unsigned index) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_bit_set(cpp_int_backend<MinBits, Signed, Allocator, false>& val, unsigned index) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
-   unsigned offset = index / cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
-   unsigned shift = index % cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+   unsigned offset = index / cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+   unsigned shift = index % cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
    limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u);
    if(offset >= val.size())
    {
@@ -2152,10 +2507,10 @@
 }
 
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_bit_unset(cpp_int_backend<MinBits, Signed, Allocator>& val, unsigned index) BOOST_NOEXCEPT
+inline void eval_bit_unset(cpp_int_backend<MinBits, Signed, Allocator, false>& val, unsigned index) BOOST_NOEXCEPT
 {
-   unsigned offset = index / cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
-   unsigned shift = index % cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+   unsigned offset = index / cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+   unsigned shift = index % cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
    limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u);
    if(offset >= val.size())
       return;
@@ -2164,10 +2519,10 @@
 }
 
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_bit_flip(cpp_int_backend<MinBits, Signed, Allocator>& val, unsigned index) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_bit_flip(cpp_int_backend<MinBits, Signed, Allocator, false>& val, unsigned index) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
-   unsigned offset = index / cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
-   unsigned shift = index % cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+   unsigned offset = index / cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
+   unsigned shift = index % cpp_int_backend<MinBits, Signed, Allocator, false>::limb_bits;
    limb_type mask = shift ? limb_type(1u) << shift : limb_type(1u);
    if(offset >= val.size())
    {
@@ -2183,9 +2538,9 @@
 }
 
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_lcm(cpp_int_backend<MinBits, Signed, Allocator>& result, const cpp_int_backend<MinBits, Signed, Allocator>& a, const cpp_int_backend<MinBits, Signed, Allocator>& b) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_lcm(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)
 {
-   cpp_int_backend<MinBits, Signed, Allocator> t;
+   cpp_int_backend<MinBits, Signed, Allocator, false> t;
    eval_gcd(t, a, b);
 
    if(eval_is_zero(t))
@@ -2202,8 +2557,8 @@
 }
 
 template <unsigned MinBits, bool Signed, class Allocator>
-inline void eval_qr(const cpp_int_backend<MinBits, Signed, Allocator>& x, const cpp_int_backend<MinBits, Signed, Allocator>& y, 
-   cpp_int_backend<MinBits, Signed, Allocator>& q, cpp_int_backend<MinBits, Signed, Allocator>& r) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline void eval_qr(const cpp_int_backend<MinBits, Signed, Allocator, false>& x, const cpp_int_backend<MinBits, Signed, Allocator, false>& y, 
+   cpp_int_backend<MinBits, Signed, Allocator, false>& q, cpp_int_backend<MinBits, Signed, Allocator, false>& r) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    divide_unsigned_helper(&q, x, y, r);
    q.sign(x.sign() != y.sign());
@@ -2211,12 +2566,12 @@
 }
 
 template <unsigned MinBits, bool Signed, class Allocator, class Integer>
-inline typename enable_if<is_unsigned<Integer>, Integer>::type eval_integer_modulus(const cpp_int_backend<MinBits, Signed, Allocator>& x, Integer val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline typename enable_if<is_unsigned<Integer>, Integer>::type eval_integer_modulus(const cpp_int_backend<MinBits, Signed, Allocator, false>& x, Integer val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    if((sizeof(Integer) <= sizeof(limb_type)) || (val <= (std::numeric_limits<limb_type>::max)()))
    {
-      cpp_int_backend<MinBits, Signed, Allocator> d;
-      divide_unsigned_helper(static_cast<cpp_int_backend<MinBits, Signed, Allocator>*>(0), x, val, d);
+      cpp_int_backend<MinBits, Signed, Allocator, false> d;
+      divide_unsigned_helper(static_cast<cpp_int_backend<MinBits, Signed, Allocator, false>*>(0), x, val, d);
       return d.limbs()[0];
    }
    else
@@ -2225,7 +2580,7 @@
    }
 }
 template <unsigned MinBits, bool Signed, class Allocator, class Integer>
-inline typename enable_if<is_signed<Integer>, Integer>::type eval_integer_modulus(const cpp_int_backend<MinBits, Signed, Allocator>& x, Integer val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
+inline typename enable_if<is_signed<Integer>, Integer>::type eval_integer_modulus(const cpp_int_backend<MinBits, Signed, Allocator, false>& x, Integer val) BOOST_NOEXCEPT_IF(boost::is_void<Allocator>::value)
 {
    typedef typename make_unsigned<Integer>::type unsigned_type;
    return eval_integer_modulus(x, static_cast<unsigned_type>(std::abs(val)));
@@ -2235,8 +2590,8 @@
 
 using boost::multiprecision::backends::cpp_int_backend;
 
-template <unsigned MinBits, bool Signed, class Allocator>
-struct number_category<cpp_int_backend<MinBits, Signed, Allocator> > : public mpl::int_<number_kind_integer>{};
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial>
+struct number_category<cpp_int_backend<MinBits, Signed, Allocator, trivial> > : public mpl::int_<number_kind_integer>{};
 
 typedef mp_number<cpp_int_backend<> >          cpp_int;
 typedef rational_adapter<cpp_int_backend<> >   cpp_rational_backend;
@@ -2260,13 +2615,15 @@
 
 }} // namespaces
 
+#include <boost/multiprecision/detail/cpp_int_trivial_ops.hpp>
+
 
 namespace std{
 
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-class numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+class numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >
 {
-   typedef boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> number_type;
+   typedef boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> number_type;
 
 public:
    BOOST_STATIC_CONSTEXPR bool is_specialized = true;
@@ -2315,57 +2672,57 @@
 
 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
 
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::digits;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::digits10;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::max_digits10;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::is_signed;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::is_integer;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::is_exact;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::radix;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::min_exponent;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::min_exponent10;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::max_exponent;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::max_exponent10;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::has_infinity;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::has_quiet_NaN;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::has_signaling_NaN;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::has_denorm;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::has_denorm_loss;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::is_iec559;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::is_bounded;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::is_modulo;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::traps;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::tinyness_before;
-template <unsigned MinBits, bool Signed, class Allocator, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator>, ExpressionTemplates> >::round_style;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::digits;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::digits10;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::max_digits10;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::is_signed;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::is_integer;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::is_exact;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::radix;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::min_exponent;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::min_exponent10;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::max_exponent;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::max_exponent10;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::has_infinity;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::has_quiet_NaN;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::has_signaling_NaN;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::has_denorm;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::has_denorm_loss;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::is_iec559;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::is_bounded;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::is_modulo;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::traps;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::tinyness_before;
+template <unsigned MinBits, bool Signed, class Allocator, bool trivial, bool ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, Signed, Allocator, trivial>, ExpressionTemplates> >::round_style;
 
 #endif
 
-template <unsigned MinBits, bool ExpressionTemplates>
-class numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates> >
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+class numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >
 {
-   typedef boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates> number_type;
+   typedef boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> number_type;
 
    struct inititializer
    {
@@ -2439,62 +2796,62 @@
    BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
 };
 
-template <unsigned MinBits, bool ExpressionTemplates>
-const typename numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates> >::inititializer numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates> >::init;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+const typename numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::inititializer numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates> >::init;
 
 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
 
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::digits;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::digits10;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::max_digits10;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::is_signed;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::is_integer;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::is_exact;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::radix;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::min_exponent;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::min_exponent10;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::max_exponent;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::max_exponent10;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::has_infinity;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::has_quiet_NaN;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::has_signaling_NaN;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::has_denorm;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::has_denorm_loss;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::is_iec559;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::is_bounded;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::is_modulo;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::traps;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::tinyness_before;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void>, ExpressionTemplates>  >::round_style;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::digits;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::digits10;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::max_digits10;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::is_signed;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::is_integer;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::is_exact;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::radix;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::min_exponent;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::min_exponent10;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::max_exponent;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::max_exponent10;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::has_infinity;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::has_quiet_NaN;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::has_signaling_NaN;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::has_denorm;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::has_denorm_loss;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::is_iec559;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::is_bounded;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::is_modulo;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::traps;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::tinyness_before;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, true, void, trivial>, ExpressionTemplates>  >::round_style;
 
 #endif
 
-template <unsigned MinBits, bool ExpressionTemplates>
-class numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+class numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >
 {
-   typedef boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> number_type;
+   typedef boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> number_type;
 
    struct inititializer
    {
@@ -2567,55 +2924,55 @@
    BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
 };
 
-template <unsigned MinBits, bool ExpressionTemplates>
-const typename numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::inititializer numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::init;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+const typename numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::inititializer numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::init;
 
 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
 
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::digits;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::digits10;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::max_digits10;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::is_signed;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::is_integer;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::is_exact;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::radix;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::min_exponent;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::min_exponent10;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::max_exponent;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::max_exponent10;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::has_infinity;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::has_quiet_NaN;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::has_signaling_NaN;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::has_denorm;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::has_denorm_loss;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::is_iec559;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::is_bounded;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::is_modulo;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::traps;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::tinyness_before;
-template <unsigned MinBits, bool ExpressionTemplates>
-BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void>, ExpressionTemplates> >::round_style;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::digits;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::digits10;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::max_digits10;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::is_signed;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::is_integer;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::is_exact;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::radix;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::min_exponent;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::min_exponent10;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::max_exponent;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::max_exponent10;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::has_infinity;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::has_quiet_NaN;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::has_signaling_NaN;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::has_denorm;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::has_denorm_loss;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::is_iec559;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::is_bounded;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::is_modulo;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::traps;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::tinyness_before;
+template <unsigned MinBits, bool ExpressionTemplates, bool trivial>
+BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<MinBits, false, void, trivial>, ExpressionTemplates> >::round_style;
 
 #endif
 
Modified: sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp	2012-07-23 04:57:44 EDT (Mon, 23 Jul 2012)
@@ -6,13 +6,63 @@
 #ifndef BOOST_MP_CPP_INT_CORE_HPP
 #define BOOST_MP_CPP_INT_CORE_HPP
 
+#include <boost/integer.hpp>
+
 namespace boost{ namespace multiprecision{
 
+namespace detail{
+
+//
+// These traits calculate the largest type in the list
+// [unsigned] ong long, long, int, which has the specified number
+// of bits.  Note that intN_t and boost::int_t<N> find the first
+// member of the above list, not the last.  We want the last in the 
+// list to ensure that mixed arithmetic operations are as efficient 
+// as possible.
+//
+template <unsigned N>
+struct largest_signed_type
+{
+   typedef typename mpl::if_c<
+      1 + std::numeric_limits<long long>::digits == N,
+      long long,
+      typename mpl::if_c<
+         1 + std::numeric_limits<long>::digits == N,
+         long,
+         typename mpl::if_c<
+            1 + std::numeric_limits<int>::digits == N,
+            int,
+            typename boost::int_t<N>::exact
+         >::type
+      >::type
+   >::type type;
+};
+
+template <unsigned N>
+struct largest_unsigned_type
+{
+   typedef typename mpl::if_c<
+      std::numeric_limits<unsigned long long>::digits == N,
+      unsigned long long,
+      typename mpl::if_c<
+         std::numeric_limits<unsigned long>::digits == N,
+         unsigned long,
+         typename mpl::if_c<
+            std::numeric_limits<unsigned int>::digits == N,
+            unsigned int,
+            typename boost::uint_t<N>::exact
+         >::type
+      >::type
+   >::type type;
+};
+
+}
+
 #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))) \
    && !defined(BOOST_INTEL) && defined(__WORDSIZE) && (__WORDSIZE == 64)
 
-typedef boost::uint64_t limb_type;
-typedef boost::int64_t signed_limb_type;
+typedef detail::largest_unsigned_type<64>::type limb_type;
+typedef detail::largest_signed_type<64>::type signed_limb_type;
 typedef unsigned __int128 double_limb_type;
 typedef __int128 signed_double_limb_type;
 static const limb_type max_block_10 = 1000000000000000000uLL;
@@ -28,8 +78,8 @@
 
 #else
 
-typedef boost::uint32_t limb_type;
-typedef boost::int32_t signed_limb_type;
+typedef detail::largest_unsigned_type<32>::type limb_type;
+typedef detail::largest_signed_type<32>::type signed_limb_type;
 typedef boost::uint64_t double_limb_type;
 typedef boost::int64_t signed_double_limb_type;
 static const limb_type max_block_10 = 1000000000;
Added: sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp	2012-07-23 04:57:44 EDT (Mon, 23 Jul 2012)
@@ -0,0 +1,284 @@
+///////////////////////////////////////////////////////////////
+//  Copyright 2012 John Maddock. Distributed under the Boost
+//  Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
+
+#ifndef BOOST_MP_CPP_INT_TRIVIAL_OPS_HPP
+#define BOOST_MP_CPP_INT_TRIVIAL_OPS_HPP
+
+#include <boost/math/common_factor_rt.hpp>
+
+namespace boost{ namespace multiprecision{ namespace backends{
+
+template <unsigned MinBits>
+inline void eval_add(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+{
+   if(result.sign() != o.sign())
+   {
+      if(*o.limbs() > *result.limbs())
+      {
+         *result.limbs() = *o.limbs() - *result.limbs();
+         result.negate();
+      }
+      else
+         *result.limbs() -= *o.limbs();
+   }
+   else
+      *result.limbs() += *o.limbs();
+}
+
+template <unsigned MinBits>
+inline void eval_add(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+{
+   *result.limbs() += *o.limbs();
+}
+
+template <unsigned MinBits>
+inline void eval_subtract(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+{
+   if(result.sign() != o.sign())
+   {
+      *result.limbs() += *o.limbs();
+   }
+   else if(*result.limbs() < *o.limbs())
+   {
+      *result.limbs() = *o.limbs() - *result.limbs();
+      result.negate();
+   }
+   else
+      *result.limbs() -= *o.limbs();
+}
+
+template <unsigned MinBits>
+inline void eval_subtract(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+{
+   *result.limbs() -= *o.limbs();
+}
+
+template <unsigned MinBits>
+inline void eval_multiply(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+{
+   *result.limbs() *= *o.limbs();
+   result.sign(result.sign() != o.sign());
+}
+
+template <unsigned MinBits>
+inline void eval_multiply(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+{
+   *result.limbs() *= *o.limbs();
+}
+
+template <unsigned MinBits>
+inline void eval_divide(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o)
+{
+   if(!*o.limbs())
+      BOOST_THROW_EXCEPTION(std::runtime_error("Division by zero."));
+   *result.limbs() /= *o.limbs();
+   result.sign(result.sign() != o.sign());
+}
+
+template <unsigned MinBits>
+inline void eval_divide(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o)
+{
+   if(!*o.limbs())
+      BOOST_THROW_EXCEPTION(std::runtime_error("Division by zero."));
+   *result.limbs() /= *o.limbs();
+}
+
+template <unsigned MinBits, bool Signed>
+inline void eval_modulus(cpp_int_backend<MinBits, Signed, void, true>& result, const cpp_int_backend<MinBits, Signed, void, true>& o)
+{
+   if(!*o.limbs())
+      BOOST_THROW_EXCEPTION(std::runtime_error("Division by zero."));
+   *result.limbs() %= *o.limbs();
+   result.sign(result.sign());
+}
+
+template <unsigned MinBits, bool Signed, class T>
+inline void eval_left_shift(cpp_int_backend<MinBits, Signed, void, true>& result, T s) BOOST_NOEXCEPT
+{
+   *result.limbs() <<= s;
+}
+
+template <unsigned MinBits, bool Signed, class T>
+inline void eval_right_shift(cpp_int_backend<MinBits, Signed, void, true>& result, T s) BOOST_NOEXCEPT
+{
+   *result.limbs() >>= s;
+}
+
+template <unsigned MinBits>
+inline void eval_bitwise_and(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+{
+   typename cpp_int_backend<MinBits, true, void, true>::local_limb_type a, b;
+   a = *result.limbs();
+   if(result.isneg())
+   {
+      a = ~a;
+      ++a;
+   }
+   b = *o.limbs();
+   if(o.isneg())
+   {
+      b = ~b;
+      ++b;
+   }
+   a &= b;
+   bool isneg = false;
+   static const typename cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (std::numeric_limits<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>::digits - 1);
+   if(a & mask)
+   {
+      a = ~a;
+      ++a;
+      isneg = true;
+   }
+   *result.limbs() = a;
+   result.sign(isneg);
+}
+
+template <unsigned MinBits>
+inline void eval_bitwise_and(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+{
+   *result.limbs() &= *o.limbs();
+}
+
+template <unsigned MinBits>
+inline void eval_bitwise_or(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+{
+   typename cpp_int_backend<MinBits, true, void, true>::local_limb_type a, b;
+   a = *result.limbs();
+   if(result.isneg())
+   {
+      a = ~a;
+      ++a;
+   }
+   b = *o.limbs();
+   if(o.isneg())
+   {
+      b = ~b;
+      ++b;
+   }
+   a |= b;
+   bool isneg = false;
+   static const typename cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (std::numeric_limits<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>::digits - 1);
+   if(a & mask)
+   {
+      a = ~a;
+      ++a;
+      isneg = true;
+   }
+   *result.limbs() = a;
+   result.sign(isneg);
+}
+
+template <unsigned MinBits>
+inline void eval_bitwise_or(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+{
+   *result.limbs() |= *o.limbs();
+}
+
+template <unsigned MinBits>
+inline void eval_bitwise_xor(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+{
+   typename cpp_int_backend<MinBits, true, void, true>::local_limb_type a, b;
+   a = *result.limbs();
+   if(result.isneg())
+   {
+      a = ~a;
+      ++a;
+   }
+   b = *o.limbs();
+   if(o.isneg())
+   {
+      b = ~b;
+      ++b;
+   }
+   a ^= b;
+   bool isneg = false;
+   static const typename cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (std::numeric_limits<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>::digits - 1);
+   if(a & mask)
+   {
+      a = ~a;
+      ++a;
+      isneg = true;
+   }
+   *result.limbs() = a;
+   result.sign(isneg);
+}
+
+template <unsigned MinBits>
+inline void eval_bitwise_xor(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+{
+   *result.limbs() ^= *o.limbs();
+}
+
+template <unsigned MinBits>
+inline void eval_complement(cpp_int_backend<MinBits, true, void, true>& result, const cpp_int_backend<MinBits, true, void, true>& o) BOOST_NOEXCEPT
+{
+   typename cpp_int_backend<MinBits, true, void, true>::local_limb_type a;
+   a = *o.limbs();
+   if(o.isneg())
+   {
+      a = ~a;
+      ++a;
+   }
+   a = ~a;
+   bool isneg = false;
+   static const typename cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (std::numeric_limits<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>::digits - 1);
+   if(a & mask)
+   {
+      a = ~a;
+      ++a;
+      isneg = true;
+   }
+   *result.limbs() = a;
+   result.sign(isneg);
+}
+
+template <unsigned MinBits>
+inline void eval_complement(cpp_int_backend<MinBits, false, void, true>& result, const cpp_int_backend<MinBits, false, void, true>& o) BOOST_NOEXCEPT
+{
+   *result.limbs() = ~*o.limbs();
+}
+
+template <unsigned MinBits, bool Signed>
+inline void eval_gcd(cpp_int_backend<MinBits, Signed, void, true>& result, const cpp_int_backend<MinBits, Signed, void, true>& a, const cpp_int_backend<MinBits, Signed, void, true>& b) BOOST_NOEXCEPT
+{
+   *result.limbs() = boost::math::gcd(*a.limbs(), *b.limbs());
+}
+
+template <unsigned MinBits, bool Signed>
+inline void eval_lcm(cpp_int_backend<MinBits, Signed, void, true>& result, const cpp_int_backend<MinBits, Signed, void, true>& a, const cpp_int_backend<MinBits, Signed, void, true>& b) BOOST_NOEXCEPT
+{
+   *result.limbs() = boost::math::lcm(*a.limbs(), *b.limbs());
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127 4018)
+#endif
+template <class R, unsigned MinBits>
+inline void eval_convert_to(R* result, const cpp_int_backend<MinBits, true, void, true>& val)
+{
+   if(std::numeric_limits<R>::is_specialized && (*val.limbs() > (std::numeric_limits<R>::max)()))
+      *result = (std::numeric_limits<R>::max)();
+   else
+      *result = static_cast<R>(*val.limbs());
+   if(val.isneg())
+      *result = negate_integer(*result, mpl::bool_<boost::is_signed<R>::value || boost::is_floating_point<R>::value>());
+}
+
+template <class R, unsigned MinBits>
+inline void eval_convert_to(R* result, const cpp_int_backend<MinBits, false, void, true>& val)
+{
+   if(std::numeric_limits<R>::is_specialized && (*val.limbs() > (std::numeric_limits<R>::max)()))
+      *result = (std::numeric_limits<R>::max)();
+   else
+      *result = static_cast<R>(*val.limbs());
+}
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+}}} // namespaces
+
+#endif
Modified: sandbox/big_number/boost/multiprecision/gmp.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/gmp.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/gmp.hpp	2012-07-23 04:57:44 EDT (Mon, 23 Jul 2012)
@@ -391,10 +391,6 @@
    {
       mpf_init2(this->m_data, ((get_default_precision() + 1) * 1000L) / 301L);
    }
-   gmp_float(unsigned digits10)
-   {
-      mpf_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
-   }
    gmp_float(mpf_t val)
    {
       mpf_init2(this->m_data, ((get_default_precision() + 1) * 1000L) / 301L);
Modified: sandbox/big_number/boost/multiprecision/mp_number.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/mp_number.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/mp_number.hpp	2012-07-23 04:57:44 EDT (Mon, 23 Jul 2012)
@@ -38,13 +38,20 @@
 public:
    typedef Backend backend_type;
    BOOST_CONSTEXPR mp_number() BOOST_NOEXCEPT_IF(noexcept(Backend())) {}
-   mp_number(const mp_number& e) BOOST_NOEXCEPT_IF(noexcept(Backend(static_cast<const Backend&>(std::declval<Backend>())))) : m_backend(e.m_backend){}
+   BOOST_CONSTEXPR mp_number(const mp_number& e) BOOST_NOEXCEPT_IF(noexcept(Backend(static_cast<const Backend&>(std::declval<Backend>())))) : m_backend(e.m_backend){}
    template <class V>
-   mp_number(V v, typename enable_if<mpl::or_<boost::is_arithmetic<V>, is_same<std::string, V>, is_convertible<V, const char*> > >::type* = 0)
+   mp_number(V v, typename enable_if_c<
+         (boost::is_arithmetic<V>::value || is_same<std::string, V>::value || is_convertible<V, const char*>::value) 
+         && !is_convertible<typename detail::canonical<V, Backend>::type, Backend>::value >::type* = 0)
    {
       m_backend = canonical_value(v);
    }
-   mp_number(const mp_number& e, unsigned digits10)
+   template <class V>
+   BOOST_CONSTEXPR mp_number(V v, typename enable_if_c<
+         (boost::is_arithmetic<V>::value || is_same<std::string, V>::value || is_convertible<V, const char*>::value) 
+         && is_convertible<typename detail::canonical<V, Backend>::type, Backend>::value >::type* = 0) 
+      : m_backend(canonical_value(v)) {}
+   BOOST_CONSTEXPR mp_number(const mp_number& e, unsigned digits10)
       : m_backend(e.m_backend, digits10){}
    /*
    //
@@ -59,7 +66,7 @@
    }
    */
    template<bool ET>
-   mp_number(const mp_number<Backend, ET>& val) BOOST_NOEXCEPT_IF(noexcept(Backend(static_cast<const Backend&>(std::declval<Backend>())))) : m_backend(val.m_backend) {}
+   BOOST_CONSTEXPR mp_number(const mp_number<Backend, ET>& val) BOOST_NOEXCEPT_IF(noexcept(Backend(static_cast<const Backend&>(std::declval<Backend>())))) : m_backend(val.m_backend) {}
 
    template <class Other, bool ET>
    mp_number(const mp_number<Other, ET>& val, typename enable_if<boost::is_convertible<Other, Backend> >::type* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval<Backend>() = std::declval<Other>()))
@@ -88,7 +95,7 @@
    }
 
    template <class V>
-   mp_number(V v, typename enable_if<mpl::and_<is_convertible<V, Backend>, mpl::not_<mpl::or_<boost::is_arithmetic<V>, is_same<std::string, V>, is_convertible<V, const char*> > > > >::type* = 0)
+   BOOST_CONSTEXPR mp_number(V v, typename enable_if<mpl::and_<is_convertible<V, Backend>, mpl::not_<mpl::or_<boost::is_arithmetic<V>, is_same<std::string, V>, is_convertible<V, const char*> > > > >::type* = 0)
       BOOST_NOEXCEPT_IF(noexcept(Backend(static_cast<const V&>(std::declval<V>()))))
       : m_backend(v){}
 
@@ -155,7 +162,7 @@
    }
 
 #ifndef BOOST_NO_RVALUE_REFERENCES
-   mp_number(mp_number&& r) BOOST_NOEXCEPT : m_backend(static_cast<Backend&&>(r.m_backend)){}
+   BOOST_CONSTEXPR mp_number(mp_number&& r) BOOST_NOEXCEPT : m_backend(static_cast<Backend&&>(r.m_backend)){}
    mp_number& operator=(mp_number&& r) BOOST_NOEXCEPT 
    {
       m_backend.swap(r.m_backend);
Modified: sandbox/big_number/boost/multiprecision/mpfr.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/mpfr.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/mpfr.hpp	2012-07-23 04:57:44 EDT (Mon, 23 Jul 2012)
@@ -402,10 +402,6 @@
    {
       mpfr_init2(this->m_data, ((get_default_precision() + 1) * 1000L) / 301L);
    }
-   mpfr_float_backend(unsigned digits10)
-   {
-      mpfr_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
-   }
    mpfr_float_backend(mpfr_t val)
    {
       mpfr_init2(this->m_data, ((get_default_precision() + 1) * 1000L) / 301L);
Modified: sandbox/big_number/libs/multiprecision/doc/multiprecision.qbk
==============================================================================
--- sandbox/big_number/libs/multiprecision/doc/multiprecision.qbk	(original)
+++ sandbox/big_number/libs/multiprecision/doc/multiprecision.qbk	2012-07-23 04:57:44 EDT (Mon, 23 Jul 2012)
@@ -119,6 +119,8 @@
 
 [h4 Expression Templates]
 
+TODO: compare to rvalue refs.
+
 Class `mp_number` is expression-template-enabled: that means that rather than having a multiplication
 operator that looks like this:
 
@@ -246,6 +248,8 @@
 again, all are using [mpfr] to carry out the underlying arithmetic, and all are operating at the same precision
 (50 decimal digits):
 
+TODO: Update, compare to rvalue refs but no ET's as well.
+
 [table Evaluation of Boost.Math's Bessel function test data
 [[Library][Relative Time][Relative Number of Memory Allocations]]
 [[mp_number][1.0 (6.21s)][1.0 (2685469)]]
@@ -1696,6 +1700,8 @@
 compulsory requirements, and optional requirements that are either to improve performance
 or provide optional features.
 
+TODO: Add optional construction support, add throws specification, clarify what compulsory means.
+
 In the following tables, type B is the `Backend` template arument to `mp_number`, `b` and `b2` are
 a variables of type B, `cb` and `cb2` are constant variables of type B, `a` is a variable of Arithmetic type, 
 `s` is a variable of type `const char*`, `ui` is a variable of type `unsigned`, `bb` is a variable of type `bool`,
Modified: sandbox/big_number/libs/multiprecision/performance/performance_test.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/performance/performance_test.cpp	(original)
+++ sandbox/big_number/libs/multiprecision/performance/performance_test.cpp	2012-07-23 04:57:44 EDT (Mon, 23 Jul 2012)
@@ -84,6 +84,13 @@
 
 unsigned bits_wanted; // for integer types
 
+namespace boost{ namespace multiprecision{
+
+template<>
+class number_category<boost::int64_t> : public mpl::int_<number_kind_integer>{};
+
+}}
+
 template <class T, int Type>
 struct tester
 {
@@ -177,13 +184,24 @@
       }
       return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
    }
-   double test_str()
+   double test_str(const boost::mpl::false_&)
+   {
+      stopwatch<boost::chrono::high_resolution_clock> w;
+      for(unsigned i = 0; i < b.size(); ++i)
+         a[i] = boost::lexical_cast<T>(boost::lexical_cast<std::string>(b[i]));
+      return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
+   }
+   double test_str(const boost::mpl::true_&)
    {
       stopwatch<boost::chrono::high_resolution_clock> w;
       for(unsigned i = 0; i < b.size(); ++i)
          a[i] = b[i].str();
       return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
    }
+   double test_str()
+   {
+      return test_str(boost::is_class<T>());
+   }
    //
    // The following tests only work for integer types:
    //
@@ -303,6 +321,7 @@
    }
    double test_gcd()
    {
+      using boost::math::gcd;
       stopwatch<boost::chrono::high_resolution_clock> w;
       for(unsigned i = 0; i < 1000; ++i)
       {
@@ -311,6 +330,54 @@
       }
       return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
    }
+   double test_construct()
+   {
+      std::allocator<T> a;
+      T* pt = a.allocate(1000);
+      stopwatch<boost::chrono::high_resolution_clock> w;
+      for(unsigned i = 0; i < 1000; ++i)
+      {
+         for(unsigned i = 0; i < 1000; ++i)
+            new(pt+i) T();
+         for(unsigned i = 0; i < 1000; ++i)
+            a.destroy(pt+i);
+      }
+      double result = boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
+      a.deallocate(pt, 1000);
+      return result;
+   }
+   double test_construct_unsigned()
+   {
+      std::allocator<T> a;
+      T* pt = a.allocate(1000);
+      stopwatch<boost::chrono::high_resolution_clock> w;
+      for(unsigned i = 0; i < 1000; ++i)
+      {
+         for(unsigned i = 0; i < 1000; ++i)
+            new(pt+i) T(i);
+         for(unsigned i = 0; i < 1000; ++i)
+            a.destroy(pt+i);
+      }
+      double result = boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
+      a.deallocate(pt, 1000);
+      return result;
+   }
+   double test_construct_unsigned_ll()
+   {
+      std::allocator<T> a;
+      T* pt = a.allocate(1000);
+      stopwatch<boost::chrono::high_resolution_clock> w;
+      for(unsigned i = 0; i < 1000; ++i)
+      {
+         for(unsigned long long j = 0; j < 1000; ++j)
+            new(pt+j) T(j);
+         for(unsigned j = 0; j < 1000; ++j)
+            a.destroy(pt+j);
+      }
+      double result = boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
+      a.deallocate(pt, 1000);
+      return result;
+   }
 private:
    T generate_random()
    {
@@ -489,6 +556,10 @@
    report_result(cat, type, "-(int)", precision, t.test_subtract_int());
    report_result(cat, type, "*(int)", precision, t.test_multiply_int());
    report_result(cat, type, "/(int)", precision, t.test_divide_int());
+   // construction and destruction:
+   report_result(cat, type, "construct", precision, t.test_construct());
+   report_result(cat, type, "construct(unsigned)", precision, t.test_construct_unsigned());
+   report_result(cat, type, "construct(unsigned long long)", precision, t.test_construct_unsigned_ll());
    test_int_ops(t, type, precision, typename boost::multiprecision::number_category<Number>::type());
 }
 
@@ -566,6 +637,9 @@
 
 int main()
 {
+#ifdef TEST_INT64
+   test<boost::int64_t>("boost::int64_t", 64);
+#endif
 #ifdef TEST_MPF
    test<boost::multiprecision::mpf_float_50>("gmp_float", 50);
    test<boost::multiprecision::mpf_float_100>("gmp_float", 100);
@@ -578,15 +652,16 @@
    test<boost::multiprecision::mpz_int>("gmp_int", 1024);
 #endif
 #ifdef TEST_CPP_INT
+   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<64, true, void>, false > >("cpp_int(fixed)", 64);
+   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<128, true, void>, false > >("cpp_int(fixed)", 128);
+   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<256, true, void>, false > >("cpp_int(fixed)", 256);
+   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<512, true, void>, false > >("cpp_int(fixed)", 512);
+   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<1024, true, void>, false > >("cpp_int(fixed)", 1024);
+
    test<boost::multiprecision::cpp_int>("cpp_int", 128);
    test<boost::multiprecision::cpp_int>("cpp_int", 256);
    test<boost::multiprecision::cpp_int>("cpp_int", 512);
    test<boost::multiprecision::cpp_int>("cpp_int", 1024);
-
-   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<128, true, void> > >("cpp_int(fixed)", 128);
-   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<256, true, void> > >("cpp_int(fixed)", 256);
-   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<512, true, void> > >("cpp_int(fixed)", 512);
-   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<1024, true, void> > >("cpp_int(fixed)", 1024);
 #endif
 #ifdef TEST_CPP_INT_RATIONAL
    test<boost::multiprecision::cpp_rational>("cpp_rational", 128);
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-07-23 04:57:44 EDT (Mon, 23 Jul 2012)
@@ -1171,6 +1171,10 @@
    test<boost::multiprecision::cpp_rational>();
    test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<>, false> >();
    test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<500, true, void> > >();
+
+   // Again with "trivial" backends:
+   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<64, true, void>, false > >();
+   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<64, false, void>, false > >();
 #endif
 #ifdef TEST_CPP_INT_BR
    test<boost::multiprecision::cpp_rational>();