userver: userver/utils/rand.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
rand.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <random>
5
6#include <userver/utils/assert.hpp>
7
8/// @file userver/utils/rand.hpp
9/// @brief Random number generators
10/// @ingroup userver_universal
11
12USERVER_NAMESPACE_BEGIN
13
14namespace utils {
15
16/// @brief Virtualized standard UniformRandomBitGenerator concept, for use
17/// with random number distributions
19 public:
20 using result_type = uint32_t;
21
22 virtual ~RandomBase() = default;
23
24 virtual result_type operator()() = 0;
25
26 static constexpr result_type min() { return std::mt19937::min(); }
27 static constexpr result_type max() { return std::mt19937::max(); }
28};
29
30/// @brief Returns a thread-local UniformRandomBitGenerator
31/// @note The provided `Random` instance is not cryptographically secure
32/// @warning Don't pass the returned `Random` across thread boundaries
34
35namespace impl {
36
37/// @brief Returns a thread-local UniformRandomBitGenerator for using in seed
38/// generating
39/// @note The provided `Random` instance is not cryptographically secure
40/// @warning Don't pass the returned `Random` across thread boundaries
41RandomBase& DefaultRandomForHashSeed();
42
43} // namespace impl
44
45/// @brief Generates a random number in range [from, to)
46/// @note The used random generator is not cryptographically secure
47/// @note `from_inclusive` must be less than `to_exclusive`
48template <typename T>
49T RandRange(T from_inclusive, T to_exclusive) {
50 UINVARIANT(from_inclusive < to_exclusive,
51 "attempt to get a random value in an incorrect range");
52 if constexpr (std::is_floating_point_v<T>) {
53 return std::uniform_real_distribution<T>{from_inclusive,
54 to_exclusive}(DefaultRandom());
55 } else {
56 // 8-bit types are not allowed in uniform_int_distribution, so increase the
57 // T size.
58 return std::uniform_int_distribution<std::common_type_t<T, unsigned short>>{
59 from_inclusive, to_exclusive - 1}(DefaultRandom());
60 }
61}
62
63/// @brief Generates a random number in range [0, to)
64/// @note The used random generator is not cryptographically secure
65template <typename T>
66T RandRange(T to_exclusive) {
67 return RandRange(T{0}, to_exclusive);
68}
69
70/// @brief Generate a random number in the whole `uint32_t` range
71/// @note The used random generator is not cryptographically secure
72/// @warning Don't use `Rand() % N`, use `RandRange` instead
73uint32_t Rand();
74
75} // namespace utils
76
77USERVER_NAMESPACE_END