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 #ifndef TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED 8 #define TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED 9 10 #include <cstdint> 11 12 namespace Catch { 13 14 // This is a simple implementation of C++11 Uniform Random Number 15 // Generator. It does not provide all operators, because Catch2 16 // does not use it, but it should behave as expected inside stdlib's 17 // distributions. 18 // The implementation is based on the PCG family (http://pcg-random.org) 19 class SimplePcg32 { 20 using state_type = std::uint64_t; 21 public: 22 using result_type = std::uint32_t; result_type(min)23 static constexpr result_type (min)() { 24 return 0; 25 } result_type(max)26 static constexpr result_type (max)() { 27 return static_cast<result_type>(-1); 28 } 29 30 // Provide some default initial state for the default constructor SimplePcg32()31 SimplePcg32():SimplePcg32(0xed743cc4U) {} 32 33 explicit SimplePcg32(result_type seed_); 34 35 void seed(result_type seed_); 36 void discard(uint64_t skip); 37 38 result_type operator()(); 39 40 private: 41 friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs); 42 friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs); 43 44 // In theory we also need operator<< and operator>> 45 // In practice we do not use them, so we will skip them for now 46 47 48 std::uint64_t m_state; 49 // This part of the state determines which "stream" of the numbers 50 // is chosen -- we take it as a constant for Catch2, so we only 51 // need to deal with seeding the main state. 52 // Picked by reading 8 bytes from `/dev/random` :-) 53 static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL; 54 }; 55 56 } // end namespace Catch 57 58 #endif // TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED 59