xrpld
Loading...
Searching...
No Matches
include/xrpl/basics/random.h
1#pragma once
2
3#include <xrpl/beast/utility/instrumentation.h>
4#include <xrpl/beast/xor_shift_engine.h>
5
6#include <cstdint>
7#include <limits>
8#include <mutex>
9#include <random>
10#include <type_traits>
11
12namespace xrpl {
13
14#ifndef __INTELLISENSE__
15static_assert(
16 // NOLINTNEXTLINE(misc-redundant-expression)
19 "The XRPL default PRNG engine must return an unsigned integral type.");
20
21static_assert(
22 // NOLINTNEXTLINE(misc-redundant-expression)
25 "The XRPL default PRNG engine return must be at least 64 bits wide.");
26#endif
27
28namespace detail {
29
30// Determines if a type can be called like an Engine
31// NOLINTNEXTLINE(readability-redundant-typename): typename required by MSVC
32template <class Engine, class Result = typename Engine::result_type>
34} // namespace detail
35
49{
50 // This is used to seed the thread-specific PRNGs on demand
51 static beast::xor_shift_engine kSeeder = [] {
54 return beast::xor_shift_engine(distribution(rng));
55 }();
56
57 // This protects the seeder
58 static std::mutex kM;
59
60 // The thread-specific PRNGs:
61 thread_local beast::xor_shift_engine kEngine = [] {
62 std::uint64_t seed = 0;
63 {
64 std::scoped_lock const lk(kM);
66 seed = distribution(kSeeder);
67 }
68 return beast::xor_shift_engine{seed};
69 }();
70
71 return kEngine;
72}
73
95template <class Engine, class Integral>
96Integral
97randInt(Engine& engine, Integral min, Integral max)
99{
100 XRPL_ASSERT(max > min, "xrpl::randInt : max over min inputs");
101
102 // This should have no state and constructing it should
103 // be very cheap. If that turns out not to be the case
104 // it could be hand-optimized.
105 return std::uniform_int_distribution<Integral>(min, max)(engine);
106}
107
108template <class Integral>
109Integral
110randInt(Integral min, Integral max)
112{
113 return randInt(defaultPrng(), min, max);
114}
115
116template <class Engine, class Integral>
117Integral
118randInt(Engine& engine, Integral max)
120{
121 return randInt(engine, Integral(0), max);
122}
123
124template <class Integral>
125Integral
126randInt(Integral max)
128{
129 return randInt(defaultPrng(), max);
130}
131
132template <class Integral, class Engine>
133Integral
139
140template <class Integral = int>
141Integral
147
148
153template <class Byte, class Engine>
154Byte
163
164template <class Byte = std::uint8_t>
165Byte
171
172
177template <class Engine>
178inline bool
179randBool(Engine& engine)
180{
181 return randInt(engine, 1) == 1;
182}
183
184inline bool
186{
187 return randBool(defaultPrng());
188}
189
190
191} // namespace xrpl
T is_integral_v
T is_same_v
T is_unsigned_v
T max(T... args)
T min(T... args)
detail::XorShiftEngine<> xor_shift_engine
XOR-shift Generator.
std::is_invocable_r< Result, Engine > is_engine
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
beast::xor_shift_engine & defaultPrng()
Return the default random engine.