2017-08-30 15:32:44 +02:00
|
|
|
/*
|
|
|
|
* 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)
|
|
|
|
*/
|
|
|
|
#ifndef TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED
|
|
|
|
#define TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED
|
|
|
|
|
2019-10-06 21:47:54 +02:00
|
|
|
#include <cstdint>
|
2017-08-30 15:32:44 +02:00
|
|
|
|
|
|
|
namespace Catch {
|
|
|
|
|
2019-10-06 21:47:54 +02:00
|
|
|
// 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;
|
2019-10-17 11:21:17 +02:00
|
|
|
static constexpr result_type (min)() {
|
2019-10-06 21:47:54 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2019-10-17 11:21:17 +02:00
|
|
|
static constexpr result_type (max)() {
|
2019-10-06 21:47:54 +02:00
|
|
|
return static_cast<result_type>(-1);
|
|
|
|
}
|
2017-08-30 15:32:44 +02:00
|
|
|
|
2019-10-06 21:47:54 +02:00
|
|
|
// Provide some default initial state for the default constructor
|
|
|
|
SimplePcg32():SimplePcg32(0xed743cc4U) {}
|
2017-08-30 15:32:44 +02:00
|
|
|
|
2019-10-06 21:47:54 +02:00
|
|
|
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
|
2017-08-30 15:32:44 +02:00
|
|
|
|
|
|
|
#endif // TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED
|