Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r79913 - in sandbox/big_number: boost/multiprecision libs/multiprecision/test
From: john_at_[hidden]
Date: 2012-08-07 13:55:32


Author: johnmaddock
Date: 2012-08-07 13:55:32 EDT (Tue, 07 Aug 2012)
New Revision: 79913
URL: http://svn.boost.org/trac/boost/changeset/79913

Log:
Add better error checking for moved-from types.
Text files modified:
   sandbox/big_number/boost/multiprecision/gmp.hpp | 180 ++++++++++++++++++++++++++++++++++-----
   sandbox/big_number/boost/multiprecision/mp_number.hpp | 3
   sandbox/big_number/boost/multiprecision/mpfr.hpp | 44 ++++++++
   sandbox/big_number/boost/multiprecision/tommath.hpp | 36 ++++++-
   sandbox/big_number/libs/multiprecision/test/test_move.cpp | 52 +++++++++++
   5 files changed, 279 insertions(+), 36 deletions(-)

Modified: sandbox/big_number/boost/multiprecision/gmp.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/gmp.hpp (original)
+++ sandbox/big_number/boost/multiprecision/gmp.hpp 2012-08-07 13:55:32 EDT (Tue, 07 Aug 2012)
@@ -56,7 +56,8 @@
       // things go badly wrong!!
       //
       mpf_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
- mpf_set(m_data, o.m_data);
+ if(o.m_data[0]._mp_d)
+ mpf_set(m_data, o.m_data);
    }
 #ifndef BOOST_NO_RVALUE_REFERENCES
    gmp_float_imp(gmp_float_imp&& o) BOOST_NOEXCEPT
@@ -67,7 +68,10 @@
 #endif
    gmp_float_imp& operator = (const gmp_float_imp& o)
    {
- mpf_set(m_data, o.m_data);
+ if(m_data[0]._mp_d == 0)
+ mpf_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
+ if(o.m_data[0]._mp_d)
+ mpf_set(m_data, o.m_data);
       return *this;
    }
 #ifndef BOOST_NO_RVALUE_REFERENCES
@@ -79,6 +83,8 @@
 #endif
    gmp_float_imp& operator = (unsigned long long i)
    {
+ if(m_data[0]._mp_d == 0)
+ mpf_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
       unsigned shift = 0;
       mpf_t t;
@@ -99,6 +105,8 @@
    gmp_float_imp& operator = (long long i)
    {
       BOOST_MP_USING_ABS
+ if(m_data[0]._mp_d == 0)
+ mpf_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       bool neg = i < 0;
       *this = static_cast<unsigned long long>(abs(i));
       if(neg)
@@ -107,16 +115,22 @@
    }
    gmp_float_imp& operator = (unsigned long i) BOOST_NOEXCEPT
    {
+ if(m_data[0]._mp_d == 0)
+ mpf_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       mpf_set_ui(m_data, i);
       return *this;
    }
    gmp_float_imp& operator = (long i) BOOST_NOEXCEPT
    {
+ if(m_data[0]._mp_d == 0)
+ mpf_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       mpf_set_si(m_data, i);
       return *this;
    }
    gmp_float_imp& operator = (double d) BOOST_NOEXCEPT
    {
+ if(m_data[0]._mp_d == 0)
+ mpf_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       mpf_set_d(m_data, d);
       return *this;
    }
@@ -126,6 +140,9 @@
       using std::ldexp;
       using std::floor;
 
+ if(m_data[0]._mp_d == 0)
+ mpf_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
+
       if (a == 0) {
          mpf_set_si(m_data, 0);
          return *this;
@@ -168,6 +185,8 @@
    }
    gmp_float_imp& operator = (const char* s)
    {
+ if(m_data[0]._mp_d == 0)
+ mpf_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       if(0 != mpf_set_str(m_data, s, 10))
          BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid floating point number.")));
       return *this;
@@ -178,6 +197,8 @@
    }
    std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
    {
+ BOOST_ASSERT(m_data[0]._mp_d);
+
       bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
       bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
       std::streamsize org_digits(digits);
@@ -278,18 +299,22 @@
    }
    void negate() BOOST_NOEXCEPT
    {
+ BOOST_ASSERT(m_data[0]._mp_d);
       mpf_neg(m_data, m_data);
    }
    int compare(const gmp_float<digits10>& o)const BOOST_NOEXCEPT
    {
+ BOOST_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d);
       return mpf_cmp(m_data, o.m_data);
    }
    int compare(long i)const BOOST_NOEXCEPT
    {
+ BOOST_ASSERT(m_data[0]._mp_d);
       return mpf_cmp_si(m_data, i);
    }
    int compare(unsigned long i)const BOOST_NOEXCEPT
    {
+ BOOST_ASSERT(m_data[0]._mp_d);
       return mpf_cmp_ui(m_data, i);
    }
    template <class V>
