test_generator.ipp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /* test_generator.ipp
  2. *
  3. * Copyright Steven Watanabe 2011
  4. * Distributed under the Boost Software License, Version 1.0. (See
  5. * accompanying file LICENSE_1_0.txt or copy at
  6. * http://www.boost.org/LICENSE_1_0.txt)
  7. *
  8. * $Id$
  9. *
  10. */
  11. #include "concepts.hpp"
  12. #include <boost/random/seed_seq.hpp>
  13. #define BOOST_TEST_MAIN
  14. #include <boost/test/unit_test.hpp>
  15. using boost::random::test::RandomNumberEngine;
  16. BOOST_CONCEPT_ASSERT((RandomNumberEngine< BOOST_RANDOM_URNG >));
  17. typedef BOOST_RANDOM_URNG::result_type result_type;
  18. typedef boost::random::detail::seed_type<result_type>::type seed_type;
  19. #ifdef BOOST_MSVC
  20. #pragma warning(push)
  21. #pragma warning(disable:4244)
  22. #endif
  23. #ifndef BOOST_RANDOM_DISCARD_COUNT1
  24. #define BOOST_RANDOM_DISCARD_COUNT1 9307
  25. #endif
  26. template<class Converted, class URNG, class T>
  27. void test_seed_conversion(URNG & urng, const T & t)
  28. {
  29. Converted c = static_cast<Converted>(t);
  30. if(static_cast<T>(c) == t) {
  31. URNG urng2(c);
  32. std::ostringstream msg;
  33. msg << "Testing seed: type " << typeid(Converted).name() << ", value " << c;
  34. BOOST_CHECK_MESSAGE(urng == urng2, msg.str());
  35. urng2.seed(c);
  36. BOOST_CHECK_MESSAGE(urng == urng2, msg.str());
  37. }
  38. }
  39. #ifdef BOOST_MSVC
  40. #pragma warning(pop)
  41. #endif
  42. void test_seed(seed_type value)
  43. {
  44. BOOST_RANDOM_URNG urng(value);
  45. // integral types
  46. test_seed_conversion<char>(urng, value);
  47. test_seed_conversion<signed char>(urng, value);
  48. test_seed_conversion<unsigned char>(urng, value);
  49. test_seed_conversion<short>(urng, value);
  50. test_seed_conversion<unsigned short>(urng, value);
  51. test_seed_conversion<int>(urng, value);
  52. test_seed_conversion<unsigned int>(urng, value);
  53. test_seed_conversion<long>(urng, value);
  54. test_seed_conversion<unsigned long>(urng, value);
  55. #if !defined(BOOST_NO_INT64_T)
  56. test_seed_conversion<boost::int64_t>(urng, value);
  57. test_seed_conversion<boost::uint64_t>(urng, value);
  58. #endif
  59. // floating point types
  60. test_seed_conversion<float>(urng, value);
  61. test_seed_conversion<double>(urng, value);
  62. test_seed_conversion<long double>(urng, value);
  63. }
  64. BOOST_AUTO_TEST_CASE(test_default_seed)
  65. {
  66. BOOST_RANDOM_URNG urng;
  67. BOOST_RANDOM_URNG urng2;
  68. urng2();
  69. BOOST_CHECK_NE(urng, urng2);
  70. urng2.seed();
  71. BOOST_CHECK_EQUAL(urng, urng2);
  72. }
  73. BOOST_AUTO_TEST_CASE(test_arithmetic_seed)
  74. {
  75. test_seed(static_cast<seed_type>(0));
  76. test_seed(static_cast<seed_type>(127));
  77. test_seed(static_cast<seed_type>(539157235));
  78. test_seed(static_cast<seed_type>(~0u));
  79. }
  80. BOOST_AUTO_TEST_CASE(test_iterator_seed)
  81. {
  82. const std::vector<int> v((std::max)(std::size_t(9999u), sizeof(BOOST_RANDOM_URNG) / 4), 0x41);
  83. std::vector<int>::const_iterator it = v.begin();
  84. std::vector<int>::const_iterator it_end = v.end();
  85. BOOST_RANDOM_URNG urng(it, it_end);
  86. BOOST_CHECK(it != v.begin());
  87. std::iterator_traits<std::vector<int>::const_iterator>::difference_type n_words = (it - v.begin());
  88. BOOST_CHECK_GT(n_words, 0);
  89. BOOST_CHECK_EQUAL(n_words, BOOST_RANDOM_SEED_WORDS);
  90. it = v.begin();
  91. BOOST_RANDOM_URNG urng2;
  92. urng2.seed(it, it_end);
  93. std::iterator_traits<std::vector<int>::const_iterator>::difference_type n_words2 = (it - v.begin());
  94. BOOST_CHECK_EQUAL(n_words, n_words2);
  95. BOOST_CHECK_EQUAL(urng, urng2);
  96. it = v.end();
  97. BOOST_CHECK_THROW(BOOST_RANDOM_URNG(it, it_end), std::invalid_argument);
  98. BOOST_CHECK_THROW(urng.seed(it, it_end), std::invalid_argument);
  99. if(n_words > 1) {
  100. it = v.end();
  101. --it;
  102. BOOST_CHECK_THROW(BOOST_RANDOM_URNG(it, it_end), std::invalid_argument);
  103. it = v.end();
  104. --it;
  105. BOOST_CHECK_THROW(urng.seed(it, it_end), std::invalid_argument);
  106. }
  107. }
  108. BOOST_AUTO_TEST_CASE(test_seed_seq_seed)
  109. {
  110. boost::random::seed_seq q;
  111. BOOST_RANDOM_URNG urng(q);
  112. BOOST_RANDOM_URNG urng2;
  113. BOOST_CHECK_NE(urng, urng2);
  114. urng2.seed(q);
  115. BOOST_CHECK_EQUAL(urng, urng2);
  116. }
  117. template<class CharT>
  118. void do_test_streaming(const BOOST_RANDOM_URNG& urng)
  119. {
  120. BOOST_RANDOM_URNG urng2;
  121. std::basic_ostringstream<CharT> output;
  122. output << urng;
  123. BOOST_CHECK_NE(urng, urng2);
  124. // restore old state
  125. std::basic_istringstream<CharT> input(output.str());
  126. input >> urng2;
  127. BOOST_CHECK_EQUAL(urng, urng2);
  128. }
  129. BOOST_AUTO_TEST_CASE(test_streaming)
  130. {
  131. BOOST_RANDOM_URNG urng;
  132. urng.discard(9307);
  133. do_test_streaming<char>(urng);
  134. #if !defined(BOOST_NO_STD_WSTREAMBUF) && !defined(BOOST_NO_STD_WSTRING)
  135. do_test_streaming<wchar_t>(urng);
  136. #endif
  137. }
  138. BOOST_AUTO_TEST_CASE(test_discard)
  139. {
  140. BOOST_RANDOM_URNG urng;
  141. BOOST_RANDOM_URNG urng2;
  142. BOOST_CHECK_EQUAL(urng, urng2);
  143. for(int i = 0; i < BOOST_RANDOM_DISCARD_COUNT1; ++i)
  144. urng();
  145. BOOST_CHECK_NE(urng, urng2);
  146. urng2.discard(BOOST_RANDOM_DISCARD_COUNT1);
  147. BOOST_CHECK_EQUAL(urng, urng2);
  148. }
  149. #ifdef BOOST_RANDOM_DISCARD_COUNT2
  150. BOOST_AUTO_TEST_CASE(test_discard2)
  151. {
  152. BOOST_RANDOM_URNG urng;
  153. BOOST_RANDOM_URNG urng2;
  154. BOOST_CHECK_EQUAL(urng, urng2);
  155. for(int i = 0; i < BOOST_RANDOM_DISCARD_COUNT2; ++i)
  156. urng();
  157. BOOST_CHECK_NE(urng, urng2);
  158. urng2.discard(BOOST_RANDOM_DISCARD_COUNT2);
  159. BOOST_CHECK_EQUAL(urng, urng2);
  160. }
  161. #endif
  162. #ifdef BOOST_RANDOM_DISCARD_MAX
  163. BOOST_AUTO_TEST_CASE(test_discard_max)
  164. {
  165. boost::uintmax_t val = (std::numeric_limits<boost::uintmax_t>::max)();
  166. boost::uintmax_t half = val / 2;
  167. BOOST_RANDOM_URNG urng;
  168. BOOST_RANDOM_URNG urng2;
  169. urng.discard(half);
  170. urng.discard(half);
  171. urng.discard(val - 2*half);
  172. urng2.discard(val);
  173. BOOST_CHECK_EQUAL(urng, urng2);
  174. }
  175. #endif
  176. BOOST_AUTO_TEST_CASE(test_copy)
  177. {
  178. BOOST_RANDOM_URNG urng;
  179. urng.discard(9307);
  180. {
  181. BOOST_RANDOM_URNG urng2 = urng;
  182. BOOST_CHECK_EQUAL(urng, urng2);
  183. }
  184. {
  185. BOOST_RANDOM_URNG urng2(urng);
  186. BOOST_CHECK_EQUAL(urng, urng2);
  187. }
  188. {
  189. BOOST_RANDOM_URNG urng2;
  190. urng2 = urng;
  191. BOOST_CHECK_EQUAL(urng, urng2);
  192. }
  193. }
  194. BOOST_AUTO_TEST_CASE(test_min_max)
  195. {
  196. BOOST_RANDOM_URNG urng;
  197. for(int i = 0; i < 10000; ++i) {
  198. result_type value = urng();
  199. BOOST_CHECK_GE(value, (BOOST_RANDOM_URNG::min)());
  200. BOOST_CHECK_LE(value, (BOOST_RANDOM_URNG::max)());
  201. }
  202. }
  203. BOOST_AUTO_TEST_CASE(test_comparison)
  204. {
  205. BOOST_RANDOM_URNG urng;
  206. BOOST_RANDOM_URNG urng2;
  207. BOOST_CHECK(urng == urng2);
  208. BOOST_CHECK(!(urng != urng2));
  209. urng();
  210. BOOST_CHECK(urng != urng2);
  211. BOOST_CHECK(!(urng == urng2));
  212. }
  213. BOOST_AUTO_TEST_CASE(validate)
  214. {
  215. BOOST_RANDOM_URNG urng;
  216. for(int i = 0; i < 9999; ++i) {
  217. urng();
  218. }
  219. BOOST_CHECK_EQUAL(urng(), BOOST_RANDOM_VALIDATION_VALUE);
  220. }
  221. BOOST_AUTO_TEST_CASE(validate_seed_seq)
  222. {
  223. boost::random::seed_seq seed;
  224. BOOST_RANDOM_URNG urng(seed);
  225. for(int i = 0; i < 9999; ++i) {
  226. urng();
  227. }
  228. BOOST_CHECK_EQUAL(urng(), BOOST_RANDOM_SEED_SEQ_VALIDATION_VALUE);
  229. }
  230. BOOST_AUTO_TEST_CASE(validate_iter)
  231. {
  232. const std::vector<int> v((std::max)(std::size_t(9999u), sizeof(BOOST_RANDOM_URNG) / 4), 0x41);
  233. std::vector<int>::const_iterator it = v.begin();
  234. std::vector<int>::const_iterator it_end = v.end();
  235. BOOST_RANDOM_URNG urng(it, it_end);
  236. for(int i = 0; i < 9999; ++i) {
  237. urng();
  238. }
  239. BOOST_CHECK_EQUAL(urng(), BOOST_RANDOM_ITERATOR_VALIDATION_VALUE);
  240. }
  241. BOOST_AUTO_TEST_CASE(test_generate)
  242. {
  243. BOOST_RANDOM_URNG urng;
  244. boost::uint32_t expected[] = BOOST_RANDOM_GENERATE_VALUES;
  245. static const std::size_t N = sizeof(expected)/sizeof(expected[0]);
  246. boost::uint32_t actual[N];
  247. urng.generate(&actual[0], &actual[0] + N);
  248. BOOST_CHECK_EQUAL_COLLECTIONS(actual, actual + N, expected, expected + N);
  249. }