]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/multiprecision/test/test_move.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / multiprecision / test / test_move.cpp
CommitLineData
7c673cae
FG
1// Copyright John Maddock 2012.
2
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)
7
8#ifdef _MSC_VER
92f5a8d4 9#define _SCL_SECURE_NO_WARNINGS
7c673cae
FG
10#endif
11
12#include <boost/config.hpp>
13#include <vector>
14
92f5a8d4
TL
15#if !defined(TEST_GMP) && !defined(TEST_MPFR) && !defined(TEST_TOMMATH) && !defined(TEST_CPP_INT) && !defined(TEST_MPC)
16#define TEST_GMP
17#define TEST_MPFR
18#define TEST_TOMMATH
19#define TEST_CPP_INT
20#define TEST_MPC
7c673cae
FG
21
22#ifdef _MSC_VER
23#pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
24#endif
25#ifdef __GNUC__
26#pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!"
27#endif
28
29#endif
30
31#if defined(TEST_GMP)
32#include <boost/multiprecision/gmp.hpp>
33#endif
34#if defined(TEST_MPFR)
35#include <boost/multiprecision/mpfr.hpp>
36#endif
37#ifdef TEST_TOMMATH
38#include <boost/multiprecision/tommath.hpp>
39#endif
40#ifdef TEST_CPP_INT
41#include <boost/multiprecision/cpp_int.hpp>
42#endif
92f5a8d4
TL
43#ifdef TEST_MPC
44#include <boost/multiprecision/mpc.hpp>
45#endif
7c673cae
FG
46
47#include "test.hpp"
48
49unsigned allocation_count = 0;
50
92f5a8d4
TL
51void* (*alloc_func_ptr)(size_t);
52void* (*realloc_func_ptr)(void*, size_t, size_t);
53void (*free_func_ptr)(void*, size_t);
7c673cae 54
92f5a8d4 55void* alloc_func(size_t n)
7c673cae
FG
56{
57 ++allocation_count;
58 return (*alloc_func_ptr)(n);
59}
60
92f5a8d4 61void free_func(void* p, size_t n)
7c673cae
FG
62{
63 (*free_func_ptr)(p, n);
64}
65
92f5a8d4 66void* realloc_func(void* p, size_t old, size_t n)
7c673cae
FG
67{
68 ++allocation_count;
69 return (*realloc_func_ptr)(p, old, n);
70}
71
72template <class T>
73void do_something(const T&)
74{
75}
76
77template <class T>
78void test_std_lib()
79{
80 std::vector<T> v;
92f5a8d4 81 for (unsigned i = 0; i < 100; ++i)
7c673cae
FG
82 v.insert(v.begin(), i);
83
84 T a(2), b(3);
85 std::swap(a, b);
86 BOOST_TEST(a == 3);
87 BOOST_TEST(b == 2);
88}
89
90template <class T, class A>
91void test_move_and_assign(T x, A val)
92{
93 // move away from x, then assign val to x.
94 T z(x);
95 T y(std::move(x));
96 x.assign(val);
97 BOOST_CHECK_EQUAL(x, T(val));
98 BOOST_CHECK_EQUAL(z, y);
99}
100
101template <class T>
102void test_move_and_assign()
103{
104 T x(23);
105 test_move_and_assign(x, static_cast<short>(2));
106 test_move_and_assign(x, static_cast<int>(2));
107 test_move_and_assign(x, static_cast<long>(2));
108 test_move_and_assign(x, static_cast<long long>(2));
109 test_move_and_assign(x, static_cast<unsigned short>(2));
110 test_move_and_assign(x, static_cast<unsigned int>(2));
111 test_move_and_assign(x, static_cast<unsigned long>(2));
112 test_move_and_assign(x, static_cast<unsigned long long>(2));
113 test_move_and_assign(x, static_cast<float>(2));
114 test_move_and_assign(x, static_cast<double>(2));
115 test_move_and_assign(x, static_cast<long double>(2));
116 test_move_and_assign(x, x);
117 test_move_and_assign(x, "23");
118}
119
7c673cae
FG
120int main()
121{
122#if defined(TEST_MPFR) || defined(TEST_GMP)
92f5a8d4
TL
123#if defined(MPFR_VERSION) && (MPFR_VERSION_MAJOR > 3)
124 mpfr_mp_memory_cleanup();
125#endif
7c673cae
FG
126 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
127 mp_set_memory_functions(&alloc_func, &realloc_func, &free_func);
128#endif
129
130 using namespace boost::multiprecision;
131
132#ifdef TEST_MPFR
133 {
134 test_std_lib<mpfr_float_50>();
135 mpfr_float_50 a = 2;
92f5a8d4
TL
136 if (allocation_count)
137 {
138 //
139 // We can only conduct meaningful tests if we're actually using our custom allocators,
140 // there are some situations where mpfr-4.x doesn't call them even though we've
141 // done everything requested to make them work....
142 //
143 allocation_count = 0;
144 mpfr_float_50 b = std::move(a);
145 BOOST_TEST(allocation_count == 0);
146 //
147 // Move assign - we rely on knowledge of the internals to make this test work!!
148 //
149 mpfr_float_50 c(3);
150 do_something(b);
151 do_something(c);
152 const void* p = b.backend().data()[0]._mpfr_d;
153 BOOST_TEST(c.backend().data()[0]._mpfr_d != p);
154 c = std::move(b);
155 BOOST_TEST(c.backend().data()[0]._mpfr_d == p);
156 BOOST_TEST(b.backend().data()[0]._mpfr_d != p);
157 //
158 // Again with variable precision, this we can test more easily:
159 //
160 mpfr_float d, e;
161 d.precision(100);
162 e.precision(1000);
163 d = 2;
164 e = 3;
165 allocation_count = 0;
166 BOOST_TEST(d == 2);
167 d = std::move(e);
168 BOOST_TEST(allocation_count == 0);
169 BOOST_TEST(d == 3);
170 e = 2;
171 BOOST_TEST(e == 2);
172 d = std::move(e);
173 e = d;
174 BOOST_TEST(e == d);
175
176 test_move_and_assign<mpfr_float>();
177 test_move_and_assign<mpfr_float_50>();
178 }
179 }
180#endif
181#ifdef TEST_MPC
182 {
183 test_std_lib<mpc_complex_50>();
184 mpc_complex_50 a = 2;
185 if (allocation_count)
186 {
187 //
188 // We can only conduct meaningful tests if we're actually using our custom allocators,
189 // there are some situations where mpfr-4.x doesn't call them even though we've
190 // done everything requested to make them work....
191 //
192 allocation_count = 0;
193 mpc_complex_50 b = std::move(a);
194 BOOST_TEST(allocation_count == 0);
195 //
196 // Move assign - we rely on knowledge of the internals to make this test work!!
197 //
198 mpc_complex_50 c(3);
199 do_something(b);
200 do_something(c);
201 //
202 // Again with variable precision, this we can test more easily:
203 //
204 mpc_complex d, e;
205 d.precision(100);
206 e.precision(1000);
207 d = 2;
208 e = 3;
209 allocation_count = 0;
210 BOOST_TEST(d == 2);
211 d = std::move(e);
212 BOOST_TEST(allocation_count == 0);
213 BOOST_TEST(d == 3);
214 e = 2;
215 BOOST_TEST(e == 2);
216 d = std::move(e);
217 e = d;
218 BOOST_TEST(e == d);
219
220 test_move_and_assign<mpc_complex>();
221 test_move_and_assign<mpc_complex_50>();
222 }
7c673cae
FG
223 }
224#endif
225#ifdef TEST_GMP
226 {
227 test_std_lib<mpf_float_50>();
228 mpf_float_50 a = 2;
229 BOOST_TEST(allocation_count); // sanity check that we are tracking allocations
230 allocation_count = 0;
92f5a8d4 231 mpf_float_50 b = std::move(a);
7c673cae
FG
232 BOOST_TEST(allocation_count == 0);
233 //
234 // Move assign: this requires knowledge of the internals to test!!
235 //
236 mpf_float_50 c(3);
237 do_something(b);
238 do_something(c);
239 const void* p = b.backend().data()[0]._mp_d;
240 BOOST_TEST(c.backend().data()[0]._mp_d != p);
241 c = std::move(b);
242 BOOST_TEST(c.backend().data()[0]._mp_d == p);
243 BOOST_TEST(b.backend().data()[0]._mp_d != p);
244 //
245 // Again with variable precision, this we can test more easily:
246 //
247 mpf_float d, e;
248 d.precision(100);
249 e.precision(1000);
92f5a8d4
TL
250 d = 2;
251 e = 3;
7c673cae
FG
252 allocation_count = 0;
253 BOOST_TEST(d == 2);
254 d = std::move(e);
255 BOOST_TEST(allocation_count == 0);
256 BOOST_TEST(d == 3);
257 e = 2;
258 BOOST_TEST(e == 2);
259 d = std::move(e);
260 e = d;
261 BOOST_TEST(e == d);
262
263 test_move_and_assign<mpf_float>();
264 test_move_and_assign<mpf_float_50>();
265 }
266 {
267 test_std_lib<mpz_int>();
268 mpz_int a = 2;
269 BOOST_TEST(allocation_count); // sanity check that we are tracking allocations
270 allocation_count = 0;
92f5a8d4 271 mpz_int b = std::move(a);
7c673cae
FG
272 BOOST_TEST(allocation_count == 0);
273
274 //
275 // Move assign:
276 //
277 mpz_int d, e;
278 d = 2;
279 d <<= 1000;
92f5a8d4 280 e = 3;
7c673cae 281 allocation_count = 0;
92f5a8d4 282 e = std::move(d);
7c673cae
FG
283 BOOST_TEST(allocation_count == 0);
284 e = 2;
285 BOOST_TEST(e == 2);
286 d = std::move(e);
287 e = d;
288 BOOST_TEST(e == d);
289
290 test_move_and_assign<mpz_int>();
291 }
292 {
293 test_std_lib<mpq_rational>();
294 mpq_rational a = 2;
295 BOOST_TEST(allocation_count); // sanity check that we are tracking allocations
296 allocation_count = 0;
92f5a8d4 297 mpq_rational b = std::move(a);
7c673cae
FG
298 BOOST_TEST(allocation_count == 0);
299
300 //
301 // Move assign:
302 //
303 mpq_rational d, e;
92f5a8d4
TL
304 d = mpz_int(2) << 1000;
305 e = 3;
7c673cae 306 allocation_count = 0;
92f5a8d4 307 e = std::move(d);
7c673cae
FG
308 BOOST_TEST(allocation_count == 0);
309 d = 2;
310 BOOST_TEST(d == 2);
311 d = std::move(e);
312 e = d;
313 BOOST_TEST(e == d);
314
315 test_move_and_assign<mpq_rational>();
316 }
317#endif
318#ifdef TEST_TOMMATH
319 {
320 test_std_lib<tom_int>();
92f5a8d4 321 tom_int a = 2;
7c673cae 322 void const* p = a.backend().data().dp;
92f5a8d4 323 tom_int b = std::move(a);
7c673cae
FG
324 BOOST_TEST(b.backend().data().dp == p);
325 // We can't test this, as it will assert inside data():
326 //BOOST_TEST(a.backend().data().dp == 0);
327
328 //
329 // Move assign:
330 //
331 tom_int d, e;
332 d = 2;
333 d <<= 1000;
334 e = 3;
335 p = d.backend().data().dp;
336 BOOST_TEST(p != e.backend().data().dp);
337 e = std::move(d);
338 BOOST_TEST(e.backend().data().dp == p);
339 d = 2;
340 BOOST_TEST(d == 2);
341 d = std::move(e);
342 e = d;
343 BOOST_TEST(e == d);
344
345 test_move_and_assign<tom_int>();
346 }
347#endif
348#ifdef TEST_CPP_INT
349 {
350 test_std_lib<cpp_int>();
351 cpp_int a = 2;
92f5a8d4 352 a <<= 1000; // Force dynamic allocation.
7c673cae 353 void const* p = a.backend().limbs();
92f5a8d4 354 cpp_int b = std::move(a);
7c673cae
FG
355 BOOST_TEST(b.backend().limbs() == p);
356
357 //
358 // Move assign:
359 //
360 cpp_int d, e;
361 d = 2;
362 d <<= 1000;
363 e = 3;
364 e <<= 1000;
365 p = d.backend().limbs();
366 BOOST_TEST(p != e.backend().limbs());
367 e = std::move(d);
368 BOOST_TEST(e.backend().limbs() == p);
369 d = 2;
370 BOOST_TEST(d == 2);
371 d = std::move(e);
372 e = d;
373 BOOST_TEST(e == d);
374
375 test_move_and_assign<cpp_int>();
376 test_move_and_assign<int512_t>();
377 }
378#endif
379 return boost::report_errors();
380}
381