@@ -299,8 +324,16 @@
       d = v;
       return compare(d);
    }
- mpf_t& data() BOOST_NOEXCEPT { return m_data; }
- const mpf_t& data()const BOOST_NOEXCEPT { return m_data; }
+ mpf_t& data() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(m_data[0]._mp_d);
+ return m_data;
+ }
+ const mpf_t& data()const BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(m_data[0]._mp_d);
+ return m_data;
+ }
 protected:
    mpf_t m_data;
    static unsigned& get_default_precision() BOOST_NOEXCEPT
@@ -363,16 +396,22 @@
    gmp_float& operator=(const gmp_rational& o);
    gmp_float& operator=(const mpf_t& val) BOOST_NOEXCEPT
    {
+ if(this->m_data[0]._mp_d == 0)
+ mpf_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
       mpf_set(this->m_data, val);
       return *this;
    }
    gmp_float& operator=(const mpz_t& val) BOOST_NOEXCEPT
    {
+ if(this->m_data[0]._mp_d == 0)
+ mpf_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
       mpf_set_z(this->m_data, val);
       return *this;
    }
    gmp_float& operator=(const mpq_t& val) BOOST_NOEXCEPT
    {
+ if(this->m_data[0]._mp_d == 0)
+ mpf_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
       mpf_set_q(this->m_data, val);
       return *this;
    }
@@ -439,6 +478,8 @@
    template <unsigned D>
    gmp_float& operator=(const gmp_float<D>& o)
    {
+ if(this->m_data[0]._mp_d == 0)
+ mpf_init2(this->m_data, ((get_default_precision() + 1) * 1000L) / 301L);
       mpf_set(this->m_data, o.data());
       return *this;
    }
@@ -446,16 +487,22 @@
    gmp_float& operator=(const gmp_rational& o);
    gmp_float& operator=(const mpf_t& val)
    {
+ if(this->m_data[0]._mp_d == 0)
+ mpf_init2(this->m_data, ((get_default_precision() + 1) * 1000L) / 301L);
       mpf_set(this->m_data, val);
       return *this;
    }
    gmp_float& operator=(const mpz_t& val)
    {
+ if(this->m_data[0]._mp_d == 0)
+ mpf_init2(this->m_data, ((get_default_precision() + 1) * 1000L) / 301L);
       mpf_set_z(this->m_data, val);
       return *this;
    }
    gmp_float& operator=(const mpq_t& val)
    {
+ if(this->m_data[0]._mp_d == 0)
+ mpf_init2(this->m_data, ((get_default_precision() + 1) * 1000L) / 301L);
       mpf_set_q(this->m_data, val);
       return *this;
    }
@@ -906,7 +953,10 @@
    }
    gmp_int(const gmp_int& o)
    {
- mpz_init_set(m_data, o.m_data);
+ if(o.m_data[0]._mp_d)
+ mpz_init_set(m_data, o.m_data);
+ else
+ mpz_init(this->m_data);
    }
 #ifndef BOOST_NO_RVALUE_REFERENCES
    gmp_int(gmp_int&& o) BOOST_NOEXCEPT
