Browse Source

Catch v2.7.0 update.

main
offa 5 years ago
parent
commit
515a998636
1 changed files with 437 additions and 200 deletions
  1. +437
    -200
      test/catch/catch2/catch.hpp

+ 437
- 200
test/catch/catch2/catch.hpp View File

/* /*
* Catch v2.6.1
* Generated: 2019-02-12 19:52:52.262497
* Catch v2.7.0
* Generated: 2019-03-07 21:34:30.252164
* ---------------------------------------------------------- * ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly * This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved. * Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved.




#define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 6
#define CATCH_VERSION_PATCH 1
#define CATCH_VERSION_MINOR 7
#define CATCH_VERSION_PATCH 0


#ifdef __clang__ #ifdef __clang__
# pragma clang system_header # pragma clang system_header
#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
#else
// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
#endif


#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)


#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
#endif #endif


#define INTERNAL_CATCH_MAKE_TYPE_LIST(types) TypeList<INTERNAL_CATCH_REMOVE_PARENS(types)>
#define INTERNAL_CATCH_MAKE_TYPE_LIST(types) Catch::TypeList<INTERNAL_CATCH_REMOVE_PARENS(types)>


#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(types)\ #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(types)\
CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,INTERNAL_CATCH_REMOVE_PARENS(types)) CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,INTERNAL_CATCH_REMOVE_PARENS(types))


#include <type_traits> #include <type_traits>


namespace Catch {
template< typename... > template< typename... >
struct TypeList{};
struct TypeList {};


template< typename... > template< typename... >
struct append; struct append;


template< template<typename...> class L1 template< template<typename...> class L1
, typename...E1
, template<typename...> class L2
, typename...E2
>
struct append< L1<E1...>, L2<E2...> >
{
using type = L1<E1..., E2...>;
, typename...E1
, template<typename...> class L2
, typename...E2
>
struct append< L1<E1...>, L2<E2...> > {
using type = L1<E1..., E2...>;
}; };


template< template<typename...> class L1 template< template<typename...> class L1
, typename...E1
, template<typename...> class L2
, typename...E2
, typename...Rest
>
struct append< L1<E1...>, L2<E2...>, Rest...>
{
using type = typename append< L1<E1..., E2...>, Rest... >::type;
, typename...E1
, template<typename...> class L2
, typename...E2
, typename...Rest
>
struct append< L1<E1...>, L2<E2...>, Rest...> {
using type = typename append< L1<E1..., E2...>, Rest... >::type;
}; };


template< template<typename...> class template< template<typename...> class
, typename...
>
, typename...
>
struct rewrap; struct rewrap;


template< template<typename...> class Container template< template<typename...> class Container
, template<typename...> class List
, typename...elems
>
struct rewrap<Container, List<elems...>>
{
, template<typename...> class List
, typename...elems
>
struct rewrap<Container, List<elems...>> {
using type = TypeList< Container< elems... > >; using type = TypeList< Container< elems... > >;
}; };


template< template<typename...> class Container template< template<typename...> class Container
, template<typename...> class List
, class...Elems
, typename...Elements>
struct rewrap<Container, List<Elems...>, Elements...>
{
, template<typename...> class List
, class...Elems
, typename...Elements>
struct rewrap<Container, List<Elems...>, Elements...> {
using type = typename append<TypeList<Container<Elems...>>, typename rewrap<Container, Elements...>::type>::type; using type = typename append<TypeList<Container<Elems...>>, typename rewrap<Container, Elements...>::type>::type;
}; };


template< template<typename...> class...Containers > template< template<typename...> class...Containers >
struct combine
{
struct combine {
template< typename...Types > template< typename...Types >
struct with_types
{
struct with_types {
template< template <typename...> class Final > template< template <typename...> class Final >
struct into
{
struct into {
using type = typename append<Final<>, typename rewrap<Containers, Types...>::type...>::type; using type = typename append<Final<>, typename rewrap<Containers, Types...>::type...>::type;
}; };
}; };
template<typename T> template<typename T>
struct always_false : std::false_type {}; struct always_false : std::false_type {};


} // namespace Catch

// end catch_meta.hpp // end catch_meta.hpp
namespace Catch { namespace Catch {


CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...) \ CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...) \
int index = 0; \ int index = 0; \
using expander = int[]; \ using expander = int[]; \
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + Catch::StringMaker<int>::convert(index++), Tags } ), 0)... };/* NOLINT */ \
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\
} \ } \
}; \ }; \
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \ static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
using TestInit = combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)> \
using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)> \
::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestName>::type; \ ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestName>::type; \
TestInit(); \ TestInit(); \
return 0; \ return 0; \
CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...)\ CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...)\
int index = 0;\ int index = 0;\
using expander = int[];\ using expander = int[];\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + Catch::StringMaker<int>::convert(index++), Tags } ), 0)... };/* NOLINT */ \
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \
}\ }\
};\ };\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
using TestInit = combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>\
using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>\
::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestNameClass>::type;\ ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestNameClass>::type;\
TestInit();\ TestInit();\
return 0;\ return 0;\
struct SectionInfo; struct SectionInfo;
struct SectionEndInfo; struct SectionEndInfo;
struct MessageInfo; struct MessageInfo;
struct MessageBuilder;
struct Counts; struct Counts;
struct BenchmarkInfo; struct BenchmarkInfo;
struct BenchmarkStats; struct BenchmarkStats;
virtual void pushScopedMessage( MessageInfo const& message ) = 0; virtual void pushScopedMessage( MessageInfo const& message ) = 0;
virtual void popScopedMessage( MessageInfo const& message ) = 0; virtual void popScopedMessage( MessageInfo const& message ) = 0;


virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;

virtual void handleFatalErrorCondition( StringRef message ) = 0; virtual void handleFatalErrorCondition( StringRef message ) = 0;


virtual void handleExpr virtual void handleExpr
class ScopedMessage { class ScopedMessage {
public: public:
explicit ScopedMessage( MessageBuilder const& builder ); explicit ScopedMessage( MessageBuilder const& builder );
ScopedMessage( ScopedMessage& duplicate ) = delete;
ScopedMessage( ScopedMessage&& old );
~ScopedMessage(); ~ScopedMessage();


MessageInfo m_info; MessageInfo m_info;
bool m_moved;
}; };


class Capturer { class Capturer {
CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
} INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \ INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( (void)0, false && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
} while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.


/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_INFO( macroName, log ) \ #define INTERNAL_CATCH_INFO( macroName, log ) \
Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ); Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );


///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )

/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Although this is matcher-based, it can be used with just a string // Although this is matcher-based, it can be used with just a string
#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \ #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... ); 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__ ); } )

// end catch_generators.hpp
// start catch_generators_generic.hpp

namespace Catch {
namespace Generators {

template <typename T> template <typename T>
class TakeGenerator : public IGenerator<T> { class TakeGenerator : public IGenerator<T> {
GeneratorWrapper<T> m_generator; GeneratorWrapper<T> m_generator;
); );
} }


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()));
template <typename T>
class ChunkGenerator final : public IGenerator<std::vector<T>> {
std::vector<T> m_chunk;
size_t m_chunk_size;
GeneratorWrapper<T> m_generator;
bool m_used_up = false;
public:
ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
m_chunk_size(size), m_generator(std::move(generator))
{
m_chunk.reserve(m_chunk_size);
m_chunk.push_back(m_generator.get());
for (size_t i = 1; i < m_chunk_size; ++i) {
if (!m_generator.next()) {
Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
}
m_chunk.push_back(m_generator.get());
}
} }
std::vector<T> const& get() const override {
return m_chunk;
}
bool next() override {
m_chunk.clear();
for (size_t idx = 0; idx < m_chunk_size; ++idx) {
if (!m_generator.next()) {
return false;
}
m_chunk.push_back(m_generator.get());
}
return true;
}
};


auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
return generator.get();
template <typename T>
GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {
return GeneratorWrapper<std::vector<T>>(
pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
);
} }


} // namespace Generators } // namespace Generators
} // namespace Catch } // namespace Catch


#define GENERATE( ... ) \
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
// end catch_generators_generic.hpp
// start catch_generators_specific.hpp


// end catch_generators.hpp
// start catch_context.h

#include <memory>

