3142        template<
typename ArgT>
 
 3145                for( 
auto matcher : m_matchers ) {
 
 3146                    if (!matcher->match(
arg))
 
 
 3153                description.
reserve( 4 + m_matchers.size()*32 );
 
 3154                description += 
"( ";
 
 3156                for( 
auto matcher : m_matchers ) {
 
 3160                        description += 
" and ";
 
 3161                    description += matcher->toString();
 
 3163                description += 
" )";
 
 
 3168                m_matchers.push_back( &other );
 
 
 
 3174        template<
typename ArgT>
 
 3178                for( 
auto matcher : m_matchers ) {
 
 3179                    if (matcher->match(
arg))
 
 
 3186                description.
reserve( 4 + m_matchers.size()*32 );
 
 3187                description += 
"( ";
 
 3189                for( 
auto matcher : m_matchers ) {
 
 3193                        description += 
" or ";
 
 3194                    description += matcher->toString();
 
 3196                description += 
" )";
 
 
 3201                m_matchers.push_back( &other );
 
 
 
 3208        template<
typename ArgT>
 
 3214                return !m_underlyingMatcher.match( 
arg );
 
 
 3218                return "not " + m_underlyingMatcher.toString();
 
 
 
 3223        template<
typename T>
 
 3227        template<
typename T>
 
 3231        template<
typename T>
 
 
 3240using namespace Matchers;
 
 3254    namespace Floating {
 
 3256        enum class FloatingPointKind : uint8_t;
 
 3260            bool match(
double const& matchee) 
const override;
 
 
 3269            bool match(
double const& matchee) 
const override;
 
 
 
 3302template <
typename T>
 
 3309        :m_predicate(
std::move(elem)),
 
 3310        m_description(Detail::finalizeDescription(descr))
 
 
 3314        return m_predicate(item);
 
 
 3318        return m_description;
 
 
 
 
 3328    template<
typename T>
 
 3344    namespace StdString {
 
 
 3414        template<
typename T>
 
 3420                for (
auto const& el : v) {
 
 3421                    if (el == m_comparator) {
 
 
 
 3435        template<
typename T>
 
 3442                if (m_comparator.size() > v.
size())
 
 3444                for (
auto const& comparator : m_comparator) {
 
 3445                    auto present = 
false;
 
 3446                    for (
const auto& el : v) {
 
 3447                        if (el == comparator) {
 
 
 
 3465        template<
typename T>
 
 3475                if (m_comparator.size() != v.
size())
 
 3478                    if (m_comparator[i] != v[i])
 
 
 
 3488        template<
typename T>
 
 3494                if (m_comparator.size() != v.
size())
 
 3497                    if (m_comparator[i] != approx(v[i]))
 
 
 3504            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>
::type>
 
 3509            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>
::type>
 
 3511                approx.
margin(newMargin);
 
 
 3514            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>
::type>
 
 3516                approx.
scale(newScale);
 
 
 
 3524        template<
typename T>
 
 3530                if (m_target.size() != vec.
size()) {
 
 
 
 
 3548    template<
typename T>
 
 3553    template<
typename T>
 
 3558    template<
typename T>
 
 3563    template<
typename T>
 
 3568    template<
typename T>
 
 3579    template<
typename ArgT, 
typename MatcherT>
 
 3588            m_matcher( matcher ),
 
 3589            m_matcherString( matcherString )
 
 
 3593            auto matcherAsString = m_matcher.toString();
 
 3595            if( matcherAsString == Detail::unprintableString )
 
 3596                os << m_matcherString;
 
 3598                os << matcherAsString;
 
 
 
 3606    template<
typename ArgT, 
typename MatcherT>
 
 3614#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ 
 3616        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ 
 3617        INTERNAL_CATCH_TRY { \ 
 3618            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \ 
 3619        } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ 
 3620        INTERNAL_CATCH_REACT( catchAssertionHandler ) \ 
 
 3624#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \ 
 3626        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ 
 3627        if( catchAssertionHandler.allowThrows() ) \ 
 3629                static_cast<void>(__VA_ARGS__ ); \ 
 3630                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ 
 3632            catch( exceptionType const& ex ) { \ 
 3633                catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \ 
 3636                catchAssertionHandler.handleUnexpectedInflightException(); \ 
 3639            catchAssertionHandler.handleThrowingCallSkipped(); \ 
 3640        INTERNAL_CATCH_REACT( catchAssertionHandler ) \ 
 
 3672        virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
 
 3673        virtual 
void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
 
 
 3684#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 
 3685    template <
typename Ex>
 
 3696#define CATCH_PREPARE_EXCEPTION( type, msg ) \ 
 3697    type( ( Catch::ReusableStringStream() << msg ).str() ) 
 
 3698#define CATCH_INTERNAL_ERROR( msg ) \ 
 3699    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg)) 
 
 3700#define CATCH_ERROR( msg ) \ 
 3701    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::domain_error, msg )) 
 
 3702#define CATCH_RUNTIME_ERROR( msg ) \ 
 3703    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::runtime_error, msg )) 
 
 3704#define CATCH_ENFORCE( condition, msg ) \ 
 3705    do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false) 
 
 3718    const char* 
const m_msg = 
"";
 
 3725    const char* 
what() const noexcept override final;
 
 
 3728namespace Generators {
 
 3732        template<
typename T, 
typename... Args>
 
 
 3738    template<
typename T>
 
 3750    template<
typename T>
 
 3765    template<
typename T>
 
 3773            return m_values[m_idx];
 
 
 3777            return m_idx < m_values.
size();
 
 
 
 3781    template <
typename T>
 
 3786            m_generator(
std::move(generator))
 
 
 3789            return m_generator->
get();
 
 
 3792            return m_generator->next();
 
 
 
 3796    template <
typename T>
 
 3800    template <
typename T>
 
 3805    template<
typename T>
 
 3808        size_t m_current = 0;
 
 3816        template<
typename U>
 
 3818            populate(
T(std::move(val)));
 
 
 3820        template<
typename U, 
typename... Gs>
 
 3821        void populate(U&& valueOrGenerator, Gs... moreGenerators) {
 
 
 3827        template <
typename... Gs>
 
 3829            m_generators.
reserve(
sizeof...(Gs));
 
 
 3834            return m_generators[m_current].get();
 
 
 3838            if (m_current >= m_generators.
size()) {
 
 3841            const bool current_status = m_generators[m_current].next();
 
 3842            if (!current_status) {
 
 3845            return m_current < m_generators.
size();
 
 
 
 3849    template<
typename... Ts>
 
 3855    template <
typename T>
 
 3858    template<
typename T, 
typename... Gs>
 
 3862    template<
typename T>
 
 3866    template<
typename T, 
typename... Gs>
 
 3870    template<
typename T, 
typename U, 
typename... Gs>
 
 3877    template<
typename L>
 
 3882        using UnderlyingType = 
typename decltype(generatorExpression())
::type;
 
 3890        return generator.
get();
 
 
 3896#define GENERATE( ... ) \ 
 3897    Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) 
 
 3898#define GENERATE_COPY( ... ) \ 
 3899    Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) 
 
 3900#define GENERATE_REF( ... ) \ 
 3901    Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) 
 
 3907namespace Generators {
 
 3909    template <
typename T>
 
 3912        size_t m_returned = 0;
 
 3916            m_generator(
std::move(generator)),
 
 3919            assert(target != 0 && 
"Empty generators are not allowed");
 
 
 3922            return m_generator.
get();
 
 
 3926            if (m_returned >= m_target) {
 
 3930            const auto success = m_generator.
next();
 
 3934                m_returned = m_target;
 
 
 
 3940    template <
typename T>
 
 3945    template <
typename T, 
typename Predicate>
 
 3950        template <
typename P = Predicate>
 
 3952            m_generator(
std::move(generator)),
 
 3953            m_predicate(
std::forward<P>(pred))
 
 3955            if (!m_predicate(m_generator.
get())) {
 
 3958                auto has_initial_value = next();
 
 3959                if (!has_initial_value) {
 
 
 3966            return m_generator.
get();
 
 
 3970            bool success = m_generator.
next();
 
 3974            while (!m_predicate(m_generator.
get()) && (success = m_generator.
next()) == 
true);
 
 
 
 3979    template <
typename T, 
typename Predicate>
 
 3984    template <
typename T>
 
 3989        size_t m_current_repeat = 0;
 
 3990        size_t m_repeat_index = 0;
 
 3993            m_generator(
std::move(generator)),
 
 3994            m_target_repeats(repeats)
 
 3996            assert(m_target_repeats > 0 && 
"Repeat generator must repeat at least once");
 
 
 4000            if (m_current_repeat == 0) {
 
 4002                return m_returned.
back();
 
 4004            return m_returned[m_repeat_index];
 
 
 4014            if (m_current_repeat == 0) {
 
 4015                const auto success = m_generator.
next();
 
 4019                return m_current_repeat < m_target_repeats;
 
 4024            if (m_repeat_index == m_returned.
size()) {
 
 4028            return m_current_repeat < m_target_repeats;
 
 
 
 4032    template <
typename T>
 
 4037    template <
typename T, 
typename U, 
typename Func>
 
 4045        template <
typename F2 = Func>
 
 4047            m_generator(
std::move(generator)),
 
 4048            m_function(
std::forward<F2>(function)),
 
 4049            m_cache(m_function(m_generator.get()))
 
 
 4056            const auto success = m_generator.
next();
 
 4058                m_cache = m_function(m_generator.
get());
 
 
 
 4064#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703 
 4068    template <
typename Func, 
typename U>
 
 4071    template <
typename Func, 
typename U>
 
 4075    template <
typename Func, 
typename U, 
typename T = MapFunctionReturnType<Func, U>>
 
 4082    template <
typename T, 
typename U, 
typename Func>
 
 4083    GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
 
 4084        return GeneratorWrapper<T>(
 
 4085            pf::make_unique<MapGenerator<T, U, Func>>(
std::forward<Func>(function), std::move(generator))
 
 4089    template <
typename T>
 
 4094        bool m_used_up = 
false;
 
 4097            m_chunk_size(size), m_generator(
std::move(generator))
 
 4099            m_chunk.
reserve(m_chunk_size);
 
 4101            for (
size_t i = 1; i < m_chunk_size; ++i) {
 
 4102                if (!m_generator.
next()) {
 
 
 4113            for (
size_t idx = 0; idx < m_chunk_size; ++idx) {
 
 4114                if (!m_generator.
next()) {
 
 
 
 4123    template <
typename T>
 
 4126            pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
 
 
 4142    struct IResultCapture;
 
 4145    struct IMutableContext;
 
 4174        if( !IMutableContext::currentContext )
 
 4175            IMutableContext::createContext();
 
 4176        return *IMutableContext::currentContext;
 
 
 4205        NoAssertions = 0x01,
 
 
 4228        BeforeStartAndExit = BeforeStart | BeforeExit
 
 
 4265namespace Generators {
 
 4267template <
typename Float>
 
 4278        static_cast<void>(next());
 
 
 4281    Float 
const& 
get()
 const override {
 
 4282        return m_current_number;
 
 
 4285        m_current_number = m_dist(m_rand);
 
 
 
 4290template <
typename Integer>
 
 4300        static_cast<void>(next());
 
 
 4303    Integer 
const& 
get()
 const override {
 
 4304        return m_current_number;
 
 
 4307        m_current_number = m_dist(m_rand);
 
 
 
 4314template <
typename T>
 
 4316GeneratorWrapper<T>>
::type 
 4323template <
typename T>
 
 4325GeneratorWrapper<T>>
::type 
 4332template <
typename T>
 
 4344        m_positive(m_step > 
T(0))
 
 4346        assert(m_current != m_end && 
"Range start and end cannot be equal");
 
 4347        assert(m_step != 
T(0) && 
"Step size cannot be zero");
 
 4348        assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && 
"Step moves away from end");
 
 
 4360        m_current += m_step;
 
 4361        return (m_positive) ? (m_current < m_end) : (m_current > m_end);
 
 
 
 4365template <
typename T>
 
 4371template <
typename T>
 
 4391#pragma clang diagnostic push 
 4392#pragma clang diagnostic ignored "-Wpadded" 
 4397    struct ITestInvoker;
 
 4403            ShouldFail = 1 << 2,
 
 4406            NonPortable = 1 << 5,
 
 
 4419        bool throws() 
const;
 
 
 4459#pragma clang diagnostic pop 
 4478#import <objc/runtime.h> 
 4500    class OcMethod : 
public ITestInvoker {
 
 4503        OcMethod( Class cls, 
SEL sel ) : m_cls( cls ), m_sel( sel ) {}
 
 4505        virtual void invoke()
 const {
 
 4506            id obj = [[m_cls alloc] init];
 
 4508            performOptionalSelector( obj, 
@selector(setUp)  );
 
 4509            performOptionalSelector( obj, m_sel );
 
 4510            performOptionalSelector( obj, 
@selector(tearDown)  );
 
 4512            arcSafeRelease( obj );
 
 4515        virtual ~OcMethod() {}
 
 4526            NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
 
 4527            SEL sel = NSSelectorFromString( selStr );
 
 4528            arcSafeRelease( selStr );
 
 4529            id value = performOptionalSelector( cls, sel );
 
 4531                return [(NSString*)
value UTF8String];
 
 4538        int noClasses = objc_getClassList( 
nullptr, 0 );
 
 4540        Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)
malloc( 
sizeof(Class) * noClasses);
 
 4541        objc_getClassList( classes, noClasses );
 
 4543        for( 
int c = 0; c < noClasses; c++ ) {
 
 4544            Class cls = classes[c];
 
 4547                Method* methods = class_copyMethodList( cls, &
count );
 
 4548                for( u_int m = 0; 
m < 
count ; 
m++ ) {
 
 4549                    SEL selector = method_getName(methods[m]);
 
 4551                    if( 
startsWith( methodName, 
"Catch_TestCase_" ) ) {
 
 4553                        std::string name = Detail::getAnnotation( cls, 
"Name", testCaseName );
 
 4554                        std::string desc = Detail::getAnnotation( cls, 
"Description", testCaseName );
 
 4555                        const char* className = class_getName( cls );
 
 4564        return noTestMethods;
 
 4567#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 
 4569    namespace Matchers {
 
 4571        namespace NSStringMatchers {
 
 4573            struct StringHolder : MatcherBase<NSString*>{
 
 4574                StringHolder( NSString* substr ) : m_substr( [substr 
copy] ){}
 
 4575                StringHolder( StringHolder 
const& other ) : m_substr( [other.m_substr 
copy] ){}
 
 4577                    arcSafeRelease( m_substr );
 
 4580                bool match( NSString* 
const& str )
 const override {
 
 4584                NSString* CATCH_ARC_STRONG m_substr;
 
 4587            struct Equals : StringHolder {
 
 4588                Equals( NSString* substr ) : StringHolder( substr ){}
 
 4590                bool match( NSString* 
const& str )
 const override {
 
 4591                    return  (str != nil || m_substr == nil ) &&
 
 4592                            [str isEqualToString:m_substr];
 
 4596                    return "equals string: " + 
Catch::Detail::stringify( m_substr );
 
 4601                Contains( NSString* substr ) : StringHolder( substr ){}
 
 4603                bool match( NSString* 
const& str )
 const override {
 
 4604                    return  (str != nil || m_substr == nil ) &&
 
 4605                            [str rangeOfString:m_substr].location != NSNotFound;
 
 4609                    return "contains string: " + 
Catch::Detail::stringify( m_substr );
 
 4614                StartsWith( NSString* substr ) : StringHolder( substr ){}
 
 4616                bool match( NSString* 
const& str )
 const override {
 
 4617                    return  (str != nil || m_substr == nil ) &&
 
 4618                            [str rangeOfString:m_substr].location == 0;
 
 4622                    return "starts with: " + 
Catch::Detail::stringify( m_substr );
 
 4626                EndsWith( NSString* substr ) : StringHolder( substr ){}
 
 4628                bool match( NSString* 
const& str )
 const override {
 
 4629                    return  (str != nil || m_substr == nil ) &&
 
 4630                            [str rangeOfString:m_substr].location == [str length] - [m_substr length];
 
 4634                    return "ends with: " + 
Catch::Detail::stringify( m_substr );
 
 4641        inline Impl::NSStringMatchers::Equals
 
 4642            Equals( NSString* substr ){ 
return Impl::NSStringMatchers::Equals( substr ); }
 
 4644        inline Impl::NSStringMatchers::Contains
 
 4645            Contains( NSString* substr ){ 
return Impl::NSStringMatchers::Contains( substr ); }
 
 4647        inline Impl::NSStringMatchers::StartsWith
 
 4648            StartsWith( NSString* substr ){ 
return Impl::NSStringMatchers::StartsWith( substr ); }
 
 4650        inline Impl::NSStringMatchers::EndsWith
 
 4651            EndsWith( NSString* substr ){ 
return Impl::NSStringMatchers::EndsWith( substr ); }
 
 4655    using namespace Matchers;
 
 4662#define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix 
 4663#define OC_TEST_CASE2( name, desc, uniqueSuffix ) \ 
 4664+(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \ 
 4668+(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \ 
 4672-(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix ) 
 4674#define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ ) 
 4679#ifdef CATCH_CONFIG_EXTERNAL_INTERFACES 
 4691#pragma clang diagnostic push 
 4692#pragma clang diagnostic ignored "-Wpadded" 
 4698#pragma clang diagnostic push 
 4699#pragma clang diagnostic ignored "-Wpadded" 
 4706    class WildcardPattern {
 
 4707        enum WildcardPosition {
 
 4709            WildcardAtStart = 1,
 
 4711            WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
 
 4716        WildcardPattern( 
std::string const& pattern, CaseSensitive::Choice caseSensitivity );
 
 4717        virtual ~WildcardPattern() = 
default;
 
 4718        virtual bool matches( 
std::string const& str ) 
const;
 
 4722        CaseSensitive::Choice m_caseSensitivity;
 
 4723        WildcardPosition m_wildcard = NoWildcard;
 
 4738            virtual bool matches( TestCaseInfo 
const& testCase ) 
const = 0;
 
 4742        class NamePattern : 
public Pattern {
 
 4745            virtual ~NamePattern();
 
 4746            bool matches( TestCaseInfo 
const& testCase ) 
const override;
 
 4748            WildcardPattern m_wildcardPattern;
 
 4751        class TagPattern : 
public Pattern {
 
 4754            virtual ~TagPattern();
 
 4755            bool matches( TestCaseInfo 
const& testCase ) 
const override;
 
 4760        class ExcludedPattern : 
public Pattern {
 
 4762            ExcludedPattern( PatternPtr 
const& underlyingPattern );
 
 4763            virtual ~ExcludedPattern();
 
 4764            bool matches( TestCaseInfo 
const& testCase ) 
const override;
 
 4766            PatternPtr m_underlyingPattern;
 
 4772            bool matches( TestCaseInfo 
const& testCase ) 
const;
 
 4776        bool hasFilters() 
const;
 
 4777        bool matches( TestCaseInfo 
const& testCase ) 
const;
 
 4782        friend class TestSpecParser;
 
 4787#pragma clang diagnostic pop 
 4799    struct ITagAliasRegistry {
 
 4800        virtual ~ITagAliasRegistry();
 
 4805        static ITagAliasRegistry 
const& 
get();
 
 4813    class TestSpecParser {
 
 4814        enum Mode{ None, Name, QuotedName, Tag, EscapedName };
 
 4816        bool m_exclusion = 
false;
 
 4817        std::size_t m_start = std::string::npos, m_pos = 0;
 
 4820        TestSpec::Filter m_currentFilter;
 
 4821        TestSpec m_testSpec;
 
 4822        ITagAliasRegistry 
const* m_tagAliases = 
nullptr;
 
 4825        TestSpecParser( ITagAliasRegistry 
const& tagAliases );
 
 4828        TestSpec testSpec();
 
 4831        void visitChar( 
char c );
 
 4832        void startNewMode( Mode mode, 
std::size_t start );
 
 4836        template<
typename T>
 
 4840                token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
 
 4841            m_escapeChars.
clear();
 
 4844                token = token.
substr( 8 );
 
 4846            if( !token.
empty() ) {
 
 4847                TestSpec::PatternPtr pattern = std::make_shared<T>( token );
 
 4849                    pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
 
 4850                m_currentFilter.m_patterns.push_back( pattern );
 
 4852            m_exclusion = 
false;
 
 4863#pragma clang diagnostic pop 
 4873#ifndef CATCH_CONFIG_CONSOLE_WIDTH 
 4874#define CATCH_CONFIG_CONSOLE_WIDTH 80 
 4882        bool listTests = 
false;
 
 4883        bool listTags = 
false;
 
 4884        bool listReporters = 
false;
 
 4885        bool listTestNamesOnly = 
false;
 
 4887        bool showSuccessfulTests = 
false;
 
 4888        bool shouldDebugBreak = 
false;
 
 4889        bool noThrow = 
false;
 
 4890        bool showHelp = 
false;
 
 4891        bool showInvisibles = 
false;
 
 4892        bool filenamesAsTags = 
false;
 
 4893        bool libIdentify = 
false;
 
 4895        int abortAfter = -1;
 
 4897        int benchmarkResolutionMultiple = 100;
 
 4899        Verbosity verbosity = Verbosity::Normal;
 
 4900        WarnAbout::What warnings = WarnAbout::Nothing;
 
 4901        ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
 
 4902        RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
 
 4903        UseColour::YesOrNo useColour = UseColour::Auto;
 
 4904        WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
 
 4909#ifndef CATCH_CONFIG_DEFAULT_REPORTER 
 4910#define CATCH_CONFIG_DEFAULT_REPORTER "console" 
 4912        std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
 
 4913#undef CATCH_CONFIG_DEFAULT_REPORTER 
 4919    class Config : 
public IConfig {
 
 4923        Config( ConfigData 
const& 
data );
 
 4924        virtual ~Config() = 
default;
 
 4928        bool listTests() 
const;
 
 4929        bool listTestNamesOnly() 
const;
 
 4930        bool listTags() 
const;
 
 4931        bool listReporters() 
const;
 
 4939        TestSpec 
const& testSpec() 
const override;
 
 4940        bool hasTestFilters() 
const override;
 
 4942        bool showHelp() 
const;
 
 4945        bool allowThrows() 
const override;
 
 4948        bool includeSuccessfulResults() 
const override;
 
 4949        bool warnAboutMissingAssertions() 
const override;
 
 4950        bool warnAboutNoTests() 
const override;
 
 4951        ShowDurations::OrNot showDurations() 
const override;
 
 4952        RunTests::InWhatOrder runOrder() 
const override;
 
 4953        unsigned int rngSeed() 
const override;
 
 4954        int benchmarkResolutionMultiple() 
const override;
 
 4955        UseColour::YesOrNo useColour() 
const override;
 
 4956        bool shouldDebugBreak() 
const override;
 
 4957        int abortAfter() 
const override;
 
 4958        bool showInvisibles() 
const override;
 
 4963        IStream 
const* openStream();
 
 4967        TestSpec m_testSpec;
 
 4968        bool m_hasTestFilters = 
false;
 
 4980    struct AssertionResultData
 
 4982        AssertionResultData() = 
delete;
 
 4984        AssertionResultData( ResultWas::OfType _resultType, LazyExpression 
const& _lazyExpression );
 
 4988        LazyExpression lazyExpression;
 
 4989        ResultWas::OfType resultType;
 
 4994    class AssertionResult {
 
 4996        AssertionResult() = 
delete;
 
 4997        AssertionResult( AssertionInfo 
const& info, AssertionResultData 
const& 
data );
 
 5000        bool succeeded() 
const;
 
 5001        ResultWas::OfType getResultType() 
const;
 
 5002        bool hasExpression() 
const;
 
 5003        bool hasMessage() 
const;
 
 5006        bool hasExpandedExpression() 
const;
 
 5009        SourceLineInfo getSourceInfo() 
const;
 
 5010        StringRef getTestMacroName() 
const;
 
 5013        AssertionInfo m_info;
 
 5014        AssertionResultData m_resultData;
 
 5025    template<
typename T>
 
 5028        Option() : nullableValue( nullptr ) {}
 
 5029        Option( 
T const& _value )
 
 5030        : nullableValue( new( storage ) 
T( _value ) )
 
 5032        Option( Option 
const& _other )
 
 5033        : nullableValue( _other ? new( storage ) 
T( *_other ) : nullptr )
 
 5040        Option& operator= ( Option 
const& _other ) {
 
 5041            if( &_other != 
this ) {
 
 5044                    nullableValue = 
new( storage ) 
T( *_other );
 
 5048        Option& operator = ( 
T const& _value ) {
 
 5050            nullableValue = 
new( storage ) 
T( _value );
 
 5056                nullableValue->~T();
 
 5057            nullableValue = 
nullptr;
 
 5061        T const& 
operator*()
 const { 
return *nullableValue; }
 
 5062        T* operator->() { 
return nullableValue; }
 
 5063        const T* operator->()
 const { 
return nullableValue; }
 
 5065        T valueOr( 
T const& defaultValue )
 const {
 
 5066            return nullableValue ? *nullableValue : defaultValue;
 
 5069        bool some()
 const { 
return nullableValue != 
nullptr; }
 
 5070        bool none()
 const { 
return nullableValue == 
nullptr; }
 
 5072        bool operator !()
 const { 
return nullableValue == 
nullptr; }
 
 5073        explicit operator bool()
 const {
 
 5079        alignas(
alignof(
T)) 
char storage[sizeof(T)];
 
 5093    struct ReporterConfig {
 
 5094        explicit ReporterConfig( IConfigPtr 
const& _fullConfig );
 
 5096        ReporterConfig( IConfigPtr 
const& _fullConfig, 
std::ostream& _stream );
 
 5106    struct ReporterPreferences {
 
 5107        bool shouldRedirectStdOut = 
false;
 
 5108        bool shouldReportAllAssertions = 
false;
 
 5111    template<
typename T>
 
 5112    struct LazyStat : Option<
T> {
 
 5113        LazyStat& operator=( 
T const& _value ) {
 
 5114            Option<T>::operator=( _value );
 
 5125    struct TestRunInfo {
 
 5139    struct AssertionStats {
 
 5140        AssertionStats( AssertionResult 
const& _assertionResult,
 
 5142                        Totals 
const& _totals );
 
 5144        AssertionStats( AssertionStats 
const& )              = 
default;
 
 5145        AssertionStats( AssertionStats && )                  = 
default;
 
 5146        AssertionStats& operator = ( AssertionStats 
const& ) = 
delete;
 
 5147        AssertionStats& operator = ( AssertionStats && )     = 
delete;
 
 5148        virtual ~AssertionStats();
 
 5150        AssertionResult assertionResult;
 
 5155    struct SectionStats {
 
 5156        SectionStats(   SectionInfo 
const& _sectionInfo,
 
 5157                        Counts 
const& _assertions,
 
 5158                        double _durationInSeconds,
 
 5159                        bool _missingAssertions );
 
 5160        SectionStats( SectionStats 
const& )              = 
default;
 
 5161        SectionStats( SectionStats && )                  = 
default;
 
 5162        SectionStats& operator = ( SectionStats 
const& ) = 
default;
 
 5163        SectionStats& operator = ( SectionStats && )     = 
default;
 
 5164        virtual ~SectionStats();
 
 5166        SectionInfo sectionInfo;
 
 5168        double durationInSeconds;
 
 5169        bool missingAssertions;
 
 5172    struct TestCaseStats {
 
 5173        TestCaseStats(  TestCaseInfo 
const& _testInfo,
 
 5174                        Totals 
const& _totals,
 
 5179        TestCaseStats( TestCaseStats 
const& )              = 
default;
 
 5180        TestCaseStats( TestCaseStats && )                  = 
default;
 
 5181        TestCaseStats& operator = ( TestCaseStats 
const& ) = 
default;
 
 5182        TestCaseStats& operator = ( TestCaseStats && )     = 
default;
 
 5183        virtual ~TestCaseStats();
 
 5185        TestCaseInfo testInfo;
 
 5192    struct TestGroupStats {
 
 5193        TestGroupStats( GroupInfo 
const& _groupInfo,
 
 5194                        Totals 
const& _totals,
 
 5196        TestGroupStats( GroupInfo 
const& _groupInfo );
 
 5198        TestGroupStats( TestGroupStats 
const& )              = 
default;
 
 5199        TestGroupStats( TestGroupStats && )                  = 
default;
 
 5200        TestGroupStats& operator = ( TestGroupStats 
const& ) = 
default;
 
 5201        TestGroupStats& operator = ( TestGroupStats && )     = 
default;
 
 5202        virtual ~TestGroupStats();
 
 5204        GroupInfo groupInfo;
 
 5209    struct TestRunStats {
 
 5210        TestRunStats(   TestRunInfo 
const& _runInfo,
 
 5211                        Totals 
const& _totals,
 
 5214        TestRunStats( TestRunStats 
const& )              = 
default;
 
 5215        TestRunStats( TestRunStats && )                  = 
default;
 
 5216        TestRunStats& operator = ( TestRunStats 
const& ) = 
default;
 
 5217        TestRunStats& operator = ( TestRunStats && )     = 
default;
 
 5218        virtual ~TestRunStats();
 
 5220        TestRunInfo runInfo;
 
 5225    struct BenchmarkInfo {
 
 5228    struct BenchmarkStats {
 
 5231        uint64_t elapsedTimeInNanoseconds;
 
 5234    struct IStreamingReporter {
 
 5235        virtual ~IStreamingReporter() = 
default;
 
 5241        virtual ReporterPreferences getPreferences() 
const = 0;
 
 5243        virtual void noMatchingTestCases( 
std::string const& spec ) = 0;
 
 5245        virtual void testRunStarting( TestRunInfo 
const& testRunInfo ) = 0;
 
 5246        virtual void testGroupStarting( GroupInfo 
const& groupInfo ) = 0;
 
 5248        virtual void testCaseStarting( TestCaseInfo 
const& testInfo ) = 0;
 
 5249        virtual void sectionStarting( SectionInfo 
const& sectionInfo ) = 0;
 
 5252        virtual void benchmarkStarting( BenchmarkInfo 
const& ) {}
 
 5254        virtual void assertionStarting( AssertionInfo 
const& assertionInfo ) = 0;
 
 5257        virtual bool assertionEnded( AssertionStats 
const& assertionStats ) = 0;
 
 5260        virtual void benchmarkEnded( BenchmarkStats 
const& ) {}
 
 5262        virtual void sectionEnded( SectionStats 
const& sectionStats ) = 0;
 
 5263        virtual void testCaseEnded( TestCaseStats 
const& testCaseStats ) = 0;
 
 5264        virtual void testGroupEnded( TestGroupStats 
const& testGroupStats ) = 0;
 
 5265        virtual void testRunEnded( TestRunStats 
const& testRunStats ) = 0;
 
 5267        virtual void skipTest( TestCaseInfo 
const& testInfo ) = 0;
 
 5270        virtual void fatalErrorEncountered( StringRef 
name );
 
 5272        virtual bool isMulti() 
const;
 
 5276    struct IReporterFactory {
 
 5277        virtual ~IReporterFactory();
 
 5278        virtual IStreamingReporterPtr 
create( ReporterConfig 
const& config ) 
const = 0;
 
 5283    struct IReporterRegistry {
 
 5287        virtual ~IReporterRegistry();
 
 5288        virtual IStreamingReporterPtr 
create( 
std::string const& 
name, IConfigPtr 
const& config ) 
const = 0;
 
 5289        virtual FactoryMap 
const& getFactories() 
const = 0;
 
 5290        virtual Listeners 
const& getListeners() 
const = 0;
 
 5305    void prepareExpandedExpression(AssertionResult& result);
 
 5308    std::string getFormattedDuration( 
double duration );
 
 5312    template<
typename DerivedT>
 
 5313    struct StreamingReporterBase : IStreamingReporter {
 
 5315        StreamingReporterBase( ReporterConfig 
const& _config )
 
 5316        :   m_config( _config.fullConfig() ),
 
 5317            stream( _config.stream() )
 
 5319            m_reporterPrefs.shouldRedirectStdOut = 
false;
 
 5320            if( !DerivedT::getSupportedVerbosities().
count( m_config->verbosity() ) )
 
 5321                CATCH_ERROR( 
"Verbosity level not supported by this reporter" );
 
 5324        ReporterPreferences getPreferences()
 const override {
 
 5325            return m_reporterPrefs;
 
 5329            return { Verbosity::Normal };
 
 5332        ~StreamingReporterBase() 
override = 
default;
 
 5334        void noMatchingTestCases(
std::string const&)
 override {}
 
 5336        void testRunStarting(TestRunInfo 
const& _testRunInfo)
 override {
 
 5337            currentTestRunInfo = _testRunInfo;
 
 5340        void testGroupStarting(GroupInfo 
const& _groupInfo)
 override {
 
 5341            currentGroupInfo = _groupInfo;
 
 5344        void testCaseStarting(TestCaseInfo 
const& _testInfo)
 override  {
 
 5345            currentTestCaseInfo = _testInfo;
 
 5347        void sectionStarting(SectionInfo 
const& _sectionInfo)
 override {
 
 5348            m_sectionStack.push_back(_sectionInfo);
 
 5351        void sectionEnded(SectionStats 
const& )
 override {
 
 5352            m_sectionStack.pop_back();
 
 5354        void testCaseEnded(TestCaseStats 
const& )
 override {
 
 5355            currentTestCaseInfo.reset();
 
 5357        void testGroupEnded(TestGroupStats 
const& )
 override {
 
 5358            currentGroupInfo.reset();
 
 5360        void testRunEnded(TestRunStats 
const& )
 override {
 
 5361            currentTestCaseInfo.reset();
 
 5362            currentGroupInfo.reset();
 
 5363            currentTestRunInfo.reset();
 
 5366        void skipTest(TestCaseInfo 
const&)
 override {
 
 5374        LazyStat<TestRunInfo> currentTestRunInfo;
 
 5375        LazyStat<GroupInfo> currentGroupInfo;
 
 5376        LazyStat<TestCaseInfo> currentTestCaseInfo;
 
 5379        ReporterPreferences m_reporterPrefs;
 
 5382    template<
typename DerivedT>
 
 5383    struct CumulativeReporterBase : IStreamingReporter {
 
 5384        template<
typename T, 
typename ChildNodeT>
 
 5386            explicit Node( 
T const& _value ) : 
value( _value ) {}
 
 5391            ChildNodes children;
 
 5393        struct SectionNode {
 
 5394            explicit SectionNode(SectionStats 
const& _stats) : stats(_stats) {}
 
 5395            virtual ~SectionNode() = 
default;
 
 5397            bool operator == (SectionNode 
const& other)
 const {
 
 5398                return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
 
 5407            ChildSections childSections;
 
 5408            Assertions assertions;
 
 5413        struct BySectionInfo {
 
 5414            BySectionInfo( SectionInfo 
const& other ) : m_other( other ) {}
 
 5415            BySectionInfo( BySectionInfo 
const& other ) : m_other( other.m_other ) {}
 
 5417                return ((node->stats.sectionInfo.name == m_other.name) &&
 
 5418                        (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
 
 5420            void operator=(BySectionInfo 
const&) = 
delete;
 
 5423            SectionInfo 
const& m_other;
 
 5426        using TestCaseNode = Node<TestCaseStats, SectionNode>;
 
 5427        using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
 
 5428        using TestRunNode = Node<TestRunStats, TestGroupNode>;
 
 5430        CumulativeReporterBase( ReporterConfig 
const& _config )
 
 5431        :   m_config( _config.fullConfig() ),
 
 5432            stream( _config.stream() )
 
 5434            m_reporterPrefs.shouldRedirectStdOut = 
false;
 
 5435            if( !DerivedT::getSupportedVerbosities().
count( m_config->verbosity() ) )
 
 5436                CATCH_ERROR( 
"Verbosity level not supported by this reporter" );
 
 5438        ~CumulativeReporterBase() 
override = 
default;
 
 5440        ReporterPreferences getPreferences()
 const override {
 
 5441            return m_reporterPrefs;
 
 5445            return { Verbosity::Normal };
 
 5448        void testRunStarting( TestRunInfo 
const& )
 override {}
 
 5449        void testGroupStarting( GroupInfo 
const& )
 override {}
 
 5451        void testCaseStarting( TestCaseInfo 
const& )
 override {}
 
 5453        void sectionStarting( SectionInfo 
const& sectionInfo )
 override {
 
 5454            SectionStats incompleteStats( sectionInfo, Counts(), 0, 
false );
 
 5456            if( m_sectionStack.empty() ) {
 
 5457                if( !m_rootSection )
 
 5459                node = m_rootSection;
 
 5462                SectionNode& parentNode = *m_sectionStack.back();
 
 5465                                    parentNode.childSections.end(),
 
 5466                                    BySectionInfo( sectionInfo ) );
 
 5467                if( it == parentNode.childSections.end() ) {
 
 5469                    parentNode.childSections.push_back( node );
 
 5474            m_sectionStack.push_back( node );
 
 5475            m_deepestSection = std::move(node);
 
 5478        void assertionStarting(AssertionInfo 
const&)
 override {}
 
 5480        bool assertionEnded(AssertionStats 
const& assertionStats)
 override {
 
 5481            assert(!m_sectionStack.empty());
 
 5487            prepareExpandedExpression(
const_cast<AssertionResult&
>( assertionStats.assertionResult ) );
 
 5488            SectionNode& sectionNode = *m_sectionStack.back();
 
 5489            sectionNode.assertions.push_back(assertionStats);
 
 5492        void sectionEnded(SectionStats 
const& sectionStats)
 override {
 
 5493            assert(!m_sectionStack.empty());
 
 5494            SectionNode& node = *m_sectionStack.back();
 
 5495            node.stats = sectionStats;
 
 5496            m_sectionStack.pop_back();
 
 5498        void testCaseEnded(TestCaseStats 
const& testCaseStats)
 override {
 
 5500            assert(m_sectionStack.size() == 0);
 
 5501            node->children.push_back(m_rootSection);
 
 5502            m_testCases.push_back(node);
 
 5503            m_rootSection.reset();
 
 5505            assert(m_deepestSection);
 
 5506            m_deepestSection->stdOut = testCaseStats.stdOut;
 
 5507            m_deepestSection->stdErr = testCaseStats.stdErr;
 
 5509        void testGroupEnded(TestGroupStats 
const& testGroupStats)
 override {
 
 5511            node->children.swap(m_testCases);
 
 5512            m_testGroups.push_back(node);
 
 5514        void testRunEnded(TestRunStats 
const& testRunStats)
 override {
 
 5516            node->children.swap(m_testGroups);
 
 5517            m_testRuns.push_back(node);
 
 5518            testRunEndedCumulative();
 
 5520        virtual void testRunEndedCumulative() = 0;
 
 5522        void skipTest(TestCaseInfo 
const&)
 override {}
 
 5536        ReporterPreferences m_reporterPrefs;
 
 5540    char const* getLineOfChars() {
 
 5541        static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
 
 5543            std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
 
 5544            line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
 
 5549    struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
 
 5550        TestEventListenerBase( ReporterConfig 
const& _config );
 
 5554        void assertionStarting(AssertionInfo 
const&) 
override;
 
 5555        bool assertionEnded(AssertionStats 
const&) 
override;
 
 5579            BrightRed = Bright | Red,
 
 5580            BrightGreen = Bright | Green,
 
 5581            LightGrey = Bright | Grey,
 
 5582            BrightWhite = Bright | White,
 
 5583            BrightYellow = Bright | Yellow,
 
 5586            FileName = LightGrey,
 
 5587            Warning = BrightYellow,
 
 5588            ResultError = BrightRed,
 
 5589            ResultSuccess = BrightGreen,
 
 5590            ResultExpectedFailure = Warning,
 
 5595            OriginalExpression = Cyan,
 
 5596            ReconstructedExpression = BrightYellow,
 
 5598            SecondaryText = LightGrey,
 
 5603        Colour( Code _colourCode );
 
 5604        Colour( Colour&& other ) 
noexcept;
 
 5605        Colour& operator=( Colour&& other ) 
noexcept;
 
 5609        static void use( Code _colourCode );
 
 5612        bool m_moved = 
false;
 
 5625    template<
typename T>
 
 5626    class ReporterRegistrar {
 
 5628        class ReporterFactory : 
public IReporterFactory {
 
 5630            IStreamingReporterPtr 
create( ReporterConfig 
const& config )
 const override {
 
 5635                return T::getDescription();
 
 5646    template<
typename T>
 
 5647    class ListenerRegistrar {
 
 5649        class ListenerFactory : 
public IReporterFactory {
 
 5651            IStreamingReporterPtr 
create( ReporterConfig 
const& config )
 const override {
 
 5661        ListenerRegistrar() {
 
 5667#if !defined(CATCH_CONFIG_DISABLE) 
 5669#define CATCH_REGISTER_REPORTER( name, reporterType ) \ 
 5670    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \ 
 5671    namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \ 
 5672    CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS 
 5674#define CATCH_REGISTER_LISTENER( listenerType ) \ 
 5675     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS   \ 
 5676     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \ 
 5677     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS 
 5680#define CATCH_REGISTER_REPORTER(name, reporterType) 
 5681#define CATCH_REGISTER_LISTENER(listenerType) 
 5691    struct CompactReporter : StreamingReporterBase<CompactReporter> {
 
 5693        using StreamingReporterBase::StreamingReporterBase;
 
 5695        ~CompactReporter() 
override;
 
 5699        ReporterPreferences getPreferences() 
const override;
 
 5701        void noMatchingTestCases(
std::string const& spec) 
override;
 
 5703        void assertionStarting(AssertionInfo 
const&) 
override;
 
 5705        bool assertionEnded(AssertionStats 
const& _assertionStats) 
override;
 
 5707        void sectionEnded(SectionStats 
const& _sectionStats) 
override;
 
 5709        void testRunEnded(TestRunStats 
const& _testRunStats) 
override;
 
 5718#if defined(_MSC_VER) 
 5719#pragma warning(push) 
 5720#pragma warning(disable:4061)  
 5727    struct SummaryColumn;
 
 5730    struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
 
 5733        ConsoleReporter(ReporterConfig 
const& config);
 
 5734        ~ConsoleReporter() 
override;
 
 5737        void noMatchingTestCases(
std::string const& spec) 
override;
 
 5739        void assertionStarting(AssertionInfo 
const&) 
override;
 
 5741        bool assertionEnded(AssertionStats 
const& _assertionStats) 
override;
 
 5743        void sectionStarting(SectionInfo 
const& _sectionInfo) 
override;
 
 5744        void sectionEnded(SectionStats 
const& _sectionStats) 
override;
 
 5746        void benchmarkStarting(BenchmarkInfo 
const& info) 
override;
 
 5747        void benchmarkEnded(BenchmarkStats 
const& stats) 
override;
 
 5749        void testCaseEnded(TestCaseStats 
const& _testCaseStats) 
override;
 
 5750        void testGroupEnded(TestGroupStats 
const& _testGroupStats) 
override;
 
 5751        void testRunEnded(TestRunStats 
const& _testRunStats) 
override;
 
 5752        void testRunStarting(TestRunInfo 
const& _testRunInfo) 
override;
 
 5757        void lazyPrintWithoutClosingBenchmarkTable();
 
 5758        void lazyPrintRunInfo();
 
 5759        void lazyPrintGroupInfo();
 
 5760        void printTestCaseAndSectionHeader();
 
 5769        void printTotals(Totals 
const& totals);
 
 5772        void printTotalsDivider(Totals 
const& totals);
 
 5773        void printSummaryDivider();
 
 5774        void printTestFilters();
 
 5777        bool m_headerPrinted = 
false;
 
 5782#if defined(_MSC_VER) 
 5797        enum ForWhat { ForTextNodes, ForAttributes };
 
 5799        XmlEncode( 
std::string const& str, ForWhat forWhat = ForTextNodes );
 
 5813        class ScopedElement {
 
 5815            ScopedElement( XmlWriter* writer );
 
 5817            ScopedElement( ScopedElement&& other ) 
noexcept;
 
 5818            ScopedElement& operator=( ScopedElement&& other ) 
noexcept;
 
 5822            ScopedElement& writeText( 
std::string const& text, 
bool indent = 
true );
 
 5824            template<
typename T>
 
 5825            ScopedElement& writeAttribute( 
std::string const& 
name, 
T const& attribute ) {
 
 5826                m_writer->writeAttribute( 
name, attribute );
 
 5831            mutable XmlWriter* m_writer = 
nullptr;
 
 5837        XmlWriter( XmlWriter 
const& ) = 
delete;
 
 5838        XmlWriter& operator=( XmlWriter 
const& ) = 
delete;
 
 5844        XmlWriter& endElement();
 
 5850        template<
typename T>
 
 5852            ReusableStringStream rss;
 
 5854            return writeAttribute( 
name, rss.str() );
 
 5857        XmlWriter& writeText( 
std::string const& text, 
bool indent = 
true );
 
 5859        XmlWriter& writeComment( 
std::string const& text );
 
 5861        void writeStylesheetRef( 
std::string const& url );
 
 5863        XmlWriter& writeBlankLine();
 
 5865        void ensureTagClosed();
 
 5869        void writeDeclaration();
 
 5871        void newlineIfNecessary();
 
 5873        bool m_tagIsOpen = 
false;
 
 5874        bool m_needsNewline = 
false;
 
 5885    class JunitReporter : 
public CumulativeReporterBase<JunitReporter> {
 
 5887        JunitReporter(ReporterConfig 
const& _config);
 
 5889        ~JunitReporter() 
override;
 
 5893        void noMatchingTestCases(
std::string const& ) 
override;
 
 5895        void testRunStarting(TestRunInfo 
const& runInfo) 
override;
 
 5897        void testGroupStarting(GroupInfo 
const& groupInfo) 
override;
 
 5899        void testCaseStarting(TestCaseInfo 
const& testCaseInfo) 
override;
 
 5900        bool assertionEnded(AssertionStats 
const& assertionStats) 
override;
 
 5902        void testCaseEnded(TestCaseStats 
const& testCaseStats) 
override;
 
 5904        void testGroupEnded(TestGroupStats 
const& testGroupStats) 
override;
 
 5906        void testRunEndedCumulative() 
override;
 
 5908        void writeGroup(TestGroupNode 
const& groupNode, 
double suiteTime);
 
 5910        void writeTestCase(TestCaseNode 
const& testCaseNode);
 
 5914                          SectionNode 
const& sectionNode);
 
 5916        void writeAssertions(SectionNode 
const& sectionNode);
 
 5917        void writeAssertion(AssertionStats 
const& stats);
 
 5923        unsigned int unexpectedExceptions = 0;
 
 5924        bool m_okToFail = 
false;
 
 5933    class XmlReporter : 
public StreamingReporterBase<XmlReporter> {
 
 5935        XmlReporter(ReporterConfig 
const& _config);
 
 5937        ~XmlReporter() 
override;
 
 5943        void writeSourceInfo(SourceLineInfo 
const& sourceInfo);
 
 5947        void noMatchingTestCases(
std::string const& s) 
override;
 
 5949        void testRunStarting(TestRunInfo 
const& testInfo) 
override;
 
 5951        void testGroupStarting(GroupInfo 
const& groupInfo) 
override;
 
 5953        void testCaseStarting(TestCaseInfo 
const& testInfo) 
override;
 
 5955        void sectionStarting(SectionInfo 
const& sectionInfo) 
override;
 
 5957        void assertionStarting(AssertionInfo 
const&) 
override;
 
 5959        bool assertionEnded(AssertionStats 
const& assertionStats) 
override;
 
 5961        void sectionEnded(SectionStats 
const& sectionStats) 
override;
 
 5963        void testCaseEnded(TestCaseStats 
const& testCaseStats) 
override;
 
 5965        void testGroupEnded(TestGroupStats 
const& testGroupStats) 
override;
 
 5967        void testRunEnded(TestRunStats 
const& testRunStats) 
override;
 
 5970        Timer m_testCaseTimer;
 
 5972        int m_sectionDepth = 0;
 
 5988#pragma clang diagnostic push 
 5989#pragma clang diagnostic ignored "-Wweak-vtables" 
 6000namespace TestCaseTracking {
 
 6002    struct NameAndLocation {
 
 6004        SourceLineInfo location;
 
 6006        NameAndLocation( 
std::string const& _name, SourceLineInfo 
const& _location );
 
 6014        virtual ~ITracker();
 
 6017        virtual NameAndLocation 
const& nameAndLocation() 
const = 0;
 
 6020        virtual bool isComplete() 
const = 0; 
 
 6021        virtual bool isSuccessfullyCompleted() 
const = 0;
 
 6022        virtual bool isOpen() 
const = 0; 
 
 6023        virtual bool hasChildren() 
const = 0;
 
 6025        virtual ITracker& parent() = 0;
 
 6028        virtual void close() = 0; 
 
 6029        virtual void fail() = 0;
 
 6030        virtual void markAsNeedingAnotherRun() = 0;
 
 6032        virtual void addChild( ITrackerPtr 
const& child ) = 0;
 
 6033        virtual ITrackerPtr findChild( NameAndLocation 
const& nameAndLocation ) = 0;
 
 6034        virtual void openChild() = 0;
 
 6037        virtual bool isSectionTracker() 
const = 0;
 
 6038        virtual bool isGeneratorTracker() 
const = 0;
 
 6041    class TrackerContext {
 
 6049        ITrackerPtr m_rootTracker;
 
 6050        ITracker* m_currentTracker = 
nullptr;
 
 6051        RunState m_runState = NotStarted;
 
 6055        ITracker& startRun();
 
 6059        void completeCycle();
 
 6061        bool completedCycle() 
const;
 
 6062        ITracker& currentTracker();
 
 6063        void setCurrentTracker( ITracker* tracker );
 
 6066    class TrackerBase : 
public ITracker {
 
 6073            CompletedSuccessfully,
 
 6078        NameAndLocation m_nameAndLocation;
 
 6079        TrackerContext& m_ctx;
 
 6081        Children m_children;
 
 6082        CycleState m_runState = NotStarted;
 
 6085        TrackerBase( NameAndLocation 
const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
 
 6087        NameAndLocation 
const& nameAndLocation() 
const override;
 
 6088        bool isComplete() 
const override;
 
 6089        bool isSuccessfullyCompleted() 
const override;
 
 6090        bool isOpen() 
const override;
 
 6091        bool hasChildren() 
const override;
 
 6093        void addChild( ITrackerPtr 
const& child ) 
override;
 
 6095        ITrackerPtr findChild( NameAndLocation 
const& nameAndLocation ) 
override;
 
 6096        ITracker& parent() 
override;
 
 6098        void openChild() 
override;
 
 6100        bool isSectionTracker() 
const override;
 
 6101        bool isGeneratorTracker() 
const override;
 
 6105        void close() 
override;
 
 6106        void fail() 
override;
 
 6107        void markAsNeedingAnotherRun() 
override;
 
 6110        void moveToParent();
 
 6114    class SectionTracker : 
public TrackerBase {
 
 6117        SectionTracker( NameAndLocation 
const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
 
 6119        bool isSectionTracker() 
const override;
 
 6121        bool isComplete() 
const override;
 
 6123        static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation 
const& nameAndLocation );
 
 6133using TestCaseTracking::ITracker;
 
 6134using TestCaseTracking::TrackerContext;
 
 6135using TestCaseTracking::SectionTracker;
 
 6145    struct LeakDetector {
 
 6162bool marginComparison(
double lhs, 
double rhs, 
double margin) {
 
 6163    return (lhs + margin >= rhs) && (rhs + margin >= lhs);
 
 6171    Approx::Approx ( 
double value )
 
 6172    :   m_epsilon( 
std::numeric_limits<float>::epsilon()*100 ),
 
 6178    Approx Approx::custom() {
 
 6182    Approx Approx::operator-()
 const {
 
 6184        temp.m_value = -temp.m_value;
 
 6189        ReusableStringStream rss;
 
 6194    bool Approx::equalityComparisonImpl(
const double other)
 const {
 
 6197        return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + 
std::fabs(m_value)));
 
 6200    void Approx::setMargin(
double newMargin) {
 
 6202            "Invalid Approx::margin: " << newMargin << 
'.' 
 6203            << 
" Approx::Margin has to be non-negative.");
 
 6204        m_margin = newMargin;
 
 6207    void Approx::setEpsilon(
double newEpsilon) {
 
 6209            "Invalid Approx::epsilon: " << newEpsilon << 
'.' 
 6210            << 
" Approx::epsilon has to be in [0, 1]");
 
 6211        m_epsilon = newEpsilon;
 
 6217    Detail::Approx 
operator "" _a(
long double val) {
 
 6218        return Detail::Approx(val);
 
 6220    Detail::Approx 
operator "" _a(
unsigned long long val) {
 
 6221        return Detail::Approx(val);
 
 6226    return value.toString();
 
 6236    bool isDebuggerActive();
 
 6239#ifdef CATCH_PLATFORM_MAC 
 6241    #define CATCH_TRAP() __asm__("int $3\n" : : )  
 6243#elif defined(CATCH_PLATFORM_LINUX) 
 6247    #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) 
 6248        #define CATCH_TRAP() asm volatile ("int $3")  
 6252        #define CATCH_TRAP() raise(SIGTRAP) 
 6254#elif defined(_MSC_VER) 
 6255    #define CATCH_TRAP() __debugbreak() 
 6256#elif defined(__MINGW32__) 
 6257    extern "C" __declspec(dllimport) 
void __stdcall DebugBreak();
 
 6258    #define CATCH_TRAP() DebugBreak() 
 6262    #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }() 
 6264    #define CATCH_BREAK_INTO_DEBUGGER() []{}() 
 6275#if defined(CATCH_PLATFORM_WINDOWS) 
 6277#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) 
 6278#  define CATCH_DEFINED_NOMINMAX 
 6281#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) 
 6282#  define CATCH_DEFINED_WIN32_LEAN_AND_MEAN 
 6283#  define WIN32_LEAN_AND_MEAN 
 6292#ifdef CATCH_DEFINED_NOMINMAX 
 6295#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN 
 6296#  undef WIN32_LEAN_AND_MEAN 
 6302#if defined( CATCH_CONFIG_WINDOWS_SEH ) 
 6306    struct FatalConditionHandler {
 
 6308        static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
 
 6309        FatalConditionHandler();
 
 6310        static void reset();
 
 6311        ~FatalConditionHandler();
 
 6315        static ULONG guaranteeSize;
 
 6316        static PVOID exceptionHandlerHandle;
 
 6321#elif defined ( CATCH_CONFIG_POSIX_SIGNALS ) 
 6327    struct FatalConditionHandler {
 
 6330        static struct sigaction oldSigActions[];
 
 6331        static stack_t oldSigStack;
 
 6332        static char altStackMem[];
 
 6334        static void handleSignal( 
int sig );
 
 6336        FatalConditionHandler();
 
 6337        ~FatalConditionHandler();
 
 6338        static void reset();
 
 6346    struct FatalConditionHandler {
 
 6358    struct IMutableContext;
 
 6362    class RunContext : 
public IResultCapture, 
public IRunner {
 
 6365        RunContext( RunContext 
const& ) = 
delete;
 
 6366        RunContext& operator =( RunContext 
const& ) = 
delete;
 
 6368        explicit RunContext( IConfigPtr 
const& _config, IStreamingReporterPtr&& reporter );
 
 6370        ~RunContext() 
override;
 
 6375        Totals runTest(TestCase 
const& testCase);
 
 6378        IStreamingReporter& reporter() 
const;
 
 6384                (   AssertionInfo 
const& info,
 
 6385                    ITransientExpression 
const& expr,
 
 6386                    AssertionReaction& reaction ) 
override;
 
 6388                (   AssertionInfo 
const& info,
 
 6389                    ResultWas::OfType resultType,
 
 6390                    StringRef 
const& message,
 
 6391                    AssertionReaction& reaction ) 
override;
 
 6392        void handleUnexpectedExceptionNotThrown
 
 6393                (   AssertionInfo 
const& info,
 
 6394                    AssertionReaction& reaction ) 
override;
 
 6395        void handleUnexpectedInflightException
 
 6396                (   AssertionInfo 
const& info,
 
 6398                    AssertionReaction& reaction ) 
override;
 
 6399        void handleIncomplete
 
 6400                (   AssertionInfo 
const& info ) 
override;
 
 6402                (   AssertionInfo 
const &info,
 
 6403                    ResultWas::OfType resultType,
 
 6404                    AssertionReaction &reaction ) 
override;
 
 6406        bool sectionStarted( SectionInfo 
const& sectionInfo, Counts& assertions ) 
override;
 
 6408        void sectionEnded( SectionEndInfo 
const& endInfo ) 
override;
 
 6409        void sectionEndedEarly( SectionEndInfo 
const& endInfo ) 
override;
 
 6413        void benchmarkStarting( BenchmarkInfo 
const& info ) 
override;
 
 6414        void benchmarkEnded( BenchmarkStats 
const& stats ) 
override;
 
 6416        void pushScopedMessage( MessageInfo 
const& message ) 
override;
 
 6417        void popScopedMessage( MessageInfo 
const& message ) 
override;
 
 6419        void emplaceUnscopedMessage( MessageBuilder 
const& builder ) 
override;
 
 6423        const AssertionResult* getLastResult() 
const override;
 
 6425        void exceptionEarlyReported() 
override;
 
 6427        void handleFatalErrorCondition( StringRef message ) 
override;
 
 6429        bool lastAssertionPassed() 
override;
 
 6431        void assertionPassed() 
override;
 
 6435        bool aborting() const final;
 
 6439        void runCurrentTest( 
std::
string& redirectedCout, 
std::
string& redirectedCerr );
 
 6440        void invokeActiveTestCase();
 
 6442        void resetAssertionInfo();
 
 6443        bool testForMissingAssertions( Counts& assertions );
 
 6445        void assertionEnded( AssertionResult const& result );
 
 6447                (   AssertionInfo const &info,
 
 6448                    ResultWas::OfType resultType,
 
 6449                    ITransientExpression const *expr,
 
 6452        void populateReaction( AssertionReaction& reaction );
 
 6456        void handleUnfinishedSections();
 
 6458        TestRunInfo m_runInfo;
 
 6459        IMutableContext& m_context;
 
 6460        TestCase const* m_activeTestCase = 
nullptr;
 
 6461        ITracker* m_testCaseTracker = 
nullptr;
 
 6462        Option<AssertionResult> m_lastResult;
 
 6464        IConfigPtr m_config;
 
 6466        IStreamingReporterPtr m_reporter;
 
 6467        std::vector<MessageInfo> m_messages;
 
 6468        std::vector<ScopedMessage> m_messageScopes; 
 
 6469        AssertionInfo m_lastAssertionInfo;
 
 6470        std::vector<SectionEndInfo> m_unfinishedSections;
 
 6471        std::vector<ITracker*> m_activeSections;
 
 6472        TrackerContext m_trackerContext;
 
 6473        bool m_lastAssertionPassed = false;
 
 6474        bool m_shouldReportUnexpected = true;
 
 6475        bool m_includeSuccessfulResults;
 
 6485            expr.streamReconstructedExpression( os );
 
 6490    LazyExpression::LazyExpression( 
bool isNegated )
 
 6491    :   m_isNegated( isNegated )
 
 6496    LazyExpression::operator 
bool()
 const {
 
 6497        return m_transientExpression != 
nullptr;
 
 6501        if( lazyExpr.m_isNegated )
 
 6505            if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
 
 6506                os << 
"(" << *lazyExpr.m_transientExpression << 
")";
 
 6508                os << *lazyExpr.m_transientExpression;
 
 6511            os << 
"{** error - unchecked empty expression requested **}";
 
 6517        (   StringRef 
const& macroName,
 
 6518            SourceLineInfo 
const& lineInfo,
 
 6519            StringRef capturedExpression,
 
 6521    :   m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
 
 6544            CATCH_BREAK_INTO_DEBUGGER();
 
 6547#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 
 6550            CATCH_ERROR( 
"Test failure requires aborting test!" );
 
 6588    AssertionResultData::AssertionResultData(
ResultWas::OfType _resultType, LazyExpression 
const & _lazyExpression):
 
 6589        lazyExpression(_lazyExpression),
 
 6590        resultType(_resultType) {}
 
 6592    std::string AssertionResultData::reconstructExpression()
 const {
 
 6594        if( reconstructedExpression.empty() ) {
 
 6595            if( lazyExpression ) {
 
 6596                ReusableStringStream rss;
 
 6597                rss << lazyExpression;
 
 6598                reconstructedExpression = rss.str();
 
 6601        return reconstructedExpression;
 
 6604    AssertionResult::AssertionResult( AssertionInfo 
const& info, AssertionResultData 
const& 
data )
 
 6606        m_resultData( 
data )
 
 6610    bool AssertionResult::succeeded()
 const {
 
 6615    bool AssertionResult::isOk()
 const {
 
 6620        return m_resultData.resultType;
 
 6623    bool AssertionResult::hasExpression()
 const {
 
 6624        return m_info.capturedExpression[0] != 0;
 
 6627    bool AssertionResult::hasMessage()
 const {
 
 6628        return !m_resultData.message.empty();
 
 6631    std::string AssertionResult::getExpression()
 const {
 
 6633            return "!(" + m_info.capturedExpression + ")";
 
 6635            return m_info.capturedExpression;
 
 6638    std::string AssertionResult::getExpressionInMacro()
 const {
 
 6640        if( m_info.macroName[0] == 0 )
 
 6641            expr = m_info.capturedExpression;
 
 6643            expr.
reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
 
 6644            expr += m_info.macroName;
 
 6646            expr += m_info.capturedExpression;
 
 6652    bool AssertionResult::hasExpandedExpression()
 const {
 
 6653        return hasExpression() && getExpandedExpression() != getExpression();
 
 6656    std::string AssertionResult::getExpandedExpression()
 const {
 
 6657        std::string expr = m_resultData.reconstructExpression();
 
 6664        return m_resultData.message;
 
 6666    SourceLineInfo AssertionResult::getSourceInfo()
 const {
 
 6667        return m_info.lineInfo;
 
 6670    StringRef AssertionResult::getTestMacroName()
 const {
 
 6671        return m_info.macroName;
 
 6688        auto elapsed = m_timer.getElapsedNanoseconds();
 
 6691        if( elapsed < m_resolution ) {
 
 6692            m_iterationsToRun *= 10;
 
 6706    using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
 
 6713        MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
 
 6714        handler.handleExpr( expr );
 
 6726#ifdef CLARA_CONFIG_CONSOLE_WIDTH 
 6727#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 
 6728#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 
 6730#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1 
 6733#pragma clang diagnostic push 
 6734#pragma clang diagnostic ignored "-Wweak-vtables" 
 6735#pragma clang diagnostic ignored "-Wexit-time-destructors" 
 6736#pragma clang diagnostic ignored "-Wshadow" 
 6750#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH 
 6751#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80 
 6754#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 
 6755#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH 
 6758#ifndef CLARA_CONFIG_OPTIONAL_TYPE 
 6760#if __has_include(<optional>) && __cplusplus >= 201703L 
 6762#define CLARA_CONFIG_OPTIONAL_TYPE std::optional 
 6784#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 
 6785#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80 
 6792inline auto isWhitespace(
char c) -> 
bool {
 
 6794    return chars.
find(c) != std::string::npos;
 
 6796inline auto isBreakableBefore(
char c) -> 
bool {
 
 6798    return chars.
find(c) != std::string::npos;
 
 6800inline auto isBreakableAfter(
char c) -> 
bool {
 
 6802    return chars.
find(c) != std::string::npos;
 
 6809    size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
 
 6810    size_t m_indent = 0;
 
 6811    size_t m_initialIndent = std::string::npos;
 
 6817        Column 
const& m_column;
 
 6818        size_t m_stringIndex = 0;
 
 6823        bool m_suffix = 
false;
 
 6825        iterator(Column 
const& column, 
size_t stringIndex)
 
 6827            m_stringIndex(stringIndex) {}
 
 6829        auto line() const -> 
std::
string const& { 
return m_column.m_strings[m_stringIndex]; }
 
 6831        auto isBoundary(
size_t at) 
const -> 
bool {
 
 6833            assert(at <= line().
size());
 
 6835            return at == line().size() ||
 
 6836                (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
 
 6837                isBreakableBefore(line()[at]) ||
 
 6838                isBreakableAfter(line()[at - 1]);
 
 6842            assert(m_stringIndex < m_column.m_strings.size());
 
 6845            auto width = m_column.m_width - indent();
 
 6847            if (line()[m_pos] == 
'\n') {
 
 6850            while (m_end < line().
size() && line()[m_end] != 
'\n')
 
 6853            if (m_end < m_pos + width) {
 
 6854                m_len = m_end - m_pos;
 
 6857                while (len > 0 && !isBoundary(m_pos + len))
 
 6859                while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
 
 6871        auto indent() const -> 
size_t {
 
 6872            auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
 
 6873            return initial == std::string::npos ? m_column.m_indent : initial;
 
 6877            return std::string(indent(), 
' ') + (m_suffix ? plain + "-" : plain);
 
 6887        explicit iterator(Column 
const& column) : m_column(column) {
 
 6888            assert(m_column.m_width > m_column.m_indent);
 
 6889            assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
 
 6895        auto operator *() const -> 
std::
string {
 
 6896            assert(m_stringIndex < m_column.m_strings.size());
 
 6897            assert(m_pos <= m_end);
 
 6898            return addIndentAndSuffix(line().substr(m_pos, m_len));
 
 6901        auto operator ++() -> iterator& {
 
 6903            if (m_pos < line().
size() && line()[m_pos] == 
'\n')
 
 6906                while (m_pos < line().
size() && isWhitespace(line()[m_pos]))
 
 6909            if (m_pos == line().
size()) {
 
 6913            if (m_stringIndex < m_column.m_strings.size())
 
 6917        auto operator ++(
int) -> iterator {
 
 6918            iterator 
prev(*
this);
 
 6923        auto operator ==(iterator 
const& other) 
const -> 
bool {
 
 6925                m_pos == other.m_pos &&
 
 6926                m_stringIndex == other.m_stringIndex &&
 
 6927                &m_column == &other.m_column;
 
 6929        auto operator !=(iterator 
const& other) 
const -> 
bool {
 
 6933    using const_iterator = iterator;
 
 6937    auto width(
size_t newWidth) -> Column& {
 
 6938        assert(newWidth > 0);
 
 6942    auto indent(
size_t newIndent) -> Column& {
 
 6943        m_indent = newIndent;
 
 6946    auto initialIndent(
size_t newIndent) -> Column& {
 
 6947        m_initialIndent = newIndent;
 
 6951    auto width() const -> 
size_t { 
return m_width; }
 
 6952    auto begin() const -> iterator { 
return iterator(*
this); }
 
 6953    auto end() const -> iterator { 
return { *
this, m_strings.
size() }; }
 
 6957        for (
auto line : col) {
 
 6967    auto operator + (Column 
const& other)->Columns;
 
 6969    auto toString() const -> 
std::
string {
 
 6976class Spacer : 
public Column {
 
 6979    explicit Spacer(
size_t spaceWidth) : Column(
"") {
 
 6995        size_t m_activeIterators;
 
 6997        iterator(Columns 
const& columns, EndTag)
 
 6998            : m_columns(columns.m_columns),
 
 6999            m_activeIterators(0) {
 
 7002            for (
auto const& col : m_columns)
 
 7003                m_iterators.push_back(col.
end());
 
 7013        explicit iterator(Columns 
const& columns)
 
 7014            : m_columns(columns.m_columns),
 
 7015            m_activeIterators(m_columns.
size()) {
 
 7018            for (
auto const& col : m_columns)
 
 7019                m_iterators.push_back(col.
begin());
 
 7022        auto operator ==(iterator 
const& other) 
const -> 
bool {
 
 7023            return m_iterators == other.m_iterators;
 
 7025        auto operator !=(iterator 
const& other) 
const -> 
bool {
 
 7026            return m_iterators != other.m_iterators;
 
 7028        auto operator *() const -> 
std::
string {
 
 7031            for (
size_t i = 0; i < m_columns.
size(); ++i) {
 
 7032                auto width = m_columns[i].width();
 
 7033                if (m_iterators[i] != m_columns[i].
end()) {
 
 7035                    row += padding + col;
 
 7036                    if (col.
size() < width)
 
 7041                    padding += 
std::string(width, ' ');
 
 7046        auto operator ++() -> iterator& {
 
 7047            for (
size_t i = 0; i < m_columns.
size(); ++i) {
 
 7048                if (m_iterators[i] != m_columns[i].
end())
 
 7053        auto operator ++(
int) -> iterator {
 
 7054            iterator 
prev(*
this);
 
 7059    using const_iterator = iterator;
 
 7061    auto begin() const -> iterator { 
return iterator(*
this); }
 
 7062    auto end() const -> iterator { 
return { *
this, iterator::EndTag() }; }
 
 7064    auto operator += (Column 
const& col) -> Columns& {
 
 7068    auto operator + (Column 
const& col) -> Columns {
 
 7069        Columns combined = *
this;
 
 7077        for (
auto line : cols) {
 
 7087    auto toString() const -> 
std::
string {
 
 7094inline auto Column::operator + (Column 
const& other) -> Columns {
 
 7114#if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) ) 
 7115#define CATCH_PLATFORM_WINDOWS 
 7118namespace Catch { 
namespace clara {
 
 7122    template<
typename L>
 
 7123    struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
 
 7125    template<
typename ClassT, 
typename ReturnT, 
typename... Args>
 
 7126    struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
 
 7127        static const bool isValid = 
false;
 
 7130    template<
typename ClassT, 
typename ReturnT, 
typename ArgT>
 
 7131    struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
 
 7132        static const bool isValid = 
true;
 
 7134        using ReturnType = ReturnT;
 
 7146        Args( 
int argc, 
char const* 
const* argv )
 
 7147            : m_exeName(argv[0]),
 
 7148              m_args(argv + 1, argv + argc) {}
 
 7151        :   m_exeName( *args.
begin() ),
 
 7152            m_args( args.
begin()+1, args.
end() )
 
 7155        auto exeName() const -> 
std::
string {
 
 7162    enum class TokenType {
 
 7170    inline auto isOptPrefix( 
char c ) -> 
bool {
 
 7172#ifdef CATCH_PLATFORM_WINDOWS 
 7186            m_tokenBuffer.
resize( 0 );
 
 7189            while( it != itEnd && it->empty() )
 
 7193                auto const &
next = *it;
 
 7194                if( isOptPrefix( next[0] ) ) {
 
 7195                    auto delimiterPos = 
next.find_first_of( 
" :=" );
 
 7196                    if( delimiterPos != std::string::npos ) {
 
 7197                        m_tokenBuffer.
push_back( { TokenType::Option, 
next.substr( 0, delimiterPos ) } );
 
 7198                        m_tokenBuffer.
push_back( { TokenType::Argument, 
next.substr( delimiterPos + 1 ) } );
 
 7200                        if( next[1] != 
'-' && 
next.size() > 2 ) {
 
 7202                            for( 
size_t i = 1; i < 
next.size(); ++i ) {
 
 7204                                m_tokenBuffer.
push_back( { TokenType::Option, opt } );
 
 7217        explicit TokenStream( Args 
const &args ) : TokenStream( args.m_args.
begin(), args.m_args.
end() ) {}
 
 7219        TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
 
 7223        explicit operator bool()
 const {
 
 7224            return !m_tokenBuffer.
empty() || it != itEnd;
 
 7227        auto count() const -> 
size_t { 
return m_tokenBuffer.
size() + (itEnd - it); }
 
 7230            assert( !m_tokenBuffer.
empty() );
 
 7231            return m_tokenBuffer.
front();
 
 7234        auto operator->() const -> Token const * {
 
 7235            assert( !m_tokenBuffer.
empty() );
 
 7236            return &m_tokenBuffer.
front();
 
 7239        auto operator++() -> TokenStream & {
 
 7240            if( m_tokenBuffer.
size() >= 2 ) {
 
 7241                m_tokenBuffer.
erase( m_tokenBuffer.
begin() );
 
 7254            Ok, LogicError, RuntimeError
 
 7258        ResultBase( Type 
type ) : m_type( 
type ) {}
 
 7259        virtual ~ResultBase() = 
default;
 
 7261        virtual void enforceOk() 
const = 0;
 
 7266    template<
typename T>
 
 7267    class ResultValueBase : 
public ResultBase {
 
 7269        auto value() const -> 
T const & {
 
 7275        ResultValueBase( Type 
type ) : ResultBase( 
type ) {}
 
 7277        ResultValueBase( ResultValueBase 
const &other ) : ResultBase( other ) {
 
 7278            if( m_type == ResultBase::Ok )
 
 7279                new( &m_value ) 
T( other.m_value );
 
 7282        ResultValueBase( Type, 
T const &
value ) : ResultBase( Ok ) {
 
 7283            new( &m_value ) 
T( 
value );
 
 7286        auto operator=( ResultValueBase 
const &other ) -> ResultValueBase & {
 
 7287            if( m_type == ResultBase::Ok )
 
 7289            ResultBase::operator=(other);
 
 7290            if( m_type == ResultBase::Ok )
 
 7291                new( &m_value ) 
T( other.m_value );
 
 7295        ~ResultValueBase()
 override {
 
 7306    class ResultValueBase<void> : 
public ResultBase {
 
 7308        using ResultBase::ResultBase;
 
 7311    template<
typename T = 
void>
 
 7312    class BasicResult : 
public ResultValueBase<
T> {
 
 7314        template<
typename U>
 
 7315        explicit BasicResult( BasicResult<U> 
const &other )
 
 7316        :   ResultValueBase<
T>( other.
type() ),
 
 7317            m_errorMessage( other.errorMessage() )
 
 7319            assert( 
type() != ResultBase::Ok );
 
 7322        template<
typename U>
 
 7323        static auto ok( U 
const &
value ) -> BasicResult { 
return { ResultBase::Ok, 
value }; }
 
 7324        static auto ok() -> BasicResult { 
return { ResultBase::Ok }; }
 
 7325        static auto logicError( 
std::string const &message ) -> BasicResult { 
return { ResultBase::LogicError, message }; }
 
 7326        static auto runtimeError( 
std::string const &message ) -> BasicResult { 
return { ResultBase::RuntimeError, message }; }
 
 7328        explicit operator bool()
 const { 
return m_type == ResultBase::Ok; }
 
 7329        auto type() const -> ResultBase::Type { 
return m_type; }
 
 7330        auto errorMessage() const -> 
std::
string { 
return m_errorMessage; }
 
 7333        void enforceOk()
 const override {
 
 7337            assert( m_type != ResultBase::LogicError );
 
 7338            assert( m_type != ResultBase::RuntimeError );
 
 7339            if( m_type != ResultBase::Ok )
 
 7346        :   ResultValueBase<
T>(
type),
 
 7347            m_errorMessage(message)
 
 7349            assert( m_type != ResultBase::Ok );
 
 7352        using ResultValueBase<
T>::ResultValueBase;
 
 7353        using ResultBase::m_type;
 
 7356    enum class ParseResultType {
 
 7357        Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
 
 7363        ParseState( ParseResultType 
type, TokenStream 
const &remainingTokens )
 
 7365          m_remainingTokens( remainingTokens )
 
 7368        auto type() const -> ParseResultType { 
return m_type; }
 
 7369        auto remainingTokens() const -> TokenStream { 
return m_remainingTokens; }
 
 7372        ParseResultType m_type;
 
 7373        TokenStream m_remainingTokens;
 
 7376    using Result = BasicResult<void>;
 
 7377    using ParserResult = BasicResult<ParseResultType>;
 
 7378    using InternalParseResult = BasicResult<ParseState>;
 
 7380    struct HelpColumns {
 
 7385    template<
typename T>
 
 7386    inline auto convertInto( 
std::string const &source, 
T& target ) -> ParserResult {
 
 7391            return ParserResult::runtimeError( 
"Unable to convert '" + source + 
"' to destination type" );
 
 7393            return ParserResult::ok( ParseResultType::Matched );
 
 7397        return ParserResult::ok( ParseResultType::Matched );
 
 7399    inline auto convertInto( 
std::string const &source, 
bool &target ) -> ParserResult {
 
 7402        if (srcLC == 
"y" || srcLC == 
"1" || srcLC == 
"true" || srcLC == 
"yes" || srcLC == 
"on")
 
 7404        else if (srcLC == 
"n" || srcLC == 
"0" || srcLC == 
"false" || srcLC == 
"no" || srcLC == 
"off")
 
 7407            return ParserResult::runtimeError( 
"Expected a boolean value but did not recognise: '" + source + 
"'" );
 
 7408        return ParserResult::ok( ParseResultType::Matched );
 
 7410#ifdef CLARA_CONFIG_OPTIONAL_TYPE 
 7411    template<
typename T>
 
 7412    inline auto convertInto( 
std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
 
 7414        auto result = convertInto( source, temp );
 
 7416            target = std::move(temp);
 
 7421    struct NonCopyable {
 
 7422        NonCopyable() = 
default;
 
 7423        NonCopyable( NonCopyable 
const & ) = 
delete;
 
 7424        NonCopyable( NonCopyable && ) = 
delete;
 
 7425        NonCopyable &operator=( NonCopyable 
const & ) = 
delete;
 
 7426        NonCopyable &operator=( NonCopyable && ) = 
delete;
 
 7429    struct BoundRef : NonCopyable {
 
 7430        virtual ~BoundRef() = 
default;
 
 7431        virtual auto isContainer() const -> 
bool { 
return false; }
 
 7432        virtual auto isFlag() const -> 
bool { 
return false; }
 
 7434    struct BoundValueRefBase : BoundRef {
 
 7435        virtual auto setValue( 
std::string const &
arg ) -> ParserResult = 0;
 
 7437    struct BoundFlagRefBase : BoundRef {
 
 7438        virtual auto setFlag( 
bool flag ) -> ParserResult = 0;
 
 7439        virtual auto isFlag() const -> 
bool { 
return true; }
 
 7442    template<
typename T>
 
 7443    struct BoundValueRef : BoundValueRefBase {
 
 7446        explicit BoundValueRef( 
T &ref ) : m_ref( 
ref ) {}
 
 7448        auto setValue( 
std::string const &
arg ) -> ParserResult 
override {
 
 7449            return convertInto( 
arg, m_ref );
 
 7453    template<
typename T>
 
 7454    struct BoundValueRef<
std::vector<
T>> : BoundValueRefBase {
 
 7459        auto isContainer() const -> 
bool override { 
return true; }
 
 7461        auto setValue( 
std::string const &
arg ) -> ParserResult 
override {
 
 7465                m_ref.push_back( temp );
 
 7470    struct BoundFlagRef : BoundFlagRefBase {
 
 7473        explicit BoundFlagRef( 
bool &ref ) : m_ref( 
ref ) {}
 
 7475        auto setFlag( 
bool flag ) -> ParserResult 
override {
 
 7477            return ParserResult::ok( ParseResultType::Matched );
 
 7481    template<
typename ReturnType>
 
 7482    struct LambdaInvoker {
 
 7485        template<
typename L, 
typename ArgType>
 
 7486        static auto invoke( L 
const &lambda, ArgType 
const &
arg ) -> ParserResult {
 
 7487            return lambda( 
arg );
 
 7492    struct LambdaInvoker<void> {
 
 7493        template<
typename L, 
typename ArgType>
 
 7494        static auto invoke( L 
const &lambda, ArgType 
const &
arg ) -> ParserResult {
 
 7496            return ParserResult::ok( ParseResultType::Matched );
 
 7500    template<
typename ArgType, 
typename L>
 
 7501    inline auto invokeLambda( L 
const &lambda, 
std::string const &
arg ) -> ParserResult {
 
 7506           : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
 
 7509    template<
typename L>
 
 7510    struct BoundLambda : BoundValueRefBase {
 
 7513        static_assert( UnaryLambdaTraits<L>::isValid, 
"Supplied lambda must take exactly one argument" );
 
 7514        explicit BoundLambda( L 
const &lambda ) : m_lambda( lambda ) {}
 
 7516        auto setValue( 
std::string const &
arg ) -> ParserResult 
override {
 
 7517            return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, 
arg );
 
 7521    template<
typename L>
 
 7522    struct BoundFlagLambda : BoundFlagRefBase {
 
 7525        static_assert( UnaryLambdaTraits<L>::isValid, 
"Supplied lambda must take exactly one argument" );
 
 7528        explicit BoundFlagLambda( L 
const &lambda ) : m_lambda( lambda ) {}
 
 7530        auto setFlag( 
bool flag ) -> ParserResult 
override {
 
 7531            return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
 
 7535    enum class Optionality { Optional, Required };
 
 7541        virtual ~ParserBase() = 
default;
 
 7542        virtual auto validate() const -> Result { 
return Result::ok(); }
 
 7543        virtual auto parse( 
std::string const& exeName, TokenStream 
const &tokens) 
const -> InternalParseResult  = 0;
 
 7544        virtual auto cardinality() const -> 
size_t { 
return 1; }
 
 7546        auto parse( Args 
const &args ) 
const -> InternalParseResult {
 
 7547            return parse( args.exeName(), TokenStream( args ) );
 
 7551    template<
typename DerivedT>
 
 7552    class ComposableParserImpl : 
public ParserBase {
 
 7554        template<
typename T>
 
 7555        auto operator|( 
T const &other ) 
const -> Parser;
 
 7557        template<
typename T>
 
 7558        auto operator+( 
T const &other ) 
const -> Parser;
 
 7562    template<
typename DerivedT>
 
 7563    class ParserRefImpl : 
public ComposableParserImpl<DerivedT> {
 
 7565        Optionality m_optionality = Optionality::Optional;
 
 7573        template<
typename T>
 
 7579        template<
typename LambdaT>
 
 7580        ParserRefImpl( LambdaT 
const &ref, 
std::string const &hint )
 
 7585        auto operator()( 
std::string const &description ) -> DerivedT & {
 
 7586            m_description = description;
 
 7587            return static_cast<DerivedT &
>( *this );
 
 7590        auto optional() -> DerivedT & {
 
 7591            m_optionality = Optionality::Optional;
 
 7592            return static_cast<DerivedT &
>( *this );
 
 7595        auto required() -> DerivedT & {
 
 7596            m_optionality = Optionality::Required;
 
 7597            return static_cast<DerivedT &
>( *this );
 
 7600        auto isOptional() const -> 
bool {
 
 7601            return m_optionality == Optionality::Optional;
 
 7604        auto cardinality() const -> 
size_t override {
 
 7605            if( m_ref->isContainer() )
 
 7611        auto hint() const -> 
std::
string { 
return m_hint; }
 
 7614    class ExeName : 
public ComposableParserImpl<ExeName> {
 
 7618        template<
typename LambdaT>
 
 7626        explicit ExeName( 
std::string &ref ) : ExeName() {
 
 7630        template<
typename LambdaT>
 
 7631        explicit ExeName( LambdaT 
const& lambda ) : ExeName() {
 
 7636        auto parse( 
std::string const&, TokenStream 
const &tokens ) 
const -> InternalParseResult 
override {
 
 7637            return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
 
 7640        auto name() const -> 
std::
string { 
return *m_name; }
 
 7641        auto set( 
std::string const& newName ) -> ParserResult {
 
 7643            auto lastSlash = newName.find_last_of( 
"\\/" );
 
 7644            auto filename = ( lastSlash == std::string::npos )
 
 7646                    : newName.substr( lastSlash+1 );
 
 7650                return m_ref->setValue( filename );
 
 7652                return ParserResult::ok( ParseResultType::Matched );
 
 7656    class Arg : 
public ParserRefImpl<Arg> {
 
 7658        using ParserRefImpl::ParserRefImpl;
 
 7660        auto parse( 
std::string const &, TokenStream 
const &tokens ) 
const -> InternalParseResult 
override {
 
 7661            auto validationResult = validate();
 
 7662            if( !validationResult )
 
 7663                return InternalParseResult( validationResult );
 
 7665            auto remainingTokens = tokens;
 
 7666            auto const &token = *remainingTokens;
 
 7667            if( token.type != TokenType::Argument )
 
 7668                return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
 
 7670            assert( !m_ref->isFlag() );
 
 7671            auto valueRef = 
static_cast<detail::BoundValueRefBase*
>( m_ref.
get() );
 
 7673            auto result = valueRef->setValue( remainingTokens->token );
 
 7675                return InternalParseResult( result );
 
 7677                return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
 
 7682#ifdef CATCH_PLATFORM_WINDOWS 
 7683        if( optName[0] == 
'/' )
 
 7684            return "-" + optName.substr( 1 );
 
 7690    class Opt : 
public ParserRefImpl<Opt> {
 
 7695        template<
typename LambdaT>
 
 7696        explicit Opt( LambdaT 
const &ref ) : ParserRefImpl( 
std::
make_shared<BoundFlagLambda<LambdaT>>( 
ref ) ) {}
 
 7698        explicit Opt( 
bool &ref ) : ParserRefImpl( 
std::
make_shared<BoundFlagRef>( 
ref ) ) {}
 
 7700        template<
typename LambdaT>
 
 7701        Opt( LambdaT 
const &ref, 
std::string const &hint ) : ParserRefImpl( 
ref, hint ) {}
 
 7703        template<
typename T>
 
 7704        Opt( 
T &ref, 
std::string const &hint ) : ParserRefImpl( 
ref, hint ) {}
 
 7706        auto operator[]( 
std::string const &optName ) -> Opt & {
 
 7711        auto getHelpColumns() const -> 
std::vector<HelpColumns> {
 
 7714            for( 
auto const &opt : m_optNames ) {
 
 7721            if( !m_hint.
empty() )
 
 7722                oss << 
" <" << m_hint << 
">";
 
 7723            return { { oss.
str(), m_description } };
 
 7726        auto isMatch( 
std::string const &optToken ) 
const -> 
bool {
 
 7727            auto normalisedToken = normaliseOpt( optToken );
 
 7728            for( 
auto const &
name : m_optNames ) {
 
 7729                if( normaliseOpt( 
name ) == normalisedToken )
 
 7735        using ParserBase::parse;
 
 7737        auto parse( 
std::string const&, TokenStream 
const &tokens ) 
const -> InternalParseResult 
override {
 
 7738            auto validationResult = validate();
 
 7739            if( !validationResult )
 
 7740                return InternalParseResult( validationResult );
 
 7742            auto remainingTokens = tokens;
 
 7743            if( remainingTokens && remainingTokens->type == TokenType::Option ) {
 
 7744                auto const &token = *remainingTokens;
 
 7745                if( isMatch(token.token ) ) {
 
 7746                    if( m_ref->isFlag() ) {
 
 7747                        auto flagRef = 
static_cast<detail::BoundFlagRefBase*
>( m_ref.
get() );
 
 7748                        auto result = flagRef->setFlag( 
true );
 
 7750                            return InternalParseResult( result );
 
 7751                        if( 
result.value() == ParseResultType::ShortCircuitAll )
 
 7752                            return InternalParseResult::ok( ParseState( 
result.value(), remainingTokens ) );
 
 7754                        auto valueRef = 
static_cast<detail::BoundValueRefBase*
>( m_ref.
get() );
 
 7756                        if( !remainingTokens )
 
 7757                            return InternalParseResult::runtimeError( 
"Expected argument following " + token.token );
 
 7758                        auto const &argToken = *remainingTokens;
 
 7759                        if( argToken.type != TokenType::Argument )
 
 7760                            return InternalParseResult::runtimeError( 
"Expected argument following " + token.token );
 
 7761                        auto result = valueRef->setValue( argToken.token );
 
 7763                            return InternalParseResult( result );
 
 7764                        if( 
result.value() == ParseResultType::ShortCircuitAll )
 
 7765                            return InternalParseResult::ok( ParseState( 
result.value(), remainingTokens ) );
 
 7767                    return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
 
 7770            return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
 
 7773        auto validate() const -> Result
 override {
 
 7774            if( m_optNames.
empty() )
 
 7775                return Result::logicError( 
"No options supplied to Opt" );
 
 7776            for( 
auto const &
name : m_optNames ) {
 
 7778                    return Result::logicError( 
"Option name cannot be empty" );
 
 7779#ifdef CATCH_PLATFORM_WINDOWS 
 7780                if( 
name[0] != 
'-' && 
name[0] != 
'/' )
 
 7781                    return Result::logicError( 
"Option name must begin with '-' or '/'" );
 
 7783                if( 
name[0] != 
'-' )
 
 7784                    return Result::logicError( 
"Option name must begin with '-'" );
 
 7787            return ParserRefImpl::validate();
 
 7792        Help( 
bool &showHelpFlag )
 
 7793        :   Opt([&]( 
bool flag ) {
 
 7794                showHelpFlag = flag;
 
 7795                return ParserResult::ok( ParseResultType::ShortCircuitAll );
 
 7798            static_cast<Opt &
>( *this )
 
 7799                    (
"display usage information")
 
 7800                    [
"-?"][
"-h"][
"--help"]
 
 7805    struct Parser : ParserBase {
 
 7807        mutable ExeName m_exeName;
 
 7811        auto operator|=( ExeName 
const &exeName ) -> Parser & {
 
 7812            m_exeName = exeName;
 
 7816        auto operator|=( Arg 
const &
arg ) -> Parser & {
 
 7821        auto operator|=( Opt 
const &opt ) -> Parser & {
 
 7826        auto operator|=( Parser 
const &other ) -> Parser & {
 
 7827            m_options.
insert(m_options.
end(), other.m_options.begin(), other.m_options.end());
 
 7828            m_args.
insert(m_args.
end(), other.m_args.begin(), other.m_args.end());
 
 7832        template<
typename T>
 
 7833        auto operator|( 
T const &other ) 
const -> Parser {
 
 7834            return Parser( *
this ) |= other;
 
 7838        template<
typename T>
 
 7839        auto operator+=( 
T const &other ) -> Parser & { 
return operator|=( other ); }
 
 7840        template<
typename T>
 
 7843        auto getHelpColumns() const -> 
std::vector<HelpColumns> {
 
 7845            for (
auto const &o : m_options) {
 
 7846                auto childCols = o.getHelpColumns();
 
 7847                cols.
insert( cols.
end(), childCols.begin(), childCols.end() );
 
 7853            if (!m_exeName.name().empty()) {
 
 7854                os << 
"usage:\n" << 
"  " << m_exeName.name() << 
" ";
 
 7855                bool required = 
true, 
first = 
true;
 
 7856                for( 
auto const &
arg : m_args ) {
 
 7861                    if( 
arg.isOptional() && required ) {
 
 7865                    os << 
"<" << 
arg.hint() << 
">";
 
 7866                    if( 
arg.cardinality() == 0 )
 
 7871                if( !m_options.
empty() )
 
 7873                os << 
"\n\nwhere options are:" << 
std::endl;
 
 7876            auto rows = getHelpColumns();
 
 7877            size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
 
 7878            size_t optWidth = 0;
 
 7879            for( 
auto const &cols : rows )
 
 7882            optWidth = (
std::min)(optWidth, consoleWidth/2);
 
 7884            for( 
auto const &cols : rows ) {
 
 7886                        TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
 
 7887                        TextFlow::Spacer(4) +
 
 7888                        TextFlow::Column( cols.
right ).width( consoleWidth - 7 - optWidth );
 
 7894            parser.writeToStream( os );
 
 7898        auto validate() const -> Result
 override {
 
 7899            for( 
auto const &opt : m_options ) {
 
 7900                auto result = opt.validate();
 
 7904            for( 
auto const &
arg : m_args ) {
 
 7909            return Result::ok();
 
 7912        using ParserBase::parse;
 
 7914        auto parse( 
std::string const& exeName, TokenStream 
const &tokens ) 
const -> InternalParseResult 
override {
 
 7917                ParserBase 
const* parser = 
nullptr;
 
 7920            const size_t totalParsers = m_options.
size() + m_args.
size();
 
 7921            assert( totalParsers < 512 );
 
 7923            ParserInfo parseInfos[512];
 
 7927                for (
auto const &opt : m_options) parseInfos[i++].parser = &opt;
 
 7928                for (
auto const &
arg : m_args) parseInfos[i++].parser = &
arg;
 
 7931            m_exeName.set( exeName );
 
 7933            auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
 
 7934            while( 
result.value().remainingTokens() ) {
 
 7935                bool tokenParsed = 
false;
 
 7937                for( 
size_t i = 0; i < totalParsers; ++i ) {
 
 7938                    auto&  parseInfo = parseInfos[i];
 
 7939                    if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
 
 7940                        result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
 
 7943                        if (result.value().type() != ParseResultType::NoMatch) {
 
 7951                if( 
result.value().type() == ParseResultType::ShortCircuitAll )
 
 7954                    return InternalParseResult::runtimeError( 
"Unrecognised token: " + 
result.value().remainingTokens()->token );
 
 7961    template<
typename DerivedT>
 
 7962    template<
typename T>
 
 7963    auto ComposableParserImpl<DerivedT>::operator|( 
T const &other ) 
const -> Parser {
 
 7964        return Parser() | 
static_cast<DerivedT 
const &
>( *this ) | other;
 
 7969using detail::Parser;
 
 7981using detail::ExeName;
 
 7987using detail::ParseResultType;
 
 7990using detail::ParserResult;
 
 7996#pragma clang diagnostic pop 
 8000#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH 
 8001#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH 
 8002#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH 
 8008    clara::Parser makeCommandLineParser( ConfigData& config );
 
 8018    clara::Parser makeCommandLineParser( ConfigData& config ) {
 
 8020        using namespace clara;
 
 8022        auto const setWarning = [&]( 
std::string const& warning ) {
 
 8023                auto warningSet = [&]() {
 
 8024                    if( warning == 
"NoAssertions" )
 
 8027                    if ( warning == 
"NoTests" )
 
 8034                    return ParserResult::runtimeError( 
"Unrecognised warning: '" + warning + 
"'" );
 
 8035                config.warnings = 
static_cast<WarnAbout::What>( config.warnings | warningSet );
 
 8036                return ParserResult::ok( ParseResultType::Matched );
 
 8038        auto const loadTestNamesFromFile = [&]( 
std::string const& filename ) {
 
 8041                    return ParserResult::runtimeError( 
"Unable to load input file: '" + filename + 
"'" );
 
 8048                            line = 
'"' + line + '"';
 
 8049                        config.testsOrTags.push_back( line + 
',' );
 
 8052                return ParserResult::ok( ParseResultType::Matched );
 
 8054        auto const setTestOrder = [&]( 
std::string const& order ) {
 
 8062                    return clara::ParserResult::runtimeError( 
"Unrecognised ordering: '" + order + 
"'" );
 
 8063                return ParserResult::ok( ParseResultType::Matched );
 
 8065        auto const setRngSeed = [&]( 
std::string const& seed ) {
 
 8066                if( seed != 
"time" )
 
 8067                    return clara::detail::convertInto( seed, config.rngSeed );
 
 8068                config.rngSeed = 
static_cast<unsigned int>( 
std::time(
nullptr) );
 
 8069                return ParserResult::ok( ParseResultType::Matched );
 
 8071        auto const setColourUsage = [&]( 
std::string const& useColour ) {
 
 8072                    auto mode = 
toLower( useColour );
 
 8076                    else if( mode == 
"no" )
 
 8078                    else if( mode == 
"auto" )
 
 8081                        return ParserResult::runtimeError( 
"colour mode must be one of: auto, yes or no. '" + useColour + 
"' not recognised" );
 
 8082                return ParserResult::ok( ParseResultType::Matched );
 
 8084        auto const setWaitForKeypress = [&]( 
std::string const& keypress ) {
 
 8085                auto keypressLc = 
toLower( keypress );
 
 8086                if( keypressLc == 
"start" )
 
 8088                else if( keypressLc == 
"exit" )
 
 8090                else if( keypressLc == 
"both" )
 
 8093                    return ParserResult::runtimeError( 
"keypress argument must be one of: start, exit or both. '" + keypress + 
"' not recognised" );
 
 8094            return ParserResult::ok( ParseResultType::Matched );
 
 8096        auto const setVerbosity = [&]( 
std::string const& verbosity ) {
 
 8097            auto lcVerbosity = 
toLower( verbosity );
 
 8098            if( lcVerbosity == 
"quiet" )
 
 8100            else if( lcVerbosity == 
"normal" )
 
 8102            else if( lcVerbosity == 
"high" )
 
 8105                return ParserResult::runtimeError( 
"Unrecognised verbosity, '" + verbosity + 
"'" );
 
 8106            return ParserResult::ok( ParseResultType::Matched );
 
 8108        auto const setReporter = [&]( 
std::string const& reporter ) {
 
 8111            auto lcReporter = 
toLower( reporter );
 
 8112            auto result = factories.find( lcReporter );
 
 8114            if( factories.end() != result )
 
 8115                config.reporterName = lcReporter;
 
 8117                return ParserResult::runtimeError( 
"Unrecognized reporter, '" + reporter + 
"'. Check available with --list-reporters" );
 
 8118            return ParserResult::ok( ParseResultType::Matched );
 
 8122            = ExeName( config.processName )
 
 8123            | Help( config.showHelp )
 
 8124            | Opt( config.listTests )
 
 8125                ["-l"]["--list-tests"]
 
 8126                ( 
"list all/matching test cases" )
 
 8127            | Opt( config.listTags )
 
 8128                ["-t"]["--list-tags"]
 
 8129                ( 
"list all/matching tags" )
 
 8130            | Opt( config.showSuccessfulTests )
 
 8132                ( 
"include successful tests in output" )
 
 8133            | Opt( config.shouldDebugBreak )
 
 8135                ( 
"break into debugger on failure" )
 
 8136            | Opt( config.noThrow )
 
 8138                ( 
"skip exception tests" )
 
 8139            | Opt( config.showInvisibles )
 
 8140                ["-i"]["--invisibles"]
 
 8141                ( 
"show invisibles (tabs, newlines)" )
 
 8142            | Opt( config.outputFilename, 
"filename" )
 
 8144                ( 
"output filename" )
 
 8145            | Opt( setReporter, 
"name" )
 
 8146                ["-r"]["--reporter"]
 
 8147                ( 
"reporter to use (defaults to console)" )
 
 8148            | Opt( config.name, 
"name" )
 
 8151            | Opt( [&]( 
bool ){ config.abortAfter = 1; } )
 
 8153                ( 
"abort at first failure" )
 
 8154            | Opt( [&]( 
int x ){ config.abortAfter = x; }, 
"no. failures" )
 
 8156                ( 
"abort after x failures" )
 
 8157            | Opt( setWarning, 
"warning name" )
 
 8159                ( 
"enable warnings" )
 
 8161                [
"-d"][
"--durations"]
 
 8162                ( 
"show test durations" )
 
 8163            | Opt( loadTestNamesFromFile, 
"filename" )
 
 8164                ["-f"]["--input-file"]
 
 8165                ( 
"load test names to run from a file" )
 
 8166            | Opt( config.filenamesAsTags )
 
 8167                ["-#"]["--filenames-as-tags"]
 
 8168                ( 
"adds a tag for the filename" )
 
 8169            | Opt( config.sectionsToRun, 
"section name" )
 
 8171                ( 
"specify section to run" )
 
 8172            | Opt( setVerbosity, 
"quiet|normal|high" )
 
 8173                ["-v"]["--verbosity"]
 
 8174                ( 
"set output verbosity" )
 
 8175            | Opt( config.listTestNamesOnly )
 
 8176                ["--list-test-names-only"]
 
 8177                ( 
"list all/matching test cases names only" )
 
 8178            | Opt( config.listReporters )
 
 8179                ["--list-reporters"]
 
 8180                ( 
"list all reporters" )
 
 8181            | Opt( setTestOrder, 
"decl|lex|rand" )
 
 8183                ( 
"test case order (defaults to decl)" )
 
 8184            | Opt( setRngSeed, 
"'time'|number" )
 
 8186                ( 
"set a specific seed for random numbers" )
 
 8187            | Opt( setColourUsage, 
"yes|no" )
 
 8189                ( 
"should output be colourised" )
 
 8190            | Opt( config.libIdentify )
 
 8192                ( 
"report name and version according to libidentify standard" )
 
 8193            | Opt( setWaitForKeypress, 
"start|exit|both" )
 
 8194                ["--wait-for-keypress"]
 
 8195                ( 
"waits for a keypress before exiting" )
 
 8196            | Opt( config.benchmarkResolutionMultiple, 
"multiplier" )
 
 8197                ["--benchmark-resolution-multiple"]
 
 8198                ( 
"multiple of clock resolution to run benchmarks" )
 
 8200            | Arg( config.testsOrTags, 
"test name|pattern|tags" )
 
 8201                ( 
"which test or tests to use" );
 
 8216        return file[0] == 
'\0';
 
 8219        return line == other.line && (file == other.file || 
std::strcmp(file, other.file) == 0);
 
 8224        return line < other.line || ( line == other.line && file != other.file && (
std::strcmp(file, other.file) < 0));
 
 8229        os << 
info.file << 
'(' << 
info.line << 
')';
 
 8231        os << 
info.file << 
':' << 
info.line;
 
 8249    Config::Config( ConfigData 
const& 
data )
 
 8251        m_stream( openStream() )
 
 8253        TestSpecParser parser(ITagAliasRegistry::get());
 
 8254        if (!
data.testsOrTags.empty()) {
 
 8255            m_hasTestFilters = 
true;
 
 8256            for( 
auto const& testOrTags : 
data.testsOrTags )
 
 8257                parser.parse( testOrTags );
 
 8259        m_testSpec = parser.testSpec();
 
 8263        return m_data.outputFilename ;
 
 8266    bool Config::listTests()
 const          { 
return m_data.listTests; }
 
 8267    bool Config::listTestNamesOnly()
 const  { 
return m_data.listTestNamesOnly; }
 
 8268    bool Config::listTags()
 const           { 
return m_data.listTags; }
 
 8269    bool Config::listReporters()
 const      { 
return m_data.listReporters; }
 
 8271    std::string Config::getProcessName()
 const { 
return m_data.processName; }
 
 8272    std::string const& Config::getReporterName()
 const { 
return m_data.reporterName; }
 
 8277    TestSpec 
const& Config::testSpec()
 const { 
return m_testSpec; }
 
 8278    bool Config::hasTestFilters()
 const { 
return m_hasTestFilters; }
 
 8280    bool Config::showHelp()
 const { 
return m_data.showHelp; }
 
 8283    bool Config::allowThrows()
 const                   { 
return !m_data.noThrow; }
 
 8284    std::ostream& Config::stream()
 const               { 
return m_stream->stream(); }
 
 8285    std::string Config::name()
 const                   { 
return m_data.name.
empty() ? m_data.processName : m_data.name; }
 
 8286    bool Config::includeSuccessfulResults()
 const      { 
return m_data.showSuccessfulTests; }
 
 8288    bool Config::warnAboutNoTests()
 const              { 
return !!(m_data.warnings & 
WarnAbout::NoTests); }
 
 8291    unsigned int Config::rngSeed()
 const               { 
return m_data.rngSeed; }
 
 8292    int Config::benchmarkResolutionMultiple()
 const    { 
return m_data.benchmarkResolutionMultiple; }
 
 8294    bool Config::shouldDebugBreak()
 const              { 
return m_data.shouldDebugBreak; }
 
 8295    int Config::abortAfter()
 const                     { 
return m_data.abortAfter; }
 
 8296    bool Config::showInvisibles()
 const                { 
return m_data.showInvisibles; }
 
 8297    Verbosity Config::verbosity()
 const                { 
return m_data.verbosity; }
 
 8299    IStream 
const* Config::openStream() {
 
 8307#if defined(__clang__) 
 8308#    pragma clang diagnostic push 
 8309#    pragma clang diagnostic ignored "-Wexit-time-destructors" 
 8332        struct IColourImpl {
 
 8333            virtual ~IColourImpl() = 
default;
 
 8334            virtual void use( Colour::Code _colourCode ) = 0;
 
 8337        struct NoColourImpl : IColourImpl {
 
 8338            void use( Colour::Code ) {}
 
 8340            static IColourImpl* instance() {
 
 8341                static NoColourImpl s_instance;
 
 8349#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) 
 8350#   ifdef CATCH_PLATFORM_WINDOWS 
 8351#       define CATCH_CONFIG_COLOUR_WINDOWS 
 8353#       define CATCH_CONFIG_COLOUR_ANSI 
 8357#if defined ( CATCH_CONFIG_COLOUR_WINDOWS )  
 8362    class Win32ColourImpl : 
public IColourImpl {
 
 8364        Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
 
 8366            CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
 
 8367            GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
 
 8368            originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
 
 8369            originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
 
 8372        void use( Colour::Code _colourCode )
 override {
 
 8373            switch( _colourCode ) {
 
 8374                case Colour::None:      
return setTextAttribute( originalForegroundAttributes );
 
 8375                case Colour::White:     
return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
 
 8376                case Colour::Red:       
return setTextAttribute( FOREGROUND_RED );
 
 8377                case Colour::Green:     
return setTextAttribute( FOREGROUND_GREEN );
 
 8378                case Colour::Blue:      
return setTextAttribute( FOREGROUND_BLUE );
 
 8379                case Colour::Cyan:      
return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
 
 8380                case Colour::Yellow:    
return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
 
 8381                case Colour::Grey:      
return setTextAttribute( 0 );
 
 8383                case Colour::LightGrey:     
return setTextAttribute( FOREGROUND_INTENSITY );
 
 8384                case Colour::BrightRed:     
return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
 
 8385                case Colour::BrightGreen:   
return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
 
 8386                case Colour::BrightWhite:   
return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
 
 8387                case Colour::BrightYellow:  
return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
 
 8397        void setTextAttribute( WORD _textAttribute ) {
 
 8398            SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
 
 8400        HANDLE stdoutHandle;
 
 8401        WORD originalForegroundAttributes;
 
 8402        WORD originalBackgroundAttributes;
 
 8405    IColourImpl* platformColourInstance() {
 
 8406        static Win32ColourImpl s_instance;
 
 8410            ? config->useColour()
 
 8416            : NoColourImpl::instance();
 
 8422#elif defined( CATCH_CONFIG_COLOUR_ANSI )  
 8433    class PosixColourImpl : 
public IColourImpl {
 
 8435        void use( Colour::Code _colourCode )
 override {
 
 8436            switch( _colourCode ) {
 
 8438                case Colour::White:     
return setColour( 
"[0m" );
 
 8439                case Colour::Red:       
return setColour( 
"[0;31m" );
 
 8440                case Colour::Green:     
return setColour( 
"[0;32m" );
 
 8441                case Colour::Blue:      
return setColour( 
"[0;34m" );
 
 8442                case Colour::Cyan:      
return setColour( 
"[0;36m" );
 
 8443                case Colour::Yellow:    
return setColour( 
"[0;33m" );
 
 8444                case Colour::Grey:      
return setColour( 
"[1;30m" );
 
 8446                case Colour::LightGrey:     
return setColour( 
"[0;37m" );
 
 8447                case Colour::BrightRed:     
return setColour( 
"[1;31m" );
 
 8448                case Colour::BrightGreen:   
return setColour( 
"[1;32m" );
 
 8449                case Colour::BrightWhite:   
return setColour( 
"[1;37m" );
 
 8450                case Colour::BrightYellow:  
return setColour( 
"[1;33m" );
 
 8456        static IColourImpl* instance() {
 
 8457            static PosixColourImpl s_instance;
 
 8462        void setColour( 
const char* _escapeCode ) {
 
 8464                << 
'\033' << _escapeCode;
 
 8468    bool useColourOnPlatform() {
 
 8470#ifdef CATCH_PLATFORM_MAC 
 8471            !isDebuggerActive() &&
 
 8473#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__)) 
 8474            isatty(STDOUT_FILENO)
 
 8480    IColourImpl* platformColourInstance() {
 
 8484            ? config->useColour()
 
 8487            colourMode = useColourOnPlatform()
 
 8491            ? PosixColourImpl::instance()
 
 8492            : NoColourImpl::instance();
 
 8502    static IColourImpl* platformColourInstance() { 
return NoColourImpl::instance(); }
 
 8510    Colour::Colour( Code _colourCode ) { use( _colourCode ); }
 
 8511    Colour::Colour( Colour&& rhs ) 
noexcept {
 
 8512        m_moved = rhs.m_moved;
 
 8515    Colour& Colour::operator=( Colour&& rhs ) 
noexcept {
 
 8516        m_moved = rhs.m_moved;
 
 8521    Colour::~Colour(){ 
if( !m_moved ) use( None ); }
 
 8523    void Colour::use( Code _colourCode ) {
 
 8524        static IColourImpl* impl = platformColourInstance();
 
 8525        impl->use( _colourCode );
 
 8534#if defined(__clang__) 
 8535#    pragma clang diagnostic pop 
 8543    class Context : 
public IMutableContext, NonCopyable {
 
 8547            return m_resultCapture;
 
 8549        IRunner* getRunner()
 override {
 
 8553        IConfigPtr const& getConfig()
 const override {
 
 8557        ~Context() 
override;
 
 8560        void setResultCapture( IResultCapture* resultCapture )
 override {
 
 8561            m_resultCapture = resultCapture;
 
 8563        void setRunner( IRunner* runner )
 override {
 
 8566        void setConfig( IConfigPtr 
const& config )
 override {
 
 8574        IRunner* m_runner = 
nullptr;
 
 8575        IResultCapture* m_resultCapture = 
nullptr;
 
 8591    Context::~Context() = 
default;
 
 8601    void writeToDebugConsole( 
std::string const& text );
 
 8605#ifdef CATCH_PLATFORM_WINDOWS 
 8608        void writeToDebugConsole( 
std::string const& text ) {
 
 8609            ::OutputDebugStringA( text.
c_str() );
 
 8616        void writeToDebugConsole( 
std::string const& text ) {
 
 8626#ifdef CATCH_PLATFORM_MAC 
 8629#  include <stdbool.h> 
 8630#  include <sys/types.h> 
 8635#ifdef __apple_build_version__ 
 8638#  include <sys/sysctl.h> 
 8642        #ifdef __apple_build_version__ 
 8648        bool isDebuggerActive(){
 
 8650            struct kinfo_proc   
info;
 
 8656            info.kp_proc.p_flag = 0;
 
 8663            mib[2] = KERN_PROC_PID;
 
 8669            if( sysctl(mib, 
sizeof(mib) / 
sizeof(*mib), &info, &size, 
nullptr, 0) != 0 ) {
 
 8670                Catch::cerr() << 
"\n** Call to sysctl failed - unable to determine if debugger is active **\n" << 
std::endl;
 
 8676            return ( (
info.kp_proc.p_flag & P_TRACED) != 0 );
 
 8679        bool isDebuggerActive() {
 
 8686#elif defined(CATCH_PLATFORM_LINUX) 
 8698        bool isDebuggerActive(){
 
 8704                static const int PREFIX_LEN = 11;
 
 8705                if( line.
compare(0, PREFIX_LEN, 
"TracerPid:\t") == 0 ) {
 
 8709                    return line.
length() > PREFIX_LEN && line[PREFIX_LEN] != 
'0';
 
 8716#elif defined(_MSC_VER) 
 8717    extern "C" __declspec(dllimport) 
int __stdcall IsDebuggerPresent();
 
 8719        bool isDebuggerActive() {
 
 8720            return IsDebuggerPresent() != 0;
 
 8723#elif defined(__MINGW32__) 
 8724    extern "C" __declspec(dllimport) 
int __stdcall IsDebuggerPresent();
 
 8726        bool isDebuggerActive() {
 
 8727            return IsDebuggerPresent() != 0;
 
 8732       bool isDebuggerActive() { 
return false; }
 
 8743        if( lhs.
size() + rhs.
size() < 40 &&
 
 8744                lhs.
find(
'\n') == std::string::npos &&
 
 8745                rhs.
find(
'\n') == std::string::npos )
 
 8746            os << lhs << 
" " << op << 
" " << rhs;
 
 8748            os << lhs << 
"\n" << op << 
"\n" << rhs;
 
 8755#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER) 
 8758        Catch::cerr() << 
"Catch will terminate because it needed to throw an exception.\n" 
 8759                      << 
"The message was: " << e.
what() << 
'\n';
 
 8777        class EnumValuesRegistry : 
public IMutableEnumValuesRegistry {
 
 8781            EnumInfo 
const& registerEnum( StringRef enumName, StringRef allEnums, 
std::vector<int> const& values) 
override;
 
 8804            parsed.
reserve( enumValues.size() );
 
 8805            for( 
auto const& enumValue : enumValues ) {
 
 8815            for( 
auto const& valueToName : 
m_values ) {
 
 8816                if( valueToName.first == 
value )
 
 8817                    return valueToName.second;
 
 8819            return "{** unexpected enum value **}";
 
 8824            enumInfo->m_name = enumName;
 
 8825            enumInfo->m_values.reserve( 
values.size() );
 
 8827            const auto valueNames = Catch::Detail::parseEnums( allValueNames );
 
 8828            assert( valueNames.size() == 
values.size() );
 
 8831                enumInfo->m_values.push_back({ 
value, valueNames[i++] });
 
 8836        EnumInfo 
const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, 
std::vector<int> const& values ) {
 
 8837            auto enumInfo = makeEnumInfo( enumName, allValueNames, values );
 
 8838            EnumInfo* raw = enumInfo.get();
 
 8839            m_enumInfos.push_back( std::move( enumInfo ) );
 
 8852        ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
 
 8853        ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
 
 8866    class ExceptionTranslatorRegistry : 
public IExceptionTranslatorRegistry {
 
 8868        ~ExceptionTranslatorRegistry();
 
 8869        virtual void registerTranslator( 
const IExceptionTranslator* translator );
 
 8880#import "Foundation/Foundation.h" 
 8885    ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
 
 8888    void ExceptionTranslatorRegistry::registerTranslator( 
const IExceptionTranslator* translator ) {
 
 8892#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 
 8893    std::string ExceptionTranslatorRegistry::translateActiveException()
 const {
 
 8898                return tryTranslators();
 
 8900            @catch (NSException *exception) {
 
 8913                return "Non C++ exception. Possibly a CLR exception.";
 
 8915            return tryTranslators();
 
 8918        catch( TestFailureException& ) {
 
 8927        catch( 
const char* msg ) {
 
 8931            return "Unknown exception";
 
 8935    std::string ExceptionTranslatorRegistry::tryTranslators()
 const {
 
 8936        if (m_translators.empty()) {
 
 8939            return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
 
 8944    std::string ExceptionTranslatorRegistry::translateActiveException()
 const {
 
 8945        CATCH_INTERNAL_ERROR(
"Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
 
 8948    std::string ExceptionTranslatorRegistry::tryTranslators()
 const {
 
 8949        CATCH_INTERNAL_ERROR(
"Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
 
 8957#if defined(__GNUC__) 
 8958#    pragma GCC diagnostic push 
 8959#    pragma GCC diagnostic ignored "-Wmissing-field-initializers" 
 8962#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS ) 
 8966    void reportFatal( 
char const * 
const message ) {
 
 8973#if defined( CATCH_CONFIG_WINDOWS_SEH ) 
 8976    struct SignalDefs { DWORD id; 
const char* 
name; };
 
 8981    static SignalDefs signalDefs[] = {
 
 8982        { 
static_cast<DWORD
>(EXCEPTION_ILLEGAL_INSTRUCTION),  
"SIGILL - Illegal instruction signal" },
 
 8983        { 
static_cast<DWORD
>(EXCEPTION_STACK_OVERFLOW), 
"SIGSEGV - Stack overflow" },
 
 8984        { 
static_cast<DWORD
>(EXCEPTION_ACCESS_VIOLATION), 
"SIGSEGV - Segmentation violation signal" },
 
 8985        { 
static_cast<DWORD
>(EXCEPTION_INT_DIVIDE_BY_ZERO), 
"Divide by zero error" },
 
 8988    LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
 
 8989        for (
auto const& def : signalDefs) {
 
 8990            if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
 
 8991                reportFatal(def.name);
 
 8996        return EXCEPTION_CONTINUE_SEARCH;
 
 8999    FatalConditionHandler::FatalConditionHandler() {
 
 9003        guaranteeSize = 32 * 1024;
 
 9004        exceptionHandlerHandle = 
nullptr;
 
 9006        exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
 
 9008        SetThreadStackGuarantee(&guaranteeSize);
 
 9011    void FatalConditionHandler::reset() {
 
 9013            RemoveVectoredExceptionHandler(exceptionHandlerHandle);
 
 9014            SetThreadStackGuarantee(&guaranteeSize);
 
 9015            exceptionHandlerHandle = 
nullptr;
 
 9020    FatalConditionHandler::~FatalConditionHandler() {
 
 9024bool FatalConditionHandler::isSet = 
false;
 
 9025ULONG FatalConditionHandler::guaranteeSize = 0;
 
 9026PVOID FatalConditionHandler::exceptionHandlerHandle = 
nullptr;
 
 9030#elif defined( CATCH_CONFIG_POSIX_SIGNALS ) 
 9041    constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
 
 9043    static SignalDefs signalDefs[] = {
 
 9044        { SIGINT,  
"SIGINT - Terminal interrupt signal" },
 
 9045        { SIGILL,  
"SIGILL - Illegal instruction signal" },
 
 9046        { SIGFPE,  
"SIGFPE - Floating point error signal" },
 
 9047        { SIGSEGV, 
"SIGSEGV - Segmentation violation signal" },
 
 9048        { SIGTERM, 
"SIGTERM - Termination request signal" },
 
 9049        { SIGABRT, 
"SIGABRT - Abort (abnormal termination) signal" }
 
 9052    void FatalConditionHandler::handleSignal( 
int sig ) {
 
 9053        char const * 
name = 
"<unknown signal>";
 
 9054        for (
auto const& def : signalDefs) {
 
 9055            if (sig == def.id) {
 
 9065    FatalConditionHandler::FatalConditionHandler() {
 
 9068        sigStack.ss_sp = altStackMem;
 
 9069        sigStack.ss_size = sigStackSize;
 
 9070        sigStack.ss_flags = 0;
 
 9071        sigaltstack(&sigStack, &oldSigStack);
 
 9072        struct sigaction sa = { };
 
 9074        sa.sa_handler = handleSignal;
 
 9075        sa.sa_flags = SA_ONSTACK;
 
 9076        for (
std::size_t i = 0; i < 
sizeof(signalDefs)/
sizeof(SignalDefs); ++i) {
 
 9077            sigaction(signalDefs[i].
id, &sa, &oldSigActions[i]);
 
 9081    FatalConditionHandler::~FatalConditionHandler() {
 
 9085    void FatalConditionHandler::reset() {
 
 9088            for( 
std::size_t i = 0; i < 
sizeof(signalDefs)/
sizeof(SignalDefs); ++i ) {
 
 9089                sigaction(signalDefs[i].
id, &oldSigActions[i], 
nullptr);
 
 9092            sigaltstack(&oldSigStack, 
nullptr);
 
 9097    bool FatalConditionHandler::isSet = 
false;
 
 9098    struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
 
 9099    stack_t FatalConditionHandler::oldSigStack = {};
 
 9100    char FatalConditionHandler::altStackMem[sigStackSize] = {};
 
 9107    void FatalConditionHandler::reset() {}
 
 9112#if defined(__GNUC__) 
 9113#    pragma GCC diagnostic pop 
 9128    void seedRng( IConfig 
const& config );
 
 9145namespace Generators {
 
 9188    class ListeningReporter : 
public IStreamingReporter {
 
 9190        Reporters m_listeners;
 
 9191        IStreamingReporterPtr m_reporter = 
nullptr;
 
 9192        ReporterPreferences m_preferences;
 
 9195        ListeningReporter();
 
 9197        void addListener( IStreamingReporterPtr&& listener );
 
 9198        void addReporter( IStreamingReporterPtr&& reporter );
 
 9202        ReporterPreferences getPreferences() 
const override;
 
 9204        void noMatchingTestCases( 
std::string const& spec ) 
override;
 
 9208        void benchmarkStarting( BenchmarkInfo 
const& benchmarkInfo ) 
override;
 
 9209        void benchmarkEnded( BenchmarkStats 
const& benchmarkStats ) 
override;
 
 9211        void testRunStarting( TestRunInfo 
const& testRunInfo ) 
override;
 
 9212        void testGroupStarting( GroupInfo 
const& groupInfo ) 
override;
 
 9213        void testCaseStarting( TestCaseInfo 
const& testInfo ) 
override;
 
 9214        void sectionStarting( SectionInfo 
const& sectionInfo ) 
override;
 
 9215        void assertionStarting( AssertionInfo 
const& assertionInfo ) 
override;
 
 9218        bool assertionEnded( AssertionStats 
const& assertionStats ) 
override;
 
 9219        void sectionEnded( SectionStats 
const& sectionStats ) 
override;
 
 9220        void testCaseEnded( TestCaseStats 
const& testCaseStats ) 
override;
 
 9221        void testGroupEnded( TestGroupStats 
const& testGroupStats ) 
override;
 
 9222        void testRunEnded( TestRunStats 
const& testRunStats ) 
override;
 
 9224        void skipTest( TestCaseInfo 
const& testInfo ) 
override;
 
 9225        bool isMulti() 
const override;
 
 9234    ReporterConfig::ReporterConfig( 
IConfigPtr const& _fullConfig )
 
 9235    :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
 
 9238    :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
 
 9240    std::ostream& ReporterConfig::stream()
 const { 
return *m_stream; }
 
 9241    IConfigPtr ReporterConfig::fullConfig()
 const { 
return m_fullConfig; }
 
 9243    TestRunInfo::TestRunInfo( 
std::string const& _name ) : 
name( _name ) {}
 
 9249        groupIndex( _groupIndex ),
 
 9250        groupsCounts( _groupsCount )
 
 9253     AssertionStats::AssertionStats( AssertionResult 
const& _assertionResult,
 
 9255                                     Totals 
const& _totals )
 
 9256    :   assertionResult( _assertionResult ),
 
 9257        infoMessages( _infoMessages ),
 
 9260        assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
 
 9262        if( assertionResult.hasMessage() ) {
 
 9265            MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
 
 9266            builder << assertionResult.getMessage();
 
 9267            builder.m_info.message = builder.m_stream.str();
 
 9269            infoMessages.push_back( builder.m_info );
 
 9273     AssertionStats::~AssertionStats() = 
default;
 
 9275    SectionStats::SectionStats(  SectionInfo 
const& _sectionInfo,
 
 9276                                 Counts 
const& _assertions,
 
 9277                                 double _durationInSeconds,
 
 9278                                 bool _missingAssertions )
 
 9279    :   sectionInfo( _sectionInfo ),
 
 9280        assertions( _assertions ),
 
 9281        durationInSeconds( _durationInSeconds ),
 
 9282        missingAssertions( _missingAssertions )
 
 9285    SectionStats::~SectionStats() = 
default;
 
 9287    TestCaseStats::TestCaseStats(  TestCaseInfo 
const& _testInfo,
 
 9288                                   Totals 
const& _totals,
 
 9292    : testInfo( _testInfo ),
 
 9296        aborting( _aborting )
 
 9299    TestCaseStats::~TestCaseStats() = 
default;
 
 9301    TestGroupStats::TestGroupStats( GroupInfo 
const& _groupInfo,
 
 9302                                    Totals 
const& _totals,
 
 9304    :   groupInfo( _groupInfo ),
 
 9306        aborting( _aborting )
 
 9309    TestGroupStats::TestGroupStats( GroupInfo 
const& _groupInfo )
 
 9310    :   groupInfo( _groupInfo ),
 
 9314    TestGroupStats::~TestGroupStats() = 
default;
 
 9316    TestRunStats::TestRunStats(   TestRunInfo 
const& _runInfo,
 
 9317                    Totals 
const& _totals,
 
 9319    :   runInfo( _runInfo ),
 
 9321        aborting( _aborting )
 
 9324    TestRunStats::~TestRunStats() = 
default;
 
 9326    void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
 
 9327    bool IStreamingReporter::isMulti()
 const { 
return false; }
 
 9329    IReporterFactory::~IReporterFactory() = 
default;
 
 9330    IReporterRegistry::~IReporterRegistry() = 
default;
 
 9349#ifdef CATCH_CONFIG_WINDOWS_CRTDBG 
 9354    LeakDetector::LeakDetector() {
 
 9355        int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
 
 9356        flag |= _CRTDBG_LEAK_CHECK_DF;
 
 9357        flag |= _CRTDBG_ALLOC_MEM_DF;
 
 9358        _CrtSetDbgFlag(flag);
 
 9359        _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
 
 9360        _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
 
 9362        _CrtSetBreakAlloc(-1);
 
 9368    Catch::LeakDetector::LeakDetector() {}
 
 9372Catch::LeakDetector::~LeakDetector() {
 
 9386    std::size_t listTestsNamesOnly( Config 
const& config );
 
 9408    using namespace clara::TextFlow;
 
 9419        TestSpec testSpec = config.testSpec();
 
 9420        if( config.hasTestFilters() )
 
 9427        for( 
auto const& testCaseInfo : matchedTestCases ) {
 
 9428            Colour::Code colour = testCaseInfo.isHidden()
 
 9429                ? Colour::SecondaryText
 
 9431            Colour colourGuard( colour );
 
 9433            Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << 
"\n";
 
 9436                std::string description = testCaseInfo.description;
 
 9437                if( description.
empty() )
 
 9438                    description = 
"(NO DESCRIPTION)";
 
 9441            if( !testCaseInfo.tags.empty() )
 
 9442                Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << 
"\n";
 
 9445        if( !config.hasTestFilters() )
 
 9448            Catch::cout() << pluralise( matchedTestCases.size(), 
"matching test case" ) << 
'\n' << 
std::endl;
 
 9449        return matchedTestCases.size();
 
 9452    std::size_t listTestsNamesOnly( Config 
const& config ) {
 
 9453        TestSpec testSpec = config.testSpec();
 
 9456        for( 
auto const& testCaseInfo : matchedTestCases ) {
 
 9466        return matchedTests;
 
 9469    void TagInfo::add( 
std::string const& spelling ) {
 
 9471        spellings.insert( spelling );
 
 9476        for( 
auto const& spelling : spellings )
 
 9477            out += 
"[" + spelling + 
"]";
 
 9482        TestSpec testSpec = config.testSpec();
 
 9483        if( config.hasTestFilters() )
 
 9484            Catch::cout() << 
"Tags for matching test cases:\n";
 
 9492        for( 
auto const& testCase : matchedTestCases ) {
 
 9493            for( 
auto const& tagName : testCase.getTestCaseInfo().tags ) {
 
 9495                auto countIt = tagCounts.
find( lcaseTagName );
 
 9496                if( countIt == tagCounts.
end() )
 
 9498                countIt->second.add( tagName );
 
 9502        for( 
auto const& tagCount : tagCounts ) {
 
 9503            ReusableStringStream rss;
 
 9504            rss << 
"  " << 
std::setw(2) << tagCount.second.count << 
"  ";
 
 9505            auto str = rss.str();
 
 9506            auto wrapper = Column( tagCount.second.all() )
 
 9508                                                    .indent( str.size() )
 
 9509                                                    .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
 
 9513        return tagCounts.
size();
 
 9520        for( 
auto const& factoryKvp : factories )
 
 9523        for( 
auto const& factoryKvp : factories ) {
 
 9525                    << Column( factoryKvp.first + 
":" )
 
 9527                            .
width( 5+maxNameLen )
 
 9528                    +  Column( factoryKvp.second->getDescription() )
 
 9531                            .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
 
 9535        return factories.size();
 
 9539        Option<std::size_t> listedCount;
 
 9541        if( config->listTests() )
 
 9542            listedCount = listedCount.valueOr(0) + listTests( *config );
 
 9543        if( config->listTestNamesOnly() )
 
 9544            listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );
 
 9545        if( config->listTags() )
 
 9546            listedCount = listedCount.valueOr(0) + listTags( *config );
 
 9547        if( config->listReporters() )
 
 9548            listedCount = listedCount.valueOr(0) + listReporters();
 
 9571using namespace Matchers;
 
 9572using Matchers::Impl::MatcherBase;
 
 9581    bool isnan(
float f);
 
 9582    bool isnan(
double d);
 
 9591    template <
typename T>
 
 9593#if defined(CATCH_CONFIG_CPP11_TO_STRING) 
 9596        ReusableStringStream rss;
 
 9611enum class FloatingPointKind : uint8_t {
 
 9621template <
typename T>
 
 9625struct Converter<float> {
 
 9626    static_assert(
sizeof(float) == 
sizeof(int32_t), 
"Important ULP matcher assumption violated");
 
 9627    Converter(
float f) {
 
 9634struct Converter<double> {
 
 9635    static_assert(
sizeof(double) == 
sizeof(int64_t), 
"Important ULP matcher assumption violated");
 
 9636    Converter(
double d) {
 
 9642template <
typename T>
 
 9643auto convert(
T t) -> Converter<T> {
 
 9644    return Converter<T>(t);
 
 9647template <
typename FP>
 
 9648bool almostEqualUlps(FP lhs, FP rhs, 
int maxUlpDiff) {
 
 9651    if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
 
 9655    auto lc = convert(lhs);
 
 9656    auto rc = convert(rhs);
 
 9658    if ((lc.i < 0) != (rc.i < 0)) {
 
 9663    auto ulpDiff = 
std::abs(lc.i - rc.i);
 
 9664    return ulpDiff <= maxUlpDiff;
 
 9673        :m_target{ target }, m_margin{ margin } {
 
 9674        CATCH_ENFORCE(margin >= 0, 
"Invalid margin: " << margin << 
'.' 
 9675            << 
" Margin has to be non-negative.");
 
 9680    bool WithinAbsMatcher::match(
double const& matchee)
 const {
 
 9681        return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
 
 9685        return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
 
 9688    WithinUlpsMatcher::WithinUlpsMatcher(
double target, 
int ulps, FloatingPointKind baseType)
 
 9689        :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
 
 9690        CATCH_ENFORCE(ulps >= 0, 
"Invalid ULP setting: " << ulps << 
'.' 
 9691            << 
" ULPs have to be non-negative.");
 
 9694#if defined(__clang__) 
 9695#pragma clang diagnostic push 
 9697#pragma clang diagnostic ignored "-Wunreachable-code" 
 9700    bool WithinUlpsMatcher::match(
double const& matchee)
 const {
 
 9702        case FloatingPointKind::Float:
 
 9703            return almostEqualUlps<float>(
static_cast<float>(matchee), 
static_cast<float>(m_target), m_ulps);
 
 9704        case FloatingPointKind::Double:
 
 9705            return almostEqualUlps<double>(matchee, m_target, m_ulps);
 
 9711#if defined(__clang__) 
 9712#pragma clang diagnostic pop 
 9716        return "is within " + 
Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
 
 9721Floating::WithinUlpsMatcher 
WithinULP(
double target, 
int maxUlpDiff) {
 
 9722    return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
 
 9725Floating::WithinUlpsMatcher 
WithinULP(
float target, 
int maxUlpDiff) {
 
 9726    return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
 
 9729Floating::WithinAbsMatcher 
WithinAbs(
double target, 
double margin) {
 
 9730    return Floating::WithinAbsMatcher(target, margin);
 
 9741        return "matches undescribed predicate";
 
 9743        return "matches predicate: \"" + desc + '"';
 
 9754    namespace StdString {
 
 9757        :   m_caseSensitivity( caseSensitivity ),
 
 9758            m_str( adjustString( str ) )
 
 9765        std::string CasedString::caseSensitivitySuffix()
 const {
 
 9767                   ? 
" (case insensitive)" 
 9771        StringMatcherBase::StringMatcherBase( 
std::string const& operation, CasedString 
const& comparator )
 
 9772        : m_comparator( comparator ),
 
 9773          m_operation( operation ) {
 
 9778            description.
reserve(5 + m_operation.size() + m_comparator.m_str.size() +
 
 9779                                        m_comparator.caseSensitivitySuffix().size());
 
 9780            description += m_operation;
 
 9781            description += ": \"";
 
 9782            description += m_comparator.m_str;
 
 9783            description += "\"";
 
 9784            description += m_comparator.caseSensitivitySuffix();
 
 9788        EqualsMatcher::EqualsMatcher( CasedString 
const& comparator ) : StringMatcherBase( 
"equals", comparator ) {}
 
 9790        bool EqualsMatcher::match( 
std::string const& source )
 const {
 
 9791            return m_comparator.adjustString( source ) == m_comparator.m_str;
 
 9794        ContainsMatcher::ContainsMatcher( CasedString 
const& comparator ) : StringMatcherBase( 
"contains", comparator ) {}
 
 9796        bool ContainsMatcher::match( 
std::string const& source )
 const {
 
 9797            return contains( m_comparator.adjustString( source ), m_comparator.m_str );
 
 9800        StartsWithMatcher::StartsWithMatcher( CasedString 
const& comparator ) : StringMatcherBase( 
"starts with", comparator ) {}
 
 9802        bool StartsWithMatcher::match( 
std::string const& source )
 const {
 
 9803            return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
 
 9806        EndsWithMatcher::EndsWithMatcher( CasedString 
const& comparator ) : StringMatcherBase( 
"ends with", comparator ) {}
 
 9808        bool EndsWithMatcher::match( 
std::string const& source )
 const {
 
 9809            return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
 
 9814        bool RegexMatcher::match(
std::string const& matchee)
 const {
 
 9815            auto flags = std::regex::ECMAScript; 
 
 9817                flags |= std::regex::icase;
 
 9824            return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
 
 9829    StdString::EqualsMatcher 
Equals( 
std::string const& str, CaseSensitive::Choice caseSensitivity ) {
 
 9830        return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
 
 9832    StdString::ContainsMatcher 
Contains( 
std::string const& str, CaseSensitive::Choice caseSensitivity ) {
 
 9833        return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
 
 9835    StdString::EndsWithMatcher 
EndsWith( 
std::string const& str, CaseSensitive::Choice caseSensitivity ) {
 
 9836        return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
 
 9838    StdString::StartsWithMatcher 
StartsWith( 
std::string const& str, CaseSensitive::Choice caseSensitivity ) {
 
 9839        return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
 
 9842    StdString::RegexMatcher 
Matches(
std::string const& regex, CaseSensitive::Choice caseSensitivity) {
 
 9843        return StdString::RegexMatcher(regex, caseSensitivity);
 
 9864                                SourceLineInfo 
const& _lineInfo,
 
 9866    :   macroName( _macroName ),
 
 9867        lineInfo( _lineInfo ),
 
 9869        sequence( ++globalCount )
 
 9886                                           SourceLineInfo 
const& lineInfo,
 
 9888        :m_info(macroName, lineInfo, 
type) {}
 
 9893    : m_info( builder.m_info ), m_moved()
 
 9895        m_info.message = builder.m_stream.str();
 
 9900    : m_info( old.m_info ), m_moved()
 
 9912        auto trimmed = [&] (
size_t start, 
size_t end) {
 
 9913            while (names[start] == 
',' || isspace(names[start])) {
 
 9916            while (names[end] == 
',' || isspace(names[end])) {
 
 9919            return names.substr(start, end - start + 1);
 
 9921        auto skipq = [&] (
size_t start, 
char quote) {
 
 9922            for (
auto i = start + 1; i < names.size() ; ++i) {
 
 9923                if (names[i] == quote)
 
 9925                if (names[i] == 
'\\')
 
 9933        for (
size_t pos = 0; pos < names.size(); ++pos) {
 
 9934            char c = names[pos];
 
 9952                pos = skipq(pos, c);
 
 9955                if (start != pos && openings.
size() == 0) {
 
 9956                    m_messages.emplace_back(macroName, lineInfo, resultType);
 
 9957                    m_messages.back().message = trimmed(start, pos);
 
 9958                    m_messages.back().message += " := ";
 
 9963        assert(openings.
size() == 0 && 
"Mismatched openings");
 
 9964        m_messages.emplace_back(macroName, lineInfo, resultType);
 
 9965        m_messages.back().message = trimmed(start, names.size() - 1);
 
 9966        m_messages.back().message += " := ";
 
 9968    Capturer::~Capturer() {
 
 9970            assert( m_captured == m_messages.size() );
 
 9971            for( 
size_t i = 0; i < m_captured; ++i  )
 
 9972                m_resultCapture.popScopedMessage( m_messages[i] );
 
 9977        assert( 
index < m_messages.size() );
 
 9978        m_messages[index].message += 
value;
 
 9988#ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H 
 9989#define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H 
 9997    class RedirectedStream {
 
10004        ~RedirectedStream();
 
10007    class RedirectedStdOut {
 
10008        ReusableStringStream m_rss;
 
10009        RedirectedStream m_cout;
 
10011        RedirectedStdOut();
 
10012        auto str() const -> 
std::
string;
 
10018    class RedirectedStdErr {
 
10019        ReusableStringStream m_rss;
 
10020        RedirectedStream m_cerr;
 
10021        RedirectedStream m_clog;
 
10023        RedirectedStdErr();
 
10024        auto str() const -> 
std::
string;
 
10027    class RedirectedStreams {
 
10029        RedirectedStreams(RedirectedStreams 
const&) = 
delete;
 
10030        RedirectedStreams& operator=(RedirectedStreams 
const&) = 
delete;
 
10031        RedirectedStreams(RedirectedStreams&&) = 
delete;
 
10032        RedirectedStreams& operator=(RedirectedStreams&&) = 
delete;
 
10035        ~RedirectedStreams();
 
10039        RedirectedStdOut m_redirectedStdOut;
 
10040        RedirectedStdErr m_redirectedStdErr;
 
10043#if defined(CATCH_CONFIG_NEW_CAPTURE) 
10051        TempFile(TempFile 
const&) = 
delete;
 
10052        TempFile& operator=(TempFile 
const&) = 
delete;
 
10053        TempFile(TempFile&&) = 
delete;
 
10054        TempFile& operator=(TempFile&&) = 
delete;
 
10064    #if defined(_MSC_VER) 
10065        char m_buffer[L_tmpnam] = { 0 };
 
10069    class OutputRedirect {
 
10071        OutputRedirect(OutputRedirect 
const&) = 
delete;
 
10072        OutputRedirect& operator=(OutputRedirect 
const&) = 
delete;
 
10073        OutputRedirect(OutputRedirect&&) = 
delete;
 
10074        OutputRedirect& operator=(OutputRedirect&&) = 
delete;
 
10080        int m_originalStdout = -1;
 
10081        int m_originalStderr = -1;
 
10082        TempFile m_stdoutFile;
 
10083        TempFile m_stderrFile;
 
10100#if defined(CATCH_CONFIG_NEW_CAPTURE) 
10101    #if defined(_MSC_VER) 
10105    #define fileno _fileno 
10107    #include <unistd.h>   
10114    :   m_originalStream( originalStream ),
 
10115        m_redirectionStream( redirectionStream ),
 
10116        m_prevBuf( m_originalStream.rdbuf() )
 
10118        m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
 
10121    RedirectedStream::~RedirectedStream() {
 
10122        m_originalStream.rdbuf( m_prevBuf );
 
10125    RedirectedStdOut::RedirectedStdOut() : m_cout( 
Catch::
cout(), m_rss.
get() ) {}
 
10126    auto RedirectedStdOut::str() const -> 
std::
string { 
return m_rss.str(); }
 
10128    RedirectedStdErr::RedirectedStdErr()
 
10132    auto RedirectedStdErr::str() const -> 
std::
string { 
return m_rss.str(); }
 
10135    :   m_redirectedCout(redirectedCout),
 
10136        m_redirectedCerr(redirectedCerr)
 
10139    RedirectedStreams::~RedirectedStreams() {
 
10140        m_redirectedCout += m_redirectedStdOut.str();
 
10141        m_redirectedCerr += m_redirectedStdErr.str();
 
10144#if defined(CATCH_CONFIG_NEW_CAPTURE) 
10146#if defined(_MSC_VER) 
10147    TempFile::TempFile() {
 
10148        if (tmpnam_s(m_buffer)) {
 
10151        if (
fopen_s(&m_file, m_buffer, 
"w")) {
 
10153            if (strerror_s(
buffer, errno)) {
 
10160    TempFile::TempFile() {
 
10169    TempFile::~TempFile() {
 
10174#if defined(_MSC_VER) 
10175         std::remove(m_buffer);
 
10179    FILE* TempFile::getFile() {
 
10194        m_originalStdout(dup(1)),
 
10195        m_originalStderr(dup(2)),
 
10196        m_stdoutDest(stdout_dest),
 
10197        m_stderrDest(stderr_dest) {
 
10198        dup2(fileno(m_stdoutFile.getFile()), 1);
 
10199        dup2(fileno(m_stderrFile.getFile()), 2);
 
10202    OutputRedirect::~OutputRedirect() {
 
10211        dup2(m_originalStdout, 1);
 
10212        dup2(m_originalStderr, 2);
 
10214        m_stdoutDest += m_stdoutFile.getContents();
 
10215        m_stderrDest += m_stderrFile.getContents();
 
10222#if defined(CATCH_CONFIG_NEW_CAPTURE) 
10223    #if defined(_MSC_VER) 
10236#if !defined(CATCH_CONFIG_POLYFILL_ISNAN) 
10237    bool isnan(
float f) {
 
10240    bool isnan(
double d) {
 
10245    bool isnan(
float f) {
 
10248    bool isnan(
double d) {
 
10264    void seedRng( IConfig 
const& config ) {
 
10265        if( config.rngSeed() != 0 ) {
 
10267            rng().seed( config.rngSeed() );
 
10291    bool matchTest( TestCase 
const& testCase, TestSpec 
const& testSpec, IConfig 
const& config );
 
10298    class TestRegistry : 
public ITestCaseRegistry {
 
10300        virtual ~TestRegistry() = 
default;
 
10302        virtual void registerTest( TestCase 
const& testCase );
 
10309        mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
 
10317    class TestInvokerAsFunction : 
public ITestInvoker {
 
10318        void(*m_testAsFunction)();
 
10320        TestInvokerAsFunction( 
void(*testAsFunction)() ) noexcept;
 
10322        void invoke() const override;
 
10325    std::
string extractClassName( StringRef const& classOrQualifiedMethodName );
 
10338    class ReporterRegistry : 
public IReporterRegistry {
 
10342        ~ReporterRegistry() 
override;
 
10346        void registerReporter( 
std::string const& 
name, IReporterFactoryPtr 
const& factory );
 
10347        void registerListener( IReporterFactoryPtr 
const& factory );
 
10349        FactoryMap 
const& getFactories() 
const override;
 
10350        Listeners 
const& getListeners() 
const override;
 
10353        FactoryMap m_factories;
 
10354        Listeners m_listeners;
 
10368        TagAlias(
std::string const& _tag, SourceLineInfo _lineInfo);
 
10371        SourceLineInfo lineInfo;
 
10381    class TagAliasRegistry : 
public ITagAliasRegistry {
 
10383        ~TagAliasRegistry() 
override;
 
10402    class StartupExceptionRegistry {
 
10407        std::vector<
std::exception_ptr> m_exceptions;
 
10417    struct ISingleton {
 
10418        virtual ~ISingleton();
 
10421    void addSingleton( ISingleton* singleton );
 
10422    void cleanupSingletons();
 
10424    template<
typename SingletonImplT, 
typename InterfaceT = SingletonImplT, 
typename MutableInterfaceT = InterfaceT>
 
10425    class Singleton : SingletonImplT, 
public ISingleton {
 
10427        static auto getInternal() -> Singleton* {
 
10428            static Singleton* s_instance = 
nullptr;
 
10429            if( !s_instance ) {
 
10430                s_instance = 
new Singleton;
 
10431                addSingleton( s_instance );
 
10437        static auto get() -> InterfaceT 
const& {
 
10438            return *getInternal();
 
10440        static auto getMutable() -> MutableInterfaceT& {
 
10441            return *getInternal();
 
10452        class RegistryHub : 
public IRegistryHub, 
public IMutableRegistryHub,
 
10453                            private NonCopyable {
 
10456            RegistryHub() = 
default;
 
10457            IReporterRegistry 
const& getReporterRegistry()
 const override {
 
10458                return m_reporterRegistry;
 
10460            ITestCaseRegistry 
const& getTestCaseRegistry()
 const override {
 
10461                return m_testCaseRegistry;
 
10463            IExceptionTranslatorRegistry 
const& getExceptionTranslatorRegistry()
 const override {
 
10464                return m_exceptionTranslatorRegistry;
 
10466            ITagAliasRegistry 
const& getTagAliasRegistry()
 const override {
 
10467                return m_tagAliasRegistry;
 
10469            StartupExceptionRegistry 
const& getStartupExceptionRegistry()
 const override {
 
10470                return m_exceptionRegistry;
 
10474            void registerReporter( 
std::string const& 
name, IReporterFactoryPtr 
const& factory )
 override {
 
10475                m_reporterRegistry.registerReporter( 
name, factory );
 
10477            void registerListener( IReporterFactoryPtr 
const& factory )
 override {
 
10478                m_reporterRegistry.registerListener( factory );
 
10480            void registerTest( TestCase 
const& testInfo )
 override {
 
10481                m_testCaseRegistry.registerTest( testInfo );
 
10483            void registerTranslator( 
const IExceptionTranslator* translator )
 override {
 
10484                m_exceptionTranslatorRegistry.registerTranslator( translator );
 
10486            void registerTagAlias( 
std::string const& alias, 
std::string const& tag, SourceLineInfo 
const& lineInfo )
 override {
 
10487                m_tagAliasRegistry.add( alias, tag, lineInfo );
 
10489            void registerStartupException() noexcept
 override {
 
10492            IMutableEnumValuesRegistry& getMutableEnumValuesRegistry()
 override {
 
10493                return m_enumValuesRegistry;
 
10497            TestRegistry m_testCaseRegistry;
 
10498            ReporterRegistry m_reporterRegistry;
 
10499            ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
 
10500            TagAliasRegistry m_tagAliasRegistry;
 
10501            StartupExceptionRegistry m_exceptionRegistry;
 
10502            Detail::EnumValuesRegistry m_enumValuesRegistry;
 
10506    using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
 
10509        return RegistryHubSingleton::get();
 
10512        return RegistryHubSingleton::getMutable();
 
10515        cleanupSingletons();
 
10528    ReporterRegistry::~ReporterRegistry() = 
default;
 
10530    IStreamingReporterPtr ReporterRegistry::create( 
std::string const& 
name, IConfigPtr 
const& config )
 const {
 
10531        auto it =  m_factories.find( 
name );
 
10532        if( it == m_factories.end() )
 
10534        return it->second->create( ReporterConfig( config ) );
 
10537    void ReporterRegistry::registerReporter( 
std::string const& 
name, IReporterFactoryPtr 
const& factory ) {
 
10538        m_factories.emplace(
name, factory);
 
10540    void ReporterRegistry::registerListener( IReporterFactoryPtr 
const& factory ) {
 
10541        m_listeners.push_back( factory );
 
10544    IReporterRegistry::FactoryMap 
const& ReporterRegistry::getFactories()
 const {
 
10545        return m_factories;
 
10547    IReporterRegistry::Listeners 
const& ReporterRegistry::getListeners()
 const {
 
10548        return m_listeners;
 
10557    bool isOk( ResultWas::OfType resultType ) {
 
10558        return ( resultType & ResultWas::FailureBit ) == 0;
 
10561        return flags == ResultWas::Info;
 
10564    ResultDisposition::Flags 
operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
 
10565        return static_cast<ResultDisposition::Flags
>( 
static_cast<int>( lhs ) | 
static_cast<int>( rhs ) );
 
10569    bool shouldSuppressFailure( 
int flags )      { 
return ( flags & ResultDisposition::SuppressFail ) != 0; }
 
10581    namespace Generators {
 
10582        struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
 
10585            GeneratorTracker( TestCaseTracking::NameAndLocation 
const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
 
10586            :   TrackerBase( nameAndLocation, ctx, parent )
 
10588            ~GeneratorTracker();
 
10590            static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation 
const& nameAndLocation ) {
 
10593                ITracker& currentTracker = ctx.currentTracker();
 
10594                if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
 
10595                    assert( childTracker );
 
10596                    assert( childTracker->isGeneratorTracker() );
 
10601                    currentTracker.addChild( tracker );
 
10604                if( !ctx.completedCycle() && !tracker->isComplete() ) {
 
10612            bool isGeneratorTracker()
 const override { 
return true; }
 
10613            auto hasGenerator() const -> 
bool override {
 
10614                return !!m_generator;
 
10616            void close()
 override {
 
10617                TrackerBase::close();
 
10619                if (m_runState == CompletedSuccessfully && m_generator->next()) {
 
10620                    m_children.clear();
 
10621                    m_runState = Executing;
 
10626            auto getGenerator() const -> GeneratorBasePtr const&
 override {
 
10627                return m_generator;
 
10629            void setGenerator( GeneratorBasePtr&& generator )
 override {
 
10630                m_generator = std::move( generator );
 
10633        GeneratorTracker::~GeneratorTracker() {}
 
10636    RunContext::RunContext(IConfigPtr 
const& _config, IStreamingReporterPtr&& reporter)
 
10637    :   m_runInfo(_config->
name()),
 
10640        m_reporter(
std::move(reporter)),
 
10641        m_lastAssertionInfo{ StringRef(), SourceLineInfo(
"",0), StringRef(), ResultDisposition::
Normal },
 
10642        m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
 
10644        m_context.setRunner(
this);
 
10645        m_context.setConfig(m_config);
 
10646        m_context.setResultCapture(
this);
 
10647        m_reporter->testRunStarting(m_runInfo);
 
10650    RunContext::~RunContext() {
 
10651        m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
 
10655        m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
 
10659        m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
 
10662    Totals RunContext::runTest(TestCase 
const& testCase) {
 
10663        Totals prevTotals = m_totals;
 
10668        auto const& testInfo = testCase.getTestCaseInfo();
 
10670        m_reporter->testCaseStarting(testInfo);
 
10672        m_activeTestCase = &testCase;
 
10674        ITracker& rootTracker = m_trackerContext.startRun();
 
10675        assert(rootTracker.isSectionTracker());
 
10676        static_cast<SectionTracker&
>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
 
10678            m_trackerContext.startCycle();
 
10679            m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
 
10680            runCurrentTest(redirectedCout, redirectedCerr);
 
10681        } 
while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
 
10683        Totals deltaTotals = m_totals.delta(prevTotals);
 
10684        if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
 
10685            deltaTotals.assertions.failed++;
 
10686            deltaTotals.testCases.passed--;
 
10687            deltaTotals.testCases.failed++;
 
10689        m_totals.testCases += deltaTotals.testCases;
 
10690        m_reporter->testCaseEnded(TestCaseStats(testInfo,
 
10696        m_activeTestCase = 
nullptr;
 
10697        m_testCaseTracker = 
nullptr;
 
10699        return deltaTotals;
 
10706    IStreamingReporter& RunContext::reporter()
 const {
 
10707        return *m_reporter;
 
10710    void RunContext::assertionEnded(AssertionResult 
const & result) {
 
10712            m_totals.assertions.passed++;
 
10713            m_lastAssertionPassed = 
true;
 
10714        } 
else if (!
result.isOk()) {
 
10715            m_lastAssertionPassed = 
false;
 
10716            if( m_activeTestCase->getTestCaseInfo().okToFail() )
 
10717                m_totals.assertions.failedButOk++;
 
10719                m_totals.assertions.failed++;
 
10722            m_lastAssertionPassed = 
true;
 
10727        static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
 
10730            m_messageScopes.clear();
 
10733        resetAssertionInfo();
 
10736    void RunContext::resetAssertionInfo() {
 
10737        m_lastAssertionInfo.macroName = StringRef();
 
10738        m_lastAssertionInfo.capturedExpression = 
"{Unknown expression after the reported line}"_sr;
 
10741    bool RunContext::sectionStarted(SectionInfo 
const & sectionInfo, Counts & assertions) {
 
10742        ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
 
10743        if (!sectionTracker.isOpen())
 
10745        m_activeSections.push_back(§ionTracker);
 
10747        m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
 
10749        m_reporter->sectionStarting(sectionInfo);
 
10751        assertions = m_totals.assertions;
 
10755    auto RunContext::acquireGeneratorTracker( SourceLineInfo 
const& lineInfo ) -> IGeneratorTracker& {
 
10756        using namespace Generators;
 
10757        GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( 
"generator", lineInfo ) );
 
10758        assert( tracker.isOpen() );
 
10759        m_lastAssertionInfo.lineInfo = lineInfo;
 
10763    bool RunContext::testForMissingAssertions(Counts& assertions) {
 
10764        if (assertions.total() != 0)
 
10766        if (!m_config->warnAboutMissingAssertions())
 
10768        if (m_trackerContext.currentTracker().hasChildren())
 
10770        m_totals.assertions.failed++;
 
10771        assertions.failed++;
 
10775    void RunContext::sectionEnded(SectionEndInfo 
const & endInfo) {
 
10776        Counts assertions = m_totals.assertions - endInfo.prevAssertions;
 
10777        bool missingAssertions = testForMissingAssertions(assertions);
 
10779        if (!m_activeSections.empty()) {
 
10780            m_activeSections.back()->close();
 
10781            m_activeSections.pop_back();
 
10784        m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
 
10785        m_messages.clear();
 
10786        m_messageScopes.clear();
 
10789    void RunContext::sectionEndedEarly(SectionEndInfo 
const & endInfo) {
 
10790        if (m_unfinishedSections.empty())
 
10791            m_activeSections.back()->fail();
 
10793            m_activeSections.back()->close();
 
10794        m_activeSections.pop_back();
 
10796        m_unfinishedSections.push_back(endInfo);
 
10798    void RunContext::benchmarkStarting( BenchmarkInfo 
const& info ) {
 
10799        m_reporter->benchmarkStarting( info );
 
10801    void RunContext::benchmarkEnded( BenchmarkStats 
const& stats ) {
 
10802        m_reporter->benchmarkEnded( stats );
 
10805    void RunContext::pushScopedMessage(MessageInfo 
const & message) {
 
10806        m_messages.push_back(message);
 
10809    void RunContext::popScopedMessage(MessageInfo 
const & message) {
 
10810        m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
 
10813    void RunContext::emplaceUnscopedMessage( MessageBuilder 
const& builder ) {
 
10814        m_messageScopes.emplace_back( builder );
 
10817    std::string RunContext::getCurrentTestName()
 const {
 
10818        return m_activeTestCase
 
10819            ? m_activeTestCase->getTestCaseInfo().name
 
10823    const AssertionResult * RunContext::getLastResult()
 const {
 
10824        return &(*m_lastResult);
 
10827    void RunContext::exceptionEarlyReported() {
 
10828        m_shouldReportUnexpected = 
false;
 
10831    void RunContext::handleFatalErrorCondition( StringRef message ) {
 
10833        m_reporter->fatalErrorEncountered(message);
 
10838        tempResult.message = message;
 
10839        AssertionResult 
result(m_lastAssertionInfo, tempResult);
 
10841        assertionEnded(result);
 
10843        handleUnfinishedSections();
 
10846        auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
 
10847        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
 
10850        assertions.failed = 1;
 
10851        SectionStats testCaseSectionStats(testCaseSection, assertions, 0, 
false);
 
10852        m_reporter->sectionEnded(testCaseSectionStats);
 
10854        auto const& testInfo = m_activeTestCase->getTestCaseInfo();
 
10856        Totals deltaTotals;
 
10857        deltaTotals.testCases.failed = 1;
 
10858        deltaTotals.assertions.failed = 1;
 
10859        m_reporter->testCaseEnded(TestCaseStats(testInfo,
 
10864        m_totals.testCases.failed++;
 
10866        m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, 
false));
 
10869    bool RunContext::lastAssertionPassed() {
 
10870         return m_lastAssertionPassed;
 
10873    void RunContext::assertionPassed() {
 
10874        m_lastAssertionPassed = 
true;
 
10875        ++m_totals.assertions.passed;
 
10876        resetAssertionInfo();
 
10877        m_messageScopes.clear();
 
10880    bool RunContext::aborting()
 const {
 
10881        return m_totals.assertions.failed >= 
static_cast<std::size_t>(m_config->abortAfter());
 
10885        auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
 
10886        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
 
10887        m_reporter->sectionStarting(testCaseSection);
 
10888        Counts prevAssertions = m_totals.assertions;
 
10889        double duration = 0;
 
10890        m_shouldReportUnexpected = 
true;
 
10893        seedRng(*m_config);
 
10897            if (m_reporter->getPreferences().shouldRedirectStdOut) {
 
10898#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) 
10899                RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
 
10902                invokeActiveTestCase();
 
10904                OutputRedirect r(redirectedCout, redirectedCerr);
 
10906                invokeActiveTestCase();
 
10910                invokeActiveTestCase();
 
10912            duration = timer.getElapsedSeconds();
 
10918            if( m_shouldReportUnexpected ) {
 
10919                AssertionReaction dummyReaction;
 
10923        Counts assertions = m_totals.assertions - prevAssertions;
 
10924        bool missingAssertions = testForMissingAssertions(assertions);
 
10926        m_testCaseTracker->close();
 
10927        handleUnfinishedSections();
 
10928        m_messages.clear();
 
10929        m_messageScopes.clear();
 
10931        SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
 
10932        m_reporter->sectionEnded(testCaseSectionStats);
 
10935    void RunContext::invokeActiveTestCase() {
 
10936        FatalConditionHandler fatalConditionHandler; 
 
10937        m_activeTestCase->invoke();
 
10938        fatalConditionHandler.reset();
 
10941    void RunContext::handleUnfinishedSections() {
 
10944        for (
auto it = m_unfinishedSections.rbegin(),
 
10945             itEnd = m_unfinishedSections.rend();
 
10949        m_unfinishedSections.clear();
 
10952    void RunContext::handleExpr(
 
10953        AssertionInfo 
const& info,
 
10954        ITransientExpression 
const& expr,
 
10955        AssertionReaction& reaction
 
10957        m_reporter->assertionStarting( info );
 
10960        bool result = expr.getResult() != negated;
 
10963            if (!m_includeSuccessfulResults) {
 
10972            populateReaction( reaction );
 
10975    void RunContext::reportExpr(
 
10976            AssertionInfo 
const &info,
 
10978            ITransientExpression 
const *expr,
 
10981        m_lastAssertionInfo = 
info;
 
10982        AssertionResultData 
data( resultType, LazyExpression( negated ) );
 
10984        AssertionResult assertionResult{ 
info, 
data };
 
10985        assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
 
10987        assertionEnded( assertionResult );
 
10990    void RunContext::handleMessage(
 
10991            AssertionInfo 
const& info,
 
10993            StringRef 
const& message,
 
10994            AssertionReaction& reaction
 
10996        m_reporter->assertionStarting( info );
 
10998        m_lastAssertionInfo = 
info;
 
11000        AssertionResultData 
data( resultType, LazyExpression( 
false ) );
 
11001        data.message = message;
 
11002        AssertionResult assertionResult{ m_lastAssertionInfo, 
data };
 
11003        assertionEnded( assertionResult );
 
11004        if( !assertionResult.isOk() )
 
11005            populateReaction( reaction );
 
11007    void RunContext::handleUnexpectedExceptionNotThrown(
 
11008            AssertionInfo 
const& info,
 
11009            AssertionReaction& reaction
 
11014    void RunContext::handleUnexpectedInflightException(
 
11015            AssertionInfo 
const& info,
 
11017            AssertionReaction& reaction
 
11019        m_lastAssertionInfo = 
info;
 
11022        data.message = message;
 
11023        AssertionResult assertionResult{ 
info, 
data };
 
11024        assertionEnded( assertionResult );
 
11025        populateReaction( reaction );
 
11028    void RunContext::populateReaction( AssertionReaction& reaction ) {
 
11029        reaction.shouldDebugBreak = m_config->shouldDebugBreak();
 
11033    void RunContext::handleIncomplete(
 
11034            AssertionInfo 
const& info
 
11036        m_lastAssertionInfo = 
info;
 
11039        data.message = 
"Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
 
11040        AssertionResult assertionResult{ 
info, 
data };
 
11041        assertionEnded( assertionResult );
 
11043    void RunContext::handleNonExpr(
 
11044            AssertionInfo 
const &info,
 
11046            AssertionReaction &reaction
 
11048        m_lastAssertionInfo = 
info;
 
11050        AssertionResultData 
data( resultType, LazyExpression( 
false ) );
 
11051        AssertionResult assertionResult{ 
info, 
data };
 
11052        assertionEnded( assertionResult );
 
11054        if( !assertionResult.isOk() )
 
11055            populateReaction( reaction );
 
11072        m_sectionIncluded( 
getResultCapture().sectionStarted( m_info, m_assertions ) )
 
11088    Section::operator 
bool()
 const {
 
11089        return m_sectionIncluded;
 
11099        (   SourceLineInfo 
const& _lineInfo,
 
11102        lineInfo( _lineInfo )
 
11115    class Session : NonCopyable {
 
11119        ~Session() 
override;
 
11121        void showHelp() 
const;
 
11122        void libIdentify();
 
11124        int applyCommandLine( 
int argc, 
char const * 
const * argv );
 
11125    #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) 
11126        int applyCommandLine( 
int argc, 
wchar_t const * 
const * argv );
 
11129        void useConfigData( ConfigData 
const& configData );
 
11131        template<
typename CharT>
 
11132        int run(
int argc, CharT 
const * 
const argv[]) {
 
11133            if (m_startupExceptions)
 
11135            int returnCode = applyCommandLine(argc, argv);
 
11136            if (returnCode == 0)
 
11137                returnCode = run();
 
11143        clara::Parser 
const& cli() 
const;
 
11144        void cli( clara::Parser 
const& newParser );
 
11145        ConfigData& configData();
 
11150        clara::Parser m_cli;
 
11151        ConfigData m_configData;
 
11153        bool m_startupExceptions = 
false;
 
11167        Version( Version 
const& ) = 
delete;
 
11168        Version& operator=( Version 
const& ) = 
delete;
 
11169        Version(    
unsigned int _majorVersion,
 
11170                    unsigned int _minorVersion,
 
11171                    unsigned int _patchNumber,
 
11172                    char const * 
const _branchName,
 
11173                    unsigned int _buildNumber );
 
11175        unsigned int const majorVersion;
 
11176        unsigned int const minorVersion;
 
11177        unsigned int const patchNumber;
 
11180        char const * 
const branchName;
 
11181        unsigned int const buildNumber;
 
11186    Version 
const& libraryVersion();
 
11196        const int MaxExitCode = 255;
 
11200            CATCH_ENFORCE(reporter, 
"No reporter registered with name: '" << reporterName << 
"'");
 
11207                return createReporter(config->getReporterName(), config);
 
11216            auto& multi = 
static_cast<ListeningReporter&
>(*ret);
 
11218            for (
auto const& listener : listeners) {
 
11219                multi.addListener(listener->create(Catch::ReporterConfig(config)));
 
11221            multi.addReporter(createReporter(config->getReporterName(), config));
 
11226            auto reporter = makeReporter(config);
 
11228            RunContext context(config, std::move(reporter));
 
11232            context.testGroupStarting(config->name(), 1, 1);
 
11234            TestSpec testSpec = config->testSpec();
 
11237            for (
auto const& testCase : allTestCases) {
 
11238                bool matching = (!testSpec.hasFilters() && !testCase.isHidden()) ||
 
11239                                 (testSpec.hasFilters() && 
matchTest(testCase, testSpec, *config));
 
11241                if (!context.aborting() && matching)
 
11242                    totals += context.runTest(testCase);
 
11244                    context.reporter().skipTest(testCase);
 
11247            if (config->warnAboutNoTests() && totals.testCases.total() == 0) {
 
11248                ReusableStringStream testConfig;
 
11251                for (
const auto& input : config->getTestsOrTags()) {
 
11252                    if (!first) { testConfig << 
' '; }
 
11254                    testConfig << input;
 
11257                context.reporter().noMatchingTestCases(testConfig.str());
 
11261            context.testGroupEnded(config->name(), totals, 1, 1);
 
11267            for (
auto& testCase : tests) {
 
11268                auto tags = testCase.tags;
 
11272                if (lastSlash != std::string::npos) {
 
11273                    filename.
erase(0, lastSlash);
 
11278                if (lastDot != std::string::npos) {
 
11279                    filename.
erase(lastDot);
 
11282                tags.push_back(std::move(filename));
 
11283                setTags(testCase, tags);
 
11289    Session::Session() {
 
11290        static bool alreadyInstantiated = 
false;
 
11291        if( alreadyInstantiated ) {
 
11297#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 
11299        if ( !exceptions.empty() ) {
 
11303            m_startupExceptions = 
true;
 
11304            Colour colourGuard( Colour::Red );
 
11305            Catch::cerr() << 
"Errors occurred during startup!" << 
'\n';
 
11307            for ( 
const auto& ex_ptr : exceptions ) {
 
11317        alreadyInstantiated = 
true;
 
11318        m_cli = makeCommandLineParser( m_configData );
 
11320    Session::~Session() {
 
11324    void Session::showHelp()
 const {
 
11326                << 
"\nCatch v" << libraryVersion() << 
"\n" 
11328                << 
"For more detailed usage please see the project docs\n" << 
std::endl;
 
11330    void Session::libIdentify() {
 
11338    int Session::applyCommandLine( 
int argc, 
char const * 
const * argv ) {
 
11339        if( m_startupExceptions )
 
11342        auto result = m_cli.parse( clara::Args( argc, argv ) );
 
11347                << Colour( Colour::Red )
 
11348                << 
"\nError(s) in input:\n" 
11349                << Column( 
result.errorMessage() ).indent( 2 )
 
11352            return MaxExitCode;
 
11355        if( m_configData.showHelp )
 
11357        if( m_configData.libIdentify )
 
11363#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) 
11364    int Session::applyCommandLine( 
int argc, 
wchar_t const * 
const * argv ) {
 
11366        char **utf8Argv = 
new char *[ argc ];
 
11368        for ( 
int i = 0; i < argc; ++i ) {
 
11369            int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
 
11371            utf8Argv[ i ] = 
new char[ bufSize ];
 
11373            WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
 
11376        int returnCode = applyCommandLine( argc, utf8Argv );
 
11378        for ( 
int i = 0; i < argc; ++i )
 
11379            delete [] utf8Argv[ i ];
 
11381        delete [] utf8Argv;
 
11387    void Session::useConfigData( ConfigData 
const& configData ) {
 
11388        m_configData = configData;
 
11392    int Session::run() {
 
11393        if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
 
11397        int exitCode = runInternal();
 
11398        if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
 
11399            Catch::cout() << 
"...waiting for enter/ return before exiting, with code: " << exitCode << 
std::endl;
 
11405    clara::Parser 
const& Session::cli()
 const {
 
11408    void Session::cli( clara::Parser 
const& newParser ) {
 
11411    ConfigData& Session::configData() {
 
11412        return m_configData;
 
11414    Config& Session::config() {
 
11420    int Session::runInternal() {
 
11421        if( m_startupExceptions )
 
11424        if (m_configData.showHelp || m_configData.libIdentify) {
 
11431            seedRng( *m_config );
 
11433            if( m_configData.filenamesAsTags )
 
11434                applyFilenamesAsTags( *m_config );
 
11437            if( Option<std::size_t> listed = list( m_config ) )
 
11438                return static_cast<int>( *listed );
 
11440            auto totals = runTests( m_config );
 
11444            return (
std::min) (MaxExitCode, (
std::max) (totals.error, 
static_cast<int>(totals.assertions.failed)));
 
11446#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 
11449            return MaxExitCode;
 
11465            if( !g_singletons )
 
11467            return g_singletons;
 
11471    ISingleton::~ISingleton() {}
 
11473    void addSingleton(ISingleton* singleton ) {
 
11474        getSingletons()->
push_back( singleton );
 
11476    void cleanupSingletons() {
 
11477        auto& singletons = getSingletons();
 
11478        for( 
auto singleton : *singletons )
 
11481        singletons = 
nullptr;
 
11491            m_exceptions.push_back(exception);
 
11499        return m_exceptions;
 
11517    namespace detail { 
namespace {
 
11518        template<
typename WriterF, std::
size_t bufferSize=256>
 
11520            char data[bufferSize];
 
11528            ~StreamBufImpl() noexcept {
 
11529                StreamBufImpl::sync();
 
11533            int overflow( 
int c )
 override {
 
11537                    if( pbase() == epptr() )
 
11538                        m_writer( 
std::string( 1, 
static_cast<char>( c ) ) );
 
11540                        sputc( 
static_cast<char>( c ) );
 
11545            int sync()
 override {
 
11546                if( pbase() != pptr() ) {
 
11547                    m_writer( 
std::string( pbase(), 
static_cast<std::string::size_type
>( pptr() - pbase() ) ) );
 
11548                    setp( pbase(), epptr() );
 
11556        struct OutputDebugWriter {
 
11559                writeToDebugConsole( str );
 
11565        class FileStream : 
public IStream {
 
11568            FileStream( StringRef filename ) {
 
11569                m_ofs.
open( filename.c_str() );
 
11572            ~FileStream() 
override = 
default;
 
11581        class CoutStream : 
public IStream {
 
11586            CoutStream() : m_os( 
Catch::
cout().rdbuf() ) {}
 
11587            ~CoutStream() 
override = 
default;
 
11590            std::ostream& stream()
 const override { 
return m_os; }
 
11595        class DebugOutStream : 
public IStream {
 
11600            :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
 
11601                m_os( m_streamBuf.
get() )
 
11604            ~DebugOutStream() 
override = 
default;
 
11607            std::ostream& stream()
 const override { 
return m_os; }
 
11614    auto makeStream( StringRef 
const &filename ) -> IStream 
const* {
 
11615        if( filename.
empty() )
 
11616            return new detail::CoutStream();
 
11617        else if( filename[0] == 
'%' ) {
 
11618            if( filename == 
"%debug" )
 
11619                return new detail::DebugOutStream();
 
11621                CATCH_ERROR( 
"Unrecognised stream: '" << filename << 
"'" );
 
11624            return new detail::FileStream( filename );
 
11628    struct StringStreams {
 
11634            if( m_unused.
empty() ) {
 
11636                return m_streams.
size()-1;
 
11646            m_streams[index]->copyfmt( m_referenceStream ); 
 
11652    :   m_index( Singleton<StringStreams>::getMutable().add() ),
 
11653        m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].
get() )
 
11659        Singleton<StringStreams>::getMutable().release( 
m_index );
 
11668#ifndef CATCH_CONFIG_NOSTDOUT  
11686        char toLowerCh(
char c) {
 
11687            return static_cast<char>( std::tolower( c ) );
 
11695        return !s.
empty() && s[0] == prefix;
 
11701        return !s.
empty() && s[s.size()-1] == suffix;
 
11704        return s.
find( infix ) != std::string::npos;
 
11715        static char const* whitespaceChars = 
"\n\r\t ";
 
11719        return start != std::string::npos ? str.
substr( start, 1+end-start ) : 
std::string();
 
11723        bool replaced = 
false;
 
11725        while( i != std::string::npos ) {
 
11727            str = str.
substr( 0, i ) + withThis + str.substr( i+replaceThis.
size() );
 
11728            if( i < str.
size()-withThis.
size() )
 
11729                i = str.
find( replaceThis, i+withThis.
size() );
 
11731                i = std::string::npos;
 
11739        for(
std::size_t pos = 0; pos < str.size(); ++pos ) {
 
11740            if( str[pos] == delimiter ) {
 
11741                if( pos - start > 1 )
 
11742                    subStrings.
push_back( str.substr( start, pos-start ) );
 
11746        if( start < str.size() )
 
11747            subStrings.
push_back( str.substr( start, str.size()-start ) );
 
11752    :   m_count( 
count ),
 
11757        os << pluraliser.m_count << 
' ' << pluraliser.m_label;
 
11758        if( pluraliser.m_count != 1 )
 
11767#if defined(__clang__) 
11768#    pragma clang diagnostic push 
11769#    pragma clang diagnostic ignored "-Wexit-time-destructors" 
11777    const uint32_t byte_2_lead = 0xC0;
 
11778    const uint32_t byte_3_lead = 0xE0;
 
11779    const uint32_t byte_4_lead = 0xF0;
 
11809        return m_data != 
nullptr;
 
11812        return m_start[m_size] != 
'\0';
 
11817            m_data = 
new char[m_size+1];
 
11822    auto StringRef::substr( size_type start, size_type size ) 
const noexcept -> StringRef {
 
11823        if( start < m_size )
 
11824            return StringRef( m_start+start, size );
 
11826            return StringRef();
 
11830            size() == other.size() &&
 
11838        return m_start[index];
 
11846            if( ( c & byte_2_lead ) == byte_2_lead ) {
 
11848                if (( c & byte_3_lead ) == byte_3_lead )
 
11850                if( ( c & byte_4_lead ) == byte_4_lead )
 
11857    auto operator + ( StringRef 
const& lhs, StringRef 
const& rhs ) -> 
std::string {
 
11859        str.
reserve( lhs.size() + rhs.size() );
 
11864    auto operator + ( StringRef 
const& lhs, 
const char* rhs ) -> 
std::string {
 
11867    auto operator + ( 
char const* lhs, StringRef 
const& rhs ) -> 
std::string {
 
11872        return os.
write(str.currentData(), str.
size());
 
11876        lhs.
append(rhs.currentData(), rhs.size());
 
11882#if defined(__clang__) 
11883#    pragma clang diagnostic pop 
11889    TagAlias::TagAlias(
std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
 
11913    TagAliasRegistry::~TagAliasRegistry() {}
 
11915    TagAlias 
const* TagAliasRegistry::find( 
std::string const& alias )
 const {
 
11916        auto it = m_registry.find( alias );
 
11917        if( it != m_registry.end() )
 
11918            return &(it->second);
 
11924        std::string expandedTestSpec = unexpandedTestSpec;
 
11925        for( 
auto const& registryKvp : m_registry ) {
 
11927            if( pos != std::string::npos ) {
 
11928                expandedTestSpec =  expandedTestSpec.
substr( 0, pos ) +
 
11929                                    registryKvp.second.tag +
 
11930                                    expandedTestSpec.substr( pos + registryKvp.
first.
size() );
 
11933        return expandedTestSpec;
 
11936    void TagAliasRegistry::add( 
std::string const& alias, 
std::string const& tag, SourceLineInfo 
const& lineInfo ) {
 
11938                      "error: tag alias, '" << alias << 
"' is not of the form [@alias name].\n" << lineInfo );
 
11941                      "error: tag alias, '" << alias << 
"' already registered.\n" 
11942                      << 
"\tFirst seen at: " << 
find(alias)->lineInfo << 
"\n" 
11943                      << 
"\tRedefined at: " << lineInfo );
 
11946    ITagAliasRegistry::~ITagAliasRegistry() {}
 
11948    ITagAliasRegistry 
const& ITagAliasRegistry::get() {
 
11968            else if( tag == 
"!throws" )
 
11970            else if( tag == 
"!shouldfail" )
 
11972            else if( tag == 
"!mayfail" )
 
11974            else if( tag == 
"!nonportable" )
 
11976            else if( tag == 
"!benchmark" )
 
11984        void enforceNotReservedTag( 
std::string const& tag, SourceLineInfo 
const& _lineInfo ) {
 
11986                          "Tag name: [" << tag << 
"] is not allowed.\n" 
11987                          << 
"Tag names starting with non alphanumeric characters are reserved\n" 
11994                            NameAndTags 
const& nameAndTags,
 
11995                            SourceLineInfo 
const& _lineInfo )
 
11997        bool isHidden = 
false;
 
12002        bool inTag = 
false;
 
12004        for (
char c : _descOrTags) {
 
12017                        enforceNotReservedTag( tag, _lineInfo );
 
12037        TestCaseInfo 
info( nameAndTags.name, _className, desc, tags, _lineInfo );
 
12038        return TestCase( _testCase, std::move(info) );
 
12044        testCaseInfo.lcaseTags.clear();
 
12046        for( 
auto const& tag : tags ) {
 
12049            testCaseInfo.lcaseTags.push_back( lcaseTag );
 
12051        testCaseInfo.tags = std::move(tags);
 
12058                                SourceLineInfo 
const& _lineInfo )
 
12060        className( _className ),
 
12061        description( _description ),
 
12062        lineInfo( _lineInfo ),
 
12065        setTags( *
this, _tags );
 
12085        for (
const auto& tag : 
tags) {
 
12086            full_size += tag.
size();
 
12089        for (
const auto& tag : 
tags) {
 
12098    TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( 
std::move(
info) ), test( testCase ) {}
 
12102        other.name = _newName;
 
12111        return  test.get() == other.test.get() &&
 
12112                name == other.name &&
 
12117        return name < other.name;
 
12137        switch( config.runOrder() ) {
 
12151    bool matchTest( TestCase 
const& testCase, TestSpec 
const& testSpec, IConfig 
const& config ) {
 
12152        return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
 
12157        for( 
auto const& function : functions ) {
 
12158            auto prev = seenFunctions.
insert( function );
 
12160                    "error: TEST_CASE( \"" << function.name << 
"\" ) already defined.\n" 
12161                    << 
"\tFirst seen at " << 
prev.first->getTestCaseInfo().lineInfo << 
"\n" 
12162                    << 
"\tRedefined at " << function.getTestCaseInfo().lineInfo );
 
12169        for (
auto const& testCase : testCases) {
 
12170            if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
 
12171                (testSpec.hasFilters() && 
matchTest(testCase, testSpec, config))) {
 
12181    void TestRegistry::registerTest( TestCase 
const& testCase ) {
 
12183        if( 
name.empty() ) {
 
12184            ReusableStringStream rss;
 
12185            rss << 
"Anonymous test case " << ++m_unnamedCount;
 
12186            return registerTest( testCase.withName( rss.str() ) );
 
12188        m_functions.push_back( testCase );
 
12192        return m_functions;
 
12195        if( m_sortedFunctions.empty() )
 
12196            enforceNoDuplicateTestCases( m_functions );
 
12198        if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
 
12199            m_sortedFunctions = sortTests( config, m_functions );
 
12200            m_currentSortOrder = config.runOrder();
 
12202        return m_sortedFunctions;
 
12206    TestInvokerAsFunction::TestInvokerAsFunction( 
void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
 
12208    void TestInvokerAsFunction::invoke()
 const {
 
12209        m_testAsFunction();
 
12212    std::string extractClassName( StringRef 
const& classOrQualifiedMethodName ) {
 
12213        std::string className = classOrQualifiedMethodName;
 
12218            if( penultimateColons == std::string::npos )
 
12219                penultimateColons = 1;
 
12220            className = className.
substr( penultimateColons, lastColons-penultimateColons );
 
12235#if defined(__clang__) 
12236#    pragma clang diagnostic push 
12237#    pragma clang diagnostic ignored "-Wexit-time-destructors" 
12241namespace TestCaseTracking {
 
12243    NameAndLocation::NameAndLocation( 
std::string const& _name, SourceLineInfo 
const& _location )
 
12245        location( _location )
 
12248    ITracker::~ITracker() = 
default;
 
12250    ITracker& TrackerContext::startRun() {
 
12252        m_currentTracker = 
nullptr;
 
12253        m_runState = Executing;
 
12254        return *m_rootTracker;
 
12257    void TrackerContext::endRun() {
 
12258        m_rootTracker.reset();
 
12259        m_currentTracker = 
nullptr;
 
12260        m_runState = NotStarted;
 
12263    void TrackerContext::startCycle() {
 
12264        m_currentTracker = m_rootTracker.get();
 
12265        m_runState = Executing;
 
12267    void TrackerContext::completeCycle() {
 
12268        m_runState = CompletedCycle;
 
12271    bool TrackerContext::completedCycle()
 const {
 
12272        return m_runState == CompletedCycle;
 
12274    ITracker& TrackerContext::currentTracker() {
 
12275        return *m_currentTracker;
 
12277    void TrackerContext::setCurrentTracker( ITracker* tracker ) {
 
12278        m_currentTracker = tracker;
 
12281    TrackerBase::TrackerBase( NameAndLocation 
const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
 
12282    :   m_nameAndLocation( nameAndLocation ),
 
12287    NameAndLocation 
const& TrackerBase::nameAndLocation()
 const {
 
12288        return m_nameAndLocation;
 
12290    bool TrackerBase::isComplete()
 const {
 
12291        return m_runState == CompletedSuccessfully || m_runState == Failed;
 
12293    bool TrackerBase::isSuccessfullyCompleted()
 const {
 
12294        return m_runState == CompletedSuccessfully;
 
12296    bool TrackerBase::isOpen()
 const {
 
12297        return m_runState != NotStarted && !isComplete();
 
12299    bool TrackerBase::hasChildren()
 const {
 
12300        return !m_children.empty();
 
12303    void TrackerBase::addChild( ITrackerPtr 
const& child ) {
 
12304        m_children.push_back( child );
 
12307    ITrackerPtr TrackerBase::findChild( NameAndLocation 
const& nameAndLocation ) {
 
12308        auto it = 
std::find_if( m_children.begin(), m_children.end(),
 
12309            [&nameAndLocation]( ITrackerPtr 
const& tracker ){
 
12311                    tracker->nameAndLocation().location == nameAndLocation.location &&
 
12312                    tracker->nameAndLocation().name == nameAndLocation.name;
 
12314        return( it != m_children.end() )
 
12318    ITracker& TrackerBase::parent() {
 
12319        assert( m_parent ); 
 
12323    void TrackerBase::openChild() {
 
12324        if( m_runState != ExecutingChildren ) {
 
12325            m_runState = ExecutingChildren;
 
12327                m_parent->openChild();
 
12331    bool TrackerBase::isSectionTracker()
 const { 
return false; }
 
12332    bool TrackerBase::isGeneratorTracker()
 const { 
return false; }
 
12334    void TrackerBase::open() {
 
12335        m_runState = Executing;
 
12338            m_parent->openChild();
 
12341    void TrackerBase::close() {
 
12344        while( &m_ctx.currentTracker() != 
this )
 
12345            m_ctx.currentTracker().close();
 
12347        switch( m_runState ) {
 
12348            case NeedsAnotherRun:
 
12352                m_runState = CompletedSuccessfully;
 
12354            case ExecutingChildren:
 
12355                if( m_children.empty() || m_children.back()->isComplete() )
 
12356                    m_runState = CompletedSuccessfully;
 
12360            case CompletedSuccessfully:
 
12368        m_ctx.completeCycle();
 
12370    void TrackerBase::fail() {
 
12371        m_runState = Failed;
 
12373            m_parent->markAsNeedingAnotherRun();
 
12375        m_ctx.completeCycle();
 
12377    void TrackerBase::markAsNeedingAnotherRun() {
 
12378        m_runState = NeedsAnotherRun;
 
12381    void TrackerBase::moveToParent() {
 
12382        assert( m_parent );
 
12383        m_ctx.setCurrentTracker( m_parent );
 
12385    void TrackerBase::moveToThis() {
 
12386        m_ctx.setCurrentTracker( 
this );
 
12389    SectionTracker::SectionTracker( NameAndLocation 
const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
 
12390    :   TrackerBase( nameAndLocation, ctx, parent )
 
12393            while( !parent->isSectionTracker() )
 
12394                parent = &parent->parent();
 
12396            SectionTracker& parentSection = 
static_cast<SectionTracker&
>( *parent );
 
12397            addNextFilters( parentSection.m_filters );
 
12401    bool SectionTracker::isComplete()
 const {
 
12402        bool complete = 
true;
 
12404        if ((m_filters.empty() || m_filters[0] == 
"") ||
 
12405             std::find(m_filters.begin(), m_filters.end(),
 
12406                       m_nameAndLocation.name) != m_filters.end())
 
12407            complete = TrackerBase::isComplete();
 
12412    bool SectionTracker::isSectionTracker()
 const { 
return true; }
 
12414    SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation 
const& nameAndLocation ) {
 
12417        ITracker& currentTracker = ctx.currentTracker();
 
12418        if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
 
12419            assert( childTracker );
 
12420            assert( childTracker->isSectionTracker() );
 
12425            currentTracker.addChild( section );
 
12427        if( !ctx.completedCycle() )
 
12428            section->tryOpen();
 
12432    void SectionTracker::tryOpen() {
 
12433        if( !isComplete() && (m_filters.empty() || m_filters[0].empty() ||  m_filters[0] == m_nameAndLocation.name ) )
 
12438        if( !filters.
empty() ) {
 
12439            m_filters.push_back(
""); 
 
12440            m_filters.push_back(
""); 
 
12441            m_filters.insert( m_filters.end(), filters.
begin(), filters.
end() );
 
12445        if( filters.
size() > 1 )
 
12446            m_filters.insert( m_filters.end(), ++filters.
begin(), filters.
end() );
 
12451using TestCaseTracking::ITracker;
 
12452using TestCaseTracking::TrackerContext;
 
12453using TestCaseTracking::SectionTracker;
 
12457#if defined(__clang__) 
12458#    pragma clang diagnostic pop 
12465    auto makeTestInvoker( 
void(*testAsFunction)() ) noexcept -> ITestInvoker* {
 
12466        return new(
std::nothrow) TestInvokerAsFunction( testAsFunction );
 
12471    AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo 
const& lineInfo, StringRef 
const& classOrMethod, NameAndTags 
const& nameAndTags ) 
noexcept {
 
12477                            extractClassName( classOrMethod ),
 
12498    TestSpec::Pattern::~Pattern() = 
default;
 
12499    TestSpec::NamePattern::~NamePattern() = 
default;
 
12500    TestSpec::TagPattern::~TagPattern() = 
default;
 
12501    TestSpec::ExcludedPattern::~ExcludedPattern() = 
default;
 
12504    : m_wildcardPattern( 
toLower( 
name ), CaseSensitive::No )
 
12506    bool TestSpec::NamePattern::matches( TestCaseInfo 
const& testCase )
 const {
 
12507        return m_wildcardPattern.matches( 
toLower( testCase.name ) );
 
12510    TestSpec::TagPattern::TagPattern( 
std::string const& tag ) : m_tag( 
toLower( tag ) ) {}
 
12511    bool TestSpec::TagPattern::matches( TestCaseInfo 
const& testCase )
 const {
 
12513                         end(testCase.lcaseTags),
 
12514                         m_tag) != 
end(testCase.lcaseTags);
 
12517    TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr 
const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
 
12518    bool TestSpec::ExcludedPattern::matches( TestCaseInfo 
const& testCase )
 const { 
return !m_underlyingPattern->matches( testCase ); }
 
12520    bool TestSpec::Filter::matches( TestCaseInfo 
const& testCase )
 const {
 
12522        for( 
auto const& pattern : m_patterns ) {
 
12523            if( !pattern->matches( testCase ) )
 
12529    bool TestSpec::hasFilters()
 const {
 
12530        return !m_filters.empty();
 
12532    bool TestSpec::matches( TestCaseInfo 
const& testCase )
 const {
 
12534        for( 
auto const& filter : m_filters )
 
12535            if( 
filter.matches( testCase ) )
 
12545    TestSpecParser::TestSpecParser( ITagAliasRegistry 
const& tagAliases ) : m_tagAliases( &tagAliases ) {}
 
12547    TestSpecParser& TestSpecParser::parse( 
std::string const& 
arg ) {
 
12549        m_exclusion = 
false;
 
12550        m_start = std::string::npos;
 
12551        m_arg = m_tagAliases->expandAliases( 
arg );
 
12552        m_escapeChars.
clear();
 
12553        for( m_pos = 0; m_pos < m_arg.
size(); ++m_pos )
 
12554            visitChar( m_arg[m_pos] );
 
12555        if( m_mode == Name )
 
12556            addPattern<TestSpec::NamePattern>();
 
12559    TestSpec TestSpecParser::testSpec() {
 
12564    void TestSpecParser::visitChar( 
char c ) {
 
12565        if( m_mode == None ) {
 
12568            case '~': m_exclusion = 
true; 
return;
 
12569            case '[': 
return startNewMode( Tag, ++m_pos );
 
12570            case '"': 
return startNewMode( QuotedName, ++m_pos );
 
12571            case '\\': 
return escape();
 
12572            default: startNewMode( Name, m_pos ); 
break;
 
12575        if( m_mode == Name ) {
 
12577                addPattern<TestSpec::NamePattern>();
 
12580            else if( c == 
'[' ) {
 
12581                if( subString() == 
"exclude:" )
 
12582                    m_exclusion = 
true;
 
12584                    addPattern<TestSpec::NamePattern>();
 
12585                startNewMode( Tag, ++m_pos );
 
12587            else if( c == 
'\\' )
 
12590        else if( m_mode == EscapedName )
 
12592        else if( m_mode == QuotedName && c == 
'"' )
 
12593            addPattern<TestSpec::NamePattern>();
 
12594        else if( m_mode == Tag && c == 
']' )
 
12595            addPattern<TestSpec::TagPattern>();
 
12597    void TestSpecParser::startNewMode( Mode mode, 
std::size_t start ) {
 
12601    void TestSpecParser::escape() {
 
12602        if( m_mode == None )
 
12604        m_mode = EscapedName;
 
12607    std::string TestSpecParser::subString()
 const { 
return m_arg.
substr( m_start, m_pos - m_start ); }
 
12609    void TestSpecParser::addFilter() {
 
12610        if( !m_currentFilter.m_patterns.empty() ) {
 
12611            m_testSpec.m_filters.push_back( m_currentFilter );
 
12612            m_currentFilter = TestSpec::Filter();
 
12617        return TestSpecParser( ITagAliasRegistry::get() ).parse( 
arg ).testSpec();
 
12626static const uint64_t nanosecondsInSecond = 1000000000;
 
12635        auto estimateClockResolution() -> uint64_t {
 
12637            static const uint64_t iterations = 1000000;
 
12647                } 
while( ticks == baseTicks );
 
12649                auto delta = ticks - baseTicks;
 
12655                if (ticks > startTime + 3 * nanosecondsInSecond) {
 
12656                    return sum / ( i + 1u );
 
12662            return sum/iterations;
 
12666        static auto s_resolution = estimateClockResolution();
 
12667        return s_resolution;
 
12670    void Timer::start() {
 
12673    auto Timer::getElapsedNanoseconds() const -> uint64_t {
 
12676    auto Timer::getElapsedMicroseconds() const -> uint64_t {
 
12677        return getElapsedNanoseconds()/1000;
 
12679    auto Timer::getElapsedMilliseconds() const -> 
unsigned int {
 
12680        return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
 
12682    auto Timer::getElapsedSeconds() const -> 
double {
 
12683        return getElapsedMicroseconds()/1000000.0;
 
12690#if defined(__clang__) 
12691#    pragma clang diagnostic push 
12692#    pragma clang diagnostic ignored "-Wexit-time-destructors" 
12693#    pragma clang diagnostic ignored "-Wglobal-constructors" 
12697#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) 
12698#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER 
12711        const int hexThreshold = 255;
 
12713        struct Endianness {
 
12714            enum Arch { Big, Little };
 
12716            static Arch which() {
 
12719                    char asChar[sizeof (int)];
 
12723                return ( u.asChar[
sizeof(
int)-1] == 1 ) ? Big : Little;
 
12730        int i = 0, 
end = 
static_cast<int>( 
size ), inc = 1;
 
12731        if( Endianness::which() == Endianness::Little ) {
 
12736        unsigned char const *
bytes = 
static_cast<unsigned char const *
>(object);
 
12737        ReusableStringStream rss;
 
12739        for( ; i != 
end; i += inc )
 
12740             rss << 
std::setw(2) << static_cast<unsigned>(
bytes[i]);
 
12745template<
typename T>
 
12747    if (Catch::isnan(
value)) {
 
12751    ReusableStringStream rss;
 
12757    if( i != std::string::npos && i != d.
size()-1 ) {
 
12773        return '"' + str + '"';
 
12777    for (
char c : str) {
 
12794#ifdef CATCH_CONFIG_CPP17_STRING_VIEW 
12796    return ::Catch::Detail::stringify(
std::string{ str });
 
12802        return ::Catch::Detail::stringify(
std::string{ str });
 
12804        return{ 
"{null string}" };
 
12809        return ::Catch::Detail::stringify(
std::string{ str });
 
12811        return{ 
"{null string}" };
 
12815#ifdef CATCH_CONFIG_WCHAR 
12819    for (
auto c : wstr) {
 
12820        s += (c <= 0xff) ? static_cast<
char>(c) : '?';
 
12822    return ::Catch::Detail::stringify(s);
 
12825# ifdef CATCH_CONFIG_CPP17_STRING_VIEW 
12833        return ::Catch::Detail::stringify(
std::wstring{ str });
 
12835        return{ 
"{null string}" };
 
12840        return ::Catch::Detail::stringify(
std::wstring{ str });
 
12842        return{ 
"{null string}" };
 
12848    return ::Catch::Detail::stringify(
static_cast<long long>(
value));
 
12851    return ::Catch::Detail::stringify(
static_cast<long long>(
value));
 
12854    ReusableStringStream rss;
 
12856    if (
value > Detail::hexThreshold) {
 
12863    return ::Catch::Detail::stringify(
static_cast<unsigned long long>(
value));
 
12866    return ::Catch::Detail::stringify(
static_cast<unsigned long long>(
value));
 
12869    ReusableStringStream rss;
 
12871    if (
value > Detail::hexThreshold) {
 
12878    return b ? 
"true" : 
"false";
 
12882    if (
value == 
'\r') {
 
12884    } 
else if (
value == 
'\f') {
 
12886    } 
else if (
value == 
'\n') {
 
12888    } 
else if (
value == 
'\t') {
 
12891        return ::Catch::Detail::stringify(
static_cast<unsigned int>(
value));
 
12893        char chstr[] = 
"' '";
 
12899    return ::Catch::Detail::stringify(
static_cast<signed char>(c));
 
12902    return ::Catch::Detail::stringify(
static_cast<char>(c));
 
12909int StringMaker<float>::precision = 5;
 
12912    return fpToString(
value, precision) + 'f';
 
12915int StringMaker<double>::precision = 10;
 
12918    return fpToString(
value, precision);
 
12921std::string ratio_string<std::atto>::symbol() { 
return "a"; }
 
12922std::string ratio_string<std::femto>::symbol() { 
return "f"; }
 
12923std::string ratio_string<std::pico>::symbol() { 
return "p"; }
 
12924std::string ratio_string<std::nano>::symbol() { 
return "n"; }
 
12925std::string ratio_string<std::micro>::symbol() { 
return "u"; }
 
12926std::string ratio_string<std::milli>::symbol() { 
return "m"; }
 
12930#if defined(__clang__) 
12931#    pragma clang diagnostic pop 
12978        Totals diff = *
this - prevTotals;
 
12979        if( diff.assertions.failed > 0 )
 
12981        else if( diff.assertions.failedButOk > 0 )
 
12996#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) 
13011        (   
unsigned int _majorVersion,
 
13012            unsigned int _minorVersion,
 
13013            unsigned int _patchNumber,
 
13014            char const * 
const _branchName,
 
13015            unsigned int _buildNumber )
 
13016    :   majorVersion( _majorVersion ),
 
13017        minorVersion( _minorVersion ),
 
13018        patchNumber( _patchNumber ),
 
13019        branchName( _branchName ),
 
13020        buildNumber( _buildNumber )
 
13024        os  << version.majorVersion << 
'.' 
13025            << version.minorVersion << 
'.' 
13026            << version.patchNumber;
 
13028        if (version.branchName[0]) {
 
13029            os << 
'-' << version.branchName
 
13030               << 
'.' << version.buildNumber;
 
13035    Version 
const& libraryVersion() {
 
13036        static Version version( 2, 8, 0, 
"", 0 );
 
13048    WildcardPattern::WildcardPattern( 
std::string const& pattern,
 
13050    :   m_caseSensitivity( caseSensitivity ),
 
13051        m_pattern( adjustCase( pattern ) )
 
13054            m_pattern = m_pattern.substr( 1 );
 
13055            m_wildcard = WildcardAtStart;
 
13057        if( 
endsWith( m_pattern, 
'*' ) ) {
 
13058            m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
 
13059            m_wildcard = 
static_cast<WildcardPosition
>( m_wildcard | WildcardAtEnd );
 
13063    bool WildcardPattern::matches( 
std::string const& str )
 const {
 
13064        switch( m_wildcard ) {
 
13066                return m_pattern == adjustCase( str );
 
13067            case WildcardAtStart:
 
13068                return endsWith( adjustCase( str ), m_pattern );
 
13069            case WildcardAtEnd:
 
13070                return startsWith( adjustCase( str ), m_pattern );
 
13071            case WildcardAtBothEnds:
 
13072                return contains( adjustCase( str ), m_pattern );
 
13087using uchar = 
unsigned char;
 
13093    size_t trailingBytes(
unsigned char c) {
 
13094        if ((c & 0xE0) == 0xC0) {
 
13097        if ((c & 0xF0) == 0xE0) {
 
13100        if ((c & 0xF8) == 0xF0) {
 
13106    uint32_t headerValue(
unsigned char c) {
 
13107        if ((c & 0xE0) == 0xC0) {
 
13110        if ((c & 0xF0) == 0xE0) {
 
13113        if ((c & 0xF8) == 0xF0) {
 
13119    void hexEscapeChar(
std::ostream& os, 
unsigned char c) {
 
13120        std::ios_base::fmtflags f(os.
flags());
 
13123            << 
static_cast<int>(c);
 
13129    XmlEncode::XmlEncode( 
std::string const& str, ForWhat forWhat )
 
13131        m_forWhat( forWhat )
 
13138        for( 
std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
 
13139            uchar c = m_str[idx];
 
13141            case '<':   os << 
"<"; 
break;
 
13142            case '&':   os << 
"&"; 
break;
 
13146                if (idx > 2 && m_str[idx - 1] == 
']' && m_str[idx - 2] == 
']')
 
13153                if (m_forWhat == ForAttributes)
 
13164                if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
 
13165                    hexEscapeChar(os, c);
 
13183                    hexEscapeChar(os, c);
 
13187                auto encBytes = trailingBytes(c);
 
13189                if (idx + encBytes - 1 >= m_str.size()) {
 
13190                    hexEscapeChar(os, c);
 
13197                uint32_t 
value = headerValue(c);
 
13199                    uchar nc = m_str[idx + n];
 
13200                    valid &= ((nc & 0xC0) == 0x80);
 
13209                    (0x80 <= 
value && value < 0x800   && encBytes > 2) ||
 
13210                    (0x800 < 
value && value < 0x10000 && encBytes > 3) ||
 
13212                    (
value >= 0x110000)
 
13214                    hexEscapeChar(os, c);
 
13220                    os << m_str[idx + n];
 
13222                idx += encBytes - 1;
 
13229        xmlEncode.encodeTo( os );
 
13233    XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
 
13234    :   m_writer( writer )
 
13237    XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
 
13238    :   m_writer( other.m_writer ){
 
13239        other.m_writer = 
nullptr;
 
13241    XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) 
noexcept {
 
13243            m_writer->endElement();
 
13245        m_writer = other.m_writer;
 
13246        other.m_writer = 
nullptr;
 
13250    XmlWriter::ScopedElement::~ScopedElement() {
 
13252            m_writer->endElement();
 
13255    XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( 
std::string const& text, 
bool indent ) {
 
13256        m_writer->writeText( text, indent );
 
13262        writeDeclaration();
 
13265    XmlWriter::~XmlWriter() {
 
13266        while( !m_tags.empty() )
 
13272        newlineIfNecessary();
 
13273        m_os << m_indent << 
'<' << 
name;
 
13274        m_tags.push_back( 
name );
 
13276        m_tagIsOpen = 
true;
 
13280    XmlWriter::ScopedElement XmlWriter::scopedElement( 
std::string const& 
name ) {
 
13281        ScopedElement scoped( 
this );
 
13282        startElement( 
name );
 
13286    XmlWriter& XmlWriter::endElement() {
 
13287        newlineIfNecessary();
 
13288        m_indent = m_indent.substr( 0, m_indent.size()-2 );
 
13289        if( m_tagIsOpen ) {
 
13291            m_tagIsOpen = 
false;
 
13294            m_os << m_indent << 
"</" << m_tags.back() << 
">";
 
13302        if( !
name.empty() && !attribute.
empty() )
 
13303            m_os << 
' ' << 
name << 
"=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << 
'"';
 
13307    XmlWriter& XmlWriter::writeAttribute( 
std::string const& 
name, 
bool attribute ) {
 
13308        m_os << 
' ' << 
name << 
"=\"" << ( attribute ? 
"true" : 
"false" ) << 
'"';
 
13312    XmlWriter& XmlWriter::writeText( 
std::string const& text, 
bool indent ) {
 
13313        if( !text.
empty() ){
 
13314            bool tagWasOpen = m_tagIsOpen;
 
13316            if( tagWasOpen && indent )
 
13318            m_os << XmlEncode( text );
 
13319            m_needsNewline = 
true;
 
13324    XmlWriter& XmlWriter::writeComment( 
std::string const& text ) {
 
13326        m_os << m_indent << 
"<!--" << text << 
"-->";
 
13327        m_needsNewline = 
true;
 
13331    void XmlWriter::writeStylesheetRef( 
std::string const& url ) {
 
13332        m_os << 
"<?xml-stylesheet type=\"text/xsl\" href=\"" << url << 
"\"?>\n";
 
13335    XmlWriter& XmlWriter::writeBlankLine() {
 
13341    void XmlWriter::ensureTagClosed() {
 
13342        if( m_tagIsOpen ) {
 
13344            m_tagIsOpen = 
false;
 
13348    void XmlWriter::writeDeclaration() {
 
13349        m_os << 
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
 
13352    void XmlWriter::newlineIfNecessary() {
 
13353        if( m_needsNewline ) {
 
13355            m_needsNewline = 
false;
 
13369    void prepareExpandedExpression(AssertionResult& result) {
 
13370        result.getExpandedExpression();
 
13375    std::string getFormattedDuration( 
double duration ) {
 
13380        const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
 
13381        char buffer[maxDoubleSize];
 
13386        sprintf_s(
buffer, 
"%.3f", duration);
 
13394        ReusableStringStream oss;
 
13396        for (
auto&& filter : container)
 
13408    TestEventListenerBase::TestEventListenerBase(ReporterConfig 
const & _config)
 
13409        :StreamingReporterBase(_config) {}
 
13415    void TestEventListenerBase::assertionStarting(AssertionInfo 
const &) {}
 
13417    bool TestEventListenerBase::assertionEnded(AssertionStats 
const &) {
 
13427#ifdef CATCH_PLATFORM_MAC 
13428    const char* failedString() { 
return "FAILED"; }
 
13429    const char* passedString() { 
return "PASSED"; }
 
13431    const char* failedString() { 
return "failed"; }
 
13432    const char* passedString() { 
return "passed"; }
 
13436    Catch::Colour::Code dimColour() { 
return Catch::Colour::FileName; }
 
13440               count == 2 ? 
"both " : 
"all " ;
 
13453void printTotals(
std::ostream& out, 
const Totals& totals) {
 
13454    if (totals.testCases.total() == 0) {
 
13455        out << 
"No tests ran.";
 
13456    } 
else if (totals.testCases.failed == totals.testCases.total()) {
 
13457        Colour colour(Colour::ResultError);
 
13459            totals.assertions.failed == totals.assertions.total() ?
 
13460            bothOrAll(totals.assertions.failed) : 
std::string();
 
13462            "Failed " << bothOrAll(totals.testCases.failed)
 
13463            << pluralise(totals.testCases.failed, 
"test case") << 
", " 
13464            "failed " << qualify_assertions_failed <<
 
13465            pluralise(totals.assertions.failed, 
"assertion") << 
'.';
 
13466    } 
else if (totals.assertions.total() == 0) {
 
13468            "Passed " << bothOrAll(totals.testCases.total())
 
13469            << pluralise(totals.testCases.total(), 
"test case")
 
13470            << 
" (no assertions).";
 
13471    } 
else if (totals.assertions.failed) {
 
13472        Colour colour(Colour::ResultError);
 
13474            "Failed " << pluralise(totals.testCases.failed, 
"test case") << 
", " 
13475            "failed " << pluralise(totals.assertions.failed, 
"assertion") << 
'.';
 
13477        Colour colour(Colour::ResultSuccess);
 
13479            "Passed " << bothOrAll(totals.testCases.passed)
 
13480            << pluralise(totals.testCases.passed, 
"test case") <<
 
13481            " with " << pluralise(totals.assertions.passed, 
"assertion") << 
'.';
 
13486class AssertionPrinter {
 
13488    AssertionPrinter& operator= (AssertionPrinter 
const&) = 
delete;
 
13489    AssertionPrinter(AssertionPrinter 
const&) = 
delete;
 
13490    AssertionPrinter(
std::ostream& _stream, AssertionStats 
const& _stats, 
bool _printInfoMessages)
 
13492        , 
result(_stats.assertionResult)
 
13493        , messages(_stats.infoMessages)
 
13494        , itMessage(_stats.infoMessages.
begin())
 
13495        , printInfoMessages(_printInfoMessages) {}
 
13500        itMessage = messages.begin();
 
13502        switch (
result.getResultType()) {
 
13503        case ResultWas::Ok:
 
13504            printResultType(Colour::ResultSuccess, passedString());
 
13505            printOriginalExpression();
 
13506            printReconstructedExpression();
 
13507            if (!
result.hasExpression())
 
13508                printRemainingMessages(Colour::None);
 
13510                printRemainingMessages();
 
13512        case ResultWas::ExpressionFailed:
 
13514                printResultType(Colour::ResultSuccess, failedString() + 
std::string(
" - but was ok"));
 
13516                printResultType(Colour::Error, failedString());
 
13517            printOriginalExpression();
 
13518            printReconstructedExpression();
 
13519            printRemainingMessages();
 
13521        case ResultWas::ThrewException:
 
13522            printResultType(Colour::Error, failedString());
 
13523            printIssue(
"unexpected exception with message:");
 
13525            printExpressionWas();
 
13526            printRemainingMessages();
 
13528        case ResultWas::FatalErrorCondition:
 
13529            printResultType(Colour::Error, failedString());
 
13530            printIssue(
"fatal error condition with message:");
 
13532            printExpressionWas();
 
13533            printRemainingMessages();
 
13535        case ResultWas::DidntThrowException:
 
13536            printResultType(Colour::Error, failedString());
 
13537            printIssue(
"expected exception, got none");
 
13538            printExpressionWas();
 
13539            printRemainingMessages();
 
13541        case ResultWas::Info:
 
13542            printResultType(Colour::None, 
"info");
 
13544            printRemainingMessages();
 
13546        case ResultWas::Warning:
 
13547            printResultType(Colour::None, 
"warning");
 
13549            printRemainingMessages();
 
13551        case ResultWas::ExplicitFailure:
 
13552            printResultType(Colour::Error, failedString());
 
13553            printIssue(
"explicitly");
 
13554            printRemainingMessages(Colour::None);
 
13557        case ResultWas::Unknown:
 
13558        case ResultWas::FailureBit:
 
13559        case ResultWas::Exception:
 
13560            printResultType(Colour::Error, 
"** internal error **");
 
13566    void printSourceInfo()
 const {
 
13567        Colour colourGuard(Colour::FileName);
 
13568        stream << 
result.getSourceInfo() << 
':';
 
13571    void printResultType(Colour::Code colour, 
std::string const& passOrFail)
 const {
 
13572        if (!passOrFail.
empty()) {
 
13574                Colour colourGuard(colour);
 
13575                stream << 
' ' << passOrFail;
 
13581    void printIssue(
std::string const& issue)
 const {
 
13582        stream << 
' ' << issue;
 
13585    void printExpressionWas() {
 
13586        if (
result.hasExpression()) {
 
13589                Colour colour(dimColour());
 
13590                stream << 
" expression was:";
 
13592            printOriginalExpression();
 
13596    void printOriginalExpression()
 const {
 
13597        if (
result.hasExpression()) {
 
13598            stream << 
' ' << 
result.getExpression();
 
13602    void printReconstructedExpression()
 const {
 
13603        if (
result.hasExpandedExpression()) {
 
13605                Colour colour(dimColour());
 
13606                stream << 
" for: ";
 
13608            stream << 
result.getExpandedExpression();
 
13612    void printMessage() {
 
13613        if (itMessage != messages.end()) {
 
13614            stream << 
" '" << itMessage->message << 
'\'';
 
13619    void printRemainingMessages(Colour::Code colour = dimColour()) {
 
13620        if (itMessage == messages.end())
 
13628            Colour colourGuard(colour);
 
13629            stream << 
" with " << pluralise(N, 
"message") << 
':';
 
13632        for (; itMessage != itEnd; ) {
 
13634            if (printInfoMessages || itMessage->type != ResultWas::Info) {
 
13635                stream << 
" '" << itMessage->message << 
'\'';
 
13636                if (++itMessage != itEnd) {
 
13637                    Colour colourGuard(dimColour());
 
13646    AssertionResult 
const& 
result;
 
13649    bool printInfoMessages;
 
13655            return "Reports test results on a single line, suitable for IDEs";
 
13658        ReporterPreferences CompactReporter::getPreferences()
 const {
 
13659            return m_reporterPrefs;
 
13662        void CompactReporter::noMatchingTestCases( 
std::string const& spec ) {
 
13663            stream << 
"No test cases matched '" << spec << 
'\'' << 
std::endl;
 
13666        void CompactReporter::assertionStarting( AssertionInfo 
const& ) {}
 
13668        bool CompactReporter::assertionEnded( AssertionStats 
const& _assertionStats ) {
 
13669            AssertionResult 
const& 
result = _assertionStats.assertionResult;
 
13671            bool printInfoMessages = 
true;
 
13674            if( !m_config->includeSuccessfulResults() && 
result.isOk() ) {
 
13677                printInfoMessages = 
false;
 
13680            AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
 
13687        void CompactReporter::sectionEnded(SectionStats 
const& _sectionStats) {
 
13689                stream << getFormattedDuration(_sectionStats.durationInSeconds) << 
" s: " << _sectionStats.sectionInfo.name << 
std::endl;
 
13693        void CompactReporter::testRunEnded( TestRunStats 
const& _testRunStats ) {
 
13694            printTotals( stream, _testRunStats.totals );
 
13696            StreamingReporterBase::testRunEnded( _testRunStats );
 
13699        CompactReporter::~CompactReporter() {}
 
13701    CATCH_REGISTER_REPORTER( 
"compact", CompactReporter )
 
13710#if defined(_MSC_VER) 
13711#pragma warning(push) 
13712#pragma warning(disable:4061)  
13722class ConsoleAssertionPrinter {
 
13724    ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter 
const&) = 
delete;
 
13725    ConsoleAssertionPrinter(ConsoleAssertionPrinter 
const&) = 
delete;
 
13726    ConsoleAssertionPrinter(
std::ostream& _stream, AssertionStats 
const& _stats, 
bool _printInfoMessages)
 
13729        result(_stats.assertionResult),
 
13730        colour(Colour::None),
 
13731        message(
result.getMessage()),
 
13732        messages(_stats.infoMessages),
 
13733        printInfoMessages(_printInfoMessages) {
 
13734        switch (
result.getResultType()) {
 
13735        case ResultWas::Ok:
 
13736            colour = Colour::Success;
 
13737            passOrFail = 
"PASSED";
 
13739            if (_stats.infoMessages.size() == 1)
 
13740                messageLabel = 
"with message";
 
13741            if (_stats.infoMessages.size() > 1)
 
13742                messageLabel = 
"with messages";
 
13744        case ResultWas::ExpressionFailed:
 
13746                colour = Colour::Success;
 
13747                passOrFail = 
"FAILED - but was ok";
 
13749                colour = Colour::Error;
 
13750                passOrFail = 
"FAILED";
 
13752            if (_stats.infoMessages.size() == 1)
 
13753                messageLabel = 
"with message";
 
13754            if (_stats.infoMessages.size() > 1)
 
13755                messageLabel = 
"with messages";
 
13757        case ResultWas::ThrewException:
 
13758            colour = Colour::Error;
 
13759            passOrFail = 
"FAILED";
 
13760            messageLabel = 
"due to unexpected exception with ";
 
13761            if (_stats.infoMessages.size() == 1)
 
13762                messageLabel += "message";
 
13763            if (_stats.infoMessages.size() > 1)
 
13764                messageLabel += "messages";
 
13766        case ResultWas::FatalErrorCondition:
 
13767            colour = Colour::Error;
 
13768            passOrFail = 
"FAILED";
 
13769            messageLabel = 
"due to a fatal error condition";
 
13771        case ResultWas::DidntThrowException:
 
13772            colour = Colour::Error;
 
13773            passOrFail = 
"FAILED";
 
13774            messageLabel = 
"because no exception was thrown where one was expected";
 
13776        case ResultWas::Info:
 
13777            messageLabel = 
"info";
 
13779        case ResultWas::Warning:
 
13780            messageLabel = 
"warning";
 
13782        case ResultWas::ExplicitFailure:
 
13783            passOrFail = 
"FAILED";
 
13784            colour = Colour::Error;
 
13785            if (_stats.infoMessages.size() == 1)
 
13786                messageLabel = 
"explicitly with message";
 
13787            if (_stats.infoMessages.size() > 1)
 
13788                messageLabel = 
"explicitly with messages";
 
13791        case ResultWas::Unknown:
 
13792        case ResultWas::FailureBit:
 
13793        case ResultWas::Exception:
 
13794            passOrFail = 
"** internal error **";
 
13795            colour = Colour::Error;
 
13800    void print()
 const {
 
13802        if (stats.totals.assertions.total() > 0) {
 
13804            printOriginalExpression();
 
13805            printReconstructedExpression();
 
13813    void printResultType()
 const {
 
13814        if (!passOrFail.
empty()) {
 
13815            Colour colourGuard(colour);
 
13816            stream << passOrFail << 
":\n";
 
13819    void printOriginalExpression()
 const {
 
13820        if (
result.hasExpression()) {
 
13821            Colour colourGuard(Colour::OriginalExpression);
 
13823            stream << 
result.getExpressionInMacro();
 
13827    void printReconstructedExpression()
 const {
 
13828        if (
result.hasExpandedExpression()) {
 
13829            stream << 
"with expansion:\n";
 
13830            Colour colourGuard(Colour::ReconstructedExpression);
 
13831            stream << Column(
result.getExpandedExpression()).indent(2) << 
'\n';
 
13834    void printMessage()
 const {
 
13835        if (!messageLabel.empty())
 
13836            stream << messageLabel << 
':' << 
'\n';
 
13837        for (
auto const& msg : messages) {
 
13839            if (printInfoMessages || msg.type != ResultWas::Info)
 
13840                stream << Column(msg.message).indent(2) << 
'\n';
 
13843    void printSourceInfo()
 const {
 
13844        Colour colourGuard(Colour::FileName);
 
13845        stream << 
result.getSourceInfo() << 
": ";
 
13849    AssertionStats 
const& stats;
 
13850    AssertionResult 
const& 
result;
 
13851    Colour::Code colour;
 
13856    bool printInfoMessages;
 
13860    std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
 
13861    return (ratio == 0 && number > 0) ? 1 : ratio;
 
13865    if (i > j && i > k)
 
13874    enum Justification { Left, Right };
 
13877    Justification justification;
 
13879struct ColumnBreak {};
 
13891    static const uint64_t s_nanosecondsInAMicrosecond = 1000;
 
13892    static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
 
13893    static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
 
13894    static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
 
13896    uint64_t m_inNanoseconds;
 
13900    explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
 
13901        : m_inNanoseconds(inNanoseconds),
 
13903        if (m_units == Unit::Auto) {
 
13904            if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
 
13905                m_units = Unit::Nanoseconds;
 
13906            else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
 
13907                m_units = Unit::Microseconds;
 
13908            else if (m_inNanoseconds < s_nanosecondsInASecond)
 
13909                m_units = Unit::Milliseconds;
 
13910            else if (m_inNanoseconds < s_nanosecondsInAMinute)
 
13911                m_units = Unit::Seconds;
 
13913                m_units = Unit::Minutes;
 
13918    auto value() const -> 
double {
 
13920        case Unit::Microseconds:
 
13921            return m_inNanoseconds / 
static_cast<double>(s_nanosecondsInAMicrosecond);
 
13922        case Unit::Milliseconds:
 
13923            return m_inNanoseconds / 
static_cast<double>(s_nanosecondsInAMillisecond);
 
13924        case Unit::Seconds:
 
13925            return m_inNanoseconds / 
static_cast<double>(s_nanosecondsInASecond);
 
13926        case Unit::Minutes:
 
13927            return m_inNanoseconds / 
static_cast<double>(s_nanosecondsInAMinute);
 
13929            return static_cast<double>(m_inNanoseconds);
 
13932    auto unitsAsString() const -> 
std::
string {
 
13934        case Unit::Nanoseconds:
 
13936        case Unit::Microseconds:
 
13938        case Unit::Milliseconds:
 
13940        case Unit::Seconds:
 
13942        case Unit::Minutes:
 
13945            return "** internal error **";
 
13950        return os << duration.value() << 
" " << duration.unitsAsString();
 
13955class TablePrinter {
 
13959    int m_currentColumn = -1;
 
13960    bool m_isOpen = 
false;
 
13965        m_columnInfos( 
std::move( columnInfos ) ) {}
 
13967    auto columnInfos() const -> 
std::vector<ColumnInfo> const& {
 
13968        return m_columnInfos;
 
13974            *
this << RowBreak();
 
13975            for (
auto const& info : m_columnInfos)
 
13976                *this << 
info.
name << ColumnBreak();
 
13977            *
this << RowBreak();
 
13978            m_os << Catch::getLineOfChars<
'-'>() << 
"\n";
 
13983            *
this << RowBreak();
 
13989    template<
typename T>
 
13995    friend TablePrinter& 
operator << (TablePrinter& tp, ColumnBreak) {
 
13996        auto colStr = tp.m_oss.str();
 
14001        if (tp.m_currentColumn == 
static_cast<int>(tp.m_columnInfos.size() - 1)) {
 
14002            tp.m_currentColumn = -1;
 
14005        tp.m_currentColumn++;
 
14007        auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
 
14008        auto padding = (strSize + 2 < static_cast<
std::size_t>(colInfo.width))
 
14009            ? std::string(colInfo.width - (strSize + 2), ' ')
 
14011        if (colInfo.justification == ColumnInfo::Left)
 
14012            tp.m_os << colStr << padding << 
" ";
 
14014            tp.m_os << padding << colStr << 
" ";
 
14018    friend TablePrinter& 
operator << (TablePrinter& tp, RowBreak) {
 
14019        if (tp.m_currentColumn > 0) {
 
14021            tp.m_currentColumn = -1;
 
14027ConsoleReporter::ConsoleReporter(ReporterConfig 
const& config)
 
14028    : StreamingReporterBase(config),
 
14029    m_tablePrinter(new TablePrinter(config.stream(),
 
14031        { 
"benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
 
14032        { 
"iters", 8, ColumnInfo::Right },
 
14033        { 
"elapsed ns", 14, ColumnInfo::Right },
 
14034        { 
"average", 14, ColumnInfo::Right }
 
14036ConsoleReporter::~ConsoleReporter() = 
default;
 
14039    return "Reports test results as plain lines of text";
 
14042void ConsoleReporter::noMatchingTestCases(
std::string const& spec) {
 
14043    stream << 
"No test cases matched '" << spec << 
'\'' << 
std::endl;
 
14046void ConsoleReporter::assertionStarting(AssertionInfo 
const&) {}
 
14048bool ConsoleReporter::assertionEnded(AssertionStats 
const& _assertionStats) {
 
14049    AssertionResult 
const& 
result = _assertionStats.assertionResult;
 
14051    bool includeResults = m_config->includeSuccessfulResults() || !
result.isOk();
 
14059    ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
 
14065void ConsoleReporter::sectionStarting(SectionInfo 
const& _sectionInfo) {
 
14066    m_headerPrinted = 
false;
 
14067    StreamingReporterBase::sectionStarting(_sectionInfo);
 
14069void ConsoleReporter::sectionEnded(SectionStats 
const& _sectionStats) {
 
14070    m_tablePrinter->close();
 
14071    if (_sectionStats.missingAssertions) {
 
14073        Colour colour(Colour::ResultError);
 
14074        if (m_sectionStack.size() > 1)
 
14075            stream << 
"\nNo assertions in section";
 
14077            stream << 
"\nNo assertions in test case";
 
14078        stream << 
" '" << _sectionStats.sectionInfo.name << 
"'\n" << 
std::endl;
 
14081        stream << getFormattedDuration(_sectionStats.durationInSeconds) << 
" s: " << _sectionStats.sectionInfo.name << 
std::endl;
 
14083    if (m_headerPrinted) {
 
14084        m_headerPrinted = 
false;
 
14086    StreamingReporterBase::sectionEnded(_sectionStats);
 
14089void ConsoleReporter::benchmarkStarting(BenchmarkInfo 
const& info) {
 
14090    lazyPrintWithoutClosingBenchmarkTable();
 
14092    auto nameCol = Column( 
info.name ).width( 
static_cast<std::size_t>( m_tablePrinter->columnInfos()[0].width - 2 ) );
 
14094    bool firstLine = 
true;
 
14095    for (
auto line : nameCol) {
 
14097            (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
 
14101        (*m_tablePrinter) << line << ColumnBreak();
 
14104void ConsoleReporter::benchmarkEnded(BenchmarkStats 
const& stats) {
 
14105    Duration average(stats.elapsedTimeInNanoseconds / stats.iterations);
 
14107        << stats.iterations << ColumnBreak()
 
14108        << stats.elapsedTimeInNanoseconds << ColumnBreak()
 
14109        << average << ColumnBreak();
 
14112void ConsoleReporter::testCaseEnded(TestCaseStats 
const& _testCaseStats) {
 
14113    m_tablePrinter->close();
 
14114    StreamingReporterBase::testCaseEnded(_testCaseStats);
 
14115    m_headerPrinted = 
false;
 
14117void ConsoleReporter::testGroupEnded(TestGroupStats 
const& _testGroupStats) {
 
14118    if (currentGroupInfo.used) {
 
14119        printSummaryDivider();
 
14120        stream << 
"Summary for group '" << _testGroupStats.groupInfo.name << 
"':\n";
 
14121        printTotals(_testGroupStats.totals);
 
14124    StreamingReporterBase::testGroupEnded(_testGroupStats);
 
14126void ConsoleReporter::testRunEnded(TestRunStats 
const& _testRunStats) {
 
14127    printTotalsDivider(_testRunStats.totals);
 
14128    printTotals(_testRunStats.totals);
 
14130    StreamingReporterBase::testRunEnded(_testRunStats);
 
14132void ConsoleReporter::testRunStarting(TestRunInfo 
const& _testInfo) {
 
14133    StreamingReporterBase::testRunStarting(_testInfo);
 
14134    printTestFilters();
 
14137void ConsoleReporter::lazyPrint() {
 
14139    m_tablePrinter->close();
 
14140    lazyPrintWithoutClosingBenchmarkTable();
 
14143void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
 
14145    if (!currentTestRunInfo.used)
 
14146        lazyPrintRunInfo();
 
14147    if (!currentGroupInfo.used)
 
14148        lazyPrintGroupInfo();
 
14150    if (!m_headerPrinted) {
 
14151        printTestCaseAndSectionHeader();
 
14152        m_headerPrinted = 
true;
 
14155void ConsoleReporter::lazyPrintRunInfo() {
 
14156    stream << '\n' << getLineOfChars<'~'>() << 
'\n';
 
14157    Colour colour(Colour::SecondaryText);
 
14158    stream << currentTestRunInfo->name
 
14159        << 
" is a Catch v" << libraryVersion() << 
" host application.\n" 
14160        << 
"Run with -? for options\n\n";
 
14162    if (m_config->rngSeed() != 0)
 
14163        stream << 
"Randomness seeded to: " << m_config->rngSeed() << 
"\n\n";
 
14165    currentTestRunInfo.used = 
true;
 
14167void ConsoleReporter::lazyPrintGroupInfo() {
 
14168    if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
 
14169        printClosedHeader(
"Group: " + currentGroupInfo->name);
 
14170        currentGroupInfo.used = 
true;
 
14173void ConsoleReporter::printTestCaseAndSectionHeader() {
 
14174    assert(!m_sectionStack.empty());
 
14175    printOpenHeader(currentTestCaseInfo->name);
 
14177    if (m_sectionStack.size() > 1) {
 
14178        Colour colourGuard(Colour::Headers);
 
14181            it = m_sectionStack.begin() + 1, 
 
14182            itEnd = m_sectionStack.
end();
 
14183        for (; it != itEnd; ++it)
 
14184            printHeaderString(it->
name, 2);
 
14187    SourceLineInfo lineInfo = m_sectionStack.
back().lineInfo;
 
14189    if (!lineInfo.empty()) {
 
14190        stream << getLineOfChars<
'-'>() << 
'\n';
 
14191        Colour colourGuard(Colour::FileName);
 
14192        stream << lineInfo << 
'\n';
 
14194    stream << getLineOfChars<
'.'>() << 
'\n' << 
std::endl;
 
14197void ConsoleReporter::printClosedHeader(
std::string const& _name) {
 
14198    printOpenHeader(_name);
 
14199    stream << getLineOfChars<
'.'>() << 
'\n';
 
14201void ConsoleReporter::printOpenHeader(
std::string const& _name) {
 
14202    stream << getLineOfChars<
'-'>() << 
'\n';
 
14204        Colour colourGuard(Colour::Headers);
 
14205        printHeaderString(_name);
 
14213    if (i != std::string::npos)
 
14217    stream << Column(_string).indent(indent + i).initialIndent(indent) << 
'\n';
 
14220struct SummaryColumn {
 
14222    SummaryColumn( 
std::string _label, Colour::Code _colour )
 
14223    :   label( 
std::move( _label ) ),
 
14224        colour( _colour ) {}
 
14226        ReusableStringStream rss;
 
14229        for (
auto& oldRow : rows) {
 
14230            while (oldRow.size() < row.
size())
 
14231                oldRow = 
' ' + oldRow;
 
14232            while (oldRow.size() > row.
size())
 
14240    Colour::Code colour;
 
14245void ConsoleReporter::printTotals( Totals 
const& totals ) {
 
14246    if (totals.testCases.total() == 0) {
 
14247        stream << Colour(Colour::Warning) << 
"No tests ran\n";
 
14248    } 
else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
 
14249        stream << Colour(Colour::ResultSuccess) << 
"All tests passed";
 
14251            << pluralise(totals.assertions.passed, 
"assertion") << 
" in " 
14252            << pluralise(totals.testCases.passed, 
"test case") << 
')' 
14257        columns.
push_back(SummaryColumn(
"", Colour::None)
 
14258                          .addRow(totals.testCases.total())
 
14259                          .addRow(totals.assertions.total()));
 
14260        columns.
push_back(SummaryColumn(
"passed", Colour::Success)
 
14261                          .addRow(totals.testCases.passed)
 
14262                          .addRow(totals.assertions.passed));
 
14263        columns.
push_back(SummaryColumn(
"failed", Colour::ResultError)
 
14264                          .addRow(totals.testCases.failed)
 
14265                          .addRow(totals.assertions.failed));
 
14266        columns.
push_back(SummaryColumn(
"failed as expected", Colour::ResultExpectedFailure)
 
14267                          .addRow(totals.testCases.failedButOk)
 
14268                          .addRow(totals.assertions.failedButOk));
 
14270        printSummaryRow(
"test cases", columns, 0);
 
14271        printSummaryRow(
"assertions", columns, 1);
 
14275    for (
auto col : cols) {
 
14277        if (col.label.empty()) {
 
14278            stream << label << 
": ";
 
14282                stream << Colour(Colour::Warning) << 
"- none -";
 
14283        } 
else if (
value != 
"0") {
 
14284            stream << Colour(Colour::LightGrey) << 
" | ";
 
14285            stream << Colour(col.colour)
 
14286                << 
value << 
' ' << col.label;
 
14292void ConsoleReporter::printTotalsDivider(Totals 
const& totals) {
 
14293    if (totals.testCases.total() > 0) {
 
14294        std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
 
14295        std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
 
14296        std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
 
14297        while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
 
14298            findMax(failedRatio, failedButOkRatio, passedRatio)++;
 
14299        while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
 
14300            findMax(failedRatio, failedButOkRatio, passedRatio)--;
 
14302        stream << Colour(Colour::Error) << 
std::string(failedRatio, 
'=');
 
14303        stream << Colour(Colour::ResultExpectedFailure) << 
std::string(failedButOkRatio, 
'=');
 
14304        if (totals.testCases.allPassed())
 
14305            stream << Colour(Colour::ResultSuccess) << 
std::string(passedRatio, 
'=');
 
14307            stream << Colour(Colour::Success) << 
std::string(passedRatio, 
'=');
 
14309        stream << Colour(Colour::Warning) << 
std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, 
'=');
 
14313void ConsoleReporter::printSummaryDivider() {
 
14314    stream << getLineOfChars<
'-'>() << 
'\n';
 
14317void ConsoleReporter::printTestFilters() {
 
14318    if (m_config->testSpec().hasFilters())
 
14319        stream << Colour(Colour::BrightYellow) << 
"Filters: " << serializeFilters( m_config->getTestsOrTags() ) << 
'\n';
 
14322CATCH_REGISTER_REPORTER(
"console", ConsoleReporter)
 
14326#if defined(_MSC_VER) 
14327#pragma warning(pop) 
14345            auto const timeStampSize = 
sizeof(
"2017-01-16T17:06:45Z");
 
14355            char timeStamp[timeStampSize];
 
14356            const char * 
const fmt = 
"%Y-%m-%dT%H:%M:%SZ";
 
14370            if (it != tags.
end())
 
14376    JunitReporter::JunitReporter( ReporterConfig 
const& _config )
 
14377        :   CumulativeReporterBase( _config ),
 
14378            xml( _config.stream() )
 
14380            m_reporterPrefs.shouldRedirectStdOut = 
true;
 
14381            m_reporterPrefs.shouldReportAllAssertions = 
true;
 
14384    JunitReporter::~JunitReporter() {}
 
14387        return "Reports test results in an XML format that looks like Ant's junitreport target";
 
14390    void JunitReporter::noMatchingTestCases( 
std::string const&  ) {}
 
14392    void JunitReporter::testRunStarting( TestRunInfo 
const& runInfo )  {
 
14393        CumulativeReporterBase::testRunStarting( runInfo );
 
14394        xml.startElement( 
"testsuites" );
 
14397    void JunitReporter::testGroupStarting( GroupInfo 
const& groupInfo ) {
 
14398        suiteTimer.start();
 
14399        stdOutForSuite.clear();
 
14400        stdErrForSuite.clear();
 
14401        unexpectedExceptions = 0;
 
14402        CumulativeReporterBase::testGroupStarting( groupInfo );
 
14405    void JunitReporter::testCaseStarting( TestCaseInfo 
const& testCaseInfo ) {
 
14406        m_okToFail = testCaseInfo.okToFail();
 
14409    bool JunitReporter::assertionEnded( AssertionStats 
const& assertionStats ) {
 
14411            unexpectedExceptions++;
 
14412        return CumulativeReporterBase::assertionEnded( assertionStats );
 
14415    void JunitReporter::testCaseEnded( TestCaseStats 
const& testCaseStats ) {
 
14416        stdOutForSuite += testCaseStats.stdOut;
 
14417        stdErrForSuite += testCaseStats.stdErr;
 
14418        CumulativeReporterBase::testCaseEnded( testCaseStats );
 
14421    void JunitReporter::testGroupEnded( TestGroupStats 
const& testGroupStats ) {
 
14422        double suiteTime = suiteTimer.getElapsedSeconds();
 
14423        CumulativeReporterBase::testGroupEnded( testGroupStats );
 
14424        writeGroup( *m_testGroups.back(), suiteTime );
 
14427    void JunitReporter::testRunEndedCumulative() {
 
14431    void JunitReporter::writeGroup( TestGroupNode 
const& groupNode, 
double suiteTime ) {
 
14432        XmlWriter::ScopedElement e = xml.scopedElement( 
"testsuite" );
 
14434        TestGroupStats 
const& stats = groupNode.value;
 
14435        xml.writeAttribute( 
"name", stats.groupInfo.name );
 
14436        xml.writeAttribute( 
"errors", unexpectedExceptions );
 
14437        xml.writeAttribute( 
"failures", stats.totals.assertions.failed-unexpectedExceptions );
 
14438        xml.writeAttribute( 
"tests", stats.totals.assertions.total() );
 
14439        xml.writeAttribute( 
"hostname", 
"tbd" ); 
 
14441            xml.writeAttribute( 
"time", 
"" );
 
14443            xml.writeAttribute( 
"time", suiteTime );
 
14444        xml.writeAttribute( 
"timestamp", getCurrentTimestamp() );
 
14447        if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
 
14448            auto properties = xml.scopedElement(
"properties");
 
14449            if (m_config->hasTestFilters()) {
 
14450                xml.scopedElement(
"property")
 
14451                    .writeAttribute(
"name", 
"filters")
 
14452                    .writeAttribute(
"value", serializeFilters(m_config->getTestsOrTags()));
 
14454            if (m_config->rngSeed() != 0) {
 
14455                xml.scopedElement(
"property")
 
14456                    .writeAttribute(
"name", 
"random-seed")
 
14457                    .writeAttribute(
"value", m_config->rngSeed());
 
14462        for( 
auto const& child : groupNode.children )
 
14463            writeTestCase( *child );
 
14465        xml.scopedElement( 
"system-out" ).writeText( 
trim( stdOutForSuite ), 
false );
 
14466        xml.scopedElement( 
"system-err" ).writeText( 
trim( stdErrForSuite ), 
false );
 
14469    void JunitReporter::writeTestCase( TestCaseNode 
const& testCaseNode ) {
 
14470        TestCaseStats 
const& stats = testCaseNode.value;
 
14474        assert( testCaseNode.children.size() == 1 );
 
14475        SectionNode 
const& rootSection = *testCaseNode.children.front();
 
14477        std::string className = stats.testInfo.className;
 
14479        if( className.
empty() ) {
 
14480            className = fileNameTag(stats.testInfo.tags);
 
14481            if ( className.
empty() )
 
14482                className = 
"global";
 
14485        if ( !m_config->name().empty() )
 
14486            className = m_config->name() + "." + className;
 
14488        writeSection( className, 
"", rootSection );
 
14491    void JunitReporter::writeSection(  
std::string const& className,
 
14493                        SectionNode 
const& sectionNode ) {
 
14495        if( !rootName.
empty() )
 
14498        if( !sectionNode.assertions.empty() ||
 
14499            !sectionNode.stdOut.empty() ||
 
14500            !sectionNode.stdErr.empty() ) {
 
14501            XmlWriter::ScopedElement e = xml.scopedElement( 
"testcase" );
 
14502            if( className.
empty() ) {
 
14503                xml.writeAttribute( 
"classname", 
name );
 
14504                xml.writeAttribute( 
"name", 
"root" );
 
14507                xml.writeAttribute( 
"classname", className );
 
14508                xml.writeAttribute( 
"name", 
name );
 
14512            writeAssertions( sectionNode );
 
14514            if( !sectionNode.stdOut.empty() )
 
14515                xml.scopedElement( 
"system-out" ).writeText( 
trim( sectionNode.stdOut ), 
false );
 
14516            if( !sectionNode.stdErr.empty() )
 
14517                xml.scopedElement( 
"system-err" ).writeText( 
trim( sectionNode.stdErr ), 
false );
 
14519        for( 
auto const& childNode : sectionNode.childSections )
 
14520            if( className.
empty() )
 
14521                writeSection( 
name, 
"", *childNode );
 
14523                writeSection( className, 
name, *childNode );
 
14526    void JunitReporter::writeAssertions( SectionNode 
const& sectionNode ) {
 
14527        for( 
auto const& assertion : sectionNode.assertions )
 
14528            writeAssertion( assertion );
 
14531    void JunitReporter::writeAssertion( AssertionStats 
const& stats ) {
 
14532        AssertionResult 
const& 
result = stats.assertionResult;
 
14535            switch( 
result.getResultType() ) {
 
14538                    elementName = 
"error";
 
14541                    elementName = 
"failure";
 
14544                    elementName = 
"failure";
 
14547                    elementName = 
"failure";
 
14557                    elementName = 
"internalError";
 
14561            XmlWriter::ScopedElement e = xml.scopedElement( elementName );
 
14563            xml.writeAttribute( 
"message", 
result.getExpandedExpression() );
 
14564            xml.writeAttribute( 
"type", 
result.getTestMacroName() );
 
14566            ReusableStringStream rss;
 
14567            if( !
result.getMessage().empty() )
 
14568                rss << 
result.getMessage() << 
'\n';
 
14569            for( 
auto const& msg : stats.infoMessages )
 
14570                if( msg.
type == ResultWas::Info )
 
14571                    rss << msg.message << 
'\n';
 
14573            rss << 
"at " << 
result.getSourceInfo();
 
14574            xml.writeText( rss.str(), 
false );
 
14578    CATCH_REGISTER_REPORTER( 
"junit", JunitReporter )
 
14588    ListeningReporter::ListeningReporter() {
 
14590        m_preferences.shouldReportAllAssertions = 
true;
 
14593    void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
 
14594        m_listeners.push_back( std::move( listener ) );
 
14597    void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
 
14598        assert(!m_reporter && 
"Listening reporter can wrap only 1 real reporter");
 
14599        m_reporter = std::move( reporter );
 
14600        m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
 
14603    ReporterPreferences ListeningReporter::getPreferences()
 const {
 
14604        return m_preferences;
 
14611    void ListeningReporter::noMatchingTestCases( 
std::string const& spec ) {
 
14612        for ( 
auto const& listener : m_listeners ) {
 
14613            listener->noMatchingTestCases( spec );
 
14615        m_reporter->noMatchingTestCases( spec );
 
14618    void ListeningReporter::benchmarkStarting( BenchmarkInfo 
const& benchmarkInfo ) {
 
14619        for ( 
auto const& listener : m_listeners ) {
 
14620            listener->benchmarkStarting( benchmarkInfo );
 
14622        m_reporter->benchmarkStarting( benchmarkInfo );
 
14624    void ListeningReporter::benchmarkEnded( BenchmarkStats 
const& benchmarkStats ) {
 
14625        for ( 
auto const& listener : m_listeners ) {
 
14626            listener->benchmarkEnded( benchmarkStats );
 
14628        m_reporter->benchmarkEnded( benchmarkStats );
 
14631    void ListeningReporter::testRunStarting( TestRunInfo 
const& testRunInfo ) {
 
14632        for ( 
auto const& listener : m_listeners ) {
 
14633            listener->testRunStarting( testRunInfo );
 
14635        m_reporter->testRunStarting( testRunInfo );
 
14638    void ListeningReporter::testGroupStarting( GroupInfo 
const& groupInfo ) {
 
14639        for ( 
auto const& listener : m_listeners ) {
 
14640            listener->testGroupStarting( groupInfo );
 
14642        m_reporter->testGroupStarting( groupInfo );
 
14645    void ListeningReporter::testCaseStarting( TestCaseInfo 
const& testInfo ) {
 
14646        for ( 
auto const& listener : m_listeners ) {
 
14647            listener->testCaseStarting( testInfo );
 
14649        m_reporter->testCaseStarting( testInfo );
 
14652    void ListeningReporter::sectionStarting( SectionInfo 
const& sectionInfo ) {
 
14653        for ( 
auto const& listener : m_listeners ) {
 
14654            listener->sectionStarting( sectionInfo );
 
14656        m_reporter->sectionStarting( sectionInfo );
 
14659    void ListeningReporter::assertionStarting( AssertionInfo 
const& assertionInfo ) {
 
14660        for ( 
auto const& listener : m_listeners ) {
 
14661            listener->assertionStarting( assertionInfo );
 
14663        m_reporter->assertionStarting( assertionInfo );
 
14667    bool ListeningReporter::assertionEnded( AssertionStats 
const& assertionStats ) {
 
14668        for( 
auto const& listener : m_listeners ) {
 
14669            static_cast<void>( listener->assertionEnded( assertionStats ) );
 
14671        return m_reporter->assertionEnded( assertionStats );
 
14674    void ListeningReporter::sectionEnded( SectionStats 
const& sectionStats ) {
 
14675        for ( 
auto const& listener : m_listeners ) {
 
14676            listener->sectionEnded( sectionStats );
 
14678        m_reporter->sectionEnded( sectionStats );
 
14681    void ListeningReporter::testCaseEnded( TestCaseStats 
const& testCaseStats ) {
 
14682        for ( 
auto const& listener : m_listeners ) {
 
14683            listener->testCaseEnded( testCaseStats );
 
14685        m_reporter->testCaseEnded( testCaseStats );
 
14688    void ListeningReporter::testGroupEnded( TestGroupStats 
const& testGroupStats ) {
 
14689        for ( 
auto const& listener : m_listeners ) {
 
14690            listener->testGroupEnded( testGroupStats );
 
14692        m_reporter->testGroupEnded( testGroupStats );
 
14695    void ListeningReporter::testRunEnded( TestRunStats 
const& testRunStats ) {
 
14696        for ( 
auto const& listener : m_listeners ) {
 
14697            listener->testRunEnded( testRunStats );
 
14699        m_reporter->testRunEnded( testRunStats );
 
14702    void ListeningReporter::skipTest( TestCaseInfo 
const& testInfo ) {
 
14703        for ( 
auto const& listener : m_listeners ) {
 
14704            listener->skipTest( testInfo );
 
14706        m_reporter->skipTest( testInfo );
 
14709    bool ListeningReporter::isMulti()
 const {
 
14717#if defined(_MSC_VER) 
14718#pragma warning(push) 
14719#pragma warning(disable:4061)  
14725    XmlReporter::XmlReporter( ReporterConfig 
const& _config )
 
14726    :   StreamingReporterBase( _config ),
 
14727        m_xml(_config.stream())
 
14729        m_reporterPrefs.shouldRedirectStdOut = 
true;
 
14730        m_reporterPrefs.shouldReportAllAssertions = 
true;
 
14733    XmlReporter::~XmlReporter() = 
default;
 
14736        return "Reports test results as an XML document";
 
14739    std::string XmlReporter::getStylesheetRef()
 const {
 
14743    void XmlReporter::writeSourceInfo( SourceLineInfo 
const& sourceInfo ) {
 
14745            .writeAttribute( 
"filename", sourceInfo.file )
 
14746            .writeAttribute( 
"line", sourceInfo.line );
 
14749    void XmlReporter::noMatchingTestCases( 
std::string const& s ) {
 
14750        StreamingReporterBase::noMatchingTestCases( s );
 
14753    void XmlReporter::testRunStarting( TestRunInfo 
const& testInfo ) {
 
14754        StreamingReporterBase::testRunStarting( testInfo );
 
14756        if( !stylesheetRef.
empty() )
 
14757            m_xml.writeStylesheetRef( stylesheetRef );
 
14758        m_xml.startElement( 
"Catch" );
 
14759        if( !m_config->name().empty() )
 
14760            m_xml.writeAttribute( 
"name", m_config->name() );
 
14761        if (m_config->testSpec().hasFilters())
 
14762            m_xml.writeAttribute( 
"filters", serializeFilters( m_config->getTestsOrTags() ) );
 
14763        if( m_config->rngSeed() != 0 )
 
14764            m_xml.scopedElement( 
"Randomness" )
 
14765                .writeAttribute( 
"seed", m_config->rngSeed() );
 
14768    void XmlReporter::testGroupStarting( GroupInfo 
const& groupInfo ) {
 
14769        StreamingReporterBase::testGroupStarting( groupInfo );
 
14770        m_xml.startElement( 
"Group" )
 
14771            .writeAttribute( 
"name", groupInfo.name );
 
14774    void XmlReporter::testCaseStarting( TestCaseInfo 
const& testInfo ) {
 
14775        StreamingReporterBase::testCaseStarting(testInfo);
 
14776        m_xml.startElement( 
"TestCase" )
 
14777            .writeAttribute( 
"name", 
trim( testInfo.name ) )
 
14778            .writeAttribute( 
"description", testInfo.description )
 
14779            .writeAttribute( 
"tags", testInfo.tagsAsString() );
 
14781        writeSourceInfo( testInfo.lineInfo );
 
14784            m_testCaseTimer.start();
 
14785        m_xml.ensureTagClosed();
 
14788    void XmlReporter::sectionStarting( SectionInfo 
const& sectionInfo ) {
 
14789        StreamingReporterBase::sectionStarting( sectionInfo );
 
14790        if( m_sectionDepth++ > 0 ) {
 
14791            m_xml.startElement( 
"Section" )
 
14792                .writeAttribute( 
"name", 
trim( sectionInfo.name ) );
 
14793            writeSourceInfo( sectionInfo.lineInfo );
 
14794            m_xml.ensureTagClosed();
 
14798    void XmlReporter::assertionStarting( AssertionInfo 
const& ) { }
 
14800    bool XmlReporter::assertionEnded( AssertionStats 
const& assertionStats ) {
 
14802        AssertionResult 
const& 
result = assertionStats.assertionResult;
 
14804        bool includeResults = m_config->includeSuccessfulResults() || !
result.isOk();
 
14808            for( 
auto const& msg : assertionStats.infoMessages ) {
 
14810                    m_xml.scopedElement( 
"Info" )
 
14811                            .writeText( msg.message );
 
14813                    m_xml.scopedElement( 
"Warning" )
 
14814                            .writeText( msg.message );
 
14824        if( 
result.hasExpression() ) {
 
14825            m_xml.startElement( 
"Expression" )
 
14826                .writeAttribute( 
"success", 
result.succeeded() )
 
14827                .writeAttribute( 
"type", 
result.getTestMacroName() );
 
14829            writeSourceInfo( 
result.getSourceInfo() );
 
14831            m_xml.scopedElement( 
"Original" )
 
14832                .writeText( 
result.getExpression() );
 
14833            m_xml.scopedElement( 
"Expanded" )
 
14834                .writeText( 
result.getExpandedExpression() );
 
14838        switch( 
result.getResultType() ) {
 
14840                m_xml.startElement( 
"Exception" );
 
14841                writeSourceInfo( 
result.getSourceInfo() );
 
14842                m_xml.writeText( 
result.getMessage() );
 
14843                m_xml.endElement();
 
14846                m_xml.startElement( 
"FatalErrorCondition" );
 
14847                writeSourceInfo( 
result.getSourceInfo() );
 
14848                m_xml.writeText( 
result.getMessage() );
 
14849                m_xml.endElement();
 
14852                m_xml.scopedElement( 
"Info" )
 
14853                    .writeText( 
result.getMessage() );
 
14859                m_xml.startElement( 
"Failure" );
 
14860                writeSourceInfo( 
result.getSourceInfo() );
 
14861                m_xml.writeText( 
result.getMessage() );
 
14862                m_xml.endElement();
 
14868        if( 
result.hasExpression() )
 
14869            m_xml.endElement();
 
14874    void XmlReporter::sectionEnded( SectionStats 
const& sectionStats ) {
 
14875        StreamingReporterBase::sectionEnded( sectionStats );
 
14876        if( --m_sectionDepth > 0 ) {
 
14877            XmlWriter::ScopedElement e = m_xml.scopedElement( 
"OverallResults" );
 
14878            e.writeAttribute( 
"successes", sectionStats.assertions.passed );
 
14879            e.writeAttribute( 
"failures", sectionStats.assertions.failed );
 
14880            e.writeAttribute( 
"expectedFailures", sectionStats.assertions.failedButOk );
 
14883                e.writeAttribute( 
"durationInSeconds", sectionStats.durationInSeconds );
 
14885            m_xml.endElement();
 
14889    void XmlReporter::testCaseEnded( TestCaseStats 
const& testCaseStats ) {
 
14890        StreamingReporterBase::testCaseEnded( testCaseStats );
 
14891        XmlWriter::ScopedElement e = m_xml.scopedElement( 
"OverallResult" );
 
14892        e.writeAttribute( 
"success", testCaseStats.totals.assertions.allOk() );
 
14895            e.writeAttribute( 
"durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
 
14897        if( !testCaseStats.stdOut.empty() )
 
14898            m_xml.scopedElement( 
"StdOut" ).writeText( 
trim( testCaseStats.stdOut ), 
false );
 
14899        if( !testCaseStats.stdErr.empty() )
 
14900            m_xml.scopedElement( 
"StdErr" ).writeText( 
trim( testCaseStats.stdErr ), 
false );
 
14902        m_xml.endElement();
 
14905    void XmlReporter::testGroupEnded( TestGroupStats 
const& testGroupStats ) {
 
14906        StreamingReporterBase::testGroupEnded( testGroupStats );
 
14908        m_xml.scopedElement( 
"OverallResults" )
 
14909            .writeAttribute( 
"successes", testGroupStats.totals.assertions.passed )
 
14910            .writeAttribute( 
"failures", testGroupStats.totals.assertions.failed )
 
14911            .writeAttribute( 
"expectedFailures", testGroupStats.totals.assertions.failedButOk );
 
14912        m_xml.endElement();
 
14915    void XmlReporter::testRunEnded( TestRunStats 
const& testRunStats ) {
 
14916        StreamingReporterBase::testRunEnded( testRunStats );
 
14917        m_xml.scopedElement( 
"OverallResults" )
 
14918            .writeAttribute( 
"successes", testRunStats.totals.assertions.passed )
 
14919            .writeAttribute( 
"failures", testRunStats.totals.assertions.failed )
 
14920            .writeAttribute( 
"expectedFailures", testRunStats.totals.assertions.failedButOk );
 
14921        m_xml.endElement();
 
14924    CATCH_REGISTER_REPORTER( 
"xml", XmlReporter )
 
14928#if defined(_MSC_VER) 
14929#pragma warning(pop) 
14934    LeakDetector leakDetector;
 
14938#pragma clang diagnostic pop 
14944#ifdef CATCH_CONFIG_MAIN 
14949#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) 
14951extern "C" int wmain (
int argc, 
wchar_t * argv[], 
wchar_t * []) {
 
14954int main (
int argc, 
char * argv[]) {
 
14957    return Catch::Session().run( argc, argv );
 
14963int main (
int argc, 
char * 
const argv[]) {
 
14964#if !CATCH_ARC_ENABLED 
14965    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
14968    Catch::registerTestMethods();
 
14969    int result = Catch::Session().run( argc, (
char**)argv );
 
14971#if !CATCH_ARC_ENABLED 
14983#if !defined(CATCH_CONFIG_IMPL_ONLY) 
14985#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED 
14986#  undef CLARA_CONFIG_MAIN 
14989#if !defined(CATCH_CONFIG_DISABLE) 
14992#ifdef CATCH_CONFIG_PREFIX_ALL 
14994#define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ ) 
14995#define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) 
14997#define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ ) 
14998#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) 
14999#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) 
15000#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 
15001#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr ) 
15003#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ ) 
15005#define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15006#define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) 
15007#define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15008#define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15009#define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ ) 
15011#define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15012#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) 
15013#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) 
15014#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 
15015#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) 
15017#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15019#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 
15020#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) 
15022#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) 
15025#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) 
15026#define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg ) 
15027#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) 
15028#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ ) 
15030#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) 
15031#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15032#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) 
15033#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) 
15034#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) 
15035#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ ) 
15036#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) 
15037#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15038#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15040#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() 
15042#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 
15043#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) 
15044#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) 
15045#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15046#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) 
15047#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) 
15048#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) 
15049#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15050#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) 
15052#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) ) 
15053#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) ) 
15054#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) 
15055#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) ) 
15056#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) ) 
15057#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) ) 
15058#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) 
15059#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) ) 
15062#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE) 
15063#define CATCH_STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__ ,      #__VA_ARGS__ );     CATCH_SUCCEED( #__VA_ARGS__ ) 
15064#define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ ) 
15066#define CATCH_STATIC_REQUIRE( ... )       CATCH_REQUIRE( __VA_ARGS__ ) 
15067#define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ ) 
15071#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) 
15072#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) 
15073#define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc ) 
15074#define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc ) 
15075#define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc ) 
15076#define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc ) 
15077#define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc ) 
15078#define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc ) 
15083#define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__  ) 
15084#define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) 
15086#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ ) 
15087#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) 
15088#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) 
15089#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 
15090#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr ) 
15092#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ ) 
15094#define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15095#define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) 
15096#define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15097#define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15098#define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ ) 
15100#define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15101#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) 
15102#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) 
15103#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 
15104#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) 
15106#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15108#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 
15109#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) 
15111#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) 
15114#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) 
15115#define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg ) 
15116#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) 
15117#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ ) 
15119#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) 
15120#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15121#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) 
15122#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) 
15123#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) 
15124#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ ) 
15125#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) 
15126#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15127#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) 
15128#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() 
15130#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 
15131#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) 
15132#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) 
15133#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15134#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) 
15135#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) 
15136#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) 
15137#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15138#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) 
15140#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) ) 
15141#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) ) 
15142#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) 
15143#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) ) 
15144#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) ) 
15145#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) ) 
15146#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) 
15147#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) ) 
15150#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE) 
15151#define STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__,  #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ ) 
15152#define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" ) 
15154#define STATIC_REQUIRE( ... )       REQUIRE( __VA_ARGS__ ) 
15155#define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ ) 
15160#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) 
15163#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) 
15164#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) 
15166#define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc ) 
15167#define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc ) 
15168#define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc ) 
15169#define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc ) 
15170#define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc ) 
15171#define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc ) 
15179#ifdef CATCH_CONFIG_PREFIX_ALL 
15181#define CATCH_REQUIRE( ... )        (void)(0) 
15182#define CATCH_REQUIRE_FALSE( ... )  (void)(0) 
15184#define CATCH_REQUIRE_THROWS( ... ) (void)(0) 
15185#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0) 
15186#define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0) 
15187#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 
15188#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) 
15190#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0) 
15192#define CATCH_CHECK( ... )         (void)(0) 
15193#define CATCH_CHECK_FALSE( ... )   (void)(0) 
15194#define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__) 
15195#define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__)) 
15196#define CATCH_CHECK_NOFAIL( ... )  (void)(0) 
15198#define CATCH_CHECK_THROWS( ... )  (void)(0) 
15199#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0) 
15200#define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0) 
15201#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 
15202#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) 
15204#define CATCH_CHECK_NOTHROW( ... ) (void)(0) 
15206#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 
15207#define CATCH_CHECK_THAT( arg, matcher )   (void)(0) 
15209#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0) 
15212#define CATCH_INFO( msg )          (void)(0) 
15213#define CATCH_UNSCOPED_INFO( msg ) (void)(0) 
15214#define CATCH_WARN( msg )          (void)(0) 
15215#define CATCH_CAPTURE( msg )       (void)(0) 
15217#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) 
15218#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) 
15219#define CATCH_METHOD_AS_TEST_CASE( method, ... ) 
15220#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0) 
15221#define CATCH_SECTION( ... ) 
15222#define CATCH_DYNAMIC_SECTION( ... ) 
15223#define CATCH_FAIL( ... ) (void)(0) 
15224#define CATCH_FAIL_CHECK( ... ) (void)(0) 
15225#define CATCH_SUCCEED( ... ) (void)(0) 
15227#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) 
15229#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 
15230#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) 
15231#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) 
15232#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__) 
15233#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) 
15234#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) 
15235#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) 
15236#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15237#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15239#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) ) 
15240#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) ) 
15241#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) ) 
15242#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) ) 
15243#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) 
15244#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) 
15245#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15246#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15250#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) 
15251#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) 
15252#define CATCH_GIVEN( desc ) 
15253#define CATCH_AND_GIVEN( desc ) 
15254#define CATCH_WHEN( desc ) 
15255#define CATCH_AND_WHEN( desc ) 
15256#define CATCH_THEN( desc ) 
15257#define CATCH_AND_THEN( desc ) 
15259#define CATCH_STATIC_REQUIRE( ... )       (void)(0) 
15260#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0) 
15265#define REQUIRE( ... )       (void)(0) 
15266#define REQUIRE_FALSE( ... ) (void)(0) 
15268#define REQUIRE_THROWS( ... ) (void)(0) 
15269#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0) 
15270#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0) 
15271#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 
15272#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) 
15274#define REQUIRE_NOTHROW( ... ) (void)(0) 
15276#define CHECK( ... ) (void)(0) 
15277#define CHECK_FALSE( ... ) (void)(0) 
15278#define CHECKED_IF( ... ) if (__VA_ARGS__) 
15279#define CHECKED_ELSE( ... ) if (!(__VA_ARGS__)) 
15280#define CHECK_NOFAIL( ... ) (void)(0) 
15282#define CHECK_THROWS( ... )  (void)(0) 
15283#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0) 
15284#define CHECK_THROWS_WITH( expr, matcher ) (void)(0) 
15285#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 
15286#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) 
15288#define CHECK_NOTHROW( ... ) (void)(0) 
15290#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) 
15291#define CHECK_THAT( arg, matcher ) (void)(0) 
15293#define REQUIRE_THAT( arg, matcher ) (void)(0) 
15296#define INFO( msg ) (void)(0) 
15297#define UNSCOPED_INFO( msg ) (void)(0) 
15298#define WARN( msg ) (void)(0) 
15299#define CAPTURE( msg ) (void)(0) 
15301#define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) 
15302#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) 
15303#define METHOD_AS_TEST_CASE( method, ... ) 
15304#define REGISTER_TEST_CASE( Function, ... ) (void)(0) 
15305#define SECTION( ... ) 
15306#define DYNAMIC_SECTION( ... ) 
15307#define FAIL( ... ) (void)(0) 
15308#define FAIL_CHECK( ... ) (void)(0) 
15309#define SUCCEED( ... ) (void)(0) 
15310#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) 
15312#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 
15313#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) 
15314#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) 
15315#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__) 
15316#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) 
15317#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ ) 
15318#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ ) 
15319#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15320#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15322#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) ) 
15323#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) ) 
15324#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) ) 
15325#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) ) 
15326#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ ) 
15327#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ ) 
15328#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15329#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) 
15332#define STATIC_REQUIRE( ... )       (void)(0) 
15333#define STATIC_REQUIRE_FALSE( ... ) (void)(0) 
15337#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) 
15340#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) ) 
15341#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) 
15343#define GIVEN( desc ) 
15344#define AND_GIVEN( desc ) 
15345#define WHEN( desc ) 
15346#define AND_WHEN( desc ) 
15347#define THEN( desc ) 
15348#define AND_THEN( desc ) 
15361#        pragma warning(pop) 
15363#        pragma clang diagnostic pop 
15365#elif defined __GNUC__ 
15366#    pragma GCC diagnostic pop