Add uniform_integer_distribution

This commit is contained in:
Martin Hořeňovský
2023-12-08 22:01:36 +01:00
parent 04a829b0e1
commit ed9d672b5c
22 changed files with 624 additions and 18 deletions

View File

@@ -415,6 +415,7 @@ b1!
:test-result: PASS tuple<string,string>
:test-result: PASS tuple<tuple<int>,tuple<>,float>
:test-result: PASS uniform samples
:test-result: PASS uniform_integer_distribution can return the bounds
:test-result: PASS unique_ptr reimplementation: basic functionality
:test-result: PASS vec<vec<string,alloc>> -> toString
:test-result: PASS vector<bool> -> toString

View File

@@ -404,6 +404,7 @@
:test-result: PASS tuple<string,string>
:test-result: PASS tuple<tuple<int>,tuple<>,float>
:test-result: PASS uniform samples
:test-result: PASS uniform_integer_distribution can return the bounds
:test-result: PASS unique_ptr reimplementation: basic functionality
:test-result: PASS vec<vec<string,alloc>> -> toString
:test-result: PASS vector<bool> -> toString

View File

@@ -2622,6 +2622,8 @@ InternalBenchmark.tests.cpp:<line number>: passed: e.point == 23 for: 23.0 == 23
InternalBenchmark.tests.cpp:<line number>: passed: e.upper_bound == 23 for: 23.0 == 23
InternalBenchmark.tests.cpp:<line number>: passed: e.lower_bound == 23 for: 23.0 == 23
InternalBenchmark.tests.cpp:<line number>: passed: e.confidence_interval == 0.95 for: 0.95 == 0.95
RandomNumberGeneration.tests.cpp:<line number>: passed: dist.a() == -10 for: -10 == -10
RandomNumberGeneration.tests.cpp:<line number>: passed: dist.b() == 10 for: 10 == 10
UniquePtr.tests.cpp:<line number>: passed: !(ptr) for: !{?}
UniquePtr.tests.cpp:<line number>: passed: ptr.get() == 0 for: 0 == 0
UniquePtr.tests.cpp:<line number>: passed: ptr for: {?}
@@ -2687,7 +2689,7 @@ InternalBenchmark.tests.cpp:<line number>: passed: med == 18. for: 18.0 == 18.0
InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0
Misc.tests.cpp:<line number>: passed:
Misc.tests.cpp:<line number>: passed:
test cases: 416 | 311 passed | 85 failed | 6 skipped | 14 failed as expected
assertions: 2258 | 2077 passed | 146 failed | 35 failed as expected
test cases: 417 | 312 passed | 85 failed | 6 skipped | 14 failed as expected
assertions: 2260 | 2079 passed | 146 failed | 35 failed as expected

View File

@@ -2611,6 +2611,8 @@ InternalBenchmark.tests.cpp:<line number>: passed: e.point == 23 for: 23.0 == 23
InternalBenchmark.tests.cpp:<line number>: passed: e.upper_bound == 23 for: 23.0 == 23
InternalBenchmark.tests.cpp:<line number>: passed: e.lower_bound == 23 for: 23.0 == 23
InternalBenchmark.tests.cpp:<line number>: passed: e.confidence_interval == 0.95 for: 0.95 == 0.95
RandomNumberGeneration.tests.cpp:<line number>: passed: dist.a() == -10 for: -10 == -10
RandomNumberGeneration.tests.cpp:<line number>: passed: dist.b() == 10 for: 10 == 10
UniquePtr.tests.cpp:<line number>: passed: !(ptr) for: !{?}
UniquePtr.tests.cpp:<line number>: passed: ptr.get() == 0 for: 0 == 0
UniquePtr.tests.cpp:<line number>: passed: ptr for: {?}
@@ -2676,7 +2678,7 @@ InternalBenchmark.tests.cpp:<line number>: passed: med == 18. for: 18.0 == 18.0
InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0
Misc.tests.cpp:<line number>: passed:
Misc.tests.cpp:<line number>: passed:
test cases: 416 | 311 passed | 85 failed | 6 skipped | 14 failed as expected
assertions: 2258 | 2077 passed | 146 failed | 35 failed as expected
test cases: 417 | 312 passed | 85 failed | 6 skipped | 14 failed as expected
assertions: 2260 | 2079 passed | 146 failed | 35 failed as expected