namespace Catch {

struct IResultCapture;
struct IRunner;
struct IConfig;
struct IMutableContext;

using IConfigPtr = std::shared_ptr<IConfig const>;

struct IContext
{
virtual ~IContext();

virtual IResultCapture* getResultCapture() = 0;
virtual IRunner* getRunner() = 0;
virtual IConfigPtr const& getConfig() const = 0;
};

struct IMutableContext : IContext
{
virtual ~IMutableContext();
virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
virtual void setRunner( IRunner* runner ) = 0;
virtual void setConfig( IConfigPtr const& config ) = 0;

private:
static IMutableContext *currentContext;
friend IMutableContext& getCurrentMutableContext();
friend void cleanUpContext();
static void createContext();
};

inline IMutableContext& getCurrentMutableContext()
{
if( !IMutableContext::currentContext )
IMutableContext::createContext();
return *IMutableContext::currentContext;
}

inline IContext& getCurrentContext()
{
return getCurrentMutableContext();
}

void cleanUpContext();
}

// end catch_context.h
// start catch_interfaces_config.h

#include <iosfwd>
#include <string>
#include <vector>
#include <memory>

namespace Catch {

enum class Verbosity {
Quiet = 0,
Normal,
High
};

struct WarnAbout { enum What {
Nothing = 0x00,
NoAssertions = 0x01,
NoTests = 0x02
}; };

struct ShowDurations { enum OrNot {
DefaultForReporter,
Always,
Never
}; };
struct RunTests { enum InWhatOrder {
InDeclarationOrder,
InLexicographicalOrder,
InRandomOrder
}; };
struct UseColour { enum YesOrNo {
Auto,
Yes,
No
}; };
struct WaitForKeypress { enum When {
Never,
BeforeStart = 1,
BeforeExit = 2,
BeforeStartAndExit = BeforeStart | BeforeExit
}; };

class TestSpec;

struct IConfig : NonCopyable {

virtual ~IConfig();

virtual bool allowThrows() const = 0;
virtual std::ostream& stream() const = 0;
virtual std::string name() const = 0;
virtual bool includeSuccessfulResults() const = 0;
virtual bool shouldDebugBreak() const = 0;
virtual bool warnAboutMissingAssertions() const = 0;
virtual bool warnAboutNoTests() const = 0;
virtual int abortAfter() const = 0;
virtual bool showInvisibles() const = 0;
virtual ShowDurations::OrNot showDurations() const = 0;
virtual TestSpec const& testSpec() const = 0;
virtual bool hasTestFilters() const = 0;
virtual RunTests::InWhatOrder runOrder() const = 0;
virtual unsigned int rngSeed() const = 0;
virtual int benchmarkResolutionMultiple() const = 0;
virtual UseColour::YesOrNo useColour() const = 0;
virtual std::vector<std::string> const& getSectionsToRun() const = 0;
virtual Verbosity verbosity() const = 0;
};

using IConfigPtr = std::shared_ptr<IConfig const>;
}

// end catch_interfaces_config.h
#include <random>

namespace Catch {
namespace Generators {

template <typename Float>
class RandomFloatingGenerator final : public IGenerator<Float> {
// FIXME: What is the right seed?
std::minstd_rand m_rand;
std::uniform_real_distribution<Float> m_dist;
Float m_current_number;
public:

RandomFloatingGenerator(Float a, Float b):
m_rand(getCurrentContext().getConfig()->rngSeed()),
m_dist(a, b) {
static_cast<void>(next());
}

Float const& get() const override {
return m_current_number;
}
bool next() override {
m_current_number = m_dist(m_rand);
return true;
}
};

template <typename Integer>
class RandomIntegerGenerator final : public IGenerator<Integer> {
std::minstd_rand m_rand;
std::uniform_int_distribution<Integer> m_dist;
Integer m_current_number;
public:

RandomIntegerGenerator(Integer a, Integer b):
m_rand(getCurrentContext().getConfig()->rngSeed()),
m_dist(a, b) {
static_cast<void>(next());
}

Integer const& get() const override {
return m_current_number;
}
bool next() override {
m_current_number = m_dist(m_rand);
return true;
}
};

// TODO: Ideally this would be also constrained against the various char types,
// but I don't expect users to run into that in practice.
template <typename T>
typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
GeneratorWrapper<T>>::type
random(T a, T b) {
return GeneratorWrapper<T>(
pf::make_unique<RandomIntegerGenerator<T>>(a, b)
);
}

template <typename T>
typename std::enable_if<std::is_floating_point<T>::value,
GeneratorWrapper<T>>::type
random(T a, T b) {
return GeneratorWrapper<T>(
pf::make_unique<RandomFloatingGenerator<T>>(a, b)
);
}

template <typename T>
class RangeGenerator final : public IGenerator<T> {
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 <typename T>
GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
}

template <typename T>
GeneratorWrapper<T> range(T const& start, T const& end) {
static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
}

} // namespace Generators
} // namespace Catch

