Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
bitwise_uniform_distribution.hpp
Go to the documentation of this file.
1
#
ifndef
INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TESTING_BITWISE_UNIFORM_DISTRIBUTION_HPP_
2
#
define
INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TESTING_BITWISE_UNIFORM_DISTRIBUTION_HPP_
3
4
#
include
"arene/base/constraints/constraints.hpp"
5
#
include
"arene/base/stdlib_choice/climits.hpp"
6
#
include
"arene/base/stdlib_choice/cstddef.hpp"
7
#
include
"arene/base/stdlib_choice/enable_if.hpp"
8
#
include
"arene/base/stdlib_choice/is_integral.hpp"
9
#
include
"arene/base/stdlib_choice/is_unsigned.hpp"
10
#
include
"arene/base/stdlib_choice/make_unsigned.hpp"
11
12
namespace
arene
{
13
namespace
base
{
14
namespace
testing
{
15
16
/// @brief A uniform distribution to apply on top of a bit generator. Primary template (deliberately undefined).
17
/// @tparam T The value type to generate
18
template
<
typename
T,
typename
= arene::base::constraints<>>
19
class
bitwise_uniform_distribution;
20
21
/// @brief A uniform distribution to apply on top of a bit generator. SFINAE overload for integral types.
22
/// @tparam T The value type to generate
23
template
<
typename
T
>
24
class
bitwise_uniform_distribution<T, arene::base::constraints<std::enable_if_t<std::is_integral<T>::value>>> {
25
/// @brief Assert that the PRNG being used covers its type's whole range, since that's all our code currently handles
26
/// @tparam BitGenerator A bit generator (PRNG) type satisfying UniformRandomBitGenerator
27
template
<
typename
BitGenerator
>
28
static
constexpr
auto
assert_generator_is_ok
()
noexcept
->
void
{
29
using
result_type
=
typename
BitGenerator
::
result_type
;
30
static_assert
(
31
std
::
is_integral
<
result_type
>::
value
&&
std
::
is_unsigned
<
result_type
>::
value
,
32
"BitGenerator::result_type must be unsigned integral for BitGenerator to satisfy UniformRandomBitGenerator"
33
);
34
static_assert
(
35
BitGenerator
::
min
() ==
result_type
{},
36
"More sophisticated generation code is needed to handle cases where the real range is smaller than the type"
37
);
38
static_assert
(
39
BitGenerator
::
max
() ==
static_cast
<
result_type
>(~
result_type
{}),
40
"More sophisticated generation code is needed to handle cases where the real range is smaller than the type"
41
);
42
}
43
44
/// @brief Use a PRNG to generate a requested number of bits; overload for when the PRNG @c result_type is big enough
45
/// @tparam ExpectedBitsType An unsigned integer type that's bit enough to be used for the subsequent type conversion
46
/// @tparam BitGenerator A bit generator (PRNG) type satisfying UniformRandomBitGenerator
47
/// @param prng A bit generator (PRNG) instance
48
/// @return A uniformly-distributed random sequence of bits which can be converted into @c T
49
template
<
50
typename
ExpectedBitsType
,
51
typename
BitGenerator
,
52
arene
::
base
::
constraints
<
53
std
::
enable_if_t
<
sizeof
(
typename
BitGenerator
::
result_type
) >=
sizeof
(
ExpectedBitsType
)>> =
nullptr
>
54
static
constexpr
auto
generate_bits
(
BitGenerator
&
prng
)
noexcept
(
noexcept
(
prng
())) ->
ExpectedBitsType
{
55
assert_generator_is_ok
<
BitGenerator
>();
56
57
return
static_cast
<
ExpectedBitsType
>(
prng
());
58
}
59
60
/// @brief Use a PRNG to generate a requested number of bits; overload for when the PRNG @c result_type is too small
61
/// @tparam ExpectedBitsType An unsigned integer type that's bit enough to be used for the subsequent type conversion
62
/// @tparam BitGenerator A bit generator (PRNG) type satisfying UniformRandomBitGenerator
63
/// @param prng A bit generator (PRNG) instance
64
/// @return A uniformly-distributed random sequence of bits which can be converted into @c T
65
template
<
66
typename
ExpectedBitsType
,
67
typename
BitGenerator
,
68
arene
::
base
::
constraints
<
69
std
::
enable_if_t
<
sizeof
(
typename
BitGenerator
::
result_type
) <
sizeof
(
ExpectedBitsType
)>> =
nullptr
>
70
static
constexpr
auto
generate_bits
(
BitGenerator
&
prng
)
noexcept
(
noexcept
(
prng
())) ->
ExpectedBitsType
{
71
assert_generator_is_ok
<
BitGenerator
>();
72
73
using
chunk_type
=
typename
BitGenerator
::
result_type
;
74
static_assert
(
75
sizeof
(
ExpectedBitsType
) %
sizeof
(
chunk_type
) == 0U,
76
"Implementation assumes that an integer number of chunks fits in ExpectedBitsType"
77
);
78
79
ExpectedBitsType
result_bits
{};
80
for
(
std
::
size_t
chunk_idx
{};
chunk_idx
< (
sizeof
(
ExpectedBitsType
) /
sizeof
(
chunk_type
)); ++
chunk_idx
) {
81
auto
new_bits
=
static_cast
<
ExpectedBitsType
>(
prng
());
82
result_bits
=
static_cast
<
ExpectedBitsType
>(
83
result_bits
|
static_cast
<
ExpectedBitsType
>(
new_bits
<< (
chunk_idx
*
sizeof
(
chunk_type
) *
CHAR_BIT
))
84
);
85
}
86
87
return
result_bits
;
88
}
89
90
public
:
91
/// @brief Generate a value of type <c>T</c>; overload for when T is integral
92
/// @tparam BitGenerator A bit generator (PRNG) type satisfying UniformRandomBitGenerator
93
/// @param prng A bit generator (PRNG) instance
94
/// @return A random, uniformly-distributed @c T value
95
template
<
96
typename
BitGenerator
,
97
arene
::
base
::
constraints
<
std
::
enable_if_t
<
std
::
is_integral
<
typename
BitGenerator
::
result_type
>::
value
>> =
nullptr
>
98
constexpr
auto
operator
()(
BitGenerator
&
prng
)
const
noexcept
(
noexcept
(
prng
())) ->
T
{
99
return
static_cast
<
T
>(
generate_bits
<
std
::
make_unsigned_t
<
T
>>(
prng
));
100
}
101
};
102
103
}
// namespace testing
104
}
// namespace base
105
}
// namespace arene
106
107
#
endif
// INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TESTING_BITWISE_UNIFORM_DISTRIBUTION_HPP_
arene::base::testing
Definition
customization.hpp:36
arene::base
Definition
array_exceptions_disabled.cpp:11
arene
Copyright 2026, Toyota Motor Corporation.
Definition
array_exceptions_disabled.cpp:10
arene
base
testing
bitwise_uniform_distribution.hpp
Generated by
1.13.2