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