// end catch_generators_specific.hpp


// These files are included here so the single_include script doesn't put them // These files are included here so the single_include script doesn't put them
// in the conditionally compiled sections // in the conditionally compiled sections
#endif #endif


// end catch_test_spec_parser.h // end catch_test_spec_parser.h
// start catch_interfaces_config.h

#include <iosfwd>
#include <string>
#include <vector>
#include <memory>

namespace Catch {

enum class Verbosity {
Quiet = 0,
Normal,
High
};

struct WarnAbout { enum What {
Nothing = 0x00,
NoAssertions = 0x01,
NoTests = 0x02
}; };

struct ShowDurations { enum OrNot {
DefaultForReporter,
Always,
Never
}; };
struct RunTests { enum InWhatOrder {
InDeclarationOrder,
InLexicographicalOrder,
InRandomOrder
}; };
struct UseColour { enum YesOrNo {
Auto,
Yes,
No
}; };
struct WaitForKeypress { enum When {
Never,
BeforeStart = 1,
BeforeExit = 2,
BeforeStartAndExit = BeforeStart | BeforeExit
}; };

class TestSpec;

struct IConfig : NonCopyable {

virtual ~IConfig();

virtual bool allowThrows() const = 0;
virtual std::ostream& stream() const = 0;
virtual std::string name() const = 0;
virtual bool includeSuccessfulResults() const = 0;
virtual bool shouldDebugBreak() const = 0;
virtual bool warnAboutMissingAssertions() const = 0;
virtual bool warnAboutNoTests() const = 0;
virtual int abortAfter() const = 0;
virtual bool showInvisibles() const = 0;
virtual ShowDurations::OrNot showDurations() const = 0;
virtual TestSpec const& testSpec() const = 0;
virtual bool hasTestFilters() const = 0;
virtual RunTests::InWhatOrder runOrder() const = 0;
virtual unsigned int rngSeed() const = 0;
virtual int benchmarkResolutionMultiple() const = 0;
virtual UseColour::YesOrNo useColour() const = 0;
virtual std::vector<std::string> const& getSectionsToRun() const = 0;
virtual Verbosity verbosity() const = 0;
};

using IConfigPtr = std::shared_ptr<IConfig const>;
}

// end catch_interfaces_config.h
// Libstdc++ doesn't like incomplete classes for unique_ptr // Libstdc++ doesn't like incomplete classes for unique_ptr


#include <memory> #include <memory>


AssertionStats( AssertionStats const& ) = default; AssertionStats( AssertionStats const& ) = default;
AssertionStats( AssertionStats && ) = default; AssertionStats( AssertionStats && ) = default;
AssertionStats& operator = ( AssertionStats const& ) = default;
AssertionStats& operator = ( AssertionStats && ) = default;
AssertionStats& operator = ( AssertionStats const& ) = delete;
AssertionStats& operator = ( AssertionStats && ) = delete;
virtual ~AssertionStats(); virtual ~AssertionStats();


AssertionResult assertionResult; AssertionResult assertionResult;
// end catch_approx.cpp // end catch_approx.cpp
// start catch_assertionhandler.cpp // start catch_assertionhandler.cpp


// start catch_context.h

#include <memory>

