diff --git a/src/catch2/generators/catch_generators.hpp b/src/catch2/generators/catch_generators.hpp index 1a3981acb7..fe9c3996b8 100644 --- a/src/catch2/generators/catch_generators.hpp +++ b/src/catch2/generators/catch_generators.hpp @@ -70,8 +70,11 @@ namespace Detail { class SingleValueGenerator final : public IGenerator { T m_value; public: + SingleValueGenerator(T const& value) : + m_value(value) + {} SingleValueGenerator(T&& value): - m_value(std::forward(value)) + m_value(std::move(value)) {} T const& get() const override { @@ -101,9 +104,11 @@ namespace Detail { } }; - template - GeneratorWrapper value(T&& value) { - return GeneratorWrapper(Catch::Detail::make_unique>(std::forward(value))); + template > + GeneratorWrapper value( T&& value ) { + return GeneratorWrapper( + Catch::Detail::make_unique>( + std::forward( value ) ) ); } template GeneratorWrapper values(std::initializer_list values) { @@ -115,27 +120,36 @@ namespace Detail { std::vector> m_generators; size_t m_current = 0; - void populate(GeneratorWrapper&& generator) { - m_generators.emplace_back(std::move(generator)); + void add_generator( GeneratorWrapper&& generator ) { + m_generators.emplace_back( std::move( generator ) ); + } + void add_generator( T const& val ) { + m_generators.emplace_back( value( val ) ); } - void populate(T&& val) { - m_generators.emplace_back(value(std::forward(val))); + void add_generator( T&& val ) { + m_generators.emplace_back( value( std::move( val ) ) ); } - template - void populate(U&& val) { - populate(T(std::forward(val))); + template + std::enable_if_t, T>::value> + add_generator( U&& val ) { + add_generator( T( std::forward( val ) ) ); } - template - void populate(U&& valueOrGenerator, Gs &&... moreGenerators) { - populate(std::forward(valueOrGenerator)); - populate(std::forward(moreGenerators)...); + + template void add_generators( U&& valueOrGenerator ) { + add_generator( std::forward( valueOrGenerator ) ); + } + + template + void add_generators( U&& valueOrGenerator, Gs&&... moreGenerators ) { + add_generator( std::forward( valueOrGenerator ) ); + add_generators( std::forward( moreGenerators )... ); } public: template Generators(Gs &&... moreGenerators) { m_generators.reserve(sizeof...(Gs)); - populate(std::forward(moreGenerators)...); + add_generators(std::forward(moreGenerators)...); } T const& get() const override { @@ -155,8 +169,9 @@ namespace Detail { }; - template - GeneratorWrapper> table( std::initializer_list...>> tuples ) { + template + GeneratorWrapper...>> + table( std::initializer_list...>> tuples ) { return values>( tuples ); } @@ -173,7 +188,7 @@ namespace Detail { return Generators(std::move(generator)); } template - auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators { + auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators> { return makeGenerators( value( std::forward( val ) ), std::forward( moreGenerators )... ); } template diff --git a/tests/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp b/tests/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp index 169cac82b0..848bb1d9e0 100644 --- a/tests/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp +++ b/tests/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp @@ -358,3 +358,33 @@ TEST_CASE("Multiple random generators in one test case output different values", REQUIRE(same < 200); } } + +TEST_CASE("#2040 - infinite compilation recursion in GENERATE with MSVC", "[generators][compilation][approvals]") { + int x = 42; + auto test = GENERATE_COPY(1, x, 2 * x); + CHECK(test < 100); +} + +namespace { + static bool always_true(int) { + return true; + } + + static bool is_even(int n) { + return n % 2 == 0; + } + + static bool is_multiple_of_3(int n) { + return n % 3 == 0; + } +} + +TEST_CASE("GENERATE handles function (pointers)", "[generators][compilation][approvals]") { + auto f = GENERATE(always_true, is_even, is_multiple_of_3); + REQUIRE(f(6)); +} + +TEST_CASE("GENERATE decays arrays", "[generators][compilation][approvals]") { + auto str = GENERATE("abc", "def", "gh"); + STATIC_REQUIRE(std::is_same::value); +}