// Copyright Catch2 Authors // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE.txt or copy at // https://www.boost.org/LICENSE_1_0.txt) // SPDX-License-Identifier: BSL-1.0 #ifndef CATCH_GENERATORS_RANGE_HPP_INCLUDED #define CATCH_GENERATORS_RANGE_HPP_INCLUDED #include #include #include namespace Catch { 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_arithmetic::value && !std::is_same::value, "Type must be numeric"); return GeneratorWrapper(Catch::Detail::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(Catch::Detail::make_unique>(start, end)); } template class IteratorGenerator final : public IGenerator { static_assert(!std::is_same::value, "IteratorGenerator currently does not support bools" "because of std::vector specialization"); std::vector m_elems; size_t m_current = 0; public: template IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) { if (m_elems.empty()) { Detail::throw_generator_exception("IteratorGenerator received no valid values"); } } T const& get() const override { return m_elems[m_current]; } bool next() override { ++m_current; return m_current != m_elems.size(); } }; template ::value_type>> GeneratorWrapper from_range(InputIterator from, InputSentinel to) { return GeneratorWrapper(Catch::Detail::make_unique>(from, to)); } template auto from_range(Container const& cnt) { using std::begin; using std::end; return from_range( begin( cnt ), end( cnt ) ); } } // namespace Generators } // namespace Catch #endif // CATCH_GENERATORS_RANGE_HPP_INCLUDED