Download build/_deps/catch2-src/include/internal/catch_generators.hpp from camenduru/thrust: direct link, hf CLI and curl.
- Browser
- Download file 7.95 kB
-
https://huggingface.co/camenduru/thrust/resolve/main/build/_deps/catch2-src/include/internal/catch_generators.hpp
- Command line
-
hf download hf://camenduru/thrust/build/_deps/catch2-src/include/internal/catch_generators.hpp
-
curl -L -o catch_generators.hpp https://huggingface.co/camenduru/thrust/resolve/main/build/_deps/catch2-src/include/internal/catch_generators.hpp
7.95 kB
| /* | |
| * 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) | |
| */ | |
| 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( StringRef generatorName, 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( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) { | |
| using UnderlyingType = typename decltype(generatorExpression())::type; | |
| IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, 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 | |