// 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_GENERATORS_RANDOM_HPP_INCLUDED #define CATCH_GENERATORS_RANDOM_HPP_INCLUDED #include #include #include #include #include namespace Catch { namespace Generators { namespace Detail { // Returns a suitable seed for a random floating generator based off // the primary internal rng. It does so by taking current value from // the rng and returning it as the seed. std::uint32_t getSeed(); } template class RandomFloatingGenerator final : public IGenerator { Catch::SimplePcg32 m_rng; Catch::uniform_floating_point_distribution m_dist; Float m_current_number; public: RandomFloatingGenerator( Float a, Float b, std::uint32_t seed ): m_rng(seed), m_dist(a, b) { static_cast(next()); } Float const& get() const override { return m_current_number; } bool next() override { m_current_number = m_dist(m_rng); return true; } }; template <> class RandomFloatingGenerator final : public IGenerator { // We still rely on for this specialization, but we don't // want to drag it into the header. struct PImpl; Catch::Detail::unique_ptr 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 class RandomIntegerGenerator final : public IGenerator { Catch::SimplePcg32 m_rng; Catch::uniform_integer_distribution m_dist; Integer m_current_number; public: RandomIntegerGenerator( Integer a, Integer b, std::uint32_t seed ): m_rng(seed), m_dist(a, b) { static_cast(next()); } Integer const& get() const override { return m_current_number; } bool next() override { m_current_number = m_dist(m_rng); return true; } }; template std::enable_if_t::value, GeneratorWrapper> random(T a, T b) { return GeneratorWrapper( Catch::Detail::make_unique>(a, b, Detail::getSeed()) ); } template std::enable_if_t::value, GeneratorWrapper> random(T a, T b) { return GeneratorWrapper( Catch::Detail::make_unique>(a, b, Detail::getSeed()) ); } } // namespace Generators } // namespace Catch #endif // CATCH_GENERATORS_RANDOM_HPP_INCLUDED