mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 05:16:10 +01:00
Add uniform_integer_distribution
This commit is contained in:
parent
04a829b0e1
commit
ed9d672b5c
@ -141,6 +141,7 @@ set(IMPL_HEADERS
|
|||||||
${SOURCES_DIR}/internal/catch_to_string.hpp
|
${SOURCES_DIR}/internal/catch_to_string.hpp
|
||||||
${SOURCES_DIR}/internal/catch_uncaught_exceptions.hpp
|
${SOURCES_DIR}/internal/catch_uncaught_exceptions.hpp
|
||||||
${SOURCES_DIR}/internal/catch_uniform_floating_point_distribution.hpp
|
${SOURCES_DIR}/internal/catch_uniform_floating_point_distribution.hpp
|
||||||
|
${SOURCES_DIR}/internal/catch_uniform_integer_distribution.hpp
|
||||||
${SOURCES_DIR}/internal/catch_unique_name.hpp
|
${SOURCES_DIR}/internal/catch_unique_name.hpp
|
||||||
${SOURCES_DIR}/internal/catch_unique_ptr.hpp
|
${SOURCES_DIR}/internal/catch_unique_ptr.hpp
|
||||||
${SOURCES_DIR}/internal/catch_void_type.hpp
|
${SOURCES_DIR}/internal/catch_void_type.hpp
|
||||||
|
@ -123,6 +123,7 @@
|
|||||||
#include <catch2/internal/catch_to_string.hpp>
|
#include <catch2/internal/catch_to_string.hpp>
|
||||||
#include <catch2/internal/catch_uncaught_exceptions.hpp>
|
#include <catch2/internal/catch_uncaught_exceptions.hpp>
|
||||||
#include <catch2/internal/catch_uniform_floating_point_distribution.hpp>
|
#include <catch2/internal/catch_uniform_floating_point_distribution.hpp>
|
||||||
|
#include <catch2/internal/catch_uniform_integer_distribution.hpp>
|
||||||
#include <catch2/internal/catch_unique_name.hpp>
|
#include <catch2/internal/catch_unique_name.hpp>
|
||||||
#include <catch2/internal/catch_unique_ptr.hpp>
|
#include <catch2/internal/catch_unique_ptr.hpp>
|
||||||
#include <catch2/internal/catch_void_type.hpp>
|
#include <catch2/internal/catch_void_type.hpp>
|
||||||
|
126
src/catch2/internal/catch_uniform_integer_distribution.hpp
Normal file
126
src/catch2/internal/catch_uniform_integer_distribution.hpp
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
|
||||||
|
// Copyright Catch2 Authors
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE.txt or copy at
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
|
||||||
|
#ifndef CATCH_UNIFORM_INTEGER_DISTRIBUTION_HPP_INCLUDED
|
||||||
|
#define CATCH_UNIFORM_INTEGER_DISTRIBUTION_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <catch2/internal/catch_random_integer_helpers.hpp>
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
|
||||||
|
namespace Detail {
|
||||||
|
// Indirection to enable make_unsigned<bool> behaviour.
|
||||||
|
template <typename T>
|
||||||
|
struct make_unsigned {
|
||||||
|
using type = std::make_unsigned_t<T>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct make_unsigned<bool> {
|
||||||
|
using type = uint8_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using make_unsigned_t = typename make_unsigned<T>::type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of uniform distribution on integers.
|
||||||
|
*
|
||||||
|
* Unlike `std::uniform_int_distribution`, this implementation supports
|
||||||
|
* various 1 byte integral types, including bool (but you should not
|
||||||
|
* actually use it for bools).
|
||||||
|
*
|
||||||
|
* The underlying algorithm is based on the one described in "Fast Random
|
||||||
|
* Integer Generation in an Interval" by Daniel Lemire, but has been
|
||||||
|
* optimized under the assumption of reuse of the same distribution object.
|
||||||
|
*/
|
||||||
|
template <typename IntegerType>
|
||||||
|
class uniform_integer_distribution {
|
||||||
|
static_assert(std::is_integral<IntegerType>::value, "...");
|
||||||
|
|
||||||
|
using UnsignedIntegerType = Detail::make_unsigned_t<IntegerType>;
|
||||||
|
|
||||||
|
// We store the left range bound converted to internal representation,
|
||||||
|
// because it will be used in computation in the () operator.
|
||||||
|
UnsignedIntegerType m_a;
|
||||||
|
// After initialization, right bound is only used for the b() getter,
|
||||||
|
// so we keep it in the original type.
|
||||||
|
IntegerType m_b;
|
||||||
|
|
||||||
|
// How many different values are there in [a, b]. a == b => 1, can be 0 for distribution over all values in the type.
|
||||||
|
UnsignedIntegerType m_ab_distance;
|
||||||
|
|
||||||
|
// We hoisted this out of the main generation function. Technically,
|
||||||
|
// this means that using this distribution will be slower than Lemire's
|
||||||
|
// algorithm if this distribution instance will be used only few times,
|
||||||
|
// but it will be faster if it is used many times. Since Catch2 uses
|
||||||
|
// distributions only to implement random generators, we assume that each
|
||||||
|
// distribution will be reused many times and this is an optimization.
|
||||||
|
UnsignedIntegerType m_rejection_threshold = 0;
|
||||||
|
|
||||||
|
// Assumes m_b and m_a are already filled
|
||||||
|
UnsignedIntegerType computeDistance() const {
|
||||||
|
// This overflows and returns 0 if ua == 0 and ub == TYPE_MAX.
|
||||||
|
// We handle that later when generating the number.
|
||||||
|
return transposeTo(m_b) - m_a + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UnsignedIntegerType computeRejectionThreshold(UnsignedIntegerType ab_distance) {
|
||||||
|
// distance == 0 means that we will return all possible values from
|
||||||
|
// the type's range, and that we shouldn't reject anything.
|
||||||
|
if ( ab_distance == 0 ) { return 0; }
|
||||||
|
return ( ~ab_distance + 1 ) % ab_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UnsignedIntegerType transposeTo(IntegerType in) {
|
||||||
|
return Detail::transposeToNaturalOrder<IntegerType>(
|
||||||
|
static_cast<UnsignedIntegerType>( in ) );
|
||||||
|
}
|
||||||
|
static IntegerType transposeBack(UnsignedIntegerType in) {
|
||||||
|
return static_cast<IntegerType>(
|
||||||
|
Detail::transposeToNaturalOrder<IntegerType>(in) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
using result_type = IntegerType;
|
||||||
|
|
||||||
|
uniform_integer_distribution( IntegerType a, IntegerType b ):
|
||||||
|
m_a( transposeTo(a) ),
|
||||||
|
m_b( b ),
|
||||||
|
m_ab_distance( computeDistance() ),
|
||||||
|
m_rejection_threshold( computeRejectionThreshold(m_ab_distance) ) {
|
||||||
|
assert( a <= b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Generator>
|
||||||
|
result_type operator()( Generator& g ) {
|
||||||
|
// All possible values of result_type are valid.
|
||||||
|
if ( m_ab_distance == 0 ) {
|
||||||
|
return transposeBack( Detail::fillBitsFrom<UnsignedIntegerType>( g ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
auto random_number = Detail::fillBitsFrom<UnsignedIntegerType>( g );
|
||||||
|
auto emul = Detail::extendedMult( random_number, m_ab_distance );
|
||||||
|
// Unlike Lemire's algorithm we skip the ab_distance check, since
|
||||||
|
// we precomputed the rejection threshold, which is always tighter.
|
||||||
|
while (emul.lower < m_rejection_threshold) {
|
||||||
|
random_number = Detail::fillBitsFrom<UnsignedIntegerType>( g );
|
||||||
|
emul = Detail::extendedMult( random_number, m_ab_distance );
|
||||||
|
}
|
||||||
|
|
||||||
|
return transposeBack(m_a + emul.upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
result_type a() const { return transposeBack(m_a); }
|
||||||
|
result_type b() const { return m_b; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace Catch
|
||||||
|
|
||||||
|
#endif // CATCH_UNIFORM_INTEGER_DISTRIBUTION_HPP_INCLUDED
|
@ -147,6 +147,7 @@ internal_headers = [
|
|||||||
'internal/catch_to_string.hpp',
|
'internal/catch_to_string.hpp',
|
||||||
'internal/catch_uncaught_exceptions.hpp',
|
'internal/catch_uncaught_exceptions.hpp',
|
||||||
'internal/catch_uniform_floating_point_distribution.hpp',
|
'internal/catch_uniform_floating_point_distribution.hpp',
|
||||||
|
'internal/catch_uniform_integer_distribution.hpp',
|
||||||
'internal/catch_unique_name.hpp',
|
'internal/catch_unique_name.hpp',
|
||||||
'internal/catch_unique_ptr.hpp',
|
'internal/catch_unique_ptr.hpp',
|
||||||
'internal/catch_void_type.hpp',
|
'internal/catch_void_type.hpp',
|
||||||
|
@ -415,6 +415,7 @@ b1!
|
|||||||
:test-result: PASS tuple<string,string>
|
:test-result: PASS tuple<string,string>
|
||||||
:test-result: PASS tuple<tuple<int>,tuple<>,float>
|
:test-result: PASS tuple<tuple<int>,tuple<>,float>
|
||||||
:test-result: PASS uniform samples
|
: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 unique_ptr reimplementation: basic functionality
|
||||||
:test-result: PASS vec<vec<string,alloc>> -> toString
|
:test-result: PASS vec<vec<string,alloc>> -> toString
|
||||||
:test-result: PASS vector<bool> -> toString
|
:test-result: PASS vector<bool> -> toString
|
||||||
|
@ -404,6 +404,7 @@
|
|||||||
:test-result: PASS tuple<string,string>
|
:test-result: PASS tuple<string,string>
|
||||||
:test-result: PASS tuple<tuple<int>,tuple<>,float>
|
:test-result: PASS tuple<tuple<int>,tuple<>,float>
|
||||||
:test-result: PASS uniform samples
|
: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 unique_ptr reimplementation: basic functionality
|
||||||
:test-result: PASS vec<vec<string,alloc>> -> toString
|
:test-result: PASS vec<vec<string,alloc>> -> toString
|
||||||
:test-result: PASS vector<bool> -> toString
|
:test-result: PASS vector<bool> -> toString
|
||||||
|
@ -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.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.lower_bound == 23 for: 23.0 == 23
|
||||||
InternalBenchmark.tests.cpp:<line number>: passed: e.confidence_interval == 0.95 for: 0.95 == 0.95
|
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) for: !{?}
|
||||||
UniquePtr.tests.cpp:<line number>: passed: ptr.get() == 0 for: 0 == 0
|
UniquePtr.tests.cpp:<line number>: passed: ptr.get() == 0 for: 0 == 0
|
||||||
UniquePtr.tests.cpp:<line number>: passed: ptr for: {?}
|
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
|
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:
|
||||||
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
|
test cases: 417 | 312 passed | 85 failed | 6 skipped | 14 failed as expected
|
||||||
assertions: 2258 | 2077 passed | 146 failed | 35 failed as expected
|
assertions: 2260 | 2079 passed | 146 failed | 35 failed as expected
|
||||||
|
|
||||||
|
|
||||||
|
@ -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.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.lower_bound == 23 for: 23.0 == 23
|
||||||
InternalBenchmark.tests.cpp:<line number>: passed: e.confidence_interval == 0.95 for: 0.95 == 0.95
|
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) for: !{?}
|
||||||
UniquePtr.tests.cpp:<line number>: passed: ptr.get() == 0 for: 0 == 0
|
UniquePtr.tests.cpp:<line number>: passed: ptr.get() == 0 for: 0 == 0
|
||||||
UniquePtr.tests.cpp:<line number>: passed: ptr for: {?}
|
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
|
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:
|
||||||
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
|
test cases: 417 | 312 passed | 85 failed | 6 skipped | 14 failed as expected
|
||||||
assertions: 2258 | 2077 passed | 146 failed | 35 failed as expected
|
assertions: 2260 | 2079 passed | 146 failed | 35 failed as expected
|
||||||
|
|
||||||
|
|
||||||
|
@ -1588,6 +1588,6 @@ due to unexpected exception with message:
|
|||||||
Why would you throw a std::string?
|
Why would you throw a std::string?
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 416 | 325 passed | 70 failed | 7 skipped | 14 failed as expected
|
test cases: 417 | 326 passed | 70 failed | 7 skipped | 14 failed as expected
|
||||||
assertions: 2241 | 2077 passed | 129 failed | 35 failed as expected
|
assertions: 2243 | 2079 passed | 129 failed | 35 failed as expected
|
||||||
|
|
||||||
|
@ -18248,6 +18248,22 @@ InternalBenchmark.tests.cpp:<line number>: PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
0.95 == 0.95
|
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
|
unique_ptr reimplementation: basic functionality
|
||||||
Default constructed unique_ptr is empty
|
Default constructed unique_ptr is empty
|
||||||
@ -18735,6 +18751,6 @@ Misc.tests.cpp:<line number>
|
|||||||
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
|
test cases: 417 | 312 passed | 85 failed | 6 skipped | 14 failed as expected
|
||||||
assertions: 2258 | 2077 passed | 146 failed | 35 failed as expected
|
assertions: 2260 | 2079 passed | 146 failed | 35 failed as expected
|
||||||
|
|
||||||
|
@ -18237,6 +18237,22 @@ InternalBenchmark.tests.cpp:<line number>: PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
0.95 == 0.95
|
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
|
unique_ptr reimplementation: basic functionality
|
||||||
Default constructed unique_ptr is empty
|
Default constructed unique_ptr is empty
|
||||||
@ -18724,6 +18740,6 @@ Misc.tests.cpp:<line number>
|
|||||||
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
|
test cases: 417 | 312 passed | 85 failed | 6 skipped | 14 failed as expected
|
||||||
assertions: 2258 | 2077 passed | 146 failed | 35 failed as expected
|
assertions: 2260 | 2079 passed | 146 failed | 35 failed as expected
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<testsuitesloose text artifact
|
<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>
|
<properties>
|
||||||
<property name="random-seed" value="1"/>
|
<property name="random-seed" value="1"/>
|
||||||
<property name="filters" value=""*" ~[!nonportable] ~[!benchmark] ~[approvals]"/>
|
<property name="filters" value=""*" ~[!nonportable] ~[!benchmark] ~[approvals]"/>
|
||||||
@ -2075,6 +2075,7 @@ at Exception.tests.cpp:<line number>
|
|||||||
<testcase classname="<exe-name>.global" name="tuple<string,string>" time="{duration}" status="run"/>
|
<testcase classname="<exe-name>.global" name="tuple<string,string>" time="{duration}" status="run"/>
|
||||||
<testcase classname="<exe-name>.global" name="tuple<tuple<int>,tuple<>,float>" time="{duration}" status="run"/>
|
<testcase classname="<exe-name>.global" name="tuple<tuple<int>,tuple<>,float>" time="{duration}" status="run"/>
|
||||||
<testcase classname="<exe-name>.global" name="uniform samples" 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/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" 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"/>
|
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Take ownership of allocation/Plain reset deallocates" time="{duration}" status="run"/>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<testsuites>
|
<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>
|
<properties>
|
||||||
<property name="random-seed" value="1"/>
|
<property name="random-seed" value="1"/>
|
||||||
<property name="filters" value=""*" ~[!nonportable] ~[!benchmark] ~[approvals]"/>
|
<property name="filters" value=""*" ~[!nonportable] ~[!benchmark] ~[approvals]"/>
|
||||||
@ -2074,6 +2074,7 @@ at Exception.tests.cpp:<line number>
|
|||||||
<testcase classname="<exe-name>.global" name="tuple<string,string>" time="{duration}" status="run"/>
|
<testcase classname="<exe-name>.global" name="tuple<string,string>" time="{duration}" status="run"/>
|
||||||
<testcase classname="<exe-name>.global" name="tuple<tuple<int>,tuple<>,float>" time="{duration}" status="run"/>
|
<testcase classname="<exe-name>.global" name="tuple<tuple<int>,tuple<>,float>" time="{duration}" status="run"/>
|
||||||
<testcase classname="<exe-name>.global" name="uniform samples" 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/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" 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"/>
|
<testcase classname="<exe-name>.global" name="unique_ptr reimplementation: basic functionality/Take ownership of allocation/Plain reset deallocates" time="{duration}" status="run"/>
|
||||||
|
@ -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="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 accepts known methods" duration="{duration}"/>
|
||||||
<testCase name="Random seed generation reports unknown 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>
|
||||||
<file path="tests/<exe-name>/IntrospectiveTests/Reporters.tests.cpp">
|
<file path="tests/<exe-name>/IntrospectiveTests/Reporters.tests.cpp">
|
||||||
<testCase name="Multireporter calls reporters and listeners in correct order" duration="{duration}"/>
|
<testCase name="Multireporter calls reporters and listeners in correct order" duration="{duration}"/>
|
||||||
|
@ -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="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 accepts known methods" duration="{duration}"/>
|
||||||
<testCase name="Random seed generation reports unknown 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>
|
||||||
<file path="tests/<exe-name>/IntrospectiveTests/Reporters.tests.cpp">
|
<file path="tests/<exe-name>/IntrospectiveTests/Reporters.tests.cpp">
|
||||||
<testCase name="Multireporter calls reporters and listeners in correct order" duration="{duration}"/>
|
<testCase name="Multireporter calls reporters and listeners in correct order" duration="{duration}"/>
|
||||||
|
@ -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
|
ok {test-number} - e.lower_bound == 23 for: 23.0 == 23
|
||||||
# uniform samples
|
# uniform samples
|
||||||
ok {test-number} - e.confidence_interval == 0.95 for: 0.95 == 0.95
|
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
|
# unique_ptr reimplementation: basic functionality
|
||||||
ok {test-number} - !(ptr) for: !{?}
|
ok {test-number} - !(ptr) for: !{?}
|
||||||
# unique_ptr reimplementation: basic functionality
|
# unique_ptr reimplementation: basic functionality
|
||||||
@ -4545,5 +4549,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
|
|||||||
ok {test-number} -
|
ok {test-number} -
|
||||||
# xmlentitycheck
|
# xmlentitycheck
|
||||||
ok {test-number} -
|
ok {test-number} -
|
||||||
1..2270
|
1..2272
|
||||||
|
|
||||||
|
@ -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
|
ok {test-number} - e.lower_bound == 23 for: 23.0 == 23
|
||||||
# uniform samples
|
# uniform samples
|
||||||
ok {test-number} - e.confidence_interval == 0.95 for: 0.95 == 0.95
|
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
|
# unique_ptr reimplementation: basic functionality
|
||||||
ok {test-number} - !(ptr) for: !{?}
|
ok {test-number} - !(ptr) for: !{?}
|
||||||
# unique_ptr reimplementation: basic functionality
|
# unique_ptr reimplementation: basic functionality
|
||||||
@ -4534,5 +4538,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
|
|||||||
ok {test-number} -
|
ok {test-number} -
|
||||||
# xmlentitycheck
|
# xmlentitycheck
|
||||||
ok {test-number} -
|
ok {test-number} -
|
||||||
1..2270
|
1..2272
|
||||||
|
|
||||||
|
@ -994,6 +994,8 @@ loose text artifact
|
|||||||
##teamcity[testFinished name='tuple<tuple<int>,tuple<>,float>' duration="{duration}"]
|
##teamcity[testFinished name='tuple<tuple<int>,tuple<>,float>' duration="{duration}"]
|
||||||
##teamcity[testStarted name='uniform samples']
|
##teamcity[testStarted name='uniform samples']
|
||||||
##teamcity[testFinished name='uniform samples' duration="{duration}"]
|
##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[testStarted name='unique_ptr reimplementation: basic functionality']
|
||||||
##teamcity[testFinished name='unique_ptr reimplementation: basic functionality' duration="{duration}"]
|
##teamcity[testFinished name='unique_ptr reimplementation: basic functionality' duration="{duration}"]
|
||||||
##teamcity[testStarted name='vec<vec<string,alloc>> -> toString']
|
##teamcity[testStarted name='vec<vec<string,alloc>> -> toString']
|
||||||
|
@ -993,6 +993,8 @@
|
|||||||
##teamcity[testFinished name='tuple<tuple<int>,tuple<>,float>' duration="{duration}"]
|
##teamcity[testFinished name='tuple<tuple<int>,tuple<>,float>' duration="{duration}"]
|
||||||
##teamcity[testStarted name='uniform samples']
|
##teamcity[testStarted name='uniform samples']
|
||||||
##teamcity[testFinished name='uniform samples' duration="{duration}"]
|
##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[testStarted name='unique_ptr reimplementation: basic functionality']
|
||||||
##teamcity[testFinished name='unique_ptr reimplementation: basic functionality' duration="{duration}"]
|
##teamcity[testFinished name='unique_ptr reimplementation: basic functionality' duration="{duration}"]
|
||||||
##teamcity[testStarted name='vec<vec<string,alloc>> -> toString']
|
##teamcity[testStarted name='vec<vec<string,alloc>> -> toString']
|
||||||
|
@ -21134,6 +21134,25 @@ b1!
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="true" skips="0"/>
|
<OverallResult success="true" skips="0"/>
|
||||||
</TestCase>
|
</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" >
|
<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" >
|
<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" >
|
<Expression success="true" type="REQUIRE_FALSE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
|
||||||
@ -21688,6 +21707,6 @@ b1!
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="true" skips="0"/>
|
<OverallResult success="true" skips="0"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<OverallResults successes="2077" failures="146" expectedFailures="35" skips="12"/>
|
<OverallResults successes="2079" failures="146" expectedFailures="35" skips="12"/>
|
||||||
<OverallResultsCases successes="311" failures="85" expectedFailures="14" skips="6"/>
|
<OverallResultsCases successes="312" failures="85" expectedFailures="14" skips="6"/>
|
||||||
</Catch2TestRun>
|
</Catch2TestRun>
|
||||||
|
@ -21133,6 +21133,25 @@ b1!
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="true" skips="0"/>
|
<OverallResult success="true" skips="0"/>
|
||||||
</TestCase>
|
</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" >
|
<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" >
|
<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" >
|
<Expression success="true" type="REQUIRE_FALSE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
|
||||||
@ -21687,6 +21706,6 @@ b1!
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="true" skips="0"/>
|
<OverallResult success="true" skips="0"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<OverallResults successes="2077" failures="146" expectedFailures="35" skips="12"/>
|
<OverallResults successes="2079" failures="146" expectedFailures="35" skips="12"/>
|
||||||
<OverallResultsCases successes="311" failures="85" expectedFailures="14" skips="6"/>
|
<OverallResultsCases successes="312" failures="85" expectedFailures="14" skips="6"/>
|
||||||
</Catch2TestRun>
|
</Catch2TestRun>
|
||||||
|
@ -12,7 +12,9 @@
|
|||||||
#include <catch2/internal/catch_random_number_generator.hpp>
|
#include <catch2/internal/catch_random_number_generator.hpp>
|
||||||
#include <catch2/internal/catch_random_seed_generation.hpp>
|
#include <catch2/internal/catch_random_seed_generation.hpp>
|
||||||
#include <catch2/internal/catch_uniform_floating_point_distribution.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/generators/catch_generators.hpp>
|
||||||
|
#include <catch2/matchers/catch_matchers_range_equals.hpp>
|
||||||
|
|
||||||
TEST_CASE("Our PCG implementation provides expected results for known seeds", "[rng]") {
|
TEST_CASE("Our PCG implementation provides expected results for known seeds", "[rng]") {
|
||||||
Catch::SimplePcg32 rng;
|
Catch::SimplePcg32 rng;
|
||||||
@ -104,3 +106,386 @@ TEST_CASE( "fillBitsFrom - shortening and stretching", "[rng][approvals]" ) {
|
|||||||
REQUIRE( stretched == 0xccbe'5f04'a424'a486 );
|
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));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user