14#include <TargetConditionals.h>
15#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
19#include <sys/random.h>
22#include <sys/random.h>
29#if defined(__wasm__) || defined(__APPLE__)
33constexpr size_t RANDOM_BUFFER_SIZE = 256;
34constexpr size_t BYTES_PER_GETENTROPY_READ = 256;
39constexpr size_t RANDOM_BUFFER_SIZE = 1UL << 20;
42struct RandomBufferWrapper {
48thread_local RandomBufferWrapper random_buffer_wrapper;
57 static_assert(size_in_unsigned_ints > 0);
58 static_assert(size_in_unsigned_ints <= 32);
60 constexpr size_t random_data_buffer_size =
sizeof(random_data);
64 if (random_buffer_wrapper.offset == -1 ||
65 (
static_cast<size_t>(random_buffer_wrapper.offset) + random_data_buffer_size) > RANDOM_BUFFER_SIZE) {
66 size_t bytes_left = RANDOM_BUFFER_SIZE;
67 uint8_t* current_offset = random_buffer_wrapper.buffer;
69 while (bytes_left != 0) {
70#if defined(__wasm__) || defined(__APPLE__)
74 getentropy(current_offset, BYTES_PER_GETENTROPY_READ) == -1 ? -1 : BYTES_PER_GETENTROPY_READ;
77 auto read_bytes = getrandom(current_offset, bytes_left, 0);
80 if (read_bytes != -1) {
81 current_offset += read_bytes;
82 bytes_left -=
static_cast<size_t>(read_bytes);
85 random_buffer_wrapper.offset = 0;
88 memcpy(&random_data, random_buffer_wrapper.buffer + random_buffer_wrapper.offset, random_data_buffer_size);
89 random_buffer_wrapper.offset +=
static_cast<ssize_t
>(random_data_buffer_size);
98 auto buf = generate_random_data<1>();
99 uint32_t out =
buf[0];
100 return static_cast<uint8_t
>(out);
105 auto buf = generate_random_data<1>();
106 uint32_t out =
buf[0];
107 return static_cast<uint16_t
>(out);
112 auto buf = generate_random_data<1>();
113 uint32_t out =
buf[0];
114 return static_cast<uint32_t
>(out);
119 auto buf = generate_random_data<2>();
120 auto lo =
static_cast<uint64_t
>(
buf[0]);
121 auto hi =
static_cast<uint64_t
>(
buf[1]);
122 return (lo + (hi << 32ULL));
127 const auto get64 = [](
const std::array<uint32_t, 4>&
buffer,
const size_t offset) {
130 return (lo + (hi << 32ULL));
132 auto buf = generate_random_data<4>();
136 return (lo + (hi <<
static_cast<uint128_t>(64ULL)));
141 const auto get64 = [](
const std::array<uint32_t, 8>&
buffer,
const size_t offset) {
144 return (lo + (hi << 32ULL));
146 auto buf = generate_random_data<8>();
147 uint64_t lolo = get64(
buf, 0);
148 uint64_t lohi = get64(
buf, 2);
149 uint64_t hilo = get64(
buf, 4);
150 uint64_t hihi = get64(
buf, 6);
151 return { lolo, lohi, hilo, hihi };
179 return (hi << 64) | lo;
189 return {
a,
b, c, d };
215#ifdef BBERG_DEBUG_LOG
uint8_t get_random_uint8() override
DebugEngine(std::uint_fast64_t seed)
std::uniform_int_distribution< uint64_t > dist
uint32_t get_random_uint32() override
uint16_t get_random_uint16() override
uint64_t get_random_uint64() override
uint128_t get_random_uint128() override
uint256_t get_random_uint256() override
uint32_t get_random_uint32() override
uint8_t get_random_uint8() override
uint16_t get_random_uint16() override
uint256_t get_random_uint256() override
uint64_t get_random_uint64() override
uint128_t get_random_uint128() override
uint8_t const size_t length
uint8_t buffer[RANDOM_BUFFER_SIZE]
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
unsigned __int128 uint128_t