namespace Catch {

struct IResultCapture;
struct IRunner;
struct IConfig;
struct IMutableContext;

using IConfigPtr = std::shared_ptr<IConfig const>;

struct IContext
{
virtual ~IContext();

virtual IResultCapture* getResultCapture() = 0;
virtual IRunner* getRunner() = 0;
virtual IConfigPtr const& getConfig() const = 0;
};

struct IMutableContext : IContext
{
virtual ~IMutableContext();
virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
virtual void setRunner( IRunner* runner ) = 0;
virtual void setConfig( IConfigPtr const& config ) = 0;

private:
static IMutableContext *currentContext;
friend IMutableContext& getCurrentMutableContext();
friend void cleanUpContext();
static void createContext();
};

inline IMutableContext& getCurrentMutableContext()
{
if( !IMutableContext::currentContext )
IMutableContext::createContext();
return *IMutableContext::currentContext;
}

inline IContext& getCurrentContext()
{
return getCurrentMutableContext();
}

void cleanUpContext();
}

// end catch_context.h
// start catch_debugger.h // start catch_debugger.h


namespace Catch { namespace Catch {
void pushScopedMessage( MessageInfo const& message ) override; void pushScopedMessage( MessageInfo const& message ) override;
void popScopedMessage( MessageInfo const& message ) override; void popScopedMessage( MessageInfo const& message ) override;


void emplaceUnscopedMessage( MessageBuilder const& builder ) override;

std::string getCurrentTestName() const override; std::string getCurrentTestName() const override;


const AssertionResult* getLastResult() const override; const AssertionResult* getLastResult() const override;
Totals m_totals; Totals m_totals;
IStreamingReporterPtr m_reporter; IStreamingReporterPtr m_reporter;
std::vector<MessageInfo> m_messages; std::vector<MessageInfo> m_messages;
std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
AssertionInfo m_lastAssertionInfo; AssertionInfo m_lastAssertionInfo;
std::vector<SectionEndInfo> m_unfinishedSections; std::vector<SectionEndInfo> m_unfinishedSections;
std::vector<ITracker*> m_activeSections; std::vector<ITracker*> m_activeSections;
// ----------- end of #include from clara_textflow.hpp ----------- // ----------- end of #include from clara_textflow.hpp -----------
// ........... back in clara.hpp // ........... back in clara.hpp


#include <cctype>
#include <string> #include <string>
#include <memory> #include <memory>
#include <set> #include <set>
} }
inline auto convertInto( std::string const &source, bool &target ) -> ParserResult { inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
std::string srcLC = source; std::string srcLC = source;
std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( ::tolower(c) ); } );
std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( std::tolower(c) ); } );
if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on") if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
target = true; target = true;
else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off") else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////


ScopedMessage::ScopedMessage( MessageBuilder const& builder ) ScopedMessage::ScopedMessage( MessageBuilder const& builder )
: m_info( builder.m_info )
: m_info( builder.m_info ), m_moved()
{ {
m_info.message = builder.m_stream.str(); m_info.message = builder.m_stream.str();
getResultCapture().pushScopedMessage( m_info ); getResultCapture().pushScopedMessage( m_info );
} }


ScopedMessage::ScopedMessage( ScopedMessage&& old )
: m_info( old.m_info ), m_moved()
{
old.m_moved = true;
}

ScopedMessage::~ScopedMessage() { ScopedMessage::~ScopedMessage() {
if ( !uncaught_exceptions() ){
if ( !uncaught_exceptions() && !m_moved ){
getResultCapture().popScopedMessage(m_info); getResultCapture().popScopedMessage(m_info);
} }
} }
auto str() const -> std::string; auto str() const -> std::string;
}; };


class RedirectedStreams {
public:
RedirectedStreams(RedirectedStreams const&) = delete;
RedirectedStreams& operator=(RedirectedStreams const&) = delete;
RedirectedStreams(RedirectedStreams&&) = delete;
RedirectedStreams& operator=(RedirectedStreams&&) = delete;

RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
~RedirectedStreams();
private:
std::string& m_redirectedCout;
std::string& m_redirectedCerr;
RedirectedStdOut m_redirectedStdOut;
RedirectedStdErr m_redirectedStdErr;
};

#if defined(CATCH_CONFIG_NEW_CAPTURE) #if defined(CATCH_CONFIG_NEW_CAPTURE)


// Windows's implementation of std::tmpfile is terrible (it tries // Windows's implementation of std::tmpfile is terrible (it tries
{} {}
auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); } auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }


RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
: m_redirectedCout(redirectedCout),
m_redirectedCerr(redirectedCerr)
{}

RedirectedStreams::~RedirectedStreams() {
m_redirectedCout += m_redirectedStdOut.str();
m_redirectedCerr += m_redirectedStdErr.str();
}

#if defined(CATCH_CONFIG_NEW_CAPTURE) #if defined(CATCH_CONFIG_NEW_CAPTURE)


#if defined(_MSC_VER) #if defined(_MSC_VER)
// and should be let to clear themselves out. // and should be let to clear themselves out.
static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));


if (result.getResultType() != ResultWas::Warning)
m_messageScopes.clear();

// Reset working state // Reset working state
resetAssertionInfo(); resetAssertionInfo();
m_lastResult = result; m_lastResult = result;


m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions)); m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
m_messages.clear(); m_messages.clear();
m_messageScopes.clear();
} }


void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) { void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end()); m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
} }


void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
m_messageScopes.emplace_back( builder );
}

std::string RunContext::getCurrentTestName() const { std::string RunContext::getCurrentTestName() const {
return m_activeTestCase return m_activeTestCase
? m_activeTestCase->getTestCaseInfo().name ? m_activeTestCase->getTestCaseInfo().name
m_lastAssertionPassed = true; m_lastAssertionPassed = true;
++m_totals.assertions.passed; ++m_totals.assertions.passed;
resetAssertionInfo(); resetAssertionInfo();
m_messageScopes.clear();
} }


bool RunContext::aborting() const { bool RunContext::aborting() const {
CATCH_TRY { CATCH_TRY {
if (m_reporter->getPreferences().shouldRedirectStdOut) { if (m_reporter->getPreferences().shouldRedirectStdOut) {
#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
RedirectedStdOut redirectedStdOut;
RedirectedStdErr redirectedStdErr;
RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);


timer.start(); timer.start();
invokeActiveTestCase(); invokeActiveTestCase();
redirectedCout += redirectedStdOut.str();
redirectedCerr += redirectedStdErr.str();
#else #else
OutputRedirect r(redirectedCout, redirectedCerr); OutputRedirect r(redirectedCout, redirectedCerr);
timer.start(); timer.start();
m_testCaseTracker->close(); m_testCaseTracker->close();
handleUnfinishedSections(); handleUnfinishedSections();
m_messages.clear(); m_messages.clear();
m_messageScopes.clear();


SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions); SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
m_reporter->sectionEnded(testCaseSectionStats); m_reporter->sectionEnded(testCaseSectionStats);
return 1; return 1;


auto result = m_cli.parse( clara::Args( argc, argv ) ); auto result = m_cli.parse( clara::Args( argc, argv ) );
config();
getCurrentMutableContext().setConfig( m_config );
if( !result ) { if( !result ) {
config();
getCurrentMutableContext().setConfig(m_config);
Catch::cerr() Catch::cerr()
<< Colour( Colour::Red ) << Colour( Colour::Red )
<< "\nError(s) in input:\n" << "\nError(s) in input:\n"
} }


Version const& libraryVersion() { Version const& libraryVersion() {
static Version version( 2, 6, 1, "", 0 );
static Version version( 2, 7, 0, "", 0 );
return version; return version;
} }


#ifdef _MSC_VER #ifdef _MSC_VER
sprintf_s(buffer, "%.3f", duration); sprintf_s(buffer, "%.3f", duration);
#else #else
sprintf(buffer, "%.3f", duration);
std::sprintf(buffer, "%.3f", duration);
#endif #endif
return std::string(buffer); return std::string(buffer);
} }
case Unit::Nanoseconds: case Unit::Nanoseconds:
return "ns"; return "ns";
case Unit::Microseconds: case Unit::Microseconds:
return "µs";
return "us";
case Unit::Milliseconds: case Unit::Milliseconds:
return "ms"; return "ms";
case Unit::Seconds: case Unit::Seconds:
#endif // CATCH_CONFIG_DISABLE_MATCHERS #endif // CATCH_CONFIG_DISABLE_MATCHERS


#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
#define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ ) #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )



Loading…
Cancel
Save