| /* |
| * Created by Martin on 30/08/2017. |
| * |
| * Distributed under the Boost Software License, Version 1.0. (See accompanying |
| * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| */ |
| |
| #include "catch_random_number_generator.h" |
| #include "catch_context.h" |
| #include "catch_run_context.h" |
| #include "catch_interfaces_config.h" |
| |
| namespace Catch { |
| |
| namespace { |
| |
| #if defined(_MSC_VER) |
| #pragma warning(push) |
| #pragma warning(disable:4146) // we negate uint32 during the rotate |
| #endif |
| // Safe rotr implementation thanks to John Regehr |
| uint32_t rotate_right(uint32_t val, uint32_t count) { |
| const uint32_t mask = 31; |
| count &= mask; |
| return (val >> count) | (val << (-count & mask)); |
| } |
| |
| #if defined(_MSC_VER) |
| #pragma warning(pop) |
| #endif |
| |
| } |
| |
| |
| SimplePcg32::SimplePcg32(result_type seed_) { |
| seed(seed_); |
| } |
| |
| |
| void SimplePcg32::seed(result_type seed_) { |
| m_state = 0; |
| (*this)(); |
| m_state += seed_; |
| (*this)(); |
| } |
| |
| void SimplePcg32::discard(uint64_t skip) { |
| // We could implement this to run in O(log n) steps, but this |
| // should suffice for our use case. |
| for (uint64_t s = 0; s < skip; ++s) { |
| static_cast<void>((*this)()); |
| } |
| } |
| |
| SimplePcg32::result_type SimplePcg32::operator()() { |
| // prepare the output value |
| const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u); |
| const auto output = rotate_right(xorshifted, m_state >> 59u); |
| |
| // advance state |
| m_state = m_state * 6364136223846793005ULL + s_inc; |
| |
| return output; |
| } |
| |
| bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) { |
| return lhs.m_state == rhs.m_state; |
| } |
| |
| bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) { |
| return lhs.m_state != rhs.m_state; |
| } |
| } |