@@ -938,21 +988,21 @@
    gmp_int(const gmp_rational& o);
    gmp_int& operator = (const gmp_int& o)
    {
- mpz_set(m_data, o.m_data);
+ if(o.m_data[0]._mp_d)
+ mpz_set(m_data, o.m_data);
       return *this;
    }
 #ifndef BOOST_NO_RVALUE_REFERENCES
    gmp_int& operator = (gmp_int&& o) BOOST_NOEXCEPT
    {
- if(m_data[0]._mp_d)
- mpz_clear(m_data);
- m_data[0] = o.m_data[0];
- o.m_data[0]._mp_d = 0;
+ mpz_swap(m_data, o.m_data);
       return *this;
    }
 #endif
    gmp_int& operator = (unsigned long long i)
    {
+ if(m_data[0]._mp_d == 0)
+ mpz_init(this->m_data);
       unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
       unsigned shift = 0;
       mpz_t t;
@@ -973,6 +1023,8 @@
    gmp_int& operator = (long long i)
    {
       BOOST_MP_USING_ABS
+ if(m_data[0]._mp_d == 0)
+ mpz_init(this->m_data);
       bool neg = i < 0;
       *this = static_cast<unsigned long long>(abs(i));
       if(neg)
@@ -981,16 +1033,22 @@
    }
    gmp_int& operator = (unsigned long i)
    {
+ if(m_data[0]._mp_d == 0)
+ mpz_init(this->m_data);
       mpz_set_ui(m_data, i);
       return *this;
    }
    gmp_int& operator = (long i)
    {
+ if(m_data[0]._mp_d == 0)
+ mpz_init(this->m_data);
       mpz_set_si(m_data, i);
       return *this;
    }
    gmp_int& operator = (double d)
    {
+ if(m_data[0]._mp_d == 0)
+ mpz_init(this->m_data);
       mpz_set_d(m_data, d);
       return *this;
    }
@@ -1000,6 +1058,9 @@
       using std::ldexp;
       using std::floor;
 
+ if(m_data[0]._mp_d == 0)
+ mpz_init(this->m_data);
+
       if (a == 0) {
          mpz_set_si(m_data, 0);
          return *this;
@@ -1042,6 +1103,8 @@
    }
    gmp_int& operator = (const char* s)
    {
+ if(m_data[0]._mp_d == 0)
+ mpz_init(this->m_data);
       std::size_t n = s ? std::strlen(s) : 0;
       int radix = 10;
       if(n && (*s == '0'))
@@ -1069,22 +1132,30 @@
    }
    gmp_int& operator=(const mpf_t& val)
    {
+ if(m_data[0]._mp_d == 0)
+ mpz_init(this->m_data);
       mpz_set_f(this->m_data, val);
       return *this;
    }
    gmp_int& operator=(const mpz_t& val)
    {
+ if(m_data[0]._mp_d == 0)
+ mpz_init(this->m_data);
       mpz_set(this->m_data, val);
       return *this;
    }
    gmp_int& operator=(const mpq_t& val)
    {
+ if(m_data[0]._mp_d == 0)
+ mpz_init(this->m_data);
       mpz_set_q(this->m_data, val);
       return *this;
    }
    template <unsigned Digits10>
    gmp_int& operator=(const gmp_float<Digits10>& o)
    {
+ if(m_data[0]._mp_d == 0)
+ mpz_init(this->m_data);
       mpz_set_f(this->m_data, o.data());
       return *this;
    }
@@ -1095,6 +1166,8 @@
    }
    std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
    {
+ BOOST_ASSERT(m_data[0]._mp_d);
+
       int base = 10;
       if((f & std::ios_base::oct) == std::ios_base::oct)
          base = 8;
@@ -1131,18 +1204,22 @@
    }
    void negate()
    {
+ BOOST_ASSERT(m_data[0]._mp_d);
       mpz_neg(m_data, m_data);
    }
    int compare(const gmp_int& o)const
    {
+ BOOST_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d);
       return mpz_cmp(m_data, o.m_data);
    }
    int compare(long i)const
    {
+ BOOST_ASSERT(m_data[0]._mp_d);
       return mpz_cmp_si(m_data, i);
    }
    int compare(unsigned long i)const
    {
+ BOOST_ASSERT(m_data[0]._mp_d);
       return mpz_cmp_ui(m_data, i);
    }
    template <class V>
@@ -1152,8 +1229,16 @@
       d = v;
       return compare(d);
    }
- mpz_t& data() { return m_data; }
- const mpz_t& data()const { return m_data; }
+ mpz_t& data()
+ {
+ BOOST_ASSERT(m_data[0]._mp_d);
+ return m_data;
+ }
+ const mpz_t& data()const
+ {
+ BOOST_ASSERT(m_data[0]._mp_d);
+ return m_data;
+ }
 protected:
    mpz_t m_data;
 };
