libdonut 2.3.6
Application framework for cross-platform game development in C++20
Loading...
Searching...
No Matches
random.hpp
Go to the documentation of this file.
1#ifndef DONUT_RANDOM_HPP
2#define DONUT_RANDOM_HPP
3
4#include <algorithm> // std::generate
5#include <array> // std::array
6#include <bit> // std::rotl
7#include <cstdint> // std::uint64_t
8#include <istream> // std::basic_istream
9#include <limits> // std::numeric_limits
10#include <ostream> // std::basic_ostream
11
12namespace donut::random {
13
29public:
30 using result_type = std::uint64_t;
31
32 static constexpr result_type default_seed = 0;
33
34 [[nodiscard]] static constexpr result_type min() {
35 return 0;
36 }
37
38 [[nodiscard]] static constexpr result_type max() {
39 return std::numeric_limits<result_type>::max();
40 }
41
42 constexpr SplitMix64Engine() noexcept
44
45 constexpr explicit SplitMix64Engine(result_type value) noexcept
46 : state(value) {}
47
48 constexpr void seed(result_type value = default_seed) noexcept {
49 state = value;
50 }
51
52 constexpr result_type operator()() noexcept {
53 state += 0x9E3779B97F4A7C15ull;
54 std::uint64_t z = state;
55 z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9ull;
56 z = (z ^ (z >> 27)) * 0x94D049BB133111EBull;
57 return z ^ (z >> 31);
58 }
59
60 constexpr void discard(unsigned long long z) noexcept {
61 while (z-- > 0) {
62 (*this)();
63 }
64 }
65
66 [[nodiscard]] constexpr bool operator==(const SplitMix64Engine& other) const noexcept {
67 return state == other.state;
68 }
69
70 template <typename CharT, typename Traits>
71 friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& stream, const SplitMix64Engine& engine) {
72 return stream << engine.state;
73 }
74
75 template <typename CharT, typename Traits>
76 friend std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& stream, SplitMix64Engine& engine) {
77 return stream >> engine.state;
78 }
79
80private:
81 std::uint64_t state;
82};
83
99public:
100 using result_type = std::uint64_t;
101
103
104 [[nodiscard]] static constexpr result_type min() {
105 return 0;
106 }
107
108 [[nodiscard]] static constexpr result_type max() {
109 return std::numeric_limits<result_type>::max();
110 }
111
114
115 constexpr explicit Xoroshiro128PlusPlusEngine(result_type value) noexcept {
116 seed(value);
117 }
118
119 constexpr void seed(result_type value = default_seed) noexcept {
120 SplitMix64Engine stateGenerator{value};
121 std::generate(state.begin(), state.end(), stateGenerator);
122 }
123
124 constexpr result_type operator()() noexcept {
125 const std::uint64_t s0 = state[0];
126 std::uint64_t s1 = state[1];
127 const std::uint64_t result = std::rotl(s0 + s1, 17) + s0;
128 s1 ^= s0;
129 state[0] = std::rotl(s0, 49) ^ s1 ^ (s1 << 21);
130 state[1] = std::rotl(s1, 28);
131 return result;
132 }
133
134 constexpr void discard(unsigned long long z) noexcept {
135 while (z-- > 0) {
136 (*this)();
137 }
138 }
139
143 constexpr void jump() noexcept {
144 std::uint64_t s0 = 0;
145 std::uint64_t s1 = 0;
146 for (const std::uint64_t c : {0x2BD7A6A6E99C2DDCull, 0x0992CCAF6A6FCA05ull}) {
147 for (int b = 0; b < 64; ++b) {
148 if ((c & (std::uint64_t{1} << b)) != 0) {
149 s0 ^= state[0];
150 s1 ^= state[1];
151 }
152 (*this)();
153 }
154 }
155 state[0] = s0;
156 state[1] = s1;
157 }
158
162 constexpr void longJump() noexcept {
163 std::uint64_t s0 = 0;
164 std::uint64_t s1 = 0;
165 for (const std::uint64_t c : {0x360FD5F2CF8D5D99ull, 0x9C6E6877736C46E3ull}) {
166 for (int b = 0; b < 64; ++b) {
167 if ((c & (std::uint64_t{1} << b)) != 0) {
168 s0 ^= state[0];
169 s1 ^= state[1];
170 }
171 (*this)();
172 }
173 }
174 state[0] = s0;
175 state[1] = s1;
176 }
177
178 [[nodiscard]] constexpr bool operator==(const Xoroshiro128PlusPlusEngine& other) const noexcept {
179 return state == other.state;
180 }
181
182 template <typename CharT, typename Traits>
183 friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& stream, const Xoroshiro128PlusPlusEngine& engine) {
184 return stream << engine.state[0] << ' ' << engine.state[1];
185 }
186
187 template <typename CharT, typename Traits>
188 friend std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& stream, Xoroshiro128PlusPlusEngine& engine) {
189 return stream >> engine.state[0] >> engine.state[1];
190 }
191
192private:
193 std::array<std::uint64_t, 2> state{};
194};
195
196} // namespace donut::random
197
198#endif
Implementation of the SplitMix64 pseudorandom number generator that provides the API required for a s...
Definition random.hpp:28
static constexpr result_type min()
Definition random.hpp:34
constexpr void discard(unsigned long long z) noexcept
Definition random.hpp:60
static constexpr result_type max()
Definition random.hpp:38
constexpr result_type operator()() noexcept
Definition random.hpp:52
constexpr void seed(result_type value=default_seed) noexcept
Definition random.hpp:48
constexpr bool operator==(const SplitMix64Engine &other) const noexcept
Definition random.hpp:66
constexpr SplitMix64Engine(result_type value) noexcept
Definition random.hpp:45
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &stream, SplitMix64Engine &engine)
Definition random.hpp:76
constexpr SplitMix64Engine() noexcept
Definition random.hpp:42
static constexpr result_type default_seed
Definition random.hpp:32
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &stream, const SplitMix64Engine &engine)
Definition random.hpp:71
std::uint64_t result_type
Definition random.hpp:30
Implementation of the xoroshiro128++ pseudorandom number generator that provides the API required for...
Definition random.hpp:98
static constexpr result_type min()
Definition random.hpp:104
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &stream, Xoroshiro128PlusPlusEngine &engine)
Definition random.hpp:188
static constexpr result_type max()
Definition random.hpp:108
std::uint64_t result_type
Definition random.hpp:100
constexpr Xoroshiro128PlusPlusEngine() noexcept
Definition random.hpp:112
static constexpr result_type default_seed
Definition random.hpp:102
constexpr void longJump() noexcept
Advance the internal state 2^96 times.
Definition random.hpp:162
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &stream, const Xoroshiro128PlusPlusEngine &engine)
Definition random.hpp:183
constexpr void seed(result_type value=default_seed) noexcept
Definition random.hpp:119
constexpr void discard(unsigned long long z) noexcept
Definition random.hpp:134
constexpr void jump() noexcept
Advance the internal state 2^64 times.
Definition random.hpp:143
constexpr bool operator==(const Xoroshiro128PlusPlusEngine &other) const noexcept
Definition random.hpp:178
constexpr result_type operator()() noexcept
Definition random.hpp:124
constexpr Xoroshiro128PlusPlusEngine(result_type value) noexcept
Definition random.hpp:115
Definition utilities.hpp:135