HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
random_pcg.hpp
1// Copyright Take Vos 2019-2020.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "math.hpp"
8#include "byte_string.hpp"
9#include "cast.hpp"
10#include <atomic>
11
12namespace tt {
13
14template<typename T>
15inline bstring get_bytes(T &generator, ssize_t count)
16{
17 decltype(generator()) random_number;
18
19 auto data = bstring(static_cast<size_t>(count), std::byte{0});
20
21 ssize_t i = 0;
22 while (i < count - ssizeof(random_number) - 1) {
23 random_number = generator();
24 for (int j = 0; j < sizeof(random_number); j++) {
25 data[i++] = static_cast<std::byte>(random_number);
26 random_number >>= 8;
27 }
28 }
29
30 random_number = generator();
31 while (i < count) {
32 data[i++] = static_cast<std::byte>(random_number);
33 random_number >>= 8;
34 }
35
36 return data;
37}
38
39
40class pcg32 {
41 static constexpr uint64_t multiplier = 6364136223846793005u;
42 static constexpr uint64_t increment = 1442695040888963407u;
43
44 uint64_t state;
45
46public:
47 pcg32(uint64_t seed = 0x4d595df4d0f33173) :
48 state(seed + increment)
49 {
50 (*this)();
51 }
52
53 uint32_t operator()() {
54 auto x = state;
55
56 state = x * multiplier + increment;
57
58 ttlet count = static_cast<unsigned int>(x >> 59);
59
60 x ^= x >> 18;
61 return std::rotr(static_cast<uint32_t>(x >> 27), count);
62 }
63
64 bstring get_bytes(ssize_t count) {
65 return tt::get_bytes(*this, count);
66 }
67};
68
70 static constexpr uint64_t multiplier = 6364136223846793005u;
71 static constexpr uint64_t increment = 1442695040888963407u;
72
74
75public:
76 atomic_pcg32(uint64_t seed = 0x4d595df4d0f33173) :
77 state(seed + increment)
78 {
79 (*this)();
80 }
81
82 uint32_t operator()() {
83 auto x = state.load(std::memory_order::relaxed);
84 uint64_t new_state;
85 do {
86 [[unlikely]] new_state = x * multiplier + increment;
87 } while (!state.compare_exchange_weak(x, new_state, std::memory_order::relaxed));
88
89 ttlet count = static_cast<unsigned int>(x >> 59);
90
91 x ^= x >> 18;
92 return std::rotr(static_cast<uint32_t>(x >> 27), count);
93 }
94
95 bstring get_bytes(ssize_t count) {
96 return tt::get_bytes(*this, count);
97 }
98};
99
100inline atomic_pcg32 global_pcg32 = atomic_pcg32();
101
102}
Definition random_pcg.hpp:40
Definition random_pcg.hpp:69
T compare_exchange_weak(T... args)
T load(T... args)