|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r84687 - in trunk: boost/multiprecision libs/multiprecision/test
From: john_at_[hidden]
Date: 2013-06-08 10:07:21
Author: johnmaddock
Date: 2013-06-08 10:07:21 EDT (Sat, 08 Jun 2013)
New Revision: 84687
URL: http://svn.boost.org/trac/boost/changeset/84687
Log:
Fix assignment operations to be safe after a move.
Added test cases to catch bug case.
Refs #8667.
Text files modified:
trunk/boost/multiprecision/gmp.hpp | 10 ++++---
trunk/boost/multiprecision/mpfr.hpp | 49 +++++++++++++++++++++++++++++++++++----
trunk/libs/multiprecision/test/test_move.cpp | 45 ++++++++++++++++++++++++++++++++++++
3 files changed, 95 insertions(+), 9 deletions(-)
Modified: trunk/boost/multiprecision/gmp.hpp
==============================================================================
--- trunk/boost/multiprecision/gmp.hpp Sat Jun 8 06:58:41 2013 (r84686)
+++ trunk/boost/multiprecision/gmp.hpp 2013-06-08 10:07:21 EDT (Sat, 08 Jun 2013) (r84687)
@@ -1015,8 +1015,9 @@
explicit gmp_int(const gmp_rational& o);
gmp_int& operator = (const gmp_int& o)
{
- if(o.m_data[0]._mp_d)
- mpz_set(m_data, o.m_data);
+ if(m_data[0]._mp_d == 0)
+ mpz_init(this->m_data);
+ mpz_set(m_data, o.m_data);
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
@@ -1728,8 +1729,9 @@
}
gmp_rational& operator = (const gmp_rational& o)
{
- if(o.m_data[0]._mp_num._mp_d)
- mpq_set(m_data, o.m_data);
+ if(m_data[0]._mp_den._mp_d == 0)
+ mpq_init(m_data);
+ mpq_set(m_data, o.m_data);
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Modified: trunk/boost/multiprecision/mpfr.hpp
==============================================================================
--- trunk/boost/multiprecision/mpfr.hpp Sat Jun 8 06:58:41 2013 (r84686)
+++ trunk/boost/multiprecision/mpfr.hpp 2013-06-08 10:07:21 EDT (Sat, 08 Jun 2013) (r84687)
@@ -702,21 +702,29 @@
}
mpfr_float_backend& operator=(const mpfr_t val)
{
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
mpfr_set(this->m_data, val, GMP_RNDN);
return *this;
}
mpfr_float_backend& operator=(const mpf_t val)
{
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
mpfr_set_f(this->m_data, val, GMP_RNDN);
return *this;
}
mpfr_float_backend& operator=(const mpz_t val)
{
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
mpfr_set_z(this->m_data, val, GMP_RNDN);
return *this;
}
mpfr_float_backend& operator=(const mpq_t val)
{
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
mpfr_set_q(this->m_data, val, GMP_RNDN);
return *this;
}
@@ -724,22 +732,30 @@
template <unsigned D, mpfr_allocation_type AT>
mpfr_float_backend& operator=(const mpfr_float_backend<D, AT>& val)
{
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
mpfr_set(this->m_data, val.data(), GMP_RNDN);
return *this;
}
template <unsigned D>
mpfr_float_backend& operator=(const gmp_float<D>& val)
{
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
return *this;
}
mpfr_float_backend& operator=(const gmp_int& val)
{
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
return *this;
}
mpfr_float_backend& operator=(const gmp_rational& val)
{
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
return *this;
}
@@ -803,7 +819,10 @@
mpfr_float_backend& operator=(const mpfr_float_backend& o)
{
- mpfr_set_prec(this->m_data, mpfr_get_prec(o.data()));
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, mpfr_get_prec(o.data()));
+ else
+ mpfr_set_prec(this->m_data, mpfr_get_prec(o.data()));
mpfr_set(this->m_data, o.data(), GMP_RNDN);
return *this;
}
@@ -822,47 +841,67 @@
}
mpfr_float_backend& operator=(const mpfr_t val)
{
- mpfr_set_prec(this->m_data, mpfr_get_prec(val));
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, mpfr_get_prec(val));
+ else
+ mpfr_set_prec(this->m_data, mpfr_get_prec(val));
mpfr_set(this->m_data, val, GMP_RNDN);
return *this;
}
mpfr_float_backend& operator=(const mpf_t val)
{
- mpfr_set_prec(this->m_data, mpf_get_prec(val));
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, mpf_get_prec(val));
+ else
+ mpfr_set_prec(this->m_data, mpf_get_prec(val));
mpfr_set_f(this->m_data, val, GMP_RNDN);
return *this;
}
mpfr_float_backend& operator=(const mpz_t val)
{
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
mpfr_set_z(this->m_data, val, GMP_RNDN);
return *this;
}
mpfr_float_backend& operator=(const mpq_t val)
{
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
mpfr_set_q(this->m_data, val, GMP_RNDN);
return *this;
}
template <unsigned D>
mpfr_float_backend& operator=(const mpfr_float_backend<D>& val)
{
- mpfr_set_prec(this->m_data, mpfr_get_prec(val.data()));
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, mpfr_get_prec(val.data()));
+ else
+ mpfr_set_prec(this->m_data, mpfr_get_prec(val.data()));
mpfr_set(this->m_data, val.data(), GMP_RNDN);
return *this;
}
template <unsigned D>
mpfr_float_backend& operator=(const gmp_float<D>& val)
{
- mpfr_set_prec(this->m_data, mpf_get_prec(val.data()));
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, mpf_get_prec(val.data()));
+ else
+ mpfr_set_prec(this->m_data, mpf_get_prec(val.data()));
mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
return *this;
}
mpfr_float_backend& operator=(const gmp_int& val)
{
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
return *this;
}
mpfr_float_backend& operator=(const gmp_rational& val)
{
+ if(this->m_data[0]._mpfr_d == 0)
+ mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
return *this;
}
Modified: trunk/libs/multiprecision/test/test_move.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_move.cpp Sat Jun 8 06:58:41 2013 (r84686)
+++ trunk/libs/multiprecision/test/test_move.cpp 2013-06-08 10:07:21 EDT (Sat, 08 Jun 2013) (r84687)
@@ -84,6 +84,36 @@
BOOST_TEST(b == 2);
}
+template <class T, class A>
+void test_move_and_assign(T x, A val)
+{
+ // move away from x, then assign val to x.
+ T z(x);
+ T y(std::move(x));
+ x.assign(val);
+ BOOST_CHECK_EQUAL(x, T(val));
+ BOOST_CHECK_EQUAL(z, y);
+}
+
+template <class T>
+void test_move_and_assign()
+{
+ T x(23);
+ test_move_and_assign(x, static_cast<short>(2));
+ test_move_and_assign(x, static_cast<int>(2));
+ test_move_and_assign(x, static_cast<long>(2));
+ test_move_and_assign(x, static_cast<long long>(2));
+ test_move_and_assign(x, static_cast<unsigned short>(2));
+ test_move_and_assign(x, static_cast<unsigned int>(2));
+ test_move_and_assign(x, static_cast<unsigned long>(2));
+ test_move_and_assign(x, static_cast<unsigned long long>(2));
+ test_move_and_assign(x, static_cast<float>(2));
+ test_move_and_assign(x, static_cast<double>(2));
+ test_move_and_assign(x, static_cast<long double>(2));
+ test_move_and_assign(x, x);
+ test_move_and_assign(x, "23");
+}
+
int main()
{
@@ -131,6 +161,9 @@
d = std::move(e);
e = d;
BOOST_TEST(e == d);
+
+ test_move_and_assign<mpfr_float>();
+ test_move_and_assign<mpfr_float_50>();
}
#endif
#ifdef TEST_GMP
@@ -170,6 +203,9 @@
d = std::move(e);
e = d;
BOOST_TEST(e == d);
+
+ test_move_and_assign<mpf_float>();
+ test_move_and_assign<mpf_float_50>();
}
{
test_std_lib<mpz_int>();
@@ -194,6 +230,8 @@
d = std::move(e);
e = d;
BOOST_TEST(e == d);
+
+ test_move_and_assign<mpz_int>();
}
{
test_std_lib<mpq_rational>();
@@ -217,6 +255,8 @@
d = std::move(e);
e = d;
BOOST_TEST(e == d);
+
+ test_move_and_assign<mpq_rational>();
}
#endif
#ifdef TEST_TOMMATH
@@ -245,6 +285,8 @@
d = std::move(e);
e = d;
BOOST_TEST(e == d);
+
+ test_move_and_assign<tom_int>();
}
#endif
#ifdef TEST_CPP_INT
@@ -273,6 +315,9 @@
d = std::move(e);
e = d;
BOOST_TEST(e == d);
+
+ test_move_and_assign<cpp_int>();
+ test_move_and_assign<int512_t>();
}
#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