Symphony Of Empires
rand.hpp
Go to the documentation of this file.
1 // Eng3D - General purpouse game engine
2 // Copyright (C) 2021, Eng3D contributors
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <https://www.gnu.org/licenses/>.
16 //
17 // ----------------------------------------------------------------------------
18 // Name:
19 // rand.hpp
20 //
21 // Abstract:
22 // Thread safe random number generator.
23 // ----------------------------------------------------------------------------
24 
25 #pragma once
26 
27 #include <random>
28 
29 #undef rot32
30 #define rot32(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
31 
32 namespace Eng3D {
34  class Rand {
35  uint32_t a = 0, b = 0, c = 0, d = 0;
36  public:
37  using result_type = uint32_t;
38  constexpr static uint32_t initial_seed = 0xf1ea5eed;
39 
40  constexpr Rand() = default;
41 
42  Rand(uint32_t seed) {
44  b = c = d = seed;
45  for(size_t i = 0; i < 20; ++i)
46  (*this)();
47  }
48 
49  constexpr Rand(Rand const& o) noexcept
50  : a{ o.a },
51  b{ o.b },
52  c{ o.c },
53  d{ o.d }
54  {
55 
56  }
57 
58  constexpr Rand(Rand&& o) noexcept
59  : a{ o.a },
60  b{ o.b },
61  c{ o.c },
62  d{ o.d }
63  {
64 
65  }
66 
69  constexpr static uint32_t max() {
70  return std::numeric_limits<uint32_t>::max();
71  }
72 
75  constexpr static uint32_t min() {
76  return std::numeric_limits<uint32_t>::min();
77  }
78 
79  constexpr uint32_t operator()() {
80  uint32_t e = a - rot32(b, 27);
81  a = b ^ rot32(c, 17);
82  b = c + d;
83  c = d + e;
84  d = e + a;
85  return d;
86  }
87 
88  template<int32_t n>
89  constexpr void advance_n() {
90  for(int32_t i = n; i--; )
91  this->operator()();
92  }
93 
94  Rand& operator=(Rand const&) noexcept = default;
95  Rand& operator=(Rand&&) noexcept = default;
96  };
97 
99  static thread_local Rand local_generator(std::random_device{}());
100  return local_generator;
101  }
102 }
103 #undef rot32
Thread safe random number generator.
Definition: rand.hpp:34
constexpr static uint32_t initial_seed
Definition: rand.hpp:38
constexpr static uint32_t max()
Obtains the maximum generable number.
Definition: rand.hpp:69
constexpr Rand(Rand &&o) noexcept
Definition: rand.hpp:58
constexpr void advance_n()
Definition: rand.hpp:89
constexpr Rand()=default
Rand & operator=(Rand &&) noexcept=default
uint32_t result_type
Definition: rand.hpp:37
constexpr Rand(Rand const &o) noexcept
Definition: rand.hpp:49
Rand & operator=(Rand const &) noexcept=default
constexpr uint32_t operator()()
Definition: rand.hpp:79
Rand(uint32_t seed)
Definition: rand.hpp:42
constexpr static uint32_t min()
Obtains the minimum generable number.
Definition: rand.hpp:75
Rand & get_local_generator()
Definition: rand.hpp:98
#define rot32(x, k)
Definition: rand.hpp:30