test_random_generator.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // (C) Copyright Andy Tompkins 2010. Permission to copy, use, modify, sell and
  2. // distribute this software is granted provided this copyright notice appears
  3. // in all copies. This software is provided "as is" without express or implied
  4. // warranty, and with no claim as to its suitability for any purpose.
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // https://www.boost.org/LICENSE_1_0.txt)
  8. // libs/uuid/test/test_random_generator.cpp -------------------------------//
  9. #include <boost/core/ignore_unused.hpp>
  10. #include <boost/detail/lightweight_test.hpp>
  11. #include <boost/predef/library/c/cloudabi.h>
  12. #include <boost/random.hpp>
  13. #include <boost/uuid/entropy_error.hpp>
  14. #include <boost/uuid/random_generator.hpp>
  15. #include <boost/uuid/uuid_io.hpp>
  16. #include <boost/uuid/uuid.hpp>
  17. #include <boost/move/utility_core.hpp>
  18. template <typename RandomUuidGenerator>
  19. void check_random_generator(RandomUuidGenerator& uuid_gen)
  20. {
  21. boost::uuids::uuid u1 = uuid_gen();
  22. boost::uuids::uuid u2 = uuid_gen();
  23. BOOST_TEST_NE(u1, u2);
  24. // check variant
  25. BOOST_TEST_EQ(u1.variant(), boost::uuids::uuid::variant_rfc_4122);
  26. // version
  27. BOOST_TEST_EQ(u1.version(), boost::uuids::uuid::version_random_number_based);
  28. }
  29. // This is the example block from the documentation - ensure it works!
  30. void test_examples()
  31. {
  32. // Depending on the platform there may be a setup cost in
  33. // initializing the generator so plan to reuse it if you can.
  34. boost::uuids::random_generator gen;
  35. boost::uuids::uuid id = gen();
  36. boost::uuids::uuid id2 = gen();
  37. #if !BOOST_LIB_C_CLOUDABI
  38. std::cout << id << std::endl;
  39. std::cout << id2 << std::endl;
  40. #endif
  41. BOOST_TEST_NE(id, id2);
  42. boost::ignore_unused(id);
  43. boost::ignore_unused(id2);
  44. // You can still use a PseudoRandomNumberGenerator to create
  45. // UUIDs, however this is not the preferred mechanism. For
  46. // large numbers of UUIDs this may be more CPU efficient but
  47. // it comes with all the perils of a PRNG. The test code
  48. // in test_bench_random identifies the transition point for
  49. // a given system.
  50. boost::uuids::random_generator_mt19937 bulkgen;
  51. for (size_t i = 0; i < 1000; ++i)
  52. {
  53. boost::uuids::uuid u = bulkgen();
  54. // do something with u
  55. boost::ignore_unused(u);
  56. }
  57. }
  58. int main(int, char*[])
  59. {
  60. using namespace boost::uuids;
  61. // default random number generator
  62. {
  63. random_generator uuid_gen1;
  64. check_random_generator(uuid_gen1);
  65. #if !BOOST_LIB_C_CLOUDABI
  66. // dump 10 of them to cout for observation
  67. for (size_t i = 0; i < 10; ++i)
  68. {
  69. std::cout << uuid_gen1() << std::endl;
  70. }
  71. #endif
  72. }
  73. // specific random number generator
  74. {
  75. basic_random_generator<boost::rand48> uuid_gen2;
  76. check_random_generator(uuid_gen2);
  77. }
  78. // pass by reference
  79. {
  80. boost::ecuyer1988 ecuyer1988_gen;
  81. basic_random_generator<boost::ecuyer1988> uuid_gen3(ecuyer1988_gen);
  82. check_random_generator(uuid_gen3);
  83. }
  84. // pass by pointer
  85. {
  86. boost::lagged_fibonacci607 lagged_fibonacci607_gen;
  87. basic_random_generator<boost::lagged_fibonacci607> uuid_gen4(&lagged_fibonacci607_gen);
  88. check_random_generator(uuid_gen4);
  89. }
  90. // check move construction
  91. {
  92. random_generator uuid_gen1;
  93. random_generator uuid_gen2(boost::move(uuid_gen1));
  94. boost::ignore_unused(uuid_gen2);
  95. }
  96. {
  97. basic_random_generator<boost::rand48> uuid_gen1;
  98. basic_random_generator<boost::rand48> uuid_gen2(boost::move(uuid_gen1));
  99. boost::ignore_unused(uuid_gen2);
  100. }
  101. // check move assignment
  102. {
  103. random_generator uuid_gen1, uuid_gen2;
  104. uuid_gen2 = boost::move(uuid_gen1);
  105. boost::ignore_unused(uuid_gen2);
  106. }
  107. {
  108. basic_random_generator<boost::rand48> uuid_gen1, uuid_gen2;
  109. uuid_gen2 = boost::move(uuid_gen1);
  110. boost::ignore_unused(uuid_gen2);
  111. }
  112. // there was a bug in basic_random_generator where it did not
  113. // produce very random numbers. This checks for that bug.
  114. {
  115. random_generator_mt19937 bulkgen;
  116. uuid u = bulkgen();
  117. if ((u.data[4] == u.data[12]) &&
  118. (u.data[5] == u.data[9] && u.data[5] == u.data[13]) &&
  119. (u.data[7] == u.data[11] && u.data[7] == u.data[15]) &&
  120. (u.data[10] == u.data[14]))
  121. {
  122. BOOST_ERROR("basic_random_generator is not producing random uuids");
  123. }
  124. // pseudo
  125. check_random_generator(bulkgen);
  126. }
  127. // make sure default construction seeding is happening for PRNGs
  128. {
  129. random_generator_mt19937 gen1;
  130. random_generator_mt19937 gen2;
  131. BOOST_TEST_NE(gen1(), gen2());
  132. }
  133. // The example code snippet in the documentation
  134. test_examples();
  135. return boost::report_errors();
  136. }