1/// Taken from SMHasher.
2
3#pragma once
4
5#include <cstdint>
6
7//-----------------------------------------------------------------------------
8// Xorshift RNG based on code by George Marsaglia
9// http://en.wikipedia.org/wiki/Xorshift
10
11struct Rand
12{
13 uint32_t x;
14 uint32_t y;
15 uint32_t z;
16 uint32_t w;
17
18 Rand()
19 {
20 reseed(static_cast<uint32_t>(0));
21 }
22
23 explicit Rand(uint32_t seed)
24 {
25 reseed(seed);
26 }
27
28 void reseed(uint32_t seed)
29 {
30 x = 0x498b3bc5 ^ seed;
31 y = 0;
32 z = 0;
33 w = 0;
34
35 for (int i = 0; i < 10; i++)
36 mix();
37 }
38
39 void reseed(uint64_t seed)
40 {
41 x = 0x498b3bc5 ^ static_cast<uint32_t>(seed >> 0);
42 y = 0x5a05089a ^ static_cast<uint32_t>(seed >> 32);
43 z = 0;
44 w = 0;
45
46 for (int i = 0; i < 10; i++)
47 mix();
48 }
49
50 //-----------------------------------------------------------------------------
51
52 void mix(void)
53 {
54 uint32_t t = x ^ (x << 11);
55 x = y;
56 y = z;
57 z = w;
58 w = w ^ (w >> 19) ^ t ^ (t >> 8);
59 }
60
61 uint32_t rand_u32(void)
62 {
63 mix();
64
65 return x;
66 }
67
68 uint64_t rand_u64(void)
69 {
70 mix();
71
72 uint64_t a = x;
73 uint64_t b = y;
74
75 return (a << 32) | b;
76 }
77
78 void rand_p(void * blob, int bytes)
79 {
80 uint32_t * blocks = reinterpret_cast<uint32_t *>(blob);
81
82 while (bytes >= 4)
83 {
84 blocks[0] = rand_u32();
85 blocks++;
86 bytes -= 4;
87 }
88
89 uint8_t * tail = reinterpret_cast<uint8_t *>(blocks);
90
91 for (int i = 0; i < bytes; i++)
92 {
93 tail[i] = static_cast<uint8_t>(rand_u32());
94 }
95 }
96};
97
98//-----------------------------------------------------------------------------
99
100extern Rand g_rand1;
101
102inline uint32_t rand_u32(void)
103{
104 return g_rand1.rand_u32();
105}
106inline uint64_t rand_u64(void)
107{
108 return g_rand1.rand_u64();
109}
110
111inline void rand_p(void * blob, int bytes)
112{
113 uint32_t * blocks = static_cast<uint32_t *>(blob);
114
115 while (bytes >= 4)
116 {
117 *blocks++ = rand_u32();
118 bytes -= 4;
119 }
120
121 uint8_t * tail = reinterpret_cast<uint8_t *>(blocks);
122
123 for (int i = 0; i < bytes; i++)
124 {
125 tail[i] = static_cast<uint8_t>(rand_u32());
126 }
127}
128
129//-----------------------------------------------------------------------------
130