@@ -1545,7 +1630,8 @@
    gmp_rational(const gmp_rational& o)
    {
       mpq_init(m_data);
- mpq_set(m_data, o.m_data);
+ if(o.m_data[0]._mp_num._mp_d)
+ mpq_set(m_data, o.m_data);
    }
    gmp_rational(const gmp_int& o)
    {
@@ -1557,8 +1643,8 @@
    {
       m_data[0]._mp_num = o.data()[0]._mp_num;
       m_data[0]._mp_den = o.data()[0]._mp_den;
- o.data()[0]._mp_num._mp_d = 0;
- o.data()[0]._mp_den._mp_d = 0;
+ o.m_data[0]._mp_num._mp_d = 0;
+ o.m_data[0]._mp_den._mp_d = 0;
    }
 #endif
    gmp_rational(mpq_t o)
@@ -1573,21 +1659,21 @@
    }
    gmp_rational& operator = (const gmp_rational& o)
    {
- mpq_set(m_data, o.m_data);
+ if(o.m_data[0]._mp_num._mp_d)
+ mpq_set(m_data, o.m_data);
       return *this;
    }
 #ifndef BOOST_NO_RVALUE_REFERENCES
    gmp_rational& operator = (gmp_rational&& o) BOOST_NOEXCEPT
    {
- m_data[0]._mp_num = o.data()[0]._mp_num;
- m_data[0]._mp_den = o.data()[0]._mp_den;
- o.data()[0]._mp_num._mp_d = 0;
- o.data()[0]._mp_den._mp_d = 0;
+ mpq_swap(m_data, o.m_data);
       return *this;
    }
 #endif
    gmp_rational& operator = (unsigned long long i)
    {
+ if(m_data[0]._mp_den._mp_d == 0)
+ mpq_init(m_data);
       unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
       unsigned shift = 0;
       mpq_t t;
@@ -1608,6 +1694,8 @@
    gmp_rational& operator = (long long i)
    {
       BOOST_MP_USING_ABS
+ if(m_data[0]._mp_den._mp_d == 0)
+ mpq_init(m_data);
       bool neg = i < 0;
       *this = static_cast<unsigned long long>(abs(i));
       if(neg)
@@ -1616,16 +1704,22 @@
    }
    gmp_rational& operator = (unsigned long i)
    {
+ if(m_data[0]._mp_den._mp_d == 0)
+ mpq_init(m_data);
       mpq_set_ui(m_data, i, 1);
       return *this;
    }
    gmp_rational& operator = (long i)
    {
+ if(m_data[0]._mp_den._mp_d == 0)
+ mpq_init(m_data);
       mpq_set_si(m_data, i, 1);
       return *this;
    }
    gmp_rational& operator = (double d)
    {
+ if(m_data[0]._mp_den._mp_d == 0)
+ mpq_init(m_data);
       mpq_set_d(m_data, d);
       return *this;
    }
@@ -1637,6 +1731,9 @@
       using default_ops::eval_add;
       using default_ops::eval_subtract;
 
+ if(m_data[0]._mp_den._mp_d == 0)
+ mpq_init(m_data);
+
       if (a == 0) {
          mpq_set_si(m_data, 0, 1);
          return *this;
@@ -1679,22 +1776,30 @@
    }
    gmp_rational& operator = (const char* s)
    {
+ if(m_data[0]._mp_den._mp_d == 0)
+ mpq_init(m_data);
       if(0 != mpq_set_str(m_data, s, 10))
          BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid rational number.")));
       return *this;
    }
    gmp_rational& operator=(const gmp_int& o)
    {
+ if(m_data[0]._mp_den._mp_d == 0)
+ mpq_init(m_data);
       mpq_set_z(m_data, o.data());
       return *this;
    }
    gmp_rational& operator=(const mpq_t& o)
    {
+ if(m_data[0]._mp_den._mp_d == 0)
+ mpq_init(m_data);
       mpq_set(m_data, o);
       return *this;
    }
    gmp_rational& operator=(const mpz_t& o)
    {
+ if(m_data[0]._mp_den._mp_d == 0)
+ mpq_init(m_data);
       mpq_set_z(m_data, o);
       return *this;
    }
@@ -1704,6 +1809,7 @@
    }
    std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags /*f*/)const
    {
+ BOOST_ASSERT(m_data[0]._mp_num._mp_d);
       // TODO make a better job of this including handling of f!!
       void *(*alloc_func_ptr) (size_t);
       void *(*realloc_func_ptr) (void *, size_t, size_t);
@@ -1721,10 +1827,12 @@
    }
    void negate()
    {
+ BOOST_ASSERT(m_data[0]._mp_num._mp_d);
       mpq_neg(m_data, m_data);
    }
    int compare(const gmp_rational& o)const
    {
+ BOOST_ASSERT(m_data[0]._mp_num._mp_d && o.m_data[0]._mp_num._mp_d);
       return mpq_cmp(m_data, o.m_data);
    }
    template <class V>
