File indexing completed on 2025-01-18 09:54:04
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/internal/catch_context.hpp>
0012 #include <catch2/generators/catch_generators.hpp>
0013 #include <catch2/internal/catch_random_number_generator.hpp>
0014
0015 #include <random>
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 std::uniform_real_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 <typename Integer>
0048 class RandomIntegerGenerator final : public IGenerator<Integer> {
0049 Catch::SimplePcg32 m_rng;
0050 std::uniform_int_distribution<Integer> m_dist;
0051 Integer m_current_number;
0052 public:
0053 RandomIntegerGenerator( Integer a, Integer b, std::uint32_t seed ):
0054 m_rng(seed),
0055 m_dist(a, b) {
0056 static_cast<void>(next());
0057 }
0058
0059 Integer const& get() const override {
0060 return m_current_number;
0061 }
0062 bool next() override {
0063 m_current_number = m_dist(m_rng);
0064 return true;
0065 }
0066 };
0067
0068 template <typename T>
0069 std::enable_if_t<std::is_integral<T>::value, GeneratorWrapper<T>>
0070 random(T a, T b) {
0071 static_assert(
0072 !std::is_same<T, char>::value &&
0073 !std::is_same<T, int8_t>::value &&
0074 !std::is_same<T, uint8_t>::value &&
0075 !std::is_same<T, signed char>::value &&
0076 !std::is_same<T, unsigned char>::value &&
0077 !std::is_same<T, bool>::value,
0078 "The requested type is not supported by the underlying random distributions from std" );
0079 return GeneratorWrapper<T>(
0080 Catch::Detail::make_unique<RandomIntegerGenerator<T>>(a, b, Detail::getSeed())
0081 );
0082 }
0083
0084 template <typename T>
0085 std::enable_if_t<std::is_floating_point<T>::value,
0086 GeneratorWrapper<T>>
0087 random(T a, T b) {
0088 return GeneratorWrapper<T>(
0089 Catch::Detail::make_unique<RandomFloatingGenerator<T>>(a, b, Detail::getSeed())
0090 );
0091 }
0092
0093
0094 }
0095 }
0096
0097
0098 #endif