mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 13:26:10 +01:00
Merge pull request #2058 from catchorg/devel-generators-cache
Fix types in generators: decay types, properly constrain forwarding
This commit is contained in:
commit
b6a3e2e26b
@ -70,8 +70,11 @@ namespace Detail {
|
|||||||
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):
|
SingleValueGenerator(T&& value):
|
||||||
m_value(std::forward<T>(value))
|
m_value(std::move(value))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
T const& get() const override {
|
T const& get() const override {
|
||||||
@ -101,9 +104,11 @@ namespace Detail {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename DecayedT = std::decay_t<T>>
|
||||||
GeneratorWrapper<T> value(T&& value) {
|
GeneratorWrapper<DecayedT> value( T&& value ) {
|
||||||
return GeneratorWrapper<T>(Catch::Detail::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
|
return GeneratorWrapper<DecayedT>(
|
||||||
|
Catch::Detail::make_unique<SingleValueGenerator<DecayedT>>(
|
||||||
|
std::forward<T>( value ) ) );
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
GeneratorWrapper<T> values(std::initializer_list<T> values) {
|
GeneratorWrapper<T> values(std::initializer_list<T> values) {
|
||||||
@ -115,27 +120,36 @@ namespace Detail {
|
|||||||
std::vector<GeneratorWrapper<T>> m_generators;
|
std::vector<GeneratorWrapper<T>> m_generators;
|
||||||
size_t m_current = 0;
|
size_t m_current = 0;
|
||||||
|
|
||||||
void populate(GeneratorWrapper<T>&& generator) {
|
void add_generator( GeneratorWrapper<T>&& generator ) {
|
||||||
m_generators.emplace_back(std::move(generator));
|
m_generators.emplace_back( std::move( generator ) );
|
||||||
}
|
}
|
||||||
void populate(T&& val) {
|
void add_generator( T const& val ) {
|
||||||
m_generators.emplace_back(value(std::forward<T>(val)));
|
m_generators.emplace_back( value( val ) );
|
||||||
}
|
}
|
||||||
template<typename U>
|
void add_generator( T&& val ) {
|
||||||
void populate(U&& val) {
|
m_generators.emplace_back( value( std::move( val ) ) );
|
||||||
populate(T(std::forward<U>(val)));
|
|
||||||
}
|
}
|
||||||
template<typename U, typename... Gs>
|
template <typename U>
|
||||||
void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
|
std::enable_if_t<!std::is_same<std::decay_t<U>, T>::value>
|
||||||
populate(std::forward<U>(valueOrGenerator));
|
add_generator( U&& val ) {
|
||||||
populate(std::forward<Gs>(moreGenerators)...);
|
add_generator( T( std::forward<U>( val ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U> void add_generators( U&& valueOrGenerator ) {
|
||||||
|
add_generator( std::forward<U>( valueOrGenerator ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U, typename... Gs>
|
||||||
|
void add_generators( U&& valueOrGenerator, Gs&&... moreGenerators ) {
|
||||||
|
add_generator( std::forward<U>( valueOrGenerator ) );
|
||||||
|
add_generators( 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)...);
|
add_generators(std::forward<Gs>(moreGenerators)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
T const& get() const override {
|
T const& get() const override {
|
||||||
@ -155,8 +169,9 @@ namespace Detail {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename... Ts>
|
template <typename... Ts>
|
||||||
GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<std::decay_t<Ts>...>> tuples ) {
|
GeneratorWrapper<std::tuple<std::decay_t<Ts>...>>
|
||||||
|
table( std::initializer_list<std::tuple<std::decay_t<Ts>...>> tuples ) {
|
||||||
return values<std::tuple<Ts...>>( tuples );
|
return values<std::tuple<Ts...>>( tuples );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +188,7 @@ namespace Detail {
|
|||||||
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<std::decay_t<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>
|
||||||
|
@ -358,3 +358,33 @@ TEST_CASE("Multiple random generators in one test case output different values",
|
|||||||
REQUIRE(same < 200);
|
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<decltype(str), const char*>::value);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user