@@ -1736,14 +1844,24 @@
    }
    int compare(unsigned long v)const
    {
+ BOOST_ASSERT(m_data[0]._mp_num._mp_d);
       return mpq_cmp_ui(m_data, v, 1);
    }
    int compare(long v)const
    {
+ BOOST_ASSERT(m_data[0]._mp_num._mp_d);
       return mpq_cmp_si(m_data, v, 1);
    }
- mpq_t& data() { return m_data; }
- const mpq_t& data()const { return m_data; }
+ mpq_t& data()
+ {
+ BOOST_ASSERT(m_data[0]._mp_num._mp_d);
+ return m_data;
+ }
+ const mpq_t& data()const
+ {
+ BOOST_ASSERT(m_data[0]._mp_num._mp_d);
+ return m_data;
+ }
 protected:
    mpq_t m_data;
 };
@@ -1870,37 +1988,43 @@
 template <unsigned D>
 inline gmp_float<Digits10>::gmp_float(const gmp_float<D>& o)
 {
- mpf_init2(this->m_data, ((Digits10 + 1) * 1000L) / 301L);
+ mpf_init2(this->m_data, (((Digits10 ? Digits10 : this->get_default_precision()) + 1) * 1000L) / 301L);
    mpf_set(this->m_data, o.data());
 }
 template <unsigned Digits10>
 inline gmp_float<Digits10>::gmp_float(const gmp_int& o)
 {
- mpf_init2(this->m_data, ((Digits10 + 1) * 1000L) / 301L);
+ mpf_init2(this->m_data, (((Digits10 ? Digits10 : this->get_default_precision()) + 1) * 1000L) / 301L);
    mpf_set_z(this->data(), o.data());
 }
 template <unsigned Digits10>
 inline gmp_float<Digits10>::gmp_float(const gmp_rational& o)
 {
- mpf_init2(this->m_data, ((Digits10 + 1) * 1000L) / 301L);
+ mpf_init2(this->m_data, (((Digits10 ? Digits10 : this->get_default_precision()) + 1) * 1000L) / 301L);
    mpf_set_q(this->data(), o.data());
 }
 template <unsigned Digits10>
 template <unsigned D>
 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_float<D>& o)
 {
+ if(this->m_data[0]._mp_d == 0)
+ mpf_init2(this->m_data, (((Digits10 ? Digits10 : this->get_default_precision()) + 1) * 1000L) / 301L);
    mpf_set(this->m_data, o.data());
    return *this;
 }
 template <unsigned Digits10>
 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_int& o)
 {
+ if(this->m_data[0]._mp_d == 0)
+ mpf_init2(this->m_data, (((Digits10 ? Digits10 : this->get_default_precision()) + 1) * 1000L) / 301L);
    mpf_set_z(this->data(), o.data());
    return *this;
 }
 template <unsigned Digits10>
 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_rational& o)
 {
+ if(this->m_data[0]._mp_d == 0)
+ mpf_init2(this->m_data, (((Digits10 ? Digits10 : this->get_default_precision()) + 1) * 1000L) / 301L);
    mpf_set_q(this->data(), o.data());
    return *this;
 }
@@ -1916,11 +2040,15 @@
 }
 inline gmp_float<0>& gmp_float<0>::operator=(const gmp_int& o)
 {
+ if(this->m_data[0]._mp_d == 0)
+ mpf_init2(this->m_data, ((this->get_default_precision() + 1) * 1000L) / 301L);
    mpf_set_z(this->data(), o.data());
    return *this;
 }
 inline gmp_float<0>& gmp_float<0>::operator=(const gmp_rational& o)
 {
+ if(this->m_data[0]._mp_d == 0)
+ mpf_init2(this->m_data, ((this->get_default_precision() + 1) * 1000L) / 301L);
    mpf_set_q(this->data(), o.data());
    return *this;
 }
@@ -1931,6 +2059,8 @@
 }
 inline gmp_int& gmp_int::operator=(const gmp_rational& o)
 {
+ if(this->m_data[0]._mp_d == 0)
+ mpz_init(this->m_data);
    mpz_set_q(this->m_data, o.data());
    return *this;
 }

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-08-07 13:55:32 EDT (Tue, 07 Aug 2012)
@@ -28,8 +28,9 @@
 
 #ifdef BOOST_MSVC
 // warning C4127: conditional expression is constant
+// warning C4714: function marked as __forceinline not inlined
 #pragma warning(push)
-#pragma warning(disable:4127)
+#pragma warning(disable:4127 4714)
 #endif
 
 template <class Backend, bool ExpressionTemplates>