View File

@@ -1588,6 +1588,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
test cases: 416 | 325 passed | 70 failed | 7 skipped | 14 failed as expected
assertions: 2241 | 2077 passed | 129 failed | 35 failed as expected
test cases: 417 | 326 passed | 70 failed | 7 skipped | 14 failed as expected
assertions: 2243 | 2079 passed | 129 failed | 35 failed as expected

View File

@@ -18248,6 +18248,22 @@ InternalBenchmark.tests.cpp:<line number>: PASSED:
with expansion:
0.95 == 0.95
-------------------------------------------------------------------------------
uniform_integer_distribution can return the bounds
-------------------------------------------------------------------------------
RandomNumberGeneration.tests.cpp:<line number>
...............................................................................
RandomNumberGeneration.tests.cpp:<line number>: PASSED:
REQUIRE( dist.a() == -10 )
with expansion:
-10 == -10
RandomNumberGeneration.tests.cpp:<line number>: PASSED:
REQUIRE( dist.b() == 10 )
with expansion:
10 == 10
-------------------------------------------------------------------------------
unique_ptr reimplementation: basic functionality
Default constructed unique_ptr is empty
@@ -18735,6 +18751,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 416 | 311 passed | 85 failed | 6 skipped | 14 failed as expected
assertions: 2258 | 2077 passed | 146 failed | 35 failed as expected
test cases: 417 | 312 passed | 85 failed | 6 skipped | 14 failed as expected
assertions: 2260 | 2079 passed | 146 failed | 35 failed as expected

View File

@@ -18237,6 +18237,22 @@ InternalBenchmark.tests.cpp:<line number>: PASSED:
with expansion:
0.95 == 0.95
-------------------------------------------------------------------------------
uniform_integer_distribution can return the bounds
-------------------------------------------------------------------------------
RandomNumberGeneration.tests.cpp:<line number>
...............................................................................
RandomNumberGeneration.tests.cpp:<line number>: PASSED:
REQUIRE( dist.a() == -10 )
with expansion:
-10 == -10
RandomNumberGeneration.tests.cpp:<line number>: PASSED:
REQUIRE( dist.b() == 10 )
with expansion:
10 == 10
-------------------------------------------------------------------------------
unique_ptr reimplementation: basic functionality
Default constructed unique_ptr is empty
@@ -18724,6 +18740,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 416 | 311 passed | 85 failed | 6 skipped | 14 failed as expected
assertions: 2258 | 2077 passed | 146 failed | 35 failed as expected
test cases: 417 | 312 passed | 85 failed | 6 skipped | 14 failed as expected
assertions: 2260 | 2079 passed | 146 failed | 35 failed as expected

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuitesloose text artifact
>
<testsuite name="<exe-name>" errors="17" failures="129" skipped="12" tests="2270" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="129" skipped="12" tests="2272" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="random-seed" value="1"/>
<property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/>
@@ -2075,6 +2075,7 @@ at Exception.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="tuple&lt;string,string>" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="tuple&lt;tuple&lt;int>,tuple&lt;>,float>" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="uniform samples" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="uniform_integer_distribution can return the bounds" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Default constructed unique_ptr is empty" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Take ownership of allocation" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Take ownership of allocation/Plain reset deallocates" time="{duration}" status="run"/>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="<exe-name>" errors="17" failures="129" skipped="12" tests="2270" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="129" skipped="12" tests="2272" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="random-seed" value="1"/>
<property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/>
@@ -2074,6 +2074,7 @@ at Exception.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="tuple&lt;string,string>" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="tuple&lt;tuple&lt;int>,tuple&lt;>,float>" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="uniform samples" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="uniform_integer_distribution can return the bounds" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Default constructed unique_ptr is empty" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Take ownership of allocation" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Take ownership of allocation/Plain reset deallocates" time="{duration}" status="run"/>

View File

