mirror of
https://github.com/catchorg/Catch2.git
synced 2024-12-22 19:33:29 +01:00
Deducing return type of map generator helper (#1576)
* Deduce map return type implicitly Giving the first template argument to map generator function to deduce return type is now optional even if the return type is different from the type generated by mapped generator.
This commit is contained in:
parent
296d447452
commit
54089c4c8c
@ -57,7 +57,7 @@ type, making their usage much nicer. These are
|
||||
* `filter(predicate, GeneratorWrapper<T>&&)` for `FilterGenerator<T, Predicate>`
|
||||
* `take(count, GeneratorWrapper<T>&&)` for `TakeGenerator<T>`
|
||||
* `repeat(repeats, GeneratorWrapper<T>&&)` for `RepeatGenerator<T>`
|
||||
* `map(func, GeneratorWrapper<T>&&)` for `MapGenerator<T, T, Func>` (map `T` to `T`)
|
||||
* `map(func, GeneratorWrapper<T>&&)` for `MapGenerator<T, U, Func>` (map `U` to `T`, deduced from `Func`)
|
||||
* `map<T>(func, GeneratorWrapper<U>&&)` for `MapGenerator<T, U, Func>` (map `U` to `T`)
|
||||
* `chunk(chunk-size, GeneratorWrapper<T>&&)` for `ChunkGenerator<T>`
|
||||
* `random(IntegerOrFloat a, IntegerOrFloat b)` for `RandomIntegerGenerator` or `RandomFloatGenerator`
|
||||
|
@ -169,16 +169,28 @@ namespace Generators {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename U, typename Func>
|
||||
#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
|
||||
// std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
|
||||
// replaced with std::invoke_result here. Also *_t format is preferred over
|
||||
// typename *::type format.
|
||||
template <typename Func, typename U>
|
||||
using MapFunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>;
|
||||
#else
|
||||
template <typename Func, typename U>
|
||||
using MapFunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type;
|
||||
#endif
|
||||
|
||||
template <typename Func, typename U, typename T = MapFunctionReturnType<Func, U>>
|
||||
GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
|
||||
return GeneratorWrapper<T>(
|
||||
pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
|
||||
);
|
||||
}
|
||||
template <typename T, typename Func>
|
||||
GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<T>&& generator) {
|
||||
|
||||
template <typename T, typename U, typename Func>
|
||||
GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
|
||||
return GeneratorWrapper<T>(
|
||||
pf::make_unique<MapGenerator<T, T, Func>>(std::forward<Func>(function), std::move(generator))
|
||||
pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -416,6 +416,9 @@ Generators.tests.cpp:<line number>: passed: i % 2 == 0 for: 0 == 0
|
||||
Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1
|
||||
Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1
|
||||
Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1
|
||||
Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1
|
||||
Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1
|
||||
Generators.tests.cpp:<line number>: passed: i.size() == 1 for: 1 == 1
|
||||
Generators.tests.cpp:<line number>: passed: j > 0 for: 1 > 0
|
||||
Generators.tests.cpp:<line number>: passed: j > 0 for: 2 > 0
|
||||
Generators.tests.cpp:<line number>: passed: j > 0 for: 3 > 0
|
||||
@ -495,6 +498,12 @@ GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 4.0 for: 4.0 == 4.0
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 6.0 for: 6.0 == 6.0
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 2.0 for: 2.0 == 2.0
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 4.0 for: 4.0 == 4.0
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: gen.next() for: true
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 6.0 for: 6.0 == 6.0
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 3 for: 3 == 3
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
|
||||
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 1 for: 1 == 1
|
||||
|
@ -1265,5 +1265,5 @@ due to unexpected exception with message:
|
||||
|
||||
===============================================================================
|
||||
test cases: 255 | 189 passed | 62 failed | 4 failed as expected
|
||||
assertions: 1393 | 1250 passed | 122 failed | 21 failed as expected
|
||||
assertions: 1402 | 1259 passed | 122 failed | 21 failed as expected
|
||||
|
||||
|
@ -3040,6 +3040,45 @@ Generators -- adapters
|
||||
Generators.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Generators.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( i.size() == 1 )
|
||||
with expansion:
|
||||
1 == 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Generators -- adapters
|
||||
Transforming elements
|
||||
Different deduced type
|
||||
-------------------------------------------------------------------------------
|
||||
Generators.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Generators.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( i.size() == 1 )
|
||||
with expansion:
|
||||
1 == 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Generators -- adapters
|
||||
Transforming elements
|
||||
Different deduced type
|
||||
-------------------------------------------------------------------------------
|
||||
Generators.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Generators.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( i.size() == 1 )
|
||||
with expansion:
|
||||
1 == 1
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Generators -- adapters
|
||||
Transforming elements
|
||||
Different deduced type
|
||||
-------------------------------------------------------------------------------
|
||||
Generators.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Generators.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( i.size() == 1 )
|
||||
with expansion:
|
||||
@ -3675,7 +3714,44 @@ with expansion:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Generators internals
|
||||
Map
|
||||
Map with explicit return type
|
||||
-------------------------------------------------------------------------------
|
||||
GeneratorsImpl.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
GeneratorsImpl.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( gen.get() == 2.0 )
|
||||
with expansion:
|
||||
2.0 == 2.0
|
||||
|
||||
GeneratorsImpl.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( gen.next() )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
GeneratorsImpl.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( gen.get() == 4.0 )
|
||||
with expansion:
|
||||
4.0 == 4.0
|
||||
|
||||
GeneratorsImpl.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( gen.next() )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
GeneratorsImpl.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( gen.get() == 6.0 )
|
||||
with expansion:
|
||||
6.0 == 6.0
|
||||
|
||||
GeneratorsImpl.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE_FALSE( gen.next() )
|
||||
with expansion:
|
||||
!false
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Generators internals
|
||||
Map with deduced return type
|
||||
-------------------------------------------------------------------------------
|
||||
GeneratorsImpl.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
@ -10850,5 +10926,5 @@ Misc.tests.cpp:<line number>: PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 255 | 174 passed | 77 failed | 4 failed as expected
|
||||
assertions: 1409 | 1250 passed | 138 failed | 21 failed as expected
|
||||
assertions: 1418 | 1259 passed | 138 failed | 21 failed as expected
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
<property name="random-seed" value="1"/>
|
||||
</properties>
|
||||
loose text artifact
|
||||
<testsuite name="<exe-name>" errors="17" failures="122" tests="1410" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testsuite name="<exe-name>" errors="17" failures="122" tests="1419" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="#1027" time="{duration}"/>
|
||||
@ -360,6 +360,7 @@ Message.tests.cpp:<line number>
|
||||
<testcase classname="<exe-name>.global" name="Generators -- adapters/Shortening a range" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators -- adapters/Transforming elements/Same type" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators -- adapters/Transforming elements/Different type" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators -- adapters/Transforming elements/Different deduced type" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators -- adapters/Repeating a generator" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators -- adapters/Chunking a generator into sized pieces/Number of elements in source is divisible by chunk size" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators -- adapters/Chunking a generator into sized pieces/Number of elements in source is not divisible by chunk size" time="{duration}"/>
|
||||
@ -373,7 +374,8 @@ Message.tests.cpp:<line number>
|
||||
<testcase classname="<exe-name>.global" name="Generators internals/Filter generator" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators internals/Take generator/Take less" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators internals/Take generator/Take more" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators internals/Map" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators internals/Map with explicit return type" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators internals/Map with deduced return type" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators internals/Repeat/Singular repeat" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators internals/Repeat/Actual repeat" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Generators internals/Range/Positive auto step/Integer" time="{duration}"/>
|
||||
|
@ -3736,6 +3736,48 @@ Nor would this
|
||||
</Section>
|
||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Transforming elements" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
|
||||
<Section name="Different deduced type" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
|
||||
<Original>
|
||||
i.size() == 1
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 == 1
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Transforming elements" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
|
||||
<Section name="Different deduced type" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
|
||||
<Original>
|
||||
i.size() == 1
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 == 1
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Transforming elements" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
|
||||
<Section name="Different deduced type" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
|
||||
<Original>
|
||||
i.size() == 1
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 == 1
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Repeating a generator" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
|
||||
<Original>
|
||||
@ -4461,7 +4503,58 @@ Nor would this
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Map" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
||||
<Section name="Map with explicit return type" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
||||
<Original>
|
||||
gen.get() == 2.0
|
||||
</Original>
|
||||
<Expanded>
|
||||
2.0 == 2.0
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
||||
<Original>
|
||||
gen.next()
|
||||
</Original>
|
||||
<Expanded>
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
||||
<Original>
|
||||
gen.get() == 4.0
|
||||
</Original>
|
||||
<Expanded>
|
||||
4.0 == 4.0
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
||||
<Original>
|
||||
gen.next()
|
||||
</Original>
|
||||
<Expanded>
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
||||
<Original>
|
||||
gen.get() == 6.0
|
||||
</Original>
|
||||
<Expanded>
|
||||
6.0 == 6.0
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_FALSE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
||||
<Original>
|
||||
!(gen.next())
|
||||
</Original>
|
||||
<Expanded>
|
||||
!false
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="6" failures="0" expectedFailures="0"/>
|
||||
</Section>
|
||||
<Section name="Map with deduced return type" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
|
||||
<Original>
|
||||
gen.get() == 2.0
|
||||
@ -13153,7 +13246,7 @@ loose text artifact
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<OverallResults successes="1250" failures="139" expectedFailures="21"/>
|
||||
<OverallResults successes="1259" failures="139" expectedFailures="21"/>
|
||||
</Group>
|
||||
<OverallResults successes="1250" failures="138" expectedFailures="21"/>
|
||||
<OverallResults successes="1259" failures="138" expectedFailures="21"/>
|
||||
</Catch>
|
||||
|
@ -68,7 +68,7 @@ TEST_CASE("Generators internals", "[generators][internals]") {
|
||||
REQUIRE_FALSE(gen.next());
|
||||
}
|
||||
}
|
||||
SECTION("Map") {
|
||||
SECTION("Map with explicit return type") {
|
||||
auto gen = map<double>([] (int i) {return 2.0 * i; }, values({ 1, 2, 3 }));
|
||||
REQUIRE(gen.get() == 2.0);
|
||||
REQUIRE(gen.next());
|
||||
@ -77,6 +77,15 @@ TEST_CASE("Generators internals", "[generators][internals]") {
|
||||
REQUIRE(gen.get() == 6.0);
|
||||
REQUIRE_FALSE(gen.next());
|
||||
}
|
||||
SECTION("Map with deduced return type") {
|
||||
auto gen = map([] (int i) {return 2.0 * i; }, values({ 1, 2, 3 }));
|
||||
REQUIRE(gen.get() == 2.0);
|
||||
REQUIRE(gen.next());
|
||||
REQUIRE(gen.get() == 4.0);
|
||||
REQUIRE(gen.next());
|
||||
REQUIRE(gen.get() == 6.0);
|
||||
REQUIRE_FALSE(gen.next());
|
||||
}
|
||||
SECTION("Repeat") {
|
||||
SECTION("Singular repeat") {
|
||||
auto gen = repeat(1, value(3));
|
||||
|
@ -144,6 +144,11 @@ TEST_CASE("Generators -- adapters", "[generators][generic]") {
|
||||
auto i = GENERATE(map<std::string>([] (int val) { return std::to_string(val); }, values({ 1, 2, 3 })));
|
||||
REQUIRE(i.size() == 1);
|
||||
}
|
||||
SECTION("Different deduced type") {
|
||||
// This takes a generator that returns ints and maps them into strings
|
||||
auto i = GENERATE(map([] (int val) { return std::to_string(val); }, values({ 1, 2, 3 })));
|
||||
REQUIRE(i.size() == 1);
|
||||
}
|
||||
}
|
||||
SECTION("Repeating a generator") {
|
||||
// This will return values [1, 2, 3, 1, 2, 3]
|
||||
|
Loading…
Reference in New Issue
Block a user