Modified: sandbox/big_number/boost/multiprecision/mpfr.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/mpfr.hpp (original)
+++ sandbox/big_number/boost/multiprecision/mpfr.hpp 2012-08-07 13:55:32 EDT (Tue, 07 Aug 2012)
@@ -40,7 +40,8 @@
    mpfr_float_imp(const mpfr_float_imp& o)
    {
       mpfr_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
- mpfr_set(m_data, o.m_data, GMP_RNDN);
+ if(o.m_data[0]._mpfr_d)
+ mpfr_set(m_data, o.m_data, GMP_RNDN);
    }
 #ifndef BOOST_NO_RVALUE_REFERENCES
    mpfr_float_imp(mpfr_float_imp&& o) BOOST_NOEXCEPT
@@ -51,7 +52,10 @@
 #endif
    mpfr_float_imp& operator = (const mpfr_float_imp& o) BOOST_NOEXCEPT
    {
- mpfr_set(m_data, o.m_data, GMP_RNDN);
+ if(m_data[0]._mpfr_d == 0)
+ mpfr_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
+ if(o.m_data[0]._mpfr_d)
+ mpfr_set(m_data, o.m_data, GMP_RNDN);
       return *this;
    }
 #ifndef BOOST_NO_RVALUE_REFERENCES
