Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / multiprecision / test / test_cpp_int_serial.cpp
1 ///////////////////////////////////////////////////////////////
2 //  Copyright 2012 John Maddock. Distributed under the Boost
3 //  Software License, Version 1.0. (See accompanying file
4 //  LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
5
6 //
7 // Compare arithmetic results using fixed_int to GMP results.
8 //
9
10 #ifdef _MSC_VER
11 #define _SCL_SECURE_NO_WARNINGS
12 #endif
13
14 #include <boost/multiprecision/cpp_int.hpp>
15 #include <boost/random/mersenne_twister.hpp>
16 #include <boost/random/uniform_int.hpp>
17 #include <boost/timer.hpp>
18 #include "test.hpp"
19
20 #include <iostream>
21 #include <iomanip>
22 #include <sstream>
23 #include <boost/archive/text_iarchive.hpp>
24 #include <boost/archive/text_oarchive.hpp>
25 #include <boost/archive/binary_iarchive.hpp>
26 #include <boost/archive/xml_iarchive.hpp>
27 #include <boost/archive/binary_oarchive.hpp>
28 #include <boost/archive/xml_oarchive.hpp>
29 #include <boost/exception/all.hpp>
30
31 template <class T>
32 T generate_random(unsigned bits_wanted)
33 {
34    static boost::random::mt19937               gen;
35    typedef boost::random::mt19937::result_type random_type;
36
37    T        max_val;
38    unsigned digits;
39    if (std::numeric_limits<T>::is_bounded && (bits_wanted == (unsigned)std::numeric_limits<T>::digits))
40    {
41       max_val = (std::numeric_limits<T>::max)();
42       digits  = std::numeric_limits<T>::digits;
43    }
44    else
45    {
46       max_val = T(1) << bits_wanted;
47       digits  = bits_wanted;
48    }
49
50    unsigned bits_per_r_val = std::numeric_limits<random_type>::digits - 1;
51    while ((random_type(1) << bits_per_r_val) > (gen.max)())
52       --bits_per_r_val;
53
54    unsigned terms_needed = digits / bits_per_r_val + 1;
55
56    T val = 0;
57    for (unsigned i = 0; i < terms_needed; ++i)
58    {
59       val *= (gen.max)();
60       val += gen();
61    }
62    val %= max_val;
63    return val;
64 }
65
66 template <class T>
67 void test_neg(const T& x, const boost::mpl::true_&)
68 {
69    T val = -x;
70 #ifndef BOOST_NO_EXCEPTIONS
71    try
72    {
73 #endif
74       std::stringstream             ss;
75       boost::archive::text_oarchive oa(ss);
76       oa << static_cast<const T&>(val);
77       boost::archive::text_iarchive ia(ss);
78       T                             val2;
79       ia >> val2;
80       BOOST_CHECK_EQUAL(val, val2);
81
82       ss.clear();
83       boost::archive::binary_oarchive ob(ss);
84       ob << static_cast<const T&>(val);
85       boost::archive::binary_iarchive ib(ss);
86       ib >> val2;
87       BOOST_CHECK_EQUAL(val, val2);
88 #ifndef BOOST_NO_EXCEPTIONS
89    }
90    catch (const boost::exception& e)
91    {
92       std::cout << "Caught boost::exception with:\n";
93       std::cout << diagnostic_information(e);
94    }
95    catch (const std::exception& e)
96    {
97       std::cout << "Caught std::exception with:\n";
98       std::cout << e.what() << std::endl;
99    }
100 #endif
101 }
102 template <class T>
103 void test_neg(const T&, const boost::mpl::false_&) {}
104
105 template <class T>
106 void test()
107 {
108    using namespace boost::multiprecision;
109
110    boost::random::mt19937 gen;
111    boost::uniform_int<>   d(3, std::numeric_limits<T>::is_bounded ? std::numeric_limits<T>::digits : 3000);
112    boost::timer           tim;
113
114    while (true)
115    {
116       T val = generate_random<T>(d(gen));
117 #ifndef BOOST_NO_EXCEPTIONS
118       try
119       {
120 #endif
121          T val2;
122          {
123             std::stringstream             ss;
124             boost::archive::text_oarchive oa(ss);
125             oa << static_cast<const T&>(val);
126             boost::archive::text_iarchive ia(ss);
127             ia >> val2;
128             BOOST_CHECK_EQUAL(val, val2);
129          }
130          {
131             std::stringstream               ss;
132             boost::archive::binary_oarchive ob(ss);
133             ob << static_cast<const T&>(val);
134             boost::archive::binary_iarchive ib(ss);
135             ib >> val2;
136             BOOST_CHECK_EQUAL(val, val2);
137          }
138          {
139             std::stringstream ss;
140             {
141                boost::archive::xml_oarchive oc(ss);
142                oc << boost::serialization::make_nvp("value", static_cast<const T&>(val));
143             }
144             boost::archive::xml_iarchive ic(ss);
145             ic >> boost::serialization::make_nvp("value", val2);
146             BOOST_CHECK_EQUAL(val, val2);
147          }
148
149 #ifndef BOOST_NO_EXCEPTIONS
150       }
151       catch (const boost::exception& e)
152       {
153          std::cout << "Caught boost::exception with:\n";
154          std::cout << diagnostic_information(e);
155       }
156       catch (const std::exception& e)
157       {
158          std::cout << "Caught std::exception with:\n";
159          std::cout << e.what() << std::endl;
160       }
161 #endif
162       test_neg(val, boost::mpl::bool_<std::numeric_limits<T>::is_signed>());
163       //
164       // Check to see if test is taking too long.
165       // Tests run on the compiler farm time out after 300 seconds,
166       // so don't get too close to that:
167       //
168 #ifndef CI_SUPPRESS_KNOWN_ISSUES
169       if (tim.elapsed() > 150)
170 #else
171       if (tim.elapsed() > 25)
172 #endif
173       {
174          std::cout << "Timeout reached, aborting tests now....\n";
175          break;
176       }
177    }
178 }
179
180 #if !defined(TEST1) && !defined(TEST2) && !defined(TEST3) && !defined(TEST4)
181 #define TEST1
182 #define TEST2
183 #define TEST3
184 #define TEST4
185 #endif
186
187 int main()
188 {
189    using namespace boost::multiprecision;
190 #ifdef TEST1
191    test<cpp_int>();
192 #endif
193 #ifdef TEST2
194    test<number<cpp_int_backend<61, 61, unsigned_magnitude, unchecked, void> > >();
195 #endif
196 #ifdef TEST3
197    test<number<cpp_int_backend<120, 120, signed_magnitude, unchecked, void> > >();
198 #endif
199 #ifdef TEST4
200    test<int1024_t>();
201 #endif
202    return boost::report_errors();
203 }