@@ -181,6 +181,7 @@ at AssertionHandler.tests.cpp:<line number>
<testCase name="Our PCG implementation provides expected results for known seeds/Specific seed" duration="{duration}"/>
<testCase name="Random seed generation accepts known methods" duration="{duration}"/>
<testCase name="Random seed generation reports unknown methods" duration="{duration}"/>
<testCase name="uniform_integer_distribution can return the bounds" duration="{duration}"/>
</file>
<file path="tests/<exe-name>/IntrospectiveTests/Reporters.tests.cpp">
<testCase name="Multireporter calls reporters and listeners in correct order" duration="{duration}"/>

View File

@@ -180,6 +180,7 @@ at AssertionHandler.tests.cpp:<line number>
<testCase name="Our PCG implementation provides expected results for known seeds/Specific seed" duration="{duration}"/>
<testCase name="Random seed generation accepts known methods" duration="{duration}"/>
<testCase name="Random seed generation reports unknown methods" duration="{duration}"/>
<testCase name="uniform_integer_distribution can return the bounds" duration="{duration}"/>
</file>
<file path="tests/<exe-name>/IntrospectiveTests/Reporters.tests.cpp">
<testCase name="Multireporter calls reporters and listeners in correct order" duration="{duration}"/>

View File

@@ -4423,6 +4423,10 @@ ok {test-number} - e.upper_bound == 23 for: 23.0 == 23
ok {test-number} - e.lower_bound == 23 for: 23.0 == 23
# uniform samples
ok {test-number} - e.confidence_interval == 0.95 for: 0.95 == 0.95
# uniform_integer_distribution can return the bounds
ok {test-number} - dist.a() == -10 for: -10 == -10
# uniform_integer_distribution can return the bounds
ok {test-number} - dist.b() == 10 for: 10 == 10
# unique_ptr reimplementation: basic functionality
ok {test-number} - !(ptr) for: !{?}
# unique_ptr reimplementation: basic functionality
@@ -4545,5 +4549,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..2270
1..2272

View File

@@ -4412,6 +4412,10 @@ ok {test-number} - e.upper_bound == 23 for: 23.0 == 23
ok {test-number} - e.lower_bound == 23 for: 23.0 == 23
# uniform samples
ok {test-number} - e.confidence_interval == 0.95 for: 0.95 == 0.95
# uniform_integer_distribution can return the bounds
ok {test-number} - dist.a() == -10 for: -10 == -10
# uniform_integer_distribution can return the bounds
ok {test-number} - dist.b() == 10 for: 10 == 10
# unique_ptr reimplementation: basic functionality
ok {test-number} - !(ptr) for: !{?}
# unique_ptr reimplementation: basic functionality
@@ -4534,5 +4538,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..2270
1..2272

View File

@@ -994,6 +994,8 @@ loose text artifact
##teamcity[testFinished name='tuple<tuple<int>,tuple<>,float>' duration="{duration}"]
##teamcity[testStarted name='uniform samples']
##teamcity[testFinished name='uniform samples' duration="{duration}"]
##teamcity[testStarted name='uniform_integer_distribution can return the bounds']
##teamcity[testFinished name='uniform_integer_distribution can return the bounds' duration="{duration}"]
##teamcity[testStarted name='unique_ptr reimplementation: basic functionality']
##teamcity[testFinished name='unique_ptr reimplementation: basic functionality' duration="{duration}"]
##teamcity[testStarted name='vec<vec<string,alloc>> -> toString']

View File

@@ -993,6 +993,8 @@
##teamcity[testFinished name='tuple<tuple<int>,tuple<>,float>' duration="{duration}"]
##teamcity[testStarted name='uniform samples']
##teamcity[testFinished name='uniform samples' duration="{duration}"]
##teamcity[testStarted name='uniform_integer_distribution can return the bounds']
##teamcity[testFinished name='uniform_integer_distribution can return the bounds' duration="{duration}"]
##teamcity[testStarted name='unique_ptr reimplementation: basic functionality']
##teamcity[testFinished name='unique_ptr reimplementation: basic functionality' duration="{duration}"]
##teamcity[testStarted name='vec<vec<string,alloc>> -> toString']

View File

