1 // Copyright John Maddock 2012.
3 // Use, modification and distribution are subject to the
4 // Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
9 #define _SCL_SECURE_NO_WARNINGS
12 #include <boost/config.hpp>
15 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
17 #if !defined(TEST_GMP) && !defined(TEST_MPFR) && !defined(TEST_TOMMATH) && !defined(TEST_CPP_INT) && !defined(TEST_MPC)
25 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
28 #pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!"
34 #include <boost/multiprecision/gmp.hpp>
36 #if defined(TEST_MPFR)
37 #include <boost/multiprecision/mpfr.hpp>
40 #include <boost/multiprecision/tommath.hpp>
43 #include <boost/multiprecision/cpp_int.hpp>
46 #include <boost/multiprecision/mpc.hpp>
51 unsigned allocation_count = 0;
53 void* (*alloc_func_ptr)(size_t);
54 void* (*realloc_func_ptr)(void*, size_t, size_t);
55 void (*free_func_ptr)(void*, size_t);
57 void* alloc_func(size_t n)
60 return (*alloc_func_ptr)(n);
63 void free_func(void* p, size_t n)
65 (*free_func_ptr)(p, n);
68 void* realloc_func(void* p, size_t old, size_t n)
71 return (*realloc_func_ptr)(p, old, n);
75 void do_something(const T&)
83 for (unsigned i = 0; i < 100; ++i)
84 v.insert(v.begin(), i);
92 template <class T, class A>
93 void test_move_and_assign(T x, A val)
95 // move away from x, then assign val to x.
99 BOOST_CHECK_EQUAL(x, T(val));
100 BOOST_CHECK_EQUAL(z, y);
104 void test_move_and_assign()
107 test_move_and_assign(x, static_cast<short>(2));
108 test_move_and_assign(x, static_cast<int>(2));
109 test_move_and_assign(x, static_cast<long>(2));
110 test_move_and_assign(x, static_cast<long long>(2));
111 test_move_and_assign(x, static_cast<unsigned short>(2));
112 test_move_and_assign(x, static_cast<unsigned int>(2));
113 test_move_and_assign(x, static_cast<unsigned long>(2));
114 test_move_and_assign(x, static_cast<unsigned long long>(2));
115 test_move_and_assign(x, static_cast<float>(2));
116 test_move_and_assign(x, static_cast<double>(2));
117 test_move_and_assign(x, static_cast<long double>(2));
118 test_move_and_assign(x, x);
119 test_move_and_assign(x, "23");
124 #if defined(TEST_MPFR) || defined(TEST_GMP)
125 #if defined(MPFR_VERSION) && (MPFR_VERSION_MAJOR > 3)
126 mpfr_mp_memory_cleanup();
128 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
129 mp_set_memory_functions(&alloc_func, &realloc_func, &free_func);
132 using namespace boost::multiprecision;
136 test_std_lib<mpfr_float_50>();
138 if (allocation_count)
141 // We can only conduct meaningful tests if we're actually using our custom allocators,
142 // there are some situations where mpfr-4.x doesn't call them even though we've
143 // done everything requested to make them work....
145 allocation_count = 0;
146 mpfr_float_50 b = std::move(a);
147 BOOST_TEST(allocation_count == 0);
149 // Move assign - we rely on knowledge of the internals to make this test work!!
154 const void* p = b.backend().data()[0]._mpfr_d;
155 BOOST_TEST(c.backend().data()[0]._mpfr_d != p);
157 BOOST_TEST(c.backend().data()[0]._mpfr_d == p);
158 BOOST_TEST(b.backend().data()[0]._mpfr_d != p);
160 // Again with variable precision, this we can test more easily:
167 allocation_count = 0;
170 BOOST_TEST(allocation_count == 0);
178 test_move_and_assign<mpfr_float>();
179 test_move_and_assign<mpfr_float_50>();
185 test_std_lib<mpc_complex_50>();
186 mpc_complex_50 a = 2;
187 if (allocation_count)
190 // We can only conduct meaningful tests if we're actually using our custom allocators,
191 // there are some situations where mpfr-4.x doesn't call them even though we've
192 // done everything requested to make them work....
194 allocation_count = 0;
195 mpc_complex_50 b = std::move(a);
196 BOOST_TEST(allocation_count == 0);
198 // Move assign - we rely on knowledge of the internals to make this test work!!
204 // Again with variable precision, this we can test more easily:
211 allocation_count = 0;
214 BOOST_TEST(allocation_count == 0);
222 test_move_and_assign<mpc_complex>();
223 test_move_and_assign<mpc_complex_50>();
229 test_std_lib<mpf_float_50>();
231 BOOST_TEST(allocation_count); // sanity check that we are tracking allocations
232 allocation_count = 0;
233 mpf_float_50 b = std::move(a);
234 BOOST_TEST(allocation_count == 0);
236 // Move assign: this requires knowledge of the internals to test!!
241 const void* p = b.backend().data()[0]._mp_d;
242 BOOST_TEST(c.backend().data()[0]._mp_d != p);
244 BOOST_TEST(c.backend().data()[0]._mp_d == p);
245 BOOST_TEST(b.backend().data()[0]._mp_d != p);
247 // Again with variable precision, this we can test more easily:
254 allocation_count = 0;
257 BOOST_TEST(allocation_count == 0);
265 test_move_and_assign<mpf_float>();
266 test_move_and_assign<mpf_float_50>();
269 test_std_lib<mpz_int>();
271 BOOST_TEST(allocation_count); // sanity check that we are tracking allocations
272 allocation_count = 0;
273 mpz_int b = std::move(a);
274 BOOST_TEST(allocation_count == 0);
283 allocation_count = 0;
285 BOOST_TEST(allocation_count == 0);
292 test_move_and_assign<mpz_int>();
295 test_std_lib<mpq_rational>();
297 BOOST_TEST(allocation_count); // sanity check that we are tracking allocations
298 allocation_count = 0;
299 mpq_rational b = std::move(a);
300 BOOST_TEST(allocation_count == 0);
306 d = mpz_int(2) << 1000;
308 allocation_count = 0;
310 BOOST_TEST(allocation_count == 0);
317 test_move_and_assign<mpq_rational>();
322 test_std_lib<tom_int>();
324 void const* p = a.backend().data().dp;
325 tom_int b = std::move(a);
326 BOOST_TEST(b.backend().data().dp == p);
327 // We can't test this, as it will assert inside data():
328 //BOOST_TEST(a.backend().data().dp == 0);
337 p = d.backend().data().dp;
338 BOOST_TEST(p != e.backend().data().dp);
340 BOOST_TEST(e.backend().data().dp == p);
347 test_move_and_assign<tom_int>();
352 test_std_lib<cpp_int>();
354 a <<= 1000; // Force dynamic allocation.
355 void const* p = a.backend().limbs();
356 cpp_int b = std::move(a);
357 BOOST_TEST(b.backend().limbs() == p);
367 p = d.backend().limbs();
368 BOOST_TEST(p != e.backend().limbs());
370 BOOST_TEST(e.backend().limbs() == p);
377 test_move_and_assign<cpp_int>();
378 test_move_and_assign<int512_t>();
381 return boost::report_errors();
386 // No rvalue refs, nothing to test: