File indexing completed on 2025-09-15 08:54:33
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef CATCH_GENERATORS_RANDOM_HPP_INCLUDED
0009 #define CATCH_GENERATORS_RANDOM_HPP_INCLUDED
0010
0011 #include <catch2/generators/catch_generators.hpp>
0012 #include <catch2/internal/catch_random_number_generator.hpp>
0013 #include <catch2/internal/catch_uniform_integer_distribution.hpp>
0014 #include <catch2/internal/catch_uniform_floating_point_distribution.hpp>
0015 #include <catch2/internal/catch_unique_ptr.hpp>
0016
0017 namespace Catch {
0018 namespace Generators {
0019 namespace Detail {
0020
0021
0022
0023 std::uint32_t getSeed();
0024 }
0025
0026 template <typename Float>
0027 class RandomFloatingGenerator final : public IGenerator<Float> {
0028 Catch::SimplePcg32 m_rng;
0029 Catch::uniform_floating_point_distribution<Float> m_dist;
0030 Float m_current_number;
0031 public:
0032 RandomFloatingGenerator( Float a, Float b, std::uint32_t seed ):
0033 m_rng(seed),
0034 m_dist(a, b) {
0035 static_cast<void>(next());
0036 }
0037
0038 Float const& get() const override {
0039 return m_current_number;
0040 }
0041 bool next() override {
0042 m_current_number = m_dist(m_rng);
0043 return true;
0044 }
0045 };
0046
0047 template <>
0048 class RandomFloatingGenerator<long double> final : public IGenerator<long double> {
0049
0050
0051 struct PImpl;
0052 Catch::Detail::unique_ptr<PImpl> m_pimpl;
0053 long double m_current_number;
0054
0055 public:
0056 RandomFloatingGenerator( long double a, long double b, std::uint32_t seed );
0057
0058 long double const& get() const override { return m_current_number; }
0059 bool next() override;
0060
0061 ~RandomFloatingGenerator() override;
0062 };
0063
0064 template <typename Integer>
0065 class RandomIntegerGenerator final : public IGenerator<Integer> {
0066 Catch::SimplePcg32 m_rng;
0067 Catch::uniform_integer_distribution<Integer> m_dist;
0068 Integer m_current_number;
0069 public:
0070 RandomIntegerGenerator( Integer a, Integer b, std::uint32_t seed ):
0071 m_rng(seed),
0072 m_dist(a, b) {
0073 static_cast<void>(next());
0074 }
0075
0076 Integer const& get() const override {
0077 return m_current_number;
0078 }
0079 bool next() override {
0080 m_current_number = m_dist(m_rng);
0081 return true;
0082 }
0083 };
0084
0085 template <typename T>
0086 std::enable_if_t<std::is_integral<T>::value, GeneratorWrapper<T>>
0087 random(T a, T b) {
0088 return GeneratorWrapper<T>(
0089 Catch::Detail::make_unique<RandomIntegerGenerator<T>>(a, b, Detail::getSeed())
0090 );
0091 }
0092
0093 template <typename T>
0094 std::enable_if_t<std::is_floating_point<T>::value,
0095 GeneratorWrapper<T>>
0096 random(T a, T b) {
0097 return GeneratorWrapper<T>(
0098 Catch::Detail::make_unique<RandomFloatingGenerator<T>>(a, b, Detail::getSeed())
0099 );
0100 }
0101
0102
0103 }
0104 }
0105
0106
0107 #endif