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