Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / multiprecision / test / test_float_serial.hpp
1 ///////////////////////////////////////////////////////////////
2 //  Copyright 2013 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 #include <boost/random/mersenne_twister.hpp>
7 #include <boost/random/uniform_int.hpp>
8 #include <boost/timer.hpp>
9 #include "test.hpp"
10
11 #include <iostream>
12 #include <iomanip>
13 #include <sstream>
14 #include <boost/archive/text_iarchive.hpp>
15 #include <boost/archive/text_oarchive.hpp>
16 #include <boost/archive/binary_iarchive.hpp>
17 #include <boost/archive/binary_oarchive.hpp>
18 #include <boost/archive/xml_iarchive.hpp>
19 #include <boost/archive/xml_oarchive.hpp>
20 #include <boost/exception/all.hpp>
21
22 #ifndef BOOST_MP_TEST_FLOAT_SERIAL_HPP
23 #define BOOST_MP_TEST_FLOAT_SERIAL_HPP
24
25 template <class T>
26 T generate_random(unsigned /*bits_wanted*/)
27 {
28    typedef typename T::backend_type::exponent_type e_type;
29    static boost::random::mt19937                   gen;
30    T                                               val      = gen();
31    T                                               prev_val = -1;
32    while (val != prev_val)
33    {
34       val *= (gen.max)();
35       prev_val = val;
36       val += gen();
37    }
38    e_type e;
39    val = frexp(val, &e);
40
41    static boost::random::uniform_int_distribution<e_type> ui(std::numeric_limits<T>::min_exponent + 1, std::numeric_limits<T>::max_exponent - 1);
42    return ldexp(val, ui(gen));
43 }
44
45 template <class T>
46 void test()
47 {
48    boost::timer tim;
49
50    while (true)
51    {
52       T           val     = generate_random<T>(boost::math::tools::digits<T>());
53       int         test_id = 0;
54       std::string stream_contents;
55 #ifndef BOOST_NO_EXCEPTIONS
56       try
57       {
58 #endif
59          test_id = 0;
60          {
61             std::stringstream             ss(std::ios_base::in | std::ios_base::out | std::ios_base::binary);
62             boost::archive::text_oarchive oa(ss);
63             oa << static_cast<const T&>(val);
64             stream_contents = ss.str();
65             boost::archive::text_iarchive ia(ss);
66             T                             val2;
67             ia >> val2;
68             BOOST_CHECK_EQUAL(val, val2);
69          }
70          {
71             std::stringstream ss(std::ios_base::in | std::ios_base::out | std::ios_base::binary);
72             {
73                boost::archive::xml_oarchive oa(ss);
74                oa << boost::serialization::make_nvp("value", static_cast<const T&>(val));
75                stream_contents = ss.str();
76             }
77             boost::archive::xml_iarchive ia(ss);
78             T                            val2;
79             ia >> boost::serialization::make_nvp("value", val2);
80             BOOST_CHECK_EQUAL(val, val2);
81          }
82          {
83             std::stringstream ss(std::ios_base::in | std::ios_base::out | std::ios_base::binary);
84             ++test_id;
85             boost::archive::binary_oarchive ba(ss);
86             ba << static_cast<const T&>(val);
87             stream_contents = ss.str();
88             boost::archive::binary_iarchive ib(ss);
89             T                               val2;
90             ib >> val2;
91             BOOST_CHECK_EQUAL(val, val2);
92          }
93          {
94             std::stringstream ss(std::ios_base::in | std::ios_base::out | std::ios_base::binary);
95             val = -val;
96             ++test_id;
97             boost::archive::text_oarchive oa2(ss);
98             oa2 << static_cast<const T&>(val);
99             stream_contents = ss.str();
100             boost::archive::text_iarchive ia2(ss);
101             T                             val2;
102             ia2 >> val2;
103             BOOST_CHECK_EQUAL(val, val2);
104          }
105          {
106             std::stringstream ss(std::ios_base::in | std::ios_base::out | std::ios_base::binary);
107             ++test_id;
108             {
109                boost::archive::xml_oarchive oa2(ss);
110                oa2 << boost::serialization::make_nvp("value", static_cast<const T&>(val));
111                stream_contents = ss.str();
112             }
113             boost::archive::xml_iarchive ia2(ss);
114             T                            val2;
115             ia2 >> boost::serialization::make_nvp("value", val2);
116             BOOST_CHECK_EQUAL(val, val2);
117          }
118          {
119             std::stringstream ss(std::ios_base::in | std::ios_base::out | std::ios_base::binary);
120             ++test_id;
121             boost::archive::binary_oarchive ba2(ss);
122             ba2 << static_cast<const T&>(val);
123             stream_contents = ss.str();
124             boost::archive::binary_iarchive ib2(ss);
125             T                               val2;
126             ib2 >> val2;
127             BOOST_CHECK_EQUAL(val, val2);
128          }
129 #ifndef BOOST_NO_EXCEPTIONS
130       }
131       catch (const boost::exception& e)
132       {
133          std::cout << "Caught boost::exception with:\n";
134          std::cout << diagnostic_information(e);
135          std::cout << "Failed test ID = " << test_id << std::endl;
136          std::cout << "Stream contents were: \n"
137                    << stream_contents << std::endl;
138          ++boost::detail::test_errors();
139          break;
140       }
141       catch (const std::exception& e)
142       {
143          std::cout << "Caught std::exception with:\n";
144          std::cout << e.what() << std::endl;
145          std::cout << "Failed test ID = " << test_id << std::endl;
146          std::cout << "Stream contents were: \n"
147                    << stream_contents << std::endl;
148          ++boost::detail::test_errors();
149          break;
150       }
151 #endif
152       //
153       // Check to see if test is taking too long.
154       // Tests run on the compiler farm time out after 300 seconds,
155       // so don't get too close to that:
156       //
157 #ifndef CI_SUPPRESS_KNOWN_ISSUES
158       if (tim.elapsed() > 150)
159 #else
160       if (tim.elapsed() > 25)
161 #endif
162       {
163          std::cout << "Timeout reached, aborting tests now....\n";
164          break;
165       }
166    }
167 }
168
169 #endif