diff options
| author | Martin Hořeňovský | 2023-12-10 16:24:46 +0100 |
|---|---|---|
| committer | Martin Hořeňovský | 2023-12-10 19:53:44 +0100 |
| commit | ae4fe16b81d819bbef8920eddf8d38a3538fe826 (patch) | |
| tree | dc6ba371ed071a0e2721fea685ae14e5db06f218 /src/catch2/generators | |
| parent | 28c66fdc5a7329aaad33db611944b832564af4d3 (diff) | |
| download | catch3-ae4fe16b81d819bbef8920eddf8d38a3538fe826.tar.gz | |
Make the user-facing random Generators reproducible
Thanks to the new distributions, this is almost trivial change.
Diffstat (limited to 'src/catch2/generators')
| -rw-r--r-- | src/catch2/generators/catch_generators_random.cpp | 32 | ||||
| -rw-r--r-- | src/catch2/generators/catch_generators_random.hpp | 34 |
2 files changed, 52 insertions, 14 deletions
diff --git a/src/catch2/generators/catch_generators_random.cpp b/src/catch2/generators/catch_generators_random.cpp index 2e3390fd..00a8e634 100644 --- a/src/catch2/generators/catch_generators_random.cpp +++ b/src/catch2/generators/catch_generators_random.cpp @@ -7,7 +7,35 @@ // SPDX-License-Identifier: BSL-1.0 #include <catch2/generators/catch_generators_random.hpp> - #include <catch2/internal/catch_context.hpp> -std::uint32_t Catch::Generators::Detail::getSeed() { return sharedRng()(); } +#include <random> + +namespace Catch { + namespace Generators { + namespace Detail { + std::uint32_t getSeed() { return sharedRng()(); } + } // namespace Detail + + struct RandomFloatingGenerator<long double>::PImpl { + PImpl( long double a, long double b, uint32_t seed ): + rng( seed ), dist( a, b ) {} + + Catch::SimplePcg32 rng; + std::uniform_real_distribution<long double> dist; + }; + + RandomFloatingGenerator<long double>::RandomFloatingGenerator( + long double a, long double b, std::uint32_t seed) : + m_pimpl(Catch::Detail::make_unique<PImpl>(a, b, seed)) { + static_cast<void>( next() ); + } + + RandomFloatingGenerator<long double>::~RandomFloatingGenerator() = + default; + bool RandomFloatingGenerator<long double>::next() { + m_current_number = m_pimpl->dist( m_pimpl->rng ); + return true; + } + } // namespace Generators +} // namespace Catch diff --git a/src/catch2/generators/catch_generators_random.hpp b/src/catch2/generators/catch_generators_random.hpp index bcd4888d..d5f307d4 100644 --- a/src/catch2/generators/catch_generators_random.hpp +++ b/src/catch2/generators/catch_generators_random.hpp @@ -11,8 +11,9 @@ #include <catch2/internal/catch_context.hpp> #include <catch2/generators/catch_generators.hpp> #include <catch2/internal/catch_random_number_generator.hpp> - -#include <random> +#include <catch2/internal/catch_uniform_integer_distribution.hpp> +#include <catch2/internal/catch_uniform_floating_point_distribution.hpp> +#include <catch2/internal/catch_unique_ptr.hpp> namespace Catch { namespace Generators { @@ -26,7 +27,7 @@ namespace Detail { template <typename Float> class RandomFloatingGenerator final : public IGenerator<Float> { Catch::SimplePcg32 m_rng; - std::uniform_real_distribution<Float> m_dist; + Catch::uniform_floating_point_distribution<Float> m_dist; Float m_current_number; public: RandomFloatingGenerator( Float a, Float b, std::uint32_t seed ): @@ -44,10 +45,27 @@ public: } }; +template <> +class RandomFloatingGenerator<long double> final : public IGenerator<long double> { + // We still rely on <random> for this specialization, but we don't + // want to drag it into the header. + struct PImpl; + Catch::Detail::unique_ptr<PImpl> m_pimpl; + long double m_current_number; + +public: + RandomFloatingGenerator( long double a, long double b, std::uint32_t seed ); + + long double const& get() const override { return m_current_number; } + bool next() override; + + ~RandomFloatingGenerator() override; // = default +}; + template <typename Integer> class RandomIntegerGenerator final : public IGenerator<Integer> { Catch::SimplePcg32 m_rng; - std::uniform_int_distribution<Integer> m_dist; + Catch::uniform_integer_distribution<Integer> m_dist; Integer m_current_number; public: RandomIntegerGenerator( Integer a, Integer b, std::uint32_t seed ): @@ -68,14 +86,6 @@ public: template <typename T> std::enable_if_t<std::is_integral<T>::value, GeneratorWrapper<T>> random(T a, T b) { - static_assert( - !std::is_same<T, char>::value && - !std::is_same<T, int8_t>::value && - !std::is_same<T, uint8_t>::value && - !std::is_same<T, signed char>::value && - !std::is_same<T, unsigned char>::value && - !std::is_same<T, bool>::value, - "The requested type is not supported by the underlying random distributions from std" ); return GeneratorWrapper<T>( Catch::Detail::make_unique<RandomIntegerGenerator<T>>(a, b, Detail::getSeed()) ); |