From fecf606a05bd64d02928992843849b1a89c30b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Mon, 6 Oct 2025 11:47:38 +0200 Subject: [PATCH] Add option to skip forward to the generator interface --- docs/generators.md | 14 +++++ examples/300-Gen-OwnGenerator.cpp | 16 +++++ .../catch_interfaces_generatortracker.cpp | 26 ++++++++ .../catch_interfaces_generatortracker.hpp | 16 +++++ .../Baselines/automake.sw.approved.txt | 1 + .../Baselines/automake.sw.multi.approved.txt | 1 + .../Baselines/compact.sw.approved.txt | 11 +++- .../Baselines/compact.sw.multi.approved.txt | 11 +++- .../Baselines/console.std.approved.txt | 4 +- .../Baselines/console.sw.approved.txt | 41 +++++++++++- .../Baselines/console.sw.multi.approved.txt | 41 +++++++++++- .../SelfTest/Baselines/junit.sw.approved.txt | 3 +- .../Baselines/junit.sw.multi.approved.txt | 3 +- .../Baselines/sonarqube.sw.approved.txt | 1 + .../Baselines/sonarqube.sw.multi.approved.txt | 1 + tests/SelfTest/Baselines/tap.sw.approved.txt | 16 ++++- .../Baselines/tap.sw.multi.approved.txt | 16 ++++- .../Baselines/teamcity.sw.approved.txt | 2 + .../Baselines/teamcity.sw.multi.approved.txt | 2 + tests/SelfTest/Baselines/xml.sw.approved.txt | 63 ++++++++++++++++++- .../Baselines/xml.sw.multi.approved.txt | 63 ++++++++++++++++++- .../GeneratorsImpl.tests.cpp | 20 +++++- 22 files changed, 353 insertions(+), 19 deletions(-) diff --git a/docs/generators.md b/docs/generators.md index 000b2009..23854e69 100644 --- a/docs/generators.md +++ b/docs/generators.md @@ -252,9 +252,23 @@ struct IGenerator : GeneratorUntypedBase { // Returns user-friendly string showing the current generator element // Does not have to be overridden, IGenerator provides default implementation virtual std::string stringifyImpl() const; + + /** + * Customization point for `skipToNthElement` + * + * Does not have to be overridden, there is a default implementation. + * Can be overridden for better performance. + * + * If there are not enough elements, shall throw an error. + * + * Going backwards is not supported. + */ + virtual void skipToNthElementImpl( std::size_t n ); }; ``` +> `skipToNthElementImpl` was added in Catch2 vX.Y.Z + However, to be able to use your custom generator inside `GENERATE`, it will need to be wrapped inside a `GeneratorWrapper`. `GeneratorWrapper` is a value wrapper around a diff --git a/examples/300-Gen-OwnGenerator.cpp b/examples/300-Gen-OwnGenerator.cpp index 9cb02e39..b7f9d5da 100644 --- a/examples/300-Gen-OwnGenerator.cpp +++ b/examples/300-Gen-OwnGenerator.cpp @@ -39,6 +39,22 @@ public: current_number = m_dist(m_rand); return true; } + + // Note: this improves the performance only a bit, but it is here + // to show how you can override the skip functionality. + void skipToNthElementImpl( std::size_t n ) override { + auto current_index = currentElementIndex(); + assert(current_index <= n); + // We cannot jump forward the underlying generator directly, + // because we do not know how many bits each distributed number + // would consume to be generated. + for (; current_index < n; ++current_index) { + (void)m_dist(m_rand); + } + + // We do not have to touch the current element index; it is handled + // by the base class. + } }; // Avoids -Wweak-vtables diff --git a/src/catch2/interfaces/catch_interfaces_generatortracker.cpp b/src/catch2/interfaces/catch_interfaces_generatortracker.cpp index e9fa5dda..782b004e 100644 --- a/src/catch2/interfaces/catch_interfaces_generatortracker.cpp +++ b/src/catch2/interfaces/catch_interfaces_generatortracker.cpp @@ -7,6 +7,8 @@ // SPDX-License-Identifier: BSL-1.0 #include +#include + #include namespace Catch { @@ -21,6 +23,30 @@ namespace Catch { return ret; } + void GeneratorUntypedBase::skipToNthElementImpl( std::size_t n ) { + for ( size_t i = m_currentElementIndex; i < n; ++i ) { + bool isValid = next(); + if ( !isValid ) { + Detail::throw_generator_exception( + "Coud not jump to Nth element: not enough elements" ); + } + } + } + + void GeneratorUntypedBase::skipToNthElement( std::size_t n ) { + if ( n < m_currentElementIndex ) { + Detail::throw_generator_exception( + "Tried to jump generator backwards" ); + } + skipToNthElementImpl(n); + + // Fixup tracking after moving the generator forward + // * Ensure that the correct element index is set after skipping + // * Invalidate cache + m_currentElementIndex = n; + m_stringReprCache.clear(); + } + StringRef GeneratorUntypedBase::currentElementAsString() const { if ( m_stringReprCache.empty() ) { m_stringReprCache = stringifyImpl(); diff --git a/src/catch2/interfaces/catch_interfaces_generatortracker.hpp b/src/catch2/interfaces/catch_interfaces_generatortracker.hpp index d70cb593..3166352a 100644 --- a/src/catch2/interfaces/catch_interfaces_generatortracker.hpp +++ b/src/catch2/interfaces/catch_interfaces_generatortracker.hpp @@ -35,6 +35,15 @@ namespace Catch { //! Customization point for `currentElementAsString` virtual std::string stringifyImpl() const = 0; + /** + * Customization point for skipping to the n-th element + * + * Defaults to successively calling `countedNext`. If there + * are not enough elements to reach the nth one, will throw + * an error. + */ + virtual void skipToNthElementImpl( std::size_t n ); + public: GeneratorUntypedBase() = default; // Generation of copy ops is deprecated (and Clang will complain) @@ -58,6 +67,13 @@ namespace Catch { std::size_t currentElementIndex() const { return m_currentElementIndex; } + /** + * Moves the generator forward **to** the n-th element + * + * Cannot move backwards. + */ + void skipToNthElement( std::size_t n ); + /** * Returns generator's current element as user-friendly string. * diff --git a/tests/SelfTest/Baselines/automake.sw.approved.txt b/tests/SelfTest/Baselines/automake.sw.approved.txt index 4a6886d6..5ad460a5 100644 --- a/tests/SelfTest/Baselines/automake.sw.approved.txt +++ b/tests/SelfTest/Baselines/automake.sw.approved.txt @@ -168,6 +168,7 @@ Nor would this :test-result: PASS GENERATE can combine literals and generators :test-result: PASS Generators -- adapters :test-result: PASS Generators -- simple +:test-result: PASS Generators can be skipped forward :test-result: PASS Generators internals :test-result: PASS Greater-than inequalities with different epsilons :test-result: PASS Hashers with different seed produce different hash with same test case diff --git a/tests/SelfTest/Baselines/automake.sw.multi.approved.txt b/tests/SelfTest/Baselines/automake.sw.multi.approved.txt index b0d30b87..96ef7e15 100644 --- a/tests/SelfTest/Baselines/automake.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/automake.sw.multi.approved.txt @@ -166,6 +166,7 @@ :test-result: PASS GENERATE can combine literals and generators :test-result: PASS Generators -- adapters :test-result: PASS Generators -- simple +:test-result: PASS Generators can be skipped forward :test-result: PASS Generators internals :test-result: PASS Greater-than inequalities with different epsilons :test-result: PASS Hashers with different seed produce different hash with same test case diff --git a/tests/SelfTest/Baselines/compact.sw.approved.txt b/tests/SelfTest/Baselines/compact.sw.approved.txt index cacb898a..f0f7c847 100644 --- a/tests/SelfTest/Baselines/compact.sw.approved.txt +++ b/tests/SelfTest/Baselines/compact.sw.approved.txt @@ -787,6 +787,13 @@ Generators.tests.cpp:: passed: j < i for: -1 < 3 Generators.tests.cpp:: passed: 4u * i > str.size() for: 12 > 1 Generators.tests.cpp:: passed: 4u * i > str.size() for: 12 > 2 Generators.tests.cpp:: passed: 4u * i > str.size() for: 12 > 3 +GeneratorsImpl.tests.cpp:: passed: generator.currentElementIndex() == 0 for: 0 == 0 +GeneratorsImpl.tests.cpp:: passed: generator.currentElementIndex() == 3 for: 3 == 3 +GeneratorsImpl.tests.cpp:: passed: generator.get() == 3 for: 3 == 3 +GeneratorsImpl.tests.cpp:: passed: generator.currentElementIndex() == 5 for: 5 == 5 +GeneratorsImpl.tests.cpp:: passed: generator.get() == 5 for: 5 == 5 +GeneratorsImpl.tests.cpp:: passed: generator.skipToNthElement( 3 ) +GeneratorsImpl.tests.cpp:: passed: generator.skipToNthElement( 6 ) GeneratorsImpl.tests.cpp:: passed: gen.get() == 123 for: 123 == 123 GeneratorsImpl.tests.cpp:: passed: !(gen.next()) for: !false GeneratorsImpl.tests.cpp:: passed: gen.get() == 1 for: 1 == 1 @@ -2888,7 +2895,7 @@ InternalBenchmark.tests.cpp:: passed: med == 18. for: 18.0 == 18.0 InternalBenchmark.tests.cpp:: passed: q3 == 23. for: 23.0 == 23.0 Misc.tests.cpp:: passed: Misc.tests.cpp:: passed: -test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected -assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected +test cases: 436 | 318 passed | 95 failed | 6 skipped | 17 failed as expected +assertions: 2310 | 2112 passed | 157 failed | 41 failed as expected diff --git a/tests/SelfTest/Baselines/compact.sw.multi.approved.txt b/tests/SelfTest/Baselines/compact.sw.multi.approved.txt index 10395c9a..1bbd088d 100644 --- a/tests/SelfTest/Baselines/compact.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/compact.sw.multi.approved.txt @@ -785,6 +785,13 @@ Generators.tests.cpp:: passed: j < i for: -1 < 3 Generators.tests.cpp:: passed: 4u * i > str.size() for: 12 > 1 Generators.tests.cpp:: passed: 4u * i > str.size() for: 12 > 2 Generators.tests.cpp:: passed: 4u * i > str.size() for: 12 > 3 +GeneratorsImpl.tests.cpp:: passed: generator.currentElementIndex() == 0 for: 0 == 0 +GeneratorsImpl.tests.cpp:: passed: generator.currentElementIndex() == 3 for: 3 == 3 +GeneratorsImpl.tests.cpp:: passed: generator.get() == 3 for: 3 == 3 +GeneratorsImpl.tests.cpp:: passed: generator.currentElementIndex() == 5 for: 5 == 5 +GeneratorsImpl.tests.cpp:: passed: generator.get() == 5 for: 5 == 5 +GeneratorsImpl.tests.cpp:: passed: generator.skipToNthElement( 3 ) +GeneratorsImpl.tests.cpp:: passed: generator.skipToNthElement( 6 ) GeneratorsImpl.tests.cpp:: passed: gen.get() == 123 for: 123 == 123 GeneratorsImpl.tests.cpp:: passed: !(gen.next()) for: !false GeneratorsImpl.tests.cpp:: passed: gen.get() == 1 for: 1 == 1 @@ -2877,7 +2884,7 @@ InternalBenchmark.tests.cpp:: passed: med == 18. for: 18.0 == 18.0 InternalBenchmark.tests.cpp:: passed: q3 == 23. for: 23.0 == 23.0 Misc.tests.cpp:: passed: Misc.tests.cpp:: passed: -test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected -assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected +test cases: 436 | 318 passed | 95 failed | 6 skipped | 17 failed as expected +assertions: 2310 | 2112 passed | 157 failed | 41 failed as expected diff --git a/tests/SelfTest/Baselines/console.std.approved.txt b/tests/SelfTest/Baselines/console.std.approved.txt index c1512db5..b69b94ce 100644 --- a/tests/SelfTest/Baselines/console.std.approved.txt +++ b/tests/SelfTest/Baselines/console.std.approved.txt @@ -1719,6 +1719,6 @@ due to unexpected exception with message: Why would you throw a std::string? =============================================================================== -test cases: 435 | 335 passed | 76 failed | 7 skipped | 17 failed as expected -assertions: 2282 | 2105 passed | 136 failed | 41 failed as expected +test cases: 436 | 336 passed | 76 failed | 7 skipped | 17 failed as expected +assertions: 2289 | 2112 passed | 136 failed | 41 failed as expected diff --git a/tests/SelfTest/Baselines/console.sw.approved.txt b/tests/SelfTest/Baselines/console.sw.approved.txt index 7fd59514..2b21ecd4 100644 --- a/tests/SelfTest/Baselines/console.sw.approved.txt +++ b/tests/SelfTest/Baselines/console.sw.approved.txt @@ -5831,6 +5831,43 @@ Generators.tests.cpp:: PASSED: with expansion: 12 > 3 +------------------------------------------------------------------------------- +Generators can be skipped forward +------------------------------------------------------------------------------- +GeneratorsImpl.tests.cpp: +............................................................................... + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE( generator.currentElementIndex() == 0 ) +with expansion: + 0 == 0 + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE( generator.currentElementIndex() == 3 ) +with expansion: + 3 == 3 + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE( generator.get() == 3 ) +with expansion: + 3 == 3 + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE( generator.currentElementIndex() == 5 ) +with expansion: + 5 == 5 + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE( generator.get() == 5 ) +with expansion: + 5 == 5 + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE_THROWS( generator.skipToNthElement( 3 ) ) + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE_THROWS( generator.skipToNthElement( 6 ) ) + ------------------------------------------------------------------------------- Generators internals Single value @@ -19295,6 +19332,6 @@ Misc.tests.cpp: Misc.tests.cpp:: PASSED: =============================================================================== -test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected -assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected +test cases: 436 | 318 passed | 95 failed | 6 skipped | 17 failed as expected +assertions: 2310 | 2112 passed | 157 failed | 41 failed as expected diff --git a/tests/SelfTest/Baselines/console.sw.multi.approved.txt b/tests/SelfTest/Baselines/console.sw.multi.approved.txt index 08ab1b2b..6bb06d6f 100644 --- a/tests/SelfTest/Baselines/console.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/console.sw.multi.approved.txt @@ -5829,6 +5829,43 @@ Generators.tests.cpp:: PASSED: with expansion: 12 > 3 +------------------------------------------------------------------------------- +Generators can be skipped forward +------------------------------------------------------------------------------- +GeneratorsImpl.tests.cpp: +............................................................................... + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE( generator.currentElementIndex() == 0 ) +with expansion: + 0 == 0 + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE( generator.currentElementIndex() == 3 ) +with expansion: + 3 == 3 + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE( generator.get() == 3 ) +with expansion: + 3 == 3 + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE( generator.currentElementIndex() == 5 ) +with expansion: + 5 == 5 + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE( generator.get() == 5 ) +with expansion: + 5 == 5 + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE_THROWS( generator.skipToNthElement( 3 ) ) + +GeneratorsImpl.tests.cpp:: PASSED: + REQUIRE_THROWS( generator.skipToNthElement( 6 ) ) + ------------------------------------------------------------------------------- Generators internals Single value @@ -19284,6 +19321,6 @@ Misc.tests.cpp: Misc.tests.cpp:: PASSED: =============================================================================== -test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected -assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected +test cases: 436 | 318 passed | 95 failed | 6 skipped | 17 failed as expected +assertions: 2310 | 2112 passed | 157 failed | 41 failed as expected diff --git a/tests/SelfTest/Baselines/junit.sw.approved.txt b/tests/SelfTest/Baselines/junit.sw.approved.txt index c12b6178..98a6fbd9 100644 --- a/tests/SelfTest/Baselines/junit.sw.approved.txt +++ b/tests/SelfTest/Baselines/junit.sw.approved.txt @@ -1,7 +1,7 @@ - + @@ -837,6 +837,7 @@ at Message.tests.cpp: + diff --git a/tests/SelfTest/Baselines/junit.sw.multi.approved.txt b/tests/SelfTest/Baselines/junit.sw.multi.approved.txt index e844ca6c..24a4581e 100644 --- a/tests/SelfTest/Baselines/junit.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/junit.sw.multi.approved.txt @@ -1,6 +1,6 @@ - + @@ -836,6 +836,7 @@ at Message.tests.cpp: + diff --git a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt index d79abd37..eccb0540 100644 --- a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt +++ b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt @@ -144,6 +144,7 @@ at AssertionHandler.tests.cpp: + diff --git a/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt index 98a06c14..1bbf4580 100644 --- a/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt @@ -143,6 +143,7 @@ at AssertionHandler.tests.cpp: + diff --git a/tests/SelfTest/Baselines/tap.sw.approved.txt b/tests/SelfTest/Baselines/tap.sw.approved.txt index 3e5d1832..e55e57b4 100644 --- a/tests/SelfTest/Baselines/tap.sw.approved.txt +++ b/tests/SelfTest/Baselines/tap.sw.approved.txt @@ -1430,6 +1430,20 @@ ok {test-number} - 4u * i > str.size() for: 12 > 1 ok {test-number} - 4u * i > str.size() for: 12 > 2 # Generators -- simple ok {test-number} - 4u * i > str.size() for: 12 > 3 +# Generators can be skipped forward +ok {test-number} - generator.currentElementIndex() == 0 for: 0 == 0 +# Generators can be skipped forward +ok {test-number} - generator.currentElementIndex() == 3 for: 3 == 3 +# Generators can be skipped forward +ok {test-number} - generator.get() == 3 for: 3 == 3 +# Generators can be skipped forward +ok {test-number} - generator.currentElementIndex() == 5 for: 5 == 5 +# Generators can be skipped forward +ok {test-number} - generator.get() == 5 for: 5 == 5 +# Generators can be skipped forward +ok {test-number} - generator.skipToNthElement( 3 ) +# Generators can be skipped forward +ok {test-number} - generator.skipToNthElement( 6 ) # Generators internals ok {test-number} - gen.get() == 123 for: 123 == 123 # Generators internals @@ -4627,5 +4641,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0 ok {test-number} - # xmlentitycheck ok {test-number} - -1..2315 +1..2322 diff --git a/tests/SelfTest/Baselines/tap.sw.multi.approved.txt b/tests/SelfTest/Baselines/tap.sw.multi.approved.txt index 0fdb266a..5851d409 100644 --- a/tests/SelfTest/Baselines/tap.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/tap.sw.multi.approved.txt @@ -1428,6 +1428,20 @@ ok {test-number} - 4u * i > str.size() for: 12 > 1 ok {test-number} - 4u * i > str.size() for: 12 > 2 # Generators -- simple ok {test-number} - 4u * i > str.size() for: 12 > 3 +# Generators can be skipped forward +ok {test-number} - generator.currentElementIndex() == 0 for: 0 == 0 +# Generators can be skipped forward +ok {test-number} - generator.currentElementIndex() == 3 for: 3 == 3 +# Generators can be skipped forward +ok {test-number} - generator.get() == 3 for: 3 == 3 +# Generators can be skipped forward +ok {test-number} - generator.currentElementIndex() == 5 for: 5 == 5 +# Generators can be skipped forward +ok {test-number} - generator.get() == 5 for: 5 == 5 +# Generators can be skipped forward +ok {test-number} - generator.skipToNthElement( 3 ) +# Generators can be skipped forward +ok {test-number} - generator.skipToNthElement( 6 ) # Generators internals ok {test-number} - gen.get() == 123 for: 123 == 123 # Generators internals @@ -4616,5 +4630,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0 ok {test-number} - # xmlentitycheck ok {test-number} - -1..2315 +1..2322 diff --git a/tests/SelfTest/Baselines/teamcity.sw.approved.txt b/tests/SelfTest/Baselines/teamcity.sw.approved.txt index 853f3d80..7ceaf321 100644 --- a/tests/SelfTest/Baselines/teamcity.sw.approved.txt +++ b/tests/SelfTest/Baselines/teamcity.sw.approved.txt @@ -414,6 +414,8 @@ ##teamcity[testFinished name='Generators -- adapters' duration="{duration}"] ##teamcity[testStarted name='Generators -- simple'] ##teamcity[testFinished name='Generators -- simple' duration="{duration}"] +##teamcity[testStarted name='Generators can be skipped forward'] +##teamcity[testFinished name='Generators can be skipped forward' duration="{duration}"] ##teamcity[testStarted name='Generators internals'] ##teamcity[testFinished name='Generators internals' duration="{duration}"] ##teamcity[testStarted name='Greater-than inequalities with different epsilons'] diff --git a/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt b/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt index 10e318de..d7b26888 100644 --- a/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt @@ -414,6 +414,8 @@ ##teamcity[testFinished name='Generators -- adapters' duration="{duration}"] ##teamcity[testStarted name='Generators -- simple'] ##teamcity[testFinished name='Generators -- simple' duration="{duration}"] +##teamcity[testStarted name='Generators can be skipped forward'] +##teamcity[testFinished name='Generators can be skipped forward' duration="{duration}"] ##teamcity[testStarted name='Generators internals'] ##teamcity[testFinished name='Generators internals' duration="{duration}"] ##teamcity[testStarted name='Greater-than inequalities with different epsilons'] diff --git a/tests/SelfTest/Baselines/xml.sw.approved.txt b/tests/SelfTest/Baselines/xml.sw.approved.txt index 142d6620..5630ce74 100644 --- a/tests/SelfTest/Baselines/xml.sw.approved.txt +++ b/tests/SelfTest/Baselines/xml.sw.approved.txt @@ -6605,6 +6605,65 @@ Approx( 1.30000000000000004 ) + + + + generator.currentElementIndex() == 0 + + + 0 == 0 + + + + + generator.currentElementIndex() == 3 + + + 3 == 3 + + + + + generator.get() == 3 + + + 3 == 3 + + + + + generator.currentElementIndex() == 5 + + + 5 == 5 + + + + + generator.get() == 5 + + + 5 == 5 + + + + + generator.skipToNthElement( 3 ) + + + generator.skipToNthElement( 3 ) + + + + + generator.skipToNthElement( 6 ) + + + generator.skipToNthElement( 6 ) + + + +
@@ -22324,6 +22383,6 @@ Approx( -1.95996398454005449 )
- - + + diff --git a/tests/SelfTest/Baselines/xml.sw.multi.approved.txt b/tests/SelfTest/Baselines/xml.sw.multi.approved.txt index 62562332..21ca7f5a 100644 --- a/tests/SelfTest/Baselines/xml.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/xml.sw.multi.approved.txt @@ -6605,6 +6605,65 @@ Approx( 1.30000000000000004 )
+ + + + generator.currentElementIndex() == 0 + + + 0 == 0 + + + + + generator.currentElementIndex() == 3 + + + 3 == 3 + + + + + generator.get() == 3 + + + 3 == 3 + + + + + generator.currentElementIndex() == 5 + + + 5 == 5 + + + + + generator.get() == 5 + + + 5 == 5 + + + + + generator.skipToNthElement( 3 ) + + + generator.skipToNthElement( 3 ) + + + + + generator.skipToNthElement( 6 ) + + + generator.skipToNthElement( 6 ) + + + +
@@ -22323,6 +22382,6 @@ Approx( -1.95996398454005449 )
- - + + diff --git a/tests/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp b/tests/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp index c044547d..372fcb0a 100644 --- a/tests/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp +++ b/tests/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp @@ -85,7 +85,7 @@ TEST_CASE("Generators internals", "[generators][internals]") { filter([](int) { return false; }, values({ 1, 2, 3 })), Catch::GeneratorException); } - + // Non-trivial usage SECTION("Out-of-line predicates are copied into the generator") { auto evilNumber = Catch::Detail::make_unique(2); @@ -586,3 +586,21 @@ TEST_CASE("from_range(container) supports ADL begin/end and arrays", "[generator } } + +TEST_CASE( "Generators can be skipped forward", "[generators]" ) { + auto generator = Catch::Generators::FixedValuesGenerator( { 0, 1, 2, 3, 4, 5 } ); + REQUIRE( generator.currentElementIndex() == 0 ); + + generator.skipToNthElement( 3 ); + REQUIRE( generator.currentElementIndex() == 3 ); + REQUIRE( generator.get() == 3 ); + + generator.skipToNthElement( 5 ); + REQUIRE( generator.currentElementIndex() == 5 ); + REQUIRE( generator.get() == 5 ); + + // Backwards + REQUIRE_THROWS( generator.skipToNthElement( 3 ) ); + // Past the end + REQUIRE_THROWS( generator.skipToNthElement( 6 ) ); +}