Fix forwarding in SingleValueGenerator and generator creation

Fixes #1809
This commit is contained in:
Joe Burzinski 2019-12-15 00:16:04 -06:00 committed by Martin Hořeňovský
parent 9a8963133f
commit 6c9a255dc2
2 changed files with 26 additions and 12 deletions

View File

@ -57,7 +57,6 @@ namespace Generators {
class SingleValueGenerator final : public IGenerator<T> { class SingleValueGenerator final : public IGenerator<T> {
T m_value; T m_value;
public: public:
SingleValueGenerator(T const& value) : m_value( value ) {}
SingleValueGenerator(T&& value) : m_value(std::move(value)) {} SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
T const& get() const override { T const& get() const override {
@ -120,21 +119,21 @@ namespace Generators {
m_generators.emplace_back(std::move(generator)); m_generators.emplace_back(std::move(generator));
} }
void populate(T&& val) { void populate(T&& val) {
m_generators.emplace_back(value(std::move(val))); m_generators.emplace_back(value(std::forward<T>(val)));
} }
template<typename U> template<typename U>
void populate(U&& val) { void populate(U&& val) {
populate(T(std::move(val))); populate(T(std::forward<U>(val)));
} }
template<typename U, typename... Gs> template<typename U, typename... Gs>
void populate(U&& valueOrGenerator, Gs... moreGenerators) { void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
populate(std::forward<U>(valueOrGenerator)); populate(std::forward<U>(valueOrGenerator));
populate(std::forward<Gs>(moreGenerators)...); populate(std::forward<Gs>(moreGenerators)...);
} }
public: public:
template <typename... Gs> template <typename... Gs>
Generators(Gs... moreGenerators) { Generators(Gs &&... moreGenerators) {
m_generators.reserve(sizeof...(Gs)); m_generators.reserve(sizeof...(Gs));
populate(std::forward<Gs>(moreGenerators)...); populate(std::forward<Gs>(moreGenerators)...);
} }
@ -166,7 +165,7 @@ namespace Generators {
struct as {}; struct as {};
template<typename T, typename... Gs> template<typename T, typename... Gs>
auto makeGenerators( GeneratorWrapper<T>&& generator, Gs... moreGenerators ) -> Generators<T> { auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {
return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...); return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
} }
template<typename T> template<typename T>
@ -174,11 +173,11 @@ namespace Generators {
return Generators<T>(std::move(generator)); return Generators<T>(std::move(generator));
} }
template<typename T, typename... Gs> template<typename T, typename... Gs>
auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> { auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {
return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... ); return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
} }
template<typename T, typename U, typename... Gs> template<typename T, typename U, typename... Gs>
auto makeGenerators( as<T>, U&& val, Gs... moreGenerators ) -> Generators<T> { auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {
return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... ); return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
} }

View File

@ -181,7 +181,7 @@ TEST_CASE("Generators internals", "[generators][internals]") {
const auto step = .1; const auto step = .1;
auto gen = range(rangeStart, rangeEnd, step); auto gen = range(rangeStart, rangeEnd, step);
auto expected = rangeStart; auto expected = rangeStart;
while( (rangeEnd - expected) > step ) { while( (rangeEnd - expected) > step ) {
INFO( "Current expected value is " << expected ) INFO( "Current expected value is " << expected )
REQUIRE(gen.get() == Approx(expected)); REQUIRE(gen.get() == Approx(expected));
@ -198,7 +198,7 @@ TEST_CASE("Generators internals", "[generators][internals]") {
const auto step = .3; const auto step = .3;
auto gen = range(rangeStart, rangeEnd, step); auto gen = range(rangeStart, rangeEnd, step);
auto expected = rangeStart; auto expected = rangeStart;
while( (rangeEnd - expected) > step ) { while( (rangeEnd - expected) > step ) {
INFO( "Current expected value is " << expected ) INFO( "Current expected value is " << expected )
REQUIRE(gen.get() == Approx(expected)); REQUIRE(gen.get() == Approx(expected));
@ -214,7 +214,7 @@ TEST_CASE("Generators internals", "[generators][internals]") {
const auto step = .3; const auto step = .3;
auto gen = range(rangeStart, rangeEnd, step); auto gen = range(rangeStart, rangeEnd, step);
auto expected = rangeStart; auto expected = rangeStart;
while( (rangeEnd - expected) > step ) { while( (rangeEnd - expected) > step ) {
INFO( "Current expected value is " << expected ) INFO( "Current expected value is " << expected )
REQUIRE(gen.get() == Approx(expected)); REQUIRE(gen.get() == Approx(expected));
@ -223,7 +223,7 @@ TEST_CASE("Generators internals", "[generators][internals]") {
expected += step; expected += step;
} }
REQUIRE_FALSE(gen.next()); REQUIRE_FALSE(gen.next());
} }
} }
} }
SECTION("Negative manual step") { SECTION("Negative manual step") {
@ -311,6 +311,21 @@ TEST_CASE("GENERATE capture macros", "[generators][internals][approvals]") {
REQUIRE(value == value2); REQUIRE(value == value2);
} }
TEST_CASE("#1809 - GENERATE_COPY and SingleValueGenerator does not compile", "[generators][compilation][approvals]") {
// Verify Issue #1809 fix, only needs to compile.
auto a = GENERATE_COPY(1, 2);
(void)a;
auto b = GENERATE_COPY(as<long>{}, 1, 2);
(void)b;
int i = 1;
int j = 2;
auto c = GENERATE_COPY(i, j);
(void)c;
auto d = GENERATE_COPY(as<long>{}, i, j);
(void)d;
SUCCEED();
}
TEST_CASE("Multiple random generators in one test case output different values", "[generators][internals][approvals]") { TEST_CASE("Multiple random generators in one test case output different values", "[generators][internals][approvals]") {
SECTION("Integer") { SECTION("Integer") {
auto random1 = Catch::Generators::random(0, 1000); auto random1 = Catch::Generators::random(0, 1000);