4#ifndef DASMIG_CORE_RNG_HPP
5#define DASMIG_CORE_RNG_HPP
29[[nodiscard]]
constexpr std::uint64_t
splitmix64_mix(std::uint64_t z)
noexcept
31 z = (z ^ (z >> 30U)) * 0xbf58476d1ce4e5b9ULL;
32 z = (z ^ (z >> 27U)) * 0x94d049bb133111ebULL;
33 return z ^ (z >> 31U);
45 constexpr explicit splitmix64(std::uint64_t seed) noexcept : _state{seed} {}
51 _state += 0x9e3779b97f4a7c15ULL;
66[[nodiscard]]
constexpr std::uint64_t
fnv1a64(std::string_view text)
noexcept
68 std::uint64_t hash = 0xcbf29ce484222325ULL;
69 for (
const char c : text)
71 hash ^=
static_cast<std::uint8_t
>(c);
72 hash *= 0x100000001b3ULL;
85[[nodiscard]]
constexpr std::uint64_t
hash_combine(std::uint64_t hash,
86 std::uint64_t value)
noexcept
128 std::random_device device;
129 const auto hi =
static_cast<std::uint64_t
>(device());
130 const auto lo =
static_cast<std::uint64_t
>(device());
131 return (hi << 32U) ^ lo;
141 for (
auto& word : _s)
154 [[nodiscard]]
constexpr std::uint64_t
seed() const noexcept {
return _seed; }
160 const std::uint64_t result = std::rotl(_s[1] * 5U, 7) * 9U;
161 const std::uint64_t t = _s[1] << 17U;
167 _s[3] = std::rotl(_s[3], 45);
178 std::string_view label)
const noexcept
191 std::uint64_t index)
const noexcept
205 std::uint64_t
seed, std::uint64_t index)
noexcept
213 [[nodiscard]]
constexpr rng split(std::string_view label)
const noexcept
221 [[nodiscard]]
constexpr rng split(std::uint64_t index)
const noexcept
234 return std::numeric_limits<result_type>::max();
241 std::array<std::uint64_t, 4> _s{};
242 std::uint64_t _seed{0};
245static_assert(std::uniform_random_bit_generator<rng>);
The core random engine: xoshiro256** (Blackman and Vigna 2018).
static constexpr result_type max() noexcept
Largest value produced.
constexpr std::uint64_t child_seed(std::uint64_t index) const noexcept
Derive the child seed for an index.
static rng from_entropy()
Construct with a seed taken from std::random_device.
constexpr rng split(std::string_view label) const noexcept
A child engine for a label, independent of this engine's state.
constexpr rng(std::uint64_t seed) noexcept
Construct from a seed.
static std::uint64_t entropy_seed()
A 64-bit seed from std::random_device.
std::uint64_t result_type
Type of the values produced.
constexpr result_type operator()() noexcept
Advance and return the next value.
constexpr rng split(std::uint64_t index) const noexcept
A child engine for an index, independent of this engine's state.
constexpr std::uint64_t child_seed(std::string_view label) const noexcept
Derive the child seed for a label.
rng & unseed()
Reseed from std::random_device.
constexpr rng & seed(std::uint64_t seed) noexcept
Reset the engine to the start of the sequence for a seed.
constexpr std::uint64_t seed() const noexcept
The seed this engine was last seeded with.
static constexpr std::uint64_t child_seed_of(std::uint64_t seed, std::uint64_t index) noexcept
child_seed(index) for a seed, without building an engine.
static constexpr result_type min() noexcept
Smallest value produced.
friend constexpr bool operator==(const rng &, const rng &) noexcept=default
Engines are equal when their seed and position are equal.
The SplitMix64 generator (Steele, Lea and Flood 2014).
constexpr std::uint64_t operator()() noexcept
Advance and return the next value.
constexpr splitmix64(std::uint64_t seed) noexcept
Construct from a seed.
constexpr std::uint64_t hash_combine(std::uint64_t hash, std::uint64_t value) noexcept
Combine a hash with another 64-bit value, order-sensitively.
constexpr std::uint64_t fnv1a64(std::string_view text) noexcept
64-bit FNV-1a hash of the bytes of a string.
constexpr std::uint64_t splitmix64_mix(std::uint64_t z) noexcept
The SplitMix64 output function (a bijection on 64-bit values).