@@ -64,17 +68,23 @@
 #ifdef _MPFR_H_HAVE_INTMAX_T
    mpfr_float_imp& operator = (unsigned long long i) BOOST_NOEXCEPT
    {
+ if(m_data[0]._mpfr_d == 0)
+ mpfr_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       mpfr_set_uj(m_data, i, GMP_RNDN);
       return *this;
    }
    mpfr_float_imp& operator = (long long i) BOOST_NOEXCEPT
    {
+ if(m_data[0]._mpfr_d == 0)
+ mpfr_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       mpfr_set_sj(m_data, i, GMP_RNDN);
       return *this;
    }
 #else
    mpfr_float_imp& operator = (unsigned long long i)
    {
+ if(m_data[0]._mpfr_d == 0)
+ mpfr_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
       unsigned shift = 0;
       mpfr_t t;
@@ -95,6 +105,8 @@
    mpfr_float_imp& operator = (long long i)
    {
       BOOST_MP_USING_ABS
+ if(m_data[0]._mpfr_d == 0)
+ mpfr_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       bool neg = i < 0;
       *this = static_cast<unsigned long long>(abs(i));
       if(neg)
@@ -104,26 +116,36 @@
 #endif
    mpfr_float_imp& operator = (unsigned long i) BOOST_NOEXCEPT
    {
+ if(m_data[0]._mpfr_d == 0)
+ mpfr_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       mpfr_set_ui(m_data, i, GMP_RNDN);
       return *this;
    }
    mpfr_float_imp& operator = (long i) BOOST_NOEXCEPT
    {
+ if(m_data[0]._mpfr_d == 0)
+ mpfr_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       mpfr_set_si(m_data, i, GMP_RNDN);
       return *this;
    }
    mpfr_float_imp& operator = (double d) BOOST_NOEXCEPT
    {
+ if(m_data[0]._mpfr_d == 0)
+ mpfr_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       mpfr_set_d(m_data, d, GMP_RNDN);
       return *this;
    }
    mpfr_float_imp& operator = (long double a) BOOST_NOEXCEPT
    {
+ if(m_data[0]._mpfr_d == 0)
+ mpfr_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       mpfr_set_ld(m_data, a, GMP_RNDN);
       return *this;
    }
    mpfr_float_imp& operator = (const char* s)
    {
+ if(m_data[0]._mpfr_d == 0)
+ mpfr_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
       if(mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
       {
          BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
@@ -136,6 +158,8 @@
    }
    std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
    {
+ BOOST_ASSERT(m_data[0]._mpfr_d);
+
       bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
       bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
 
@@ -246,18 +270,22 @@
    }
    void negate() BOOST_NOEXCEPT
    {
+ BOOST_ASSERT(m_data[0]._mpfr_d);
       mpfr_neg(m_data, m_data, GMP_RNDN);
    }
    int compare(const mpfr_float_backend<digits10>& o)const BOOST_NOEXCEPT
    {
+ BOOST_ASSERT(m_data[0]._mpfr_d && o.m_data[0]._mpfr_d);
       return mpfr_cmp(m_data, o.m_data);
    }
    int compare(long i)const BOOST_NOEXCEPT
    {
+ BOOST_ASSERT(m_data[0]._mpfr_d);
       return mpfr_cmp_si(m_data, i);
    }
    int compare(unsigned long i)const BOOST_NOEXCEPT
    {
+ BOOST_ASSERT(m_data[0]._mpfr_d);
       return mpfr_cmp_ui(m_data, i);
    }
    template <class V>
@@ -267,8 +295,16 @@
       d = v;
       return compare(d);
    }
- mpfr_t& data() BOOST_NOEXCEPT { return m_data; }
- const mpfr_t& data()const BOOST_NOEXCEPT { return m_data; }
+ mpfr_t& data() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(m_data[0]._mpfr_d);
+ return m_data;
+ }
+ const mpfr_t& data()const BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(m_data[0]._mpfr_d);
+ return m_data;
+ }
 protected:
    mpfr_t m_data;
    static unsigned& get_default_precision() BOOST_NOEXCEPT

Modified: sandbox/big_number/boost/multiprecision/tommath.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/tommath.hpp (original)
+++ sandbox/big_number/boost/multiprecision/tommath.hpp 2012-08-07 13:55:32 EDT (Tue, 07 Aug 2012)
@@ -54,18 +54,22 @@
    }
    tommath_int& operator = (tommath_int&& o)
    {
- m_data = o.m_data;
- o.m_data.dp = 0;
+ mp_exch(&m_data, &o.data());
       return *this;
    }
 #endif
    tommath_int& operator = (const tommath_int& o)
    {
- detail::check_tommath_result(mp_copy(const_cast< ::mp_int*>(&o.m_data), &m_data));
+ if(m_data.dp == 0)
+ detail::check_tommath_result(mp_init(&m_data));
+ if(o.m_data.dp)
+ detail::check_tommath_result(mp_copy(const_cast< ::mp_int*>(&o.m_data), &m_data));
       return *this;
    }
    tommath_int& operator = (unsigned long long i)
    {
+ if(m_data.dp == 0)
+ detail::check_tommath_result(mp_init(&m_data));
       unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
       unsigned shift = 0;
       ::mp_int t;
@@ -86,6 +90,8 @@
    tommath_int& operator = (long long i)
    {
       BOOST_MP_USING_ABS
+ if(m_data.dp == 0)
+ detail::check_tommath_result(mp_init(&m_data));
       bool neg = i < 0;
       *this = static_cast<unsigned long long>(abs(i));
       if(neg)
@@ -99,11 +105,15 @@
    //
    tommath_int& operator = (boost::uint32_t i)
    {
+ if(m_data.dp == 0)
+ detail::check_tommath_result(mp_init(&m_data));
       detail::check_tommath_result((mp_set_int(&m_data, i)));
       return *this;
    }
    tommath_int& operator = (boost::int32_t i)
    {
+ if(m_data.dp == 0)
+ detail::check_tommath_result(mp_init(&m_data));
       bool neg = i < 0;
       *this = static_cast<boost::uint32_t>(std::abs(i));
       if(neg)
@@ -116,6 +126,9 @@
       using std::ldexp;
       using std::floor;
 
+ if(m_data.dp == 0)
+ detail::check_tommath_result(mp_init(&m_data));
+
       if (a == 0) {
          detail::check_tommath_result(mp_set_int(&m_data, 0));
          return *this;
@@ -175,6 +188,8 @@
       //
       using default_ops::eval_multiply;
       using default_ops::eval_add;
+ if(m_data.dp == 0)
+ detail::check_tommath_result(mp_init(&m_data));
       std::size_t n = s ? std::strlen(s) : 0;
       *this = static_cast<boost::uint32_t>(0u);
       unsigned radix = 10;
@@ -275,6 +290,7 @@
    }
    std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
    {
+ BOOST_ASSERT(m_data.dp);
       int base = 10;
       if((f & std::ios_base::oct) == std::ios_base::oct)
          base = 8;
@@ -307,10 +323,12 @@
    }
    void negate()
    {
+ BOOST_ASSERT(m_data.dp);
       mp_neg(&m_data, &m_data);
    }
    int compare(const tommath_int& o)const
    {
+ BOOST_ASSERT(m_data.dp && o.m_data.dp);
       return mp_cmp(const_cast< ::mp_int*>(&m_data), const_cast< ::mp_int*>(&o.m_data));
    }
    template <class V>
@@ -322,8 +340,16 @@
       d = v;
       return t.compare(d);
    }
- ::mp_int& data() { return m_data; }
- const ::mp_int& data()const { return m_data; }
+ ::mp_int& data()
+ {
+ BOOST_ASSERT(m_data.dp);
+ return m_data;
+ }
+ const ::mp_int& data()const
+ {
+ BOOST_ASSERT(m_data.dp);
+ return m_data;
+ }
    void swap(tommath_int& o)BOOST_NOEXCEPT
    {
       mp_exch(&m_data, &o.data());

Modified: sandbox/big_number/libs/multiprecision/test/test_move.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_move.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_move.cpp 2012-08-07 13:55:32 EDT (Tue, 07 Aug 2012)
@@ -71,6 +71,19 @@
 {
 }
 
+template <class T>
+void test_std_lib()
+{
+ std::vector<T> v;
+ for(unsigned i = 0; i < 100; ++i)
+ v.insert(v.begin(), i);
+
+ T a(2), b(3);
+ std::swap(a, b);
+ BOOST_TEST(a == 3);
+ BOOST_TEST(b == 2);
+}
+
 
 int main()
 {
@@ -83,6 +96,7 @@
 
 #ifdef TEST_MPFR
    {
+ test_std_lib<mpfr_float_50>();
       mpfr_float_50 a = 2;
       BOOST_TEST(allocation_count); // sanity check that we are tracking allocations
       allocation_count = 0;
@@ -112,10 +126,16 @@
       d = std::move(e);
       BOOST_TEST(allocation_count == 0);
       BOOST_TEST(d == 3);
+ e = 2;
+ BOOST_TEST(e == 2);
+ d = std::move(e);
+ e = d;
+ BOOST_TEST(e == d);
    }
 #endif
 #ifdef TEST_GMP
    {
+ test_std_lib<mpf_float_50>();
       mpf_float_50 a = 2;
       BOOST_TEST(allocation_count); // sanity check that we are tracking allocations
       allocation_count = 0;
@@ -145,8 +165,14 @@
       d = std::move(e);
       BOOST_TEST(allocation_count == 0);
       BOOST_TEST(d == 3);
+ e = 2;
+ BOOST_TEST(e == 2);
+ d = std::move(e);
+ e = d;
+ BOOST_TEST(e == d);
    }
    {
+ test_std_lib<mpz_int>();
       mpz_int a = 2;
       BOOST_TEST(allocation_count); // sanity check that we are tracking allocations
       allocation_count = 0;
@@ -163,8 +189,14 @@
       allocation_count = 0;
       e = std::move(d);
       BOOST_TEST(allocation_count == 0);
+ e = 2;
+ BOOST_TEST(e == 2);
+ d = std::move(e);
+ e = d;
+ BOOST_TEST(e == d);
    }
    {
+ test_std_lib<mpq_rational>();
       mpq_rational a = 2;
       BOOST_TEST(allocation_count); // sanity check that we are tracking allocations
       allocation_count = 0;
@@ -180,15 +212,22 @@
       allocation_count = 0;
       e = std::move(d);
       BOOST_TEST(allocation_count == 0);
+ d = 2;
+ BOOST_TEST(d == 2);
+ d = std::move(e);
+ e = d;
+ BOOST_TEST(e == d);
    }
 #endif
 #ifdef TEST_TOMMATH
    {
+ test_std_lib<tom_int>();
       tom_int a = 2;
       void const* p = a.backend().data().dp;
       tom_int b = std::move(a);
       BOOST_TEST(b.backend().data().dp == p);
- BOOST_TEST(a.backend().data().dp == 0);
+ // We can't test this, as it will assert inside data():
+ //BOOST_TEST(a.backend().data().dp == 0);
 
       //
       // Move assign:
@@ -201,10 +240,16 @@
       BOOST_TEST(p != e.backend().data().dp);
       e = std::move(d);
       BOOST_TEST(e.backend().data().dp == p);
+ d = 2;
+ BOOST_TEST(d == 2);
+ d = std::move(e);
+ e = d;
+ BOOST_TEST(e == d);
    }
 #endif
 #ifdef TEST_CPP_INT
    {
+ test_std_lib<cpp_int>();
       cpp_int a = 2;
       a <<= 1000; // Force dynamic allocation.
       void const* p = a.backend().limbs();
@@ -223,6 +268,11 @@
       BOOST_TEST(p != e.backend().limbs());
       e = std::move(d);
       BOOST_TEST(e.backend().limbs() == p);
+ d = 2;
+ BOOST_TEST(d == 2);
+ d = std::move(e);
+ e = d;
+ BOOST_TEST(e == d);
    }
 #endif
    return boost::report_errors();


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