Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:54:33

0001 
0002 //              Copyright Catch2 Authors
0003 // Distributed under the Boost Software License, Version 1.0.
0004 //   (See accompanying file LICENSE.txt or copy at
0005 //        https://www.boost.org/LICENSE_1_0.txt)
0006 
0007 // SPDX-License-Identifier: BSL-1.0
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     // Returns a suitable seed for a random floating generator based off
0021     // the primary internal rng. It does so by taking current value from
0022     // the rng and returning it as the seed.
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     // We still rely on <random> for this specialization, but we don't
0050     // want to drag it into the header.
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; // = default
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 } // namespace Generators
0104 } // namespace Catch
0105 
0106 
0107 #endif // CATCH_GENERATORS_RANDOM_HPP_INCLUDED