@@ -21134,6 +21134,25 @@ b1!
</Expression>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="uniform_integer_distribution can return the bounds" tags="[distribution][rng]" filename="tests/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
<Original>
dist.a() == -10
</Original>
<Expanded>
-10 == -10
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
<Original>
dist.b() == 10
</Original>
<Expanded>
10 == 10
</Expanded>
</Expression>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="unique_ptr reimplementation: basic functionality" tags="[internals][unique-ptr]" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Section name="Default constructed unique_ptr is empty" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE_FALSE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
@@ -21688,6 +21707,6 @@ b1!
</Section>
<OverallResult success="true" skips="0"/>
</TestCase>
<OverallResults successes="2077" failures="146" expectedFailures="35" skips="12"/>
<OverallResultsCases successes="311" failures="85" expectedFailures="14" skips="6"/>
<OverallResults successes="2079" failures="146" expectedFailures="35" skips="12"/>
<OverallResultsCases successes="312" failures="85" expectedFailures="14" skips="6"/>
</Catch2TestRun>

View File

@@ -21133,6 +21133,25 @@ b1!
</Expression>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="uniform_integer_distribution can return the bounds" tags="[distribution][rng]" filename="tests/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
<Original>
dist.a() == -10
</Original>
<Expanded>
-10 == -10
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
<Original>
dist.b() == 10
</Original>
<Expanded>
10 == 10
</Expanded>
</Expression>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="unique_ptr reimplementation: basic functionality" tags="[internals][unique-ptr]" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Section name="Default constructed unique_ptr is empty" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE_FALSE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
@@ -21687,6 +21706,6 @@ b1!
</Section>
<OverallResult success="true" skips="0"/>
</TestCase>
<OverallResults successes="2077" failures="146" expectedFailures="35" skips="12"/>
<OverallResultsCases successes="311" failures="85" expectedFailures="14" skips="6"/>
<OverallResults successes="2079" failures="146" expectedFailures="35" skips="12"/>
<OverallResultsCases successes="312" failures="85" expectedFailures="14" skips="6"/>
</Catch2TestRun>

View File

