test_float_serial.hpp 5.7 KB

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