diff options
Diffstat (limited to 'include/internal/catch_random_number_generator.h')
-rw-r--r-- | include/internal/catch_random_number_generator.h | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/include/internal/catch_random_number_generator.h b/include/internal/catch_random_number_generator.h index 817b7841..79d62794 100644 --- a/include/internal/catch_random_number_generator.h +++ b/include/internal/catch_random_number_generator.h @@ -7,17 +7,52 @@ #ifndef TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED #define TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED -#include <algorithm> -#include <random> +#include <cstdint> namespace Catch { - struct IConfig; + // This is a simple implementation of C++11 Uniform Random Number + // Generator. It does not provide all operators, because Catch2 + // does not use it, but it should behave as expected inside stdlib's + // distributions. + // The implementation is based on the PCG family (http://pcg-random.org) + class SimplePcg32 { + using state_type = std::uint64_t; + public: + using result_type = std::uint32_t; + static constexpr result_type (min)() { + return 0; + } + static constexpr result_type (max)() { + return static_cast<result_type>(-1); + } - std::mt19937& rng(); - void seedRng( IConfig const& config ); - unsigned int rngSeed(); + // Provide some default initial state for the default constructor + SimplePcg32():SimplePcg32(0xed743cc4U) {} -} + explicit SimplePcg32(result_type seed_); + + void seed(result_type seed_); + void discard(uint64_t skip); + + result_type operator()(); + + private: + friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs); + friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs); + + // In theory we also need operator<< and operator>> + // In practice we do not use them, so we will skip them for now + + + std::uint64_t m_state; + // This part of the state determines which "stream" of the numbers + // is chosen -- we take it as a constant for Catch2, so we only + // need to deal with seeding the main state. + // Picked by reading 8 bytes from `/dev/random` :-) + static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL; + }; + +} // end namespace Catch #endif // TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED |