diff --git a/docs/generators.md b/docs/generators.md index 19c31a67..21578ac0 100644 --- a/docs/generators.md +++ b/docs/generators.md @@ -33,10 +33,9 @@ Catch2's provided generator functionality consists of three parts, * `GENERATE` macro, that serves to integrate generator expression with a test case, -* 3 fundamental generators +* 2 fundamental generators * `ValueGenerator` -- contains only single element * `ValuesGenerator` -- contains multiple elements - * `RangeGenerator` -- generates all values between `start` and `end` * 4 generic generators that modify other generators * `FilterGenerator` -- filters out elements from a generator for which the predicate returns "false" @@ -44,23 +43,25 @@ a test case, * `RepeatGenerator` -- repeats output from a generator `n` times * `MapGenerator` -- returns the result of applying `Func` on elements from a different generator -* 2 specific purpose generators +* 3 specific purpose generators * `RandomIntegerGenerator` -- generates random Integrals from range * `RandomFloatGenerator` -- generates random Floats from range + * `RangeGenerator` -- generates all values inside a specific range The generators also have associated helper functions that infer their type, making their usage much nicer. These are * `value(T&&)` for `ValueGenerator` * `values(std::initializer_list)` for `ValuesGenerator` -* `range(start, end)` for `RangeGenerator` with a step size of `1` -* `range(start, end, step)` for `RangeGenerator` with a custom step size * `filter(predicate, GeneratorWrapper&&)` for `FilterGenerator` * `take(count, GeneratorWrapper&&)` for `TakeGenerator` * `repeat(repeats, GeneratorWrapper&&)` for `RepeatGenerator` * `map(func, GeneratorWrapper&&)` for `MapGenerator` (map `T` to `T`) * `map(func, GeneratorWrapper&&)` for `MapGenerator` (map `U` to `T`) -* `range(IntegerOrFloat a, IntegerOrFloat b)` for `RandomIntegerGenerator` or `RandomFloatGenerator` +* `random(IntegerOrFloat a, IntegerOrFloat b)` for `RandomIntegerGenerator` or `RandomFloatGenerator` +* `range(start, end)` for `RangeGenerator` with a step size of `1` +* `range(start, end, step)` for `RangeGenerator` with a custom step size + And can be used as shown in the example below to create a generator that returns 100 odd random number: diff --git a/include/internal/catch_generators.hpp b/include/internal/catch_generators.hpp index 281dc4bc..3deffc3d 100644 --- a/include/internal/catch_generators.hpp +++ b/include/internal/catch_generators.hpp @@ -349,51 +349,6 @@ namespace Generators { ); } - template - class RangeGenerator final : public IGenerator { - T m_current; - T m_end; - T m_step; - bool m_positive; - - public: - RangeGenerator(T const& start, T const& end, T const& step): - m_current(start), - m_end(end), - m_step(step), - m_positive(m_step > T(0)) - { - assert(m_current != m_end && "Range start and end cannot be equal"); - assert(m_step != T(0) && "Step size cannot be zero"); - assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end"); - } - - RangeGenerator(T const& start, T const& end): - RangeGenerator(start, end, (start < end) ? T(1) : T(-1)) - {} - - T const& get() const override { - return m_current; - } - - bool next() override { - m_current += m_step; - return (m_positive) ? (m_current < m_end) : (m_current > m_end); - } - }; - - template - GeneratorWrapper range(T const& start, T const& end, T const& step) { - static_assert(std::is_integral::value && !std::is_same::value, "Type must be an integer"); - return GeneratorWrapper(pf::make_unique>(start, end, step)); - } - - template - GeneratorWrapper range(T const& start, T const& end) { - static_assert(std::is_integral::value && !std::is_same::value, "Type must be an integer"); - return GeneratorWrapper(pf::make_unique>(start, end)); - } - auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&; template diff --git a/include/internal/catch_generators_specific.hpp b/include/internal/catch_generators_specific.hpp index 9d9f5e65..7aae06bd 100644 --- a/include/internal/catch_generators_specific.hpp +++ b/include/internal/catch_generators_specific.hpp @@ -81,6 +81,53 @@ random(T a, T b) { ); } + +template +class RangeGenerator final : public IGenerator { + T m_current; + T m_end; + T m_step; + bool m_positive; + +public: + RangeGenerator(T const& start, T const& end, T const& step): + m_current(start), + m_end(end), + m_step(step), + m_positive(m_step > T(0)) + { + assert(m_current != m_end && "Range start and end cannot be equal"); + assert(m_step != T(0) && "Step size cannot be zero"); + assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end"); + } + + RangeGenerator(T const& start, T const& end): + RangeGenerator(start, end, (start < end) ? T(1) : T(-1)) + {} + + T const& get() const override { + return m_current; + } + + bool next() override { + m_current += m_step; + return (m_positive) ? (m_current < m_end) : (m_current > m_end); + } +}; + +template +GeneratorWrapper range(T const& start, T const& end, T const& step) { + static_assert(std::is_integral::value && !std::is_same::value, "Type must be an integer"); + return GeneratorWrapper(pf::make_unique>(start, end, step)); +} + +template +GeneratorWrapper range(T const& start, T const& end) { + static_assert(std::is_integral::value && !std::is_same::value, "Type must be an integer"); + return GeneratorWrapper(pf::make_unique>(start, end)); +} + + } // namespace Generators } // namespace Catch