diff options
Diffstat (limited to 'include/internal/catch_generators.hpp')
-rw-r--r-- | include/internal/catch_generators.hpp | 212 |
1 files changed, 0 insertions, 212 deletions
diff --git a/include/internal/catch_generators.hpp b/include/internal/catch_generators.hpp deleted file mode 100644 index d0fbe8bf..00000000 --- a/include/internal/catch_generators.hpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Created by Phil Nash on 15/6/2018. - * - * Distributed under the Boost Software License, Version 1.0. (See accompanying - * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED -#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED - -#include "catch_interfaces_generatortracker.h" -#include "catch_common.h" -#include "catch_enforce.h" - -#include <memory> -#include <vector> -#include <cassert> - -#include <utility> -#include <exception> - -namespace Catch { - -class GeneratorException : public std::exception { - const char* const m_msg = ""; - -public: - GeneratorException(const char* msg): - m_msg(msg) - {} - - const char* what() const noexcept override final; -}; - -namespace Generators { - - // !TBD move this into its own location? - namespace pf{ - template<typename T, typename... Args> - std::unique_ptr<T> make_unique( Args&&... args ) { - return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); - } - } - - template<typename T> - struct IGenerator : GeneratorUntypedBase { - virtual ~IGenerator() = default; - - // Returns the current element of the generator - // - // \Precondition The generator is either freshly constructed, - // or the last call to `next()` returned true - virtual T const& get() const = 0; - using type = T; - }; - - template<typename T> - class SingleValueGenerator final : public IGenerator<T> { - T m_value; - public: - SingleValueGenerator(T&& value) : m_value(std::move(value)) {} - - T const& get() const override { - return m_value; - } - bool next() override { - return false; - } - }; - - template<typename T> - class FixedValuesGenerator final : public IGenerator<T> { - static_assert(!std::is_same<T, bool>::value, - "FixedValuesGenerator does not support bools because of std::vector<bool>" - "specialization, use SingleValue Generator instead."); - std::vector<T> m_values; - size_t m_idx = 0; - public: - FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {} - - T const& get() const override { - return m_values[m_idx]; - } - bool next() override { - ++m_idx; - return m_idx < m_values.size(); - } - }; - - template <typename T> - class GeneratorWrapper final { - std::unique_ptr<IGenerator<T>> m_generator; - public: - GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator): - m_generator(std::move(generator)) - {} - T const& get() const { - return m_generator->get(); - } - bool next() { - return m_generator->next(); - } - }; - - template <typename T> - GeneratorWrapper<T> value(T&& value) { - return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value))); - } - template <typename T> - GeneratorWrapper<T> values(std::initializer_list<T> values) { - return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values)); - } - - template<typename T> - class Generators : public IGenerator<T> { - std::vector<GeneratorWrapper<T>> m_generators; - size_t m_current = 0; - - void populate(GeneratorWrapper<T>&& generator) { - m_generators.emplace_back(std::move(generator)); - } - void populate(T&& val) { - m_generators.emplace_back(value(std::forward<T>(val))); - } - template<typename U> - void populate(U&& val) { - populate(T(std::forward<U>(val))); - } - template<typename U, typename... Gs> - void populate(U&& valueOrGenerator, Gs &&... moreGenerators) { - populate(std::forward<U>(valueOrGenerator)); - populate(std::forward<Gs>(moreGenerators)...); - } - - public: - template <typename... Gs> - Generators(Gs &&... moreGenerators) { - m_generators.reserve(sizeof...(Gs)); - populate(std::forward<Gs>(moreGenerators)...); - } - - T const& get() const override { - return m_generators[m_current].get(); - } - - bool next() override { - if (m_current >= m_generators.size()) { - return false; - } - const bool current_status = m_generators[m_current].next(); - if (!current_status) { - ++m_current; - } - return m_current < m_generators.size(); - } - }; - - - template<typename... Ts> - GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) { - return values<std::tuple<Ts...>>( tuples ); - } - - // Tag type to signal that a generator sequence should convert arguments to a specific type - template <typename T> - struct as {}; - - template<typename T, typename... Gs> - auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> { - return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...); - } - template<typename T> - auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> { - return Generators<T>(std::move(generator)); - } - template<typename T, typename... Gs> - auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> { - return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... ); - } - template<typename T, typename U, typename... Gs> - auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> { - return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... ); - } - - auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&; - - template<typename L> - // Note: The type after -> is weird, because VS2015 cannot parse - // the expression used in the typedef inside, when it is in - // return type. Yeah. - auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) { - using UnderlyingType = typename decltype(generatorExpression())::type; - - IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo ); - if (!tracker.hasGenerator()) { - tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression())); - } - - auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() ); - return generator.get(); - } - -} // namespace Generators -} // namespace Catch - -#define GENERATE( ... ) \ - Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) -#define GENERATE_COPY( ... ) \ - Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) -#define GENERATE_REF( ... ) \ - Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) - -#endif // TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED |