catch_random_number_generator.cpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /*
  2. * Created by Martin on 30/08/2017.
  3. *
  4. * Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. #include "catch_random_number_generator.h"
  8. #include "catch_context.h"
  9. #include "catch_run_context.h"
  10. #include "catch_interfaces_config.h"
  11. namespace Catch {
  12. namespace {
  13. #if defined(_MSC_VER)
  14. #pragma warning(push)
  15. #pragma warning(disable:4146) // we negate uint32 during the rotate
  16. #endif
  17. // Safe rotr implementation thanks to John Regehr
  18. uint32_t rotate_right(uint32_t val, uint32_t count) {
  19. const uint32_t mask = 31;
  20. count &= mask;
  21. return (val >> count) | (val << (-count & mask));
  22. }
  23. #if defined(_MSC_VER)
  24. #pragma warning(pop)
  25. #endif
  26. }
  27. SimplePcg32::SimplePcg32(result_type seed_) {
  28. seed(seed_);
  29. }
  30. void SimplePcg32::seed(result_type seed_) {
  31. m_state = 0;
  32. (*this)();
  33. m_state += seed_;
  34. (*this)();
  35. }
  36. void SimplePcg32::discard(uint64_t skip) {
  37. // We could implement this to run in O(log n) steps, but this
  38. // should suffice for our use case.
  39. for (uint64_t s = 0; s < skip; ++s) {
  40. static_cast<void>((*this)());
  41. }
  42. }
  43. SimplePcg32::result_type SimplePcg32::operator()() {
  44. // prepare the output value
  45. const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
  46. const auto output = rotate_right(xorshifted, m_state >> 59u);
  47. // advance state
  48. m_state = m_state * 6364136223846793005ULL + s_inc;
  49. return output;
  50. }
  51. bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
  52. return lhs.m_state == rhs.m_state;
  53. }
  54. bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
  55. return lhs.m_state != rhs.m_state;
  56. }
  57. }