|
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