// Copyright (c) 2026 Progmasoft. // SPDX-License-Identifier: MPL-2.0 WITH AdditionRef-Progmasoft-Exception-1.1 #pragma once #include #include #include #include #include namespace Progmasoft::Catch3 { /// A value source paired with an ordered sequence of simpler candidates. /// /// The property runner owns the shrinking policy; generators only describe /// which candidates are valid and which order is most useful for /// minimization. template class Generator final { public: using GenerationFunction = std::function; using ShrinkingFunction = std::function( const ValueType& )>; Generator( GenerationFunction generate, ShrinkingFunction shrink ): generate_( std::move( generate ) ), shrink_( std::move( shrink ) ) { if ( !generate_ || !shrink_ ) { throw std::invalid_argument( "a generator requires both callbacks" ); } } [[nodiscard]] ValueType Generate( Random& random ) const { return generate_( random ); } [[nodiscard]] std::vector Shrink( const ValueType& value ) const { return shrink_( value ); } private: GenerationFunction generate_; ShrinkingFunction shrink_; }; /// Adapts user callables into a reusable generator. template [[nodiscard]] Generator MakeGenerator( GenerateFunction&& generate, ShrinkFunction&& shrink ) { return Generator( typename Generator::GenerationFunction( std::forward( generate ) ), typename Generator::ShrinkingFunction( std::forward( shrink ) ) ); } } // namespace Progmasoft::Catch3