@@ -12,7 +12,9 @@
#include <catch2/internal/catch_random_number_generator.hpp>
#include <catch2/internal/catch_random_seed_generation.hpp>
#include <catch2/internal/catch_uniform_floating_point_distribution.hpp>
#include <catch2/internal/catch_uniform_integer_distribution.hpp>
#include <catch2/generators/catch_generators.hpp>
#include <catch2/matchers/catch_matchers_range_equals.hpp>
TEST_CASE("Our PCG implementation provides expected results for known seeds", "[rng]") {
Catch::SimplePcg32 rng;
@@ -104,3 +106,386 @@ TEST_CASE( "fillBitsFrom - shortening and stretching", "[rng][approvals]" ) {
REQUIRE( stretched == 0xccbe'5f04'a424'a486 );
}
}
TEST_CASE("uniform_integer_distribution can return the bounds", "[rng][distribution]") {
Catch::uniform_integer_distribution<int32_t> dist( -10, 10 );
REQUIRE( dist.a() == -10 );
REQUIRE( dist.b() == 10 );
}
namespace {
template <typename T>
static void CheckReturnValue(Catch::uniform_integer_distribution<T>& dist,
Catch::SimplePcg32& rng,
T target) {
REQUIRE( dist.a() == dist.b() );
for (int i = 0; i < 1'000; ++i) {
REQUIRE( dist( rng ) == target );
}
}
}
TEMPLATE_TEST_CASE( "uniform_integer_distribution can handle unit ranges",
"[rng][distribution][approvals]",
unsigned char,
signed char,
char,
uint8_t,
int8_t,
uint16_t,
int16_t,
uint32_t,
int32_t,
uint64_t,
int64_t ) {
// We want random seed to sample different parts of the rng state,
// the output is predetermined anyway
std::random_device rd;
auto seed = rd();
CAPTURE( seed );
Catch::SimplePcg32 pcg( seed );
// We check unitary ranges of 3 different values, min for type, max for type,
// some value inbetween just to make sure
SECTION("lowest value") {
constexpr auto lowest = std::numeric_limits<TestType>::min();
Catch::uniform_integer_distribution<TestType> dist( lowest, lowest );
CheckReturnValue( dist, pcg, lowest );
}
SECTION( "highest value" ) {
constexpr auto highest = std::numeric_limits<TestType>::max();
Catch::uniform_integer_distribution<TestType> dist( highest, highest );
CheckReturnValue( dist, pcg, highest );
}
SECTION( "some value" ) {
constexpr auto some = TestType( 42 );
Catch::uniform_integer_distribution<TestType> dist( some, some );
CheckReturnValue( dist, pcg, some );
}
}
// Bool needs its own test because it doesn't have a valid "third" value
TEST_CASE( "uniform_integer_distribution can handle boolean unit ranges",
"[rng][distribution][approvals]" ) {
// We want random seed to sample different parts of the rng state,
// the output is predetermined anyway
std::random_device rd;
auto seed = rd();
CAPTURE( seed );
Catch::SimplePcg32 pcg( seed );
// We check unitary ranges of 3 different values, min for type, max for
// type, some value inbetween just to make sure
SECTION( "lowest value" ) {
Catch::uniform_integer_distribution<bool> dist( false, false );
CheckReturnValue( dist, pcg, false );
}
SECTION( "highest value" ) {
Catch::uniform_integer_distribution<bool> dist( true, true );
CheckReturnValue( dist, pcg, true );
}
}
TEMPLATE_TEST_CASE( "uniform_integer_distribution can handle full width ranges",
"[rng][distribution][approvals]",
unsigned char,
signed char,
char,
uint8_t,
int8_t,
uint16_t,
int16_t,
uint32_t,
int32_t,
uint64_t,
int64_t ) {
// We want random seed to sample different parts of the rng state,
// the output is predetermined anyway
std::random_device rd;
auto seed = rd();
CAPTURE( seed );
Catch::SimplePcg32 pcg( seed );
constexpr auto lowest = std::numeric_limits<TestType>::min();
constexpr auto highest = std::numeric_limits<TestType>::max();
Catch::uniform_integer_distribution<TestType> dist( lowest, highest );
STATIC_REQUIRE( std::is_same<TestType, decltype( dist( pcg ) )>::value );
// We need to do bit operations on the results, so we will have to
// cast them to unsigned type.
using BitType = std::make_unsigned_t<TestType>;
BitType ORs = 0;
BitType ANDs = BitType(-1);
for (int i = 0; i < 100; ++i) {
auto bits = static_cast<BitType>( dist( pcg ) );
ORs |= bits;
ANDs &= bits;
}
// Assuming both our RNG and distribution are unbiased, asking for
// the full range should essentially give us random bit generator.
// Over long run, OR of all the generated values should have all
// bits set to 1, while AND should have all bits set to 0.
// The chance of this test failing for unbiased pipeline is
// 1 / 2**iters, which for 100 iterations is astronomical.
REQUIRE( ORs == BitType( -1 ) );
REQUIRE( ANDs == 0 );
}
namespace {
template <typename T>
struct uniform_integer_test_params;
template <>
struct uniform_integer_test_params<bool> {
static constexpr bool lowest = false;
static constexpr bool highest = true;
// This seems weird, but it is an artifact of the specific seed
static constexpr bool expected[] = { true,
true,
true,
true,
true,
true,
false,
true,
true,
true,
true,
true,
false,
true,
true };
};
template <>
struct uniform_integer_test_params<char> {
static constexpr char lowest = 32;
static constexpr char highest = 126;
static constexpr char expected[] = { 'k',
'\\',
'Z',
'X',
'`',
'Q',
';',
'o',
']',
'T',
'v',
'p',
':',
'S',
't' };
};
template <>
struct uniform_integer_test_params<uint8_t> {
static constexpr uint8_t lowest = 3;
static constexpr uint8_t highest = 123;
static constexpr uint8_t expected[] = { 'c',
'P',
'M',
'J',
'U',
'A',
'%',
'h',
'Q',
'F',
'q',
'i',
'$',
'E',
'o' };
};
template <>
struct uniform_integer_test_params<int8_t> {
static constexpr int8_t lowest = -27;
static constexpr int8_t highest = 73;
static constexpr int8_t expected[] = { '5',
'%',
'#',
' ',
'*',
25,
2,
'9',
'&',
29,
'A',
':',
1,
28,
'?' };
};
template <>
struct uniform_integer_test_params<uint16_t> {
static constexpr uint16_t lowest = 123;
static constexpr uint16_t highest = 33333;
static constexpr uint16_t expected[] = { 26684,
21417,
20658,
19791,
22896,
17433,
9806,
27948,
21767,
18588,
30556,
28244,
9439,
18293,
29949 };
};
template <>
struct uniform_integer_test_params<int16_t> {
static constexpr int16_t lowest = -17222;
static constexpr int16_t highest = 17222;
static constexpr int16_t expected[] = { 10326,
4863,
4076,
3177,
6397,
731,
-7179,
11637,
5226,
1929,
14342,
11944,
-7560,
1623,
13712 };
};
template <>
struct uniform_integer_test_params<uint32_t> {
static constexpr uint32_t lowest = 17222;
static constexpr uint32_t highest = 234234;
static constexpr uint32_t expected[] = { 190784,
156367,
151409,
145743,
166032,
130337,
80501,
199046,
158654,
137883,
216091,
200981,
78099,
135954,
212120 };
};
template <>
struct uniform_integer_test_params<int32_t> {
static constexpr int32_t lowest = -237272;
static constexpr int32_t highest = 234234;
static constexpr int32_t expected[] = { 139829,
65050,
54278,
41969,
86051,
8494,
-99785,
157781,
70021,
24890,
194815,
161985,
-105004,
20699,
186186 };
};
template <>
struct uniform_integer_test_params<uint64_t> {
static constexpr uint64_t lowest = 1234;
static constexpr uint64_t highest = 1234567890;
static constexpr uint64_t expected[] = { 987382749,
763380386,
846572137,
359990258,
804599765,
1131353566,
346324913,
1108760730,
1141693933,
856999148,
879390623,
1149485521,
900556586,
952385958,
807916408 };
};
template <>
struct uniform_integer_test_params<int64_t> {
static constexpr int64_t lowest = -1234567890;
static constexpr int64_t highest = 1234567890;
static constexpr int64_t expected[] = { 740197113,
292191940,
458575608,
-514589122,
374630781,
1028139036,
-541919840,
982953318,
1048819790,
479429651,
524212647,
1064402981,
566544615,
670203462,
381264073 };
};
// We need these definitions for C++14 and earlier, but
// GCC will complain about them in newer C++ standards
#if __cplusplus <= 201402L
constexpr bool uniform_integer_test_params<bool>::expected[];
constexpr char uniform_integer_test_params<char>::expected[];
constexpr uint8_t uniform_integer_test_params<uint8_t>::expected[];
constexpr int8_t uniform_integer_test_params<int8_t>::expected[];
constexpr uint16_t uniform_integer_test_params<uint16_t>::expected[];
constexpr int16_t uniform_integer_test_params<int16_t>::expected[];
constexpr uint32_t uniform_integer_test_params<uint32_t>::expected[];
constexpr int32_t uniform_integer_test_params<int32_t>::expected[];
constexpr uint64_t uniform_integer_test_params<uint64_t>::expected[];
constexpr int64_t uniform_integer_test_params<int64_t>::expected[];
#endif
}
TEMPLATE_TEST_CASE( "uniform_integer_distribution is reproducible",
"[rng][distribution][approvals]",
bool,
char,
uint8_t,
int8_t,
uint16_t,
int16_t,
uint32_t,
int32_t,
uint64_t,
int64_t) {
Catch::SimplePcg32 pcg( 0xaabb'ccdd );
constexpr auto lowest = uniform_integer_test_params<TestType>::lowest;
constexpr auto highest = uniform_integer_test_params<TestType>::highest;
Catch::uniform_integer_distribution<TestType> dist(lowest, highest);
constexpr auto iters = 15;
std::array<TestType, iters> generated;
for (int i = 0; i < iters; ++i) {
generated[i] = dist( pcg );
}
REQUIRE_THAT(generated, Catch::Matchers::RangeEquals(uniform_integer_test_params<TestType>::expected));
}