Home | History | Annotate | Download | only in cc
      1 /*
      2  *  Catch v1.4.0
      3  *  Generated: 2016-03-15 07:23:12.623111
      4  *  ----------------------------------------------------------
      5  *  This file has been merged from multiple headers. Please don't edit it directly
      6  *  Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
      7  *
      8  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
      9  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     10  */
     11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
     12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
     13 
     14 #define TWOBLUECUBES_CATCH_HPP_INCLUDED
     15 
     16 #ifdef __clang__
     17 #    pragma clang system_header
     18 #elif defined __GNUC__
     19 #    pragma GCC system_header
     20 #endif
     21 
     22 // #included from: internal/catch_suppress_warnings.h
     23 
     24 #ifdef __clang__
     25 #   ifdef __ICC // icpc defines the __clang__ macro
     26 #       pragma warning(push)
     27 #       pragma warning(disable: 161 1682)
     28 #   else // __ICC
     29 #       pragma clang diagnostic ignored "-Wglobal-constructors"
     30 #       pragma clang diagnostic ignored "-Wvariadic-macros"
     31 #       pragma clang diagnostic ignored "-Wc99-extensions"
     32 #       pragma clang diagnostic ignored "-Wunused-variable"
     33 #       pragma clang diagnostic push
     34 #       pragma clang diagnostic ignored "-Wpadded"
     35 #       pragma clang diagnostic ignored "-Wc++98-compat"
     36 #       pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
     37 #       pragma clang diagnostic ignored "-Wswitch-enum"
     38 #       pragma clang diagnostic ignored "-Wcovered-switch-default"
     39 #    endif
     40 #elif defined __GNUC__
     41 #    pragma GCC diagnostic ignored "-Wvariadic-macros"
     42 #    pragma GCC diagnostic ignored "-Wunused-variable"
     43 #    pragma GCC diagnostic push
     44 #    pragma GCC diagnostic ignored "-Wpadded"
     45 #endif
     46 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
     47 #  define CATCH_IMPL
     48 #endif
     49 
     50 #ifdef CATCH_IMPL
     51 #  ifndef CLARA_CONFIG_MAIN
     52 #    define CLARA_CONFIG_MAIN_NOT_DEFINED
     53 #    define CLARA_CONFIG_MAIN
     54 #  endif
     55 #endif
     56 
     57 // #included from: internal/catch_notimplemented_exception.h
     58 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
     59 
     60 // #included from: catch_common.h
     61 #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
     62 
     63 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
     64 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
     65 #ifdef CATCH_CONFIG_COUNTER
     66 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
     67 #else
     68 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
     69 #endif
     70 
     71 #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
     72 #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
     73 
     74 #include <sstream>
     75 #include <stdexcept>
     76 #include <algorithm>
     77 
     78 // #included from: catch_compiler_capabilities.h
     79 #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
     80 
     81 // Detect a number of compiler features - mostly C++11/14 conformance - by compiler
     82 // The following features are defined:
     83 //
     84 // CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
     85 // CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
     86 // CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
     87 // CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
     88 // CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
     89 // CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
     90 // CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
     91 // CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
     92 
     93 // CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
     94 
     95 // CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
     96 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
     97 // ****************
     98 // Note to maintainers: if new toggles are added please document them
     99 // in configuration.md, too
    100 // ****************
    101 
    102 // In general each macro has a _NO_<feature name> form
    103 // (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
    104 // Many features, at point of detection, define an _INTERNAL_ macro, so they
    105 // can be combined, en-mass, with the _NO_ forms later.
    106 
    107 // All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
    108 
    109 #if defined(__cplusplus) && __cplusplus >= 201103L
    110 #  define CATCH_CPP11_OR_GREATER
    111 #endif
    112 
    113 #ifdef __clang__
    114 
    115 #  if __has_feature(cxx_nullptr)
    116 #    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
    117 #  endif
    118 
    119 #  if __has_feature(cxx_noexcept)
    120 #    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
    121 #  endif
    122 
    123 #   if defined(CATCH_CPP11_OR_GREATER)
    124 #       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
    125 #   endif
    126 
    127 #endif // __clang__
    128 
    129 ////////////////////////////////////////////////////////////////////////////////
    130 // Borland
    131 #ifdef __BORLANDC__
    132 
    133 #endif // __BORLANDC__
    134 
    135 ////////////////////////////////////////////////////////////////////////////////
    136 // EDG
    137 #ifdef __EDG_VERSION__
    138 
    139 #endif // __EDG_VERSION__
    140 
    141 ////////////////////////////////////////////////////////////////////////////////
    142 // Digital Mars
    143 #ifdef __DMC__
    144 
    145 #endif // __DMC__
    146 
    147 ////////////////////////////////////////////////////////////////////////////////
    148 // GCC
    149 #ifdef __GNUC__
    150 
    151 #   if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
    152 #       define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
    153 #   endif
    154 
    155 #   if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)
    156 #       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
    157 #   endif
    158 
    159 // - otherwise more recent versions define __cplusplus >= 201103L
    160 // and will get picked up below
    161 
    162 #endif // __GNUC__
    163 
    164 ////////////////////////////////////////////////////////////////////////////////
    165 // Visual C++
    166 #ifdef _MSC_VER
    167 
    168 #if (_MSC_VER >= 1600)
    169 #   define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
    170 #   define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
    171 #endif
    172 
    173 #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
    174 #define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
    175 #define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
    176 #endif
    177 
    178 #endif // _MSC_VER
    179 
    180 ////////////////////////////////////////////////////////////////////////////////
    181 
    182 // Use variadic macros if the compiler supports them
    183 #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
    184     ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
    185     ( defined __GNUC__ && __GNUC__ >= 3 ) || \
    186     ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
    187 
    188 #define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
    189 
    190 #endif
    191 
    192 // Use __COUNTER__ if the compiler supports it
    193 #if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
    194     ( defined __GNUC__  && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
    195     ( defined __clang__ && __clang_major__ >= 3 )
    196 
    197 #define CATCH_INTERNAL_CONFIG_COUNTER
    198 
    199 #endif
    200 
    201 ////////////////////////////////////////////////////////////////////////////////
    202 // C++ language feature support
    203 
    204 // catch all support for C++11
    205 #if defined(CATCH_CPP11_OR_GREATER)
    206 
    207 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
    208 #    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
    209 #  endif
    210 
    211 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
    212 #    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
    213 #  endif
    214 
    215 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
    216 #    define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
    217 #  endif
    218 
    219 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
    220 #    define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
    221 #  endif
    222 
    223 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
    224 #    define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
    225 #  endif
    226 
    227 #  ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
    228 #    define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
    229 #  endif
    230 
    231 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
    232 #    define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
    233 #  endif
    234 
    235 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
    236 #    define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
    237 #  endif
    238 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
    239 #    define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
    240 #  endif
    241 
    242 #endif // __cplusplus >= 201103L
    243 
    244 // Now set the actual defines based on the above + anything the user has configured
    245 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
    246 #   define CATCH_CONFIG_CPP11_NULLPTR
    247 #endif
    248 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
    249 #   define CATCH_CONFIG_CPP11_NOEXCEPT
    250 #endif
    251 #if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
    252 #   define CATCH_CONFIG_CPP11_GENERATED_METHODS
    253 #endif
    254 #if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
    255 #   define CATCH_CONFIG_CPP11_IS_ENUM
    256 #endif
    257 #if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
    258 #   define CATCH_CONFIG_CPP11_TUPLE
    259 #endif
    260 #if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
    261 #   define CATCH_CONFIG_VARIADIC_MACROS
    262 #endif
    263 #if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
    264 #   define CATCH_CONFIG_CPP11_LONG_LONG
    265 #endif
    266 #if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
    267 #   define CATCH_CONFIG_CPP11_OVERRIDE
    268 #endif
    269 #if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
    270 #   define CATCH_CONFIG_CPP11_UNIQUE_PTR
    271 #endif
    272 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
    273 #   define CATCH_CONFIG_COUNTER
    274 #endif
    275 
    276 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
    277 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
    278 #endif
    279 
    280 // noexcept support:
    281 #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
    282 #  define CATCH_NOEXCEPT noexcept
    283 #  define CATCH_NOEXCEPT_IS(x) noexcept(x)
    284 #else
    285 #  define CATCH_NOEXCEPT throw()
    286 #  define CATCH_NOEXCEPT_IS(x)
    287 #endif
    288 
    289 // nullptr support
    290 #ifdef CATCH_CONFIG_CPP11_NULLPTR
    291 #   define CATCH_NULL nullptr
    292 #else
    293 #   define CATCH_NULL NULL
    294 #endif
    295 
    296 // override support
    297 #ifdef CATCH_CONFIG_CPP11_OVERRIDE
    298 #   define CATCH_OVERRIDE override
    299 #else
    300 #   define CATCH_OVERRIDE
    301 #endif
    302 
    303 // unique_ptr support
    304 #ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
    305 #   define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
    306 #else
    307 #   define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
    308 #endif
    309 
    310 namespace Catch {
    311 
    312     struct IConfig;
    313 
    314     struct CaseSensitive { enum Choice {
    315         Yes,
    316         No
    317     }; };
    318 
    319     class NonCopyable {
    320 #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
    321         NonCopyable( NonCopyable const& )              = delete;
    322         NonCopyable( NonCopyable && )                  = delete;
    323         NonCopyable& operator = ( NonCopyable const& ) = delete;
    324         NonCopyable& operator = ( NonCopyable && )     = delete;
    325 #else
    326         NonCopyable( NonCopyable const& info );
    327         NonCopyable& operator = ( NonCopyable const& );
    328 #endif
    329 
    330     protected:
    331         NonCopyable() {}
    332         virtual ~NonCopyable();
    333     };
    334 
    335     class SafeBool {
    336     public:
    337         typedef void (SafeBool::*type)() const;
    338 
    339         static type makeSafe( bool value ) {
    340             return value ? &SafeBool::trueValue : 0;
    341         }
    342     private:
    343         void trueValue() const {}
    344     };
    345 
    346     template<typename ContainerT>
    347     inline void deleteAll( ContainerT& container ) {
    348         typename ContainerT::const_iterator it = container.begin();
    349         typename ContainerT::const_iterator itEnd = container.end();
    350         for(; it != itEnd; ++it )
    351             delete *it;
    352     }
    353     template<typename AssociativeContainerT>
    354     inline void deleteAllValues( AssociativeContainerT& container ) {
    355         typename AssociativeContainerT::const_iterator it = container.begin();
    356         typename AssociativeContainerT::const_iterator itEnd = container.end();
    357         for(; it != itEnd; ++it )
    358             delete it->second;
    359     }
    360 
    361     bool startsWith( std::string const& s, std::string const& prefix );
    362     bool endsWith( std::string const& s, std::string const& suffix );
    363     bool contains( std::string const& s, std::string const& infix );
    364     void toLowerInPlace( std::string& s );
    365     std::string toLower( std::string const& s );
    366     std::string trim( std::string const& str );
    367     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
    368 
    369     struct pluralise {
    370         pluralise( std::size_t count, std::string const& label );
    371 
    372         friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
    373 
    374         std::size_t m_count;
    375         std::string m_label;
    376     };
    377 
    378     struct SourceLineInfo {
    379 
    380         SourceLineInfo();
    381         SourceLineInfo( char const* _file, std::size_t _line );
    382         SourceLineInfo( SourceLineInfo const& other );
    383 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
    384         SourceLineInfo( SourceLineInfo && )                  = default;
    385         SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
    386         SourceLineInfo& operator = ( SourceLineInfo && )     = default;
    387 #  endif
    388         bool empty() const;
    389         bool operator == ( SourceLineInfo const& other ) const;
    390         bool operator < ( SourceLineInfo const& other ) const;
    391 
    392         std::string file;
    393         std::size_t line;
    394     };
    395 
    396     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
    397 
    398     // This is just here to avoid compiler warnings with macro constants and boolean literals
    399     inline bool isTrue( bool value ){ return value; }
    400     inline bool alwaysTrue() { return true; }
    401     inline bool alwaysFalse() { return false; }
    402 
    403     void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
    404 
    405     void seedRng( IConfig const& config );
    406     unsigned int rngSeed();
    407 
    408     // Use this in variadic streaming macros to allow
    409     //    >> +StreamEndStop
    410     // as well as
    411     //    >> stuff +StreamEndStop
    412     struct StreamEndStop {
    413         std::string operator+() {
    414             return std::string();
    415         }
    416     };
    417     template<typename T>
    418     T const& operator + ( T const& value, StreamEndStop ) {
    419         return value;
    420     }
    421 }
    422 
    423 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
    424 #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
    425 
    426 #include <ostream>
    427 
    428 namespace Catch {
    429 
    430     class NotImplementedException : public std::exception
    431     {
    432     public:
    433         NotImplementedException( SourceLineInfo const& lineInfo );
    434         NotImplementedException( NotImplementedException const& ) {}
    435 
    436         virtual ~NotImplementedException() CATCH_NOEXCEPT {}
    437 
    438         virtual const char* what() const CATCH_NOEXCEPT;
    439 
    440     private:
    441         std::string m_what;
    442         SourceLineInfo m_lineInfo;
    443     };
    444 
    445 } // end namespace Catch
    446 
    447 ///////////////////////////////////////////////////////////////////////////////
    448 #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
    449 
    450 // #included from: internal/catch_context.h
    451 #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
    452 
    453 // #included from: catch_interfaces_generators.h
    454 #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
    455 
    456 #include <string>
    457 
    458 namespace Catch {
    459 
    460     struct IGeneratorInfo {
    461         virtual ~IGeneratorInfo();
    462         virtual bool moveNext() = 0;
    463         virtual std::size_t getCurrentIndex() const = 0;
    464     };
    465 
    466     struct IGeneratorsForTest {
    467         virtual ~IGeneratorsForTest();
    468 
    469         virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
    470         virtual bool moveNext() = 0;
    471     };
    472 
    473     IGeneratorsForTest* createGeneratorsForTest();
    474 
    475 } // end namespace Catch
    476 
    477 // #included from: catch_ptr.hpp
    478 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
    479 
    480 #ifdef __clang__
    481 #pragma clang diagnostic push
    482 #pragma clang diagnostic ignored "-Wpadded"
    483 #endif
    484 
    485 namespace Catch {
    486 
    487     // An intrusive reference counting smart pointer.
    488     // T must implement addRef() and release() methods
    489     // typically implementing the IShared interface
    490     template<typename T>
    491     class Ptr {
    492     public:
    493         Ptr() : m_p( CATCH_NULL ){}
    494         Ptr( T* p ) : m_p( p ){
    495             if( m_p )
    496                 m_p->addRef();
    497         }
    498         Ptr( Ptr const& other ) : m_p( other.m_p ){
    499             if( m_p )
    500                 m_p->addRef();
    501         }
    502         ~Ptr(){
    503             if( m_p )
    504                 m_p->release();
    505         }
    506         void reset() {
    507             if( m_p )
    508                 m_p->release();
    509             m_p = CATCH_NULL;
    510         }
    511         Ptr& operator = ( T* p ){
    512             Ptr temp( p );
    513             swap( temp );
    514             return *this;
    515         }
    516         Ptr& operator = ( Ptr const& other ){
    517             Ptr temp( other );
    518             swap( temp );
    519             return *this;
    520         }
    521         void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
    522         T* get() const{ return m_p; }
    523         T& operator*() const { return *m_p; }
    524         T* operator->() const { return m_p; }
    525         bool operator !() const { return m_p == CATCH_NULL; }
    526         operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
    527 
    528     private:
    529         T* m_p;
    530     };
    531 
    532     struct IShared : NonCopyable {
    533         virtual ~IShared();
    534         virtual void addRef() const = 0;
    535         virtual void release() const = 0;
    536     };
    537 
    538     template<typename T = IShared>
    539     struct SharedImpl : T {
    540 
    541         SharedImpl() : m_rc( 0 ){}
    542 
    543         virtual void addRef() const {
    544             ++m_rc;
    545         }
    546         virtual void release() const {
    547             if( --m_rc == 0 )
    548                 delete this;
    549         }
    550 
    551         mutable unsigned int m_rc;
    552     };
    553 
    554 } // end namespace Catch
    555 
    556 #ifdef __clang__
    557 #pragma clang diagnostic pop
    558 #endif
    559 
    560 #include <memory>
    561 #include <vector>
    562 #include <stdlib.h>
    563 
    564 namespace Catch {
    565 
    566     class TestCase;
    567     class Stream;
    568     struct IResultCapture;
    569     struct IRunner;
    570     struct IGeneratorsForTest;
    571     struct IConfig;
    572 
    573     struct IContext
    574     {
    575         virtual ~IContext();
    576 
    577         virtual IResultCapture* getResultCapture() = 0;
    578         virtual IRunner* getRunner() = 0;
    579         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
    580         virtual bool advanceGeneratorsForCurrentTest() = 0;
    581         virtual Ptr<IConfig const> getConfig() const = 0;
    582     };
    583 
    584     struct IMutableContext : IContext
    585     {
    586         virtual ~IMutableContext();
    587         virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
    588         virtual void setRunner( IRunner* runner ) = 0;
    589         virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
    590     };
    591 
    592     IContext& getCurrentContext();
    593     IMutableContext& getCurrentMutableContext();
    594     void cleanUpContext();
    595     Stream createStream( std::string const& streamName );
    596 
    597 }
    598 
    599 // #included from: internal/catch_test_registry.hpp
    600 #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
    601 
    602 // #included from: catch_interfaces_testcase.h
    603 #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
    604 
    605 #include <vector>
    606 
    607 namespace Catch {
    608 
    609     class TestSpec;
    610 
    611     struct ITestCase : IShared {
    612         virtual void invoke () const = 0;
    613     protected:
    614         virtual ~ITestCase();
    615     };
    616 
    617     class TestCase;
    618     struct IConfig;
    619 
    620     struct ITestCaseRegistry {
    621         virtual ~ITestCaseRegistry();
    622         virtual std::vector<TestCase> const& getAllTests() const = 0;
    623         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
    624     };
    625 
    626     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
    627     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
    628     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
    629 
    630 }
    631 
    632 namespace Catch {
    633 
    634 template<typename C>
    635 class MethodTestCase : public SharedImpl<ITestCase> {
    636 
    637 public:
    638     MethodTestCase( void (C::*method)() ) : m_method( method ) {}
    639 
    640     virtual void invoke() const {
    641         C obj;
    642         (obj.*m_method)();
    643     }
    644 
    645 private:
    646     virtual ~MethodTestCase() {}
    647 
    648     void (C::*m_method)();
    649 };
    650 
    651 typedef void(*TestFunction)();
    652 
    653 struct NameAndDesc {
    654     NameAndDesc( const char* _name = "", const char* _description= "" )
    655     : name( _name ), description( _description )
    656     {}
    657 
    658     const char* name;
    659     const char* description;
    660 };
    661 
    662 void registerTestCase
    663     (   ITestCase* testCase,
    664         char const* className,
    665         NameAndDesc const& nameAndDesc,
    666         SourceLineInfo const& lineInfo );
    667 
    668 struct AutoReg {
    669 
    670     AutoReg
    671         (   TestFunction function,
    672             SourceLineInfo const& lineInfo,
    673             NameAndDesc const& nameAndDesc );
    674 
    675     template<typename C>
    676     AutoReg
    677         (   void (C::*method)(),
    678             char const* className,
    679             NameAndDesc const& nameAndDesc,
    680             SourceLineInfo const& lineInfo ) {
    681 
    682         registerTestCase
    683             (   new MethodTestCase<C>( method ),
    684                 className,
    685                 nameAndDesc,
    686                 lineInfo );
    687     }
    688 
    689     ~AutoReg();
    690 
    691 private:
    692     AutoReg( AutoReg const& );
    693     void operator= ( AutoReg const& );
    694 };
    695 
    696 void registerTestCaseFunction
    697     (   TestFunction function,
    698         SourceLineInfo const& lineInfo,
    699         NameAndDesc const& nameAndDesc );
    700 
    701 } // end namespace Catch
    702 
    703 #ifdef CATCH_CONFIG_VARIADIC_MACROS
    704     ///////////////////////////////////////////////////////////////////////////////
    705     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
    706         static void TestName(); \
    707         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
    708         static void TestName()
    709     #define INTERNAL_CATCH_TESTCASE( ... ) \
    710         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
    711 
    712     ///////////////////////////////////////////////////////////////////////////////
    713     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
    714         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
    715 
    716     ///////////////////////////////////////////////////////////////////////////////
    717     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
    718         namespace{ \
    719             struct TestName : ClassName{ \
    720                 void test(); \
    721             }; \
    722             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
    723         } \
    724         void TestName::test()
    725     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
    726         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
    727 
    728     ///////////////////////////////////////////////////////////////////////////////
    729     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
    730         Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
    731 
    732 #else
    733     ///////////////////////////////////////////////////////////////////////////////
    734     #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
    735         static void TestName(); \
    736         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
    737         static void TestName()
    738     #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
    739         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
    740 
    741     ///////////////////////////////////////////////////////////////////////////////
    742     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
    743         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
    744 
    745     ///////////////////////////////////////////////////////////////////////////////
    746     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
    747         namespace{ \
    748             struct TestCaseName : ClassName{ \
    749                 void test(); \
    750             }; \
    751             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
    752         } \
    753         void TestCaseName::test()
    754     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
    755         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
    756 
    757     ///////////////////////////////////////////////////////////////////////////////
    758     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
    759         Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
    760 #endif
    761 
    762 // #included from: internal/catch_capture.hpp
    763 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
    764 
    765 // #included from: catch_result_builder.h
    766 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
    767 
    768 // #included from: catch_result_type.h
    769 #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
    770 
    771 namespace Catch {
    772 
    773     // ResultWas::OfType enum
    774     struct ResultWas { enum OfType {
    775         Unknown = -1,
    776         Ok = 0,
    777         Info = 1,
    778         Warning = 2,
    779 
    780         FailureBit = 0x10,
    781 
    782         ExpressionFailed = FailureBit | 1,
    783         ExplicitFailure = FailureBit | 2,
    784 
    785         Exception = 0x100 | FailureBit,
    786 
    787         ThrewException = Exception | 1,
    788         DidntThrowException = Exception | 2,
    789 
    790         FatalErrorCondition = 0x200 | FailureBit
    791 
    792     }; };
    793 
    794     inline bool isOk( ResultWas::OfType resultType ) {
    795         return ( resultType & ResultWas::FailureBit ) == 0;
    796     }
    797     inline bool isJustInfo( int flags ) {
    798         return flags == ResultWas::Info;
    799     }
    800 
    801     // ResultDisposition::Flags enum
    802     struct ResultDisposition { enum Flags {
    803         Normal = 0x01,
    804 
    805         ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
    806         FalseTest = 0x04,           // Prefix expression with !
    807         SuppressFail = 0x08         // Failures are reported but do not fail the test
    808     }; };
    809 
    810     inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
    811         return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
    812     }
    813 
    814     inline bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
    815     inline bool isFalseTest( int flags )                { return ( flags & ResultDisposition::FalseTest ) != 0; }
    816     inline bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
    817 
    818 } // end namespace Catch
    819 
    820 // #included from: catch_assertionresult.h
    821 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
    822 
    823 #include <string>
    824 
    825 namespace Catch {
    826 
    827     struct AssertionInfo
    828     {
    829         AssertionInfo() {}
    830         AssertionInfo(  std::string const& _macroName,
    831                         SourceLineInfo const& _lineInfo,
    832                         std::string const& _capturedExpression,
    833                         ResultDisposition::Flags _resultDisposition );
    834 
    835         std::string macroName;
    836         SourceLineInfo lineInfo;
    837         std::string capturedExpression;
    838         ResultDisposition::Flags resultDisposition;
    839     };
    840 
    841     struct AssertionResultData
    842     {
    843         AssertionResultData() : resultType( ResultWas::Unknown ) {}
    844 
    845         std::string reconstructedExpression;
    846         std::string message;
    847         ResultWas::OfType resultType;
    848     };
    849 
    850     class AssertionResult {
    851     public:
    852         AssertionResult();
    853         AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
    854         ~AssertionResult();
    855 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
    856          AssertionResult( AssertionResult const& )              = default;
    857          AssertionResult( AssertionResult && )                  = default;
    858          AssertionResult& operator = ( AssertionResult const& ) = default;
    859          AssertionResult& operator = ( AssertionResult && )     = default;
    860 #  endif
    861 
    862         bool isOk() const;
    863         bool succeeded() const;
    864         ResultWas::OfType getResultType() const;
    865         bool hasExpression() const;
    866         bool hasMessage() const;
    867         std::string getExpression() const;
    868         std::string getExpressionInMacro() const;
    869         bool hasExpandedExpression() const;
    870         std::string getExpandedExpression() const;
    871         std::string getMessage() const;
    872         SourceLineInfo getSourceInfo() const;
    873         std::string getTestMacroName() const;
    874 
    875     protected:
    876         AssertionInfo m_info;
    877         AssertionResultData m_resultData;
    878     };
    879 
    880 } // end namespace Catch
    881 
    882 // #included from: catch_matchers.hpp
    883 #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
    884 
    885 namespace Catch {
    886 namespace Matchers {
    887     namespace Impl {
    888 
    889     namespace Generic {
    890         template<typename ExpressionT> class AllOf;
    891         template<typename ExpressionT> class AnyOf;
    892         template<typename ExpressionT> class Not;
    893     }
    894 
    895     template<typename ExpressionT>
    896     struct Matcher : SharedImpl<IShared>
    897     {
    898         typedef ExpressionT ExpressionType;
    899 
    900         virtual ~Matcher() {}
    901         virtual Ptr<Matcher> clone() const = 0;
    902         virtual bool match( ExpressionT const& expr ) const = 0;
    903         virtual std::string toString() const = 0;
    904 
    905         Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;
    906         Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;
    907         Generic::Not<ExpressionT> operator ! () const;
    908     };
    909 
    910     template<typename DerivedT, typename ExpressionT>
    911     struct MatcherImpl : Matcher<ExpressionT> {
    912 
    913         virtual Ptr<Matcher<ExpressionT> > clone() const {
    914             return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
    915         }
    916     };
    917 
    918     namespace Generic {
    919         template<typename ExpressionT>
    920         class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {
    921         public:
    922             explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
    923             Not( Not const& other ) : m_matcher( other.m_matcher ) {}
    924 
    925             virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
    926                 return !m_matcher->match( expr );
    927             }
    928 
    929             virtual std::string toString() const CATCH_OVERRIDE {
    930                 return "not " + m_matcher->toString();
    931             }
    932         private:
    933             Ptr< Matcher<ExpressionT> > m_matcher;
    934         };
    935 
    936         template<typename ExpressionT>
    937         class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
    938         public:
    939 
    940             AllOf() {}
    941             AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
    942 
    943             AllOf& add( Matcher<ExpressionT> const& matcher ) {
    944                 m_matchers.push_back( matcher.clone() );
    945                 return *this;
    946             }
    947             virtual bool match( ExpressionT const& expr ) const
    948             {
    949                 for( std::size_t i = 0; i < m_matchers.size(); ++i )
    950                     if( !m_matchers[i]->match( expr ) )
    951                         return false;
    952                 return true;
    953             }
    954             virtual std::string toString() const {
    955                 std::ostringstream oss;
    956                 oss << "( ";
    957                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
    958                     if( i != 0 )
    959                         oss << " and ";
    960                     oss << m_matchers[i]->toString();
    961                 }
    962                 oss << " )";
    963                 return oss.str();
    964             }
    965 
    966             AllOf operator && ( Matcher<ExpressionT> const& other ) const {
    967                 AllOf allOfExpr( *this );
    968                 allOfExpr.add( other );
    969                 return allOfExpr;
    970             }
    971 
    972         private:
    973             std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
    974         };
    975 
    976         template<typename ExpressionT>
    977         class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
    978         public:
    979 
    980             AnyOf() {}
    981             AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
    982 
    983             AnyOf& add( Matcher<ExpressionT> const& matcher ) {
    984                 m_matchers.push_back( matcher.clone() );
    985                 return *this;
    986             }
    987             virtual bool match( ExpressionT const& expr ) const
    988             {
    989                 for( std::size_t i = 0; i < m_matchers.size(); ++i )
    990                     if( m_matchers[i]->match( expr ) )
    991                         return true;
    992                 return false;
    993             }
    994             virtual std::string toString() const {
    995                 std::ostringstream oss;
    996                 oss << "( ";
    997                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
    998                     if( i != 0 )
    999                         oss << " or ";
   1000                     oss << m_matchers[i]->toString();
   1001                 }
   1002                 oss << " )";
   1003                 return oss.str();
   1004             }
   1005 
   1006             AnyOf operator || ( Matcher<ExpressionT> const& other ) const {
   1007                 AnyOf anyOfExpr( *this );
   1008                 anyOfExpr.add( other );
   1009                 return anyOfExpr;
   1010             }
   1011 
   1012         private:
   1013             std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
   1014         };
   1015 
   1016     } // namespace Generic
   1017 
   1018     template<typename ExpressionT>
   1019     Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {
   1020         Generic::AllOf<ExpressionT> allOfExpr;
   1021         allOfExpr.add( *this );
   1022         allOfExpr.add( other );
   1023         return allOfExpr;
   1024     }
   1025 
   1026     template<typename ExpressionT>
   1027     Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {
   1028         Generic::AnyOf<ExpressionT> anyOfExpr;
   1029         anyOfExpr.add( *this );
   1030         anyOfExpr.add( other );
   1031         return anyOfExpr;
   1032     }
   1033 
   1034     template<typename ExpressionT>
   1035     Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {
   1036         return Generic::Not<ExpressionT>( *this );
   1037     }
   1038 
   1039     namespace StdString {
   1040 
   1041         inline std::string makeString( std::string const& str ) { return str; }
   1042         inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
   1043 
   1044         struct CasedString
   1045         {
   1046             CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
   1047             :   m_caseSensitivity( caseSensitivity ),
   1048                 m_str( adjustString( str ) )
   1049             {}
   1050             std::string adjustString( std::string const& str ) const {
   1051                 return m_caseSensitivity == CaseSensitive::No
   1052                     ? toLower( str )
   1053                     : str;
   1054 
   1055             }
   1056             std::string toStringSuffix() const
   1057             {
   1058                 return m_caseSensitivity == CaseSensitive::No
   1059                     ? " (case insensitive)"
   1060                     : "";
   1061             }
   1062             CaseSensitive::Choice m_caseSensitivity;
   1063             std::string m_str;
   1064         };
   1065 
   1066         struct Equals : MatcherImpl<Equals, std::string> {
   1067             Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
   1068             :   m_data( str, caseSensitivity )
   1069             {}
   1070             Equals( Equals const& other ) : m_data( other.m_data ){}
   1071 
   1072             virtual ~Equals();
   1073 
   1074             virtual bool match( std::string const& expr ) const {
   1075                 return m_data.m_str == m_data.adjustString( expr );;
   1076             }
   1077             virtual std::string toString() const {
   1078                 return "equals: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
   1079             }
   1080 
   1081             CasedString m_data;
   1082         };
   1083 
   1084         struct Contains : MatcherImpl<Contains, std::string> {
   1085             Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
   1086             : m_data( substr, caseSensitivity ){}
   1087             Contains( Contains const& other ) : m_data( other.m_data ){}
   1088 
   1089             virtual ~Contains();
   1090 
   1091             virtual bool match( std::string const& expr ) const {
   1092                 return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
   1093             }
   1094             virtual std::string toString() const {
   1095                 return "contains: \"" + m_data.m_str  + "\"" + m_data.toStringSuffix();
   1096             }
   1097 
   1098             CasedString m_data;
   1099         };
   1100 
   1101         struct StartsWith : MatcherImpl<StartsWith, std::string> {
   1102             StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
   1103             : m_data( substr, caseSensitivity ){}
   1104 
   1105             StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
   1106 
   1107             virtual ~StartsWith();
   1108 
   1109             virtual bool match( std::string const& expr ) const {
   1110                 return startsWith( m_data.adjustString( expr ), m_data.m_str );
   1111             }
   1112             virtual std::string toString() const {
   1113                 return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
   1114             }
   1115 
   1116             CasedString m_data;
   1117         };
   1118 
   1119         struct EndsWith : MatcherImpl<EndsWith, std::string> {
   1120             EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
   1121             : m_data( substr, caseSensitivity ){}
   1122             EndsWith( EndsWith const& other ) : m_data( other.m_data ){}
   1123 
   1124             virtual ~EndsWith();
   1125 
   1126             virtual bool match( std::string const& expr ) const {
   1127                 return endsWith( m_data.adjustString( expr ), m_data.m_str );
   1128             }
   1129             virtual std::string toString() const {
   1130                 return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
   1131             }
   1132 
   1133             CasedString m_data;
   1134         };
   1135     } // namespace StdString
   1136     } // namespace Impl
   1137 
   1138     // The following functions create the actual matcher objects.
   1139     // This allows the types to be inferred
   1140     template<typename ExpressionT>
   1141     inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {
   1142         return Impl::Generic::Not<ExpressionT>( m );
   1143     }
   1144 
   1145     template<typename ExpressionT>
   1146     inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
   1147                                                     Impl::Matcher<ExpressionT> const& m2 ) {
   1148         return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
   1149     }
   1150     template<typename ExpressionT>
   1151     inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
   1152                                                     Impl::Matcher<ExpressionT> const& m2,
   1153                                                     Impl::Matcher<ExpressionT> const& m3 ) {
   1154         return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
   1155     }
   1156     template<typename ExpressionT>
   1157     inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
   1158                                                     Impl::Matcher<ExpressionT> const& m2 ) {
   1159         return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
   1160     }
   1161     template<typename ExpressionT>
   1162     inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
   1163                                                     Impl::Matcher<ExpressionT> const& m2,
   1164                                                     Impl::Matcher<ExpressionT> const& m3 ) {
   1165         return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
   1166     }
   1167 
   1168     inline Impl::StdString::Equals      Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
   1169         return Impl::StdString::Equals( str, caseSensitivity );
   1170     }
   1171     inline Impl::StdString::Equals      Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
   1172         return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );
   1173     }
   1174     inline Impl::StdString::Contains    Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
   1175         return Impl::StdString::Contains( substr, caseSensitivity );
   1176     }
   1177     inline Impl::StdString::Contains    Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
   1178         return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );
   1179     }
   1180     inline Impl::StdString::StartsWith  StartsWith( std::string const& substr ) {
   1181         return Impl::StdString::StartsWith( substr );
   1182     }
   1183     inline Impl::StdString::StartsWith  StartsWith( const char* substr ) {
   1184         return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
   1185     }
   1186     inline Impl::StdString::EndsWith    EndsWith( std::string const& substr ) {
   1187         return Impl::StdString::EndsWith( substr );
   1188     }
   1189     inline Impl::StdString::EndsWith    EndsWith( const char* substr ) {
   1190         return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
   1191     }
   1192 
   1193 } // namespace Matchers
   1194 
   1195 using namespace Matchers;
   1196 
   1197 } // namespace Catch
   1198 
   1199 namespace Catch {
   1200 
   1201     struct TestFailureException{};
   1202 
   1203     template<typename T> class ExpressionLhs;
   1204 
   1205     struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
   1206 
   1207     struct CopyableStream {
   1208         CopyableStream() {}
   1209         CopyableStream( CopyableStream const& other ) {
   1210             oss << other.oss.str();
   1211         }
   1212         CopyableStream& operator=( CopyableStream const& other ) {
   1213             oss.str("");
   1214             oss << other.oss.str();
   1215             return *this;
   1216         }
   1217         std::ostringstream oss;
   1218     };
   1219 
   1220     class ResultBuilder {
   1221     public:
   1222         ResultBuilder(  char const* macroName,
   1223                         SourceLineInfo const& lineInfo,
   1224                         char const* capturedExpression,
   1225                         ResultDisposition::Flags resultDisposition,
   1226                         char const* secondArg = "" );
   1227 
   1228         template<typename T>
   1229         ExpressionLhs<T const&> operator <= ( T const& operand );
   1230         ExpressionLhs<bool> operator <= ( bool value );
   1231 
   1232         template<typename T>
   1233         ResultBuilder& operator << ( T const& value ) {
   1234             m_stream.oss << value;
   1235             return *this;
   1236         }
   1237 
   1238         template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
   1239         template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
   1240 
   1241         ResultBuilder& setResultType( ResultWas::OfType result );
   1242         ResultBuilder& setResultType( bool result );
   1243         ResultBuilder& setLhs( std::string const& lhs );
   1244         ResultBuilder& setRhs( std::string const& rhs );
   1245         ResultBuilder& setOp( std::string const& op );
   1246 
   1247         void endExpression();
   1248 
   1249         std::string reconstructExpression() const;
   1250         AssertionResult build() const;
   1251 
   1252         void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
   1253         void captureResult( ResultWas::OfType resultType );
   1254         void captureExpression();
   1255         void captureExpectedException( std::string const& expectedMessage );
   1256         void captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher );
   1257         void handleResult( AssertionResult const& result );
   1258         void react();
   1259         bool shouldDebugBreak() const;
   1260         bool allowThrows() const;
   1261 
   1262     private:
   1263         AssertionInfo m_assertionInfo;
   1264         AssertionResultData m_data;
   1265         struct ExprComponents {
   1266             ExprComponents() : testFalse( false ) {}
   1267             bool testFalse;
   1268             std::string lhs, rhs, op;
   1269         } m_exprComponents;
   1270         CopyableStream m_stream;
   1271 
   1272         bool m_shouldDebugBreak;
   1273         bool m_shouldThrow;
   1274     };
   1275 
   1276 } // namespace Catch
   1277 
   1278 // Include after due to circular dependency:
   1279 // #included from: catch_expression_lhs.hpp
   1280 #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
   1281 
   1282 // #included from: catch_evaluate.hpp
   1283 #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
   1284 
   1285 #ifdef _MSC_VER
   1286 #pragma warning(push)
   1287 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
   1288 #endif
   1289 
   1290 #include <cstddef>
   1291 
   1292 namespace Catch {
   1293 namespace Internal {
   1294 
   1295     enum Operator {
   1296         IsEqualTo,
   1297         IsNotEqualTo,
   1298         IsLessThan,
   1299         IsGreaterThan,
   1300         IsLessThanOrEqualTo,
   1301         IsGreaterThanOrEqualTo
   1302     };
   1303 
   1304     template<Operator Op> struct OperatorTraits             { static const char* getName(){ return "*error*"; } };
   1305     template<> struct OperatorTraits<IsEqualTo>             { static const char* getName(){ return "=="; } };
   1306     template<> struct OperatorTraits<IsNotEqualTo>          { static const char* getName(){ return "!="; } };
   1307     template<> struct OperatorTraits<IsLessThan>            { static const char* getName(){ return "<"; } };
   1308     template<> struct OperatorTraits<IsGreaterThan>         { static const char* getName(){ return ">"; } };
   1309     template<> struct OperatorTraits<IsLessThanOrEqualTo>   { static const char* getName(){ return "<="; } };
   1310     template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
   1311 
   1312     template<typename T>
   1313     inline T& opCast(T const& t) { return const_cast<T&>(t); }
   1314 
   1315 // nullptr_t support based on pull request #154 from Konstantin Baumann
   1316 #ifdef CATCH_CONFIG_CPP11_NULLPTR
   1317     inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
   1318 #endif // CATCH_CONFIG_CPP11_NULLPTR
   1319 
   1320     // So the compare overloads can be operator agnostic we convey the operator as a template
   1321     // enum, which is used to specialise an Evaluator for doing the comparison.
   1322     template<typename T1, typename T2, Operator Op>
   1323     class Evaluator{};
   1324 
   1325     template<typename T1, typename T2>
   1326     struct Evaluator<T1, T2, IsEqualTo> {
   1327         static bool evaluate( T1 const& lhs, T2 const& rhs) {
   1328             return bool( opCast( lhs ) ==  opCast( rhs ) );
   1329         }
   1330     };
   1331     template<typename T1, typename T2>
   1332     struct Evaluator<T1, T2, IsNotEqualTo> {
   1333         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
   1334             return bool( opCast( lhs ) != opCast( rhs ) );
   1335         }
   1336     };
   1337     template<typename T1, typename T2>
   1338     struct Evaluator<T1, T2, IsLessThan> {
   1339         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
   1340             return bool( opCast( lhs ) < opCast( rhs ) );
   1341         }
   1342     };
   1343     template<typename T1, typename T2>
   1344     struct Evaluator<T1, T2, IsGreaterThan> {
   1345         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
   1346             return bool( opCast( lhs ) > opCast( rhs ) );
   1347         }
   1348     };
   1349     template<typename T1, typename T2>
   1350     struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
   1351         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
   1352             return bool( opCast( lhs ) >= opCast( rhs ) );
   1353         }
   1354     };
   1355     template<typename T1, typename T2>
   1356     struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
   1357         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
   1358             return bool( opCast( lhs ) <= opCast( rhs ) );
   1359         }
   1360     };
   1361 
   1362     template<Operator Op, typename T1, typename T2>
   1363     bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
   1364         return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
   1365     }
   1366 
   1367     // This level of indirection allows us to specialise for integer types
   1368     // to avoid signed/ unsigned warnings
   1369 
   1370     // "base" overload
   1371     template<Operator Op, typename T1, typename T2>
   1372     bool compare( T1 const& lhs, T2 const& rhs ) {
   1373         return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
   1374     }
   1375 
   1376     // unsigned X to int
   1377     template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
   1378         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
   1379     }
   1380     template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
   1381         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
   1382     }
   1383     template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
   1384         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
   1385     }
   1386 
   1387     // unsigned X to long
   1388     template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
   1389         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
   1390     }
   1391     template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
   1392         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
   1393     }
   1394     template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
   1395         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
   1396     }
   1397 
   1398     // int to unsigned X
   1399     template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
   1400         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
   1401     }
   1402     template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
   1403         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
   1404     }
   1405     template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
   1406         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
   1407     }
   1408 
   1409     // long to unsigned X
   1410     template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
   1411         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
   1412     }
   1413     template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
   1414         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
   1415     }
   1416     template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
   1417         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
   1418     }
   1419 
   1420     // pointer to long (when comparing against NULL)
   1421     template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
   1422         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
   1423     }
   1424     template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
   1425         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
   1426     }
   1427 
   1428     // pointer to int (when comparing against NULL)
   1429     template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
   1430         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
   1431     }
   1432     template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
   1433         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
   1434     }
   1435 
   1436 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
   1437     // long long to unsigned X
   1438     template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
   1439         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
   1440     }
   1441     template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
   1442         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
   1443     }
   1444     template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
   1445         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
   1446     }
   1447     template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
   1448         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
   1449     }
   1450 
   1451     // unsigned long long to X
   1452     template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
   1453         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
   1454     }
   1455     template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
   1456         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
   1457     }
   1458     template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
   1459         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
   1460     }
   1461     template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
   1462         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
   1463     }
   1464 
   1465     // pointer to long long (when comparing against NULL)
   1466     template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
   1467         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
   1468     }
   1469     template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
   1470         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
   1471     }
   1472 #endif // CATCH_CONFIG_CPP11_LONG_LONG
   1473 
   1474 #ifdef CATCH_CONFIG_CPP11_NULLPTR
   1475     // pointer to nullptr_t (when comparing against nullptr)
   1476     template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
   1477         return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
   1478     }
   1479     template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
   1480         return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
   1481     }
   1482 #endif // CATCH_CONFIG_CPP11_NULLPTR
   1483 
   1484 } // end of namespace Internal
   1485 } // end of namespace Catch
   1486 
   1487 #ifdef _MSC_VER
   1488 #pragma warning(pop)
   1489 #endif
   1490 
   1491 // #included from: catch_tostring.h
   1492 #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
   1493 
   1494 #include <sstream>
   1495 #include <iomanip>
   1496 #include <limits>
   1497 #include <vector>
   1498 #include <cstddef>
   1499 
   1500 #ifdef __OBJC__
   1501 // #included from: catch_objc_arc.hpp
   1502 #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
   1503 
   1504 #import <Foundation/Foundation.h>
   1505 
   1506 #ifdef __has_feature
   1507 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
   1508 #else
   1509 #define CATCH_ARC_ENABLED 0
   1510 #endif
   1511 
   1512 void arcSafeRelease( NSObject* obj );
   1513 id performOptionalSelector( id obj, SEL sel );
   1514 
   1515 #if !CATCH_ARC_ENABLED
   1516 inline void arcSafeRelease( NSObject* obj ) {
   1517     [obj release];
   1518 }
   1519 inline id performOptionalSelector( id obj, SEL sel ) {
   1520     if( [obj respondsToSelector: sel] )
   1521         return [obj performSelector: sel];
   1522     return nil;
   1523 }
   1524 #define CATCH_UNSAFE_UNRETAINED
   1525 #define CATCH_ARC_STRONG
   1526 #else
   1527 inline void arcSafeRelease( NSObject* ){}
   1528 inline id performOptionalSelector( id obj, SEL sel ) {
   1529 #ifdef __clang__
   1530 #pragma clang diagnostic push
   1531 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
   1532 #endif
   1533     if( [obj respondsToSelector: sel] )
   1534         return [obj performSelector: sel];
   1535 #ifdef __clang__
   1536 #pragma clang diagnostic pop
   1537 #endif
   1538     return nil;
   1539 }
   1540 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
   1541 #define CATCH_ARC_STRONG __strong
   1542 #endif
   1543 
   1544 #endif
   1545 
   1546 #ifdef CATCH_CONFIG_CPP11_TUPLE
   1547 #include <tuple>
   1548 #endif
   1549 
   1550 #ifdef CATCH_CONFIG_CPP11_IS_ENUM
   1551 #include <type_traits>
   1552 #endif
   1553 
   1554 namespace Catch {
   1555 
   1556 // Why we're here.
   1557 template<typename T>
   1558 std::string toString( T const& value );
   1559 
   1560 // Built in overloads
   1561 
   1562 std::string toString( std::string const& value );
   1563 std::string toString( std::wstring const& value );
   1564 std::string toString( const char* const value );
   1565 std::string toString( char* const value );
   1566 std::string toString( const wchar_t* const value );
   1567 std::string toString( wchar_t* const value );
   1568 std::string toString( int value );
   1569 std::string toString( unsigned long value );
   1570 std::string toString( unsigned int value );
   1571 std::string toString( const double value );
   1572 std::string toString( const float value );
   1573 std::string toString( bool value );
   1574 std::string toString( char value );
   1575 std::string toString( signed char value );
   1576 std::string toString( unsigned char value );
   1577 
   1578 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
   1579 std::string toString( long long value );
   1580 std::string toString( unsigned long long value );
   1581 #endif
   1582 
   1583 #ifdef CATCH_CONFIG_CPP11_NULLPTR
   1584 std::string toString( std::nullptr_t );
   1585 #endif
   1586 
   1587 #ifdef __OBJC__
   1588     std::string toString( NSString const * const& nsstring );
   1589     std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
   1590     std::string toString( NSObject* const& nsObject );
   1591 #endif
   1592 
   1593 namespace Detail {
   1594 
   1595     extern const std::string unprintableString;
   1596 
   1597     struct BorgType {
   1598         template<typename T> BorgType( T const& );
   1599     };
   1600 
   1601     struct TrueType { char sizer[1]; };
   1602     struct FalseType { char sizer[2]; };
   1603 
   1604     TrueType& testStreamable( std::ostream& );
   1605     FalseType testStreamable( FalseType );
   1606 
   1607     FalseType operator<<( std::ostream const&, BorgType const& );
   1608 
   1609     template<typename T>
   1610     struct IsStreamInsertable {
   1611         static std::ostream &s;
   1612         static T  const&t;
   1613         enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
   1614     };
   1615 
   1616 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
   1617     template<typename T,
   1618              bool IsEnum = std::is_enum<T>::value
   1619              >
   1620     struct EnumStringMaker
   1621     {
   1622         static std::string convert( T const& ) { return unprintableString; }
   1623     };
   1624 
   1625     template<typename T>
   1626     struct EnumStringMaker<T,true>
   1627     {
   1628         static std::string convert( T const& v )
   1629         {
   1630             return ::Catch::toString(
   1631                 static_cast<typename std::underlying_type<T>::type>(v)
   1632                 );
   1633         }
   1634     };
   1635 #endif
   1636     template<bool C>
   1637     struct StringMakerBase {
   1638 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
   1639         template<typename T>
   1640         static std::string convert( T const& v )
   1641         {
   1642             return EnumStringMaker<T>::convert( v );
   1643         }
   1644 #else
   1645         template<typename T>
   1646         static std::string convert( T const& ) { return unprintableString; }
   1647 #endif
   1648     };
   1649 
   1650     template<>
   1651     struct StringMakerBase<true> {
   1652         template<typename T>
   1653         static std::string convert( T const& _value ) {
   1654             std::ostringstream oss;
   1655             oss << _value;
   1656             return oss.str();
   1657         }
   1658     };
   1659 
   1660     std::string rawMemoryToString( const void *object, std::size_t size );
   1661 
   1662     template<typename T>
   1663     inline std::string rawMemoryToString( const T& object ) {
   1664       return rawMemoryToString( &object, sizeof(object) );
   1665     }
   1666 
   1667 } // end namespace Detail
   1668 
   1669 template<typename T>
   1670 struct StringMaker :
   1671     Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
   1672 
   1673 template<typename T>
   1674 struct StringMaker<T*> {
   1675     template<typename U>
   1676     static std::string convert( U* p ) {
   1677         if( !p )
   1678             return "NULL";
   1679         else
   1680             return Detail::rawMemoryToString( p );
   1681     }
   1682 };
   1683 
   1684 template<typename R, typename C>
   1685 struct StringMaker<R C::*> {
   1686     static std::string convert( R C::* p ) {
   1687         if( !p )
   1688             return "NULL";
   1689         else
   1690             return Detail::rawMemoryToString( p );
   1691     }
   1692 };
   1693 
   1694 namespace Detail {
   1695     template<typename InputIterator>
   1696     std::string rangeToString( InputIterator first, InputIterator last );
   1697 }
   1698 
   1699 //template<typename T, typename Allocator>
   1700 //struct StringMaker<std::vector<T, Allocator> > {
   1701 //    static std::string convert( std::vector<T,Allocator> const& v ) {
   1702 //        return Detail::rangeToString( v.begin(), v.end() );
   1703 //    }
   1704 //};
   1705 
   1706 template<typename T, typename Allocator>
   1707 std::string toString( std::vector<T,Allocator> const& v ) {
   1708     return Detail::rangeToString( v.begin(), v.end() );
   1709 }
   1710 
   1711 #ifdef CATCH_CONFIG_CPP11_TUPLE
   1712 
   1713 // toString for tuples
   1714 namespace TupleDetail {
   1715   template<
   1716       typename Tuple,
   1717       std::size_t N = 0,
   1718       bool = (N < std::tuple_size<Tuple>::value)
   1719       >
   1720   struct ElementPrinter {
   1721       static void print( const Tuple& tuple, std::ostream& os )
   1722       {
   1723           os << ( N ? ", " : " " )
   1724              << Catch::toString(std::get<N>(tuple));
   1725           ElementPrinter<Tuple,N+1>::print(tuple,os);
   1726       }
   1727   };
   1728 
   1729   template<
   1730       typename Tuple,
   1731       std::size_t N
   1732       >
   1733   struct ElementPrinter<Tuple,N,false> {
   1734       static void print( const Tuple&, std::ostream& ) {}
   1735   };
   1736 
   1737 }
   1738 
   1739 template<typename ...Types>
   1740 struct StringMaker<std::tuple<Types...>> {
   1741 
   1742     static std::string convert( const std::tuple<Types...>& tuple )
   1743     {
   1744         std::ostringstream os;
   1745         os << '{';
   1746         TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
   1747         os << " }";
   1748         return os.str();
   1749     }
   1750 };
   1751 #endif // CATCH_CONFIG_CPP11_TUPLE
   1752 
   1753 namespace Detail {
   1754     template<typename T>
   1755     std::string makeString( T const& value ) {
   1756         return StringMaker<T>::convert( value );
   1757     }
   1758 } // end namespace Detail
   1759 
   1760 /// \brief converts any type to a string
   1761 ///
   1762 /// The default template forwards on to ostringstream - except when an
   1763 /// ostringstream overload does not exist - in which case it attempts to detect
   1764 /// that and writes {?}.
   1765 /// Overload (not specialise) this template for custom typs that you don't want
   1766 /// to provide an ostream overload for.
   1767 template<typename T>
   1768 std::string toString( T const& value ) {
   1769     return StringMaker<T>::convert( value );
   1770 }
   1771 
   1772     namespace Detail {
   1773     template<typename InputIterator>
   1774     std::string rangeToString( InputIterator first, InputIterator last ) {
   1775         std::ostringstream oss;
   1776         oss << "{ ";
   1777         if( first != last ) {
   1778             oss << Catch::toString( *first );
   1779             for( ++first ; first != last ; ++first )
   1780                 oss << ", " << Catch::toString( *first );
   1781         }
   1782         oss << " }";
   1783         return oss.str();
   1784     }
   1785 }
   1786 
   1787 } // end namespace Catch
   1788 
   1789 namespace Catch {
   1790 
   1791 // Wraps the LHS of an expression and captures the operator and RHS (if any) -
   1792 // wrapping them all in a ResultBuilder object
   1793 template<typename T>
   1794 class ExpressionLhs {
   1795     ExpressionLhs& operator = ( ExpressionLhs const& );
   1796 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
   1797     ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
   1798 #  endif
   1799 
   1800 public:
   1801     ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
   1802 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
   1803     ExpressionLhs( ExpressionLhs const& ) = default;
   1804     ExpressionLhs( ExpressionLhs && )     = default;
   1805 #  endif
   1806 
   1807     template<typename RhsT>
   1808     ResultBuilder& operator == ( RhsT const& rhs ) {
   1809         return captureExpression<Internal::IsEqualTo>( rhs );
   1810     }
   1811 
   1812     template<typename RhsT>
   1813     ResultBuilder& operator != ( RhsT const& rhs ) {
   1814         return captureExpression<Internal::IsNotEqualTo>( rhs );
   1815     }
   1816 
   1817     template<typename RhsT>
   1818     ResultBuilder& operator < ( RhsT const& rhs ) {
   1819         return captureExpression<Internal::IsLessThan>( rhs );
   1820     }
   1821 
   1822     template<typename RhsT>
   1823     ResultBuilder& operator > ( RhsT const& rhs ) {
   1824         return captureExpression<Internal::IsGreaterThan>( rhs );
   1825     }
   1826 
   1827     template<typename RhsT>
   1828     ResultBuilder& operator <= ( RhsT const& rhs ) {
   1829         return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
   1830     }
   1831 
   1832     template<typename RhsT>
   1833     ResultBuilder& operator >= ( RhsT const& rhs ) {
   1834         return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
   1835     }
   1836 
   1837     ResultBuilder& operator == ( bool rhs ) {
   1838         return captureExpression<Internal::IsEqualTo>( rhs );
   1839     }
   1840 
   1841     ResultBuilder& operator != ( bool rhs ) {
   1842         return captureExpression<Internal::IsNotEqualTo>( rhs );
   1843     }
   1844 
   1845     void endExpression() {
   1846         bool value = m_lhs ? true : false;
   1847         m_rb
   1848             .setLhs( Catch::toString( value ) )
   1849             .setResultType( value )
   1850             .endExpression();
   1851     }
   1852 
   1853     // Only simple binary expressions are allowed on the LHS.
   1854     // If more complex compositions are required then place the sub expression in parentheses
   1855     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
   1856     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
   1857     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
   1858     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
   1859     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
   1860     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
   1861 
   1862 private:
   1863     template<Internal::Operator Op, typename RhsT>
   1864     ResultBuilder& captureExpression( RhsT const& rhs ) {
   1865         return m_rb
   1866             .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
   1867             .setLhs( Catch::toString( m_lhs ) )
   1868             .setRhs( Catch::toString( rhs ) )
   1869             .setOp( Internal::OperatorTraits<Op>::getName() );
   1870     }
   1871 
   1872 private:
   1873     ResultBuilder& m_rb;
   1874     T m_lhs;
   1875 };
   1876 
   1877 } // end namespace Catch
   1878 
   1879 
   1880 namespace Catch {
   1881 
   1882     template<typename T>
   1883     inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
   1884         return ExpressionLhs<T const&>( *this, operand );
   1885     }
   1886 
   1887     inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
   1888         return ExpressionLhs<bool>( *this, value );
   1889     }
   1890 
   1891 } // namespace Catch
   1892 
   1893 // #included from: catch_message.h
   1894 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
   1895 
   1896 #include <string>
   1897 
   1898 namespace Catch {
   1899 
   1900     struct MessageInfo {
   1901         MessageInfo(    std::string const& _macroName,
   1902                         SourceLineInfo const& _lineInfo,
   1903                         ResultWas::OfType _type );
   1904 
   1905         std::string macroName;
   1906         SourceLineInfo lineInfo;
   1907         ResultWas::OfType type;
   1908         std::string message;
   1909         unsigned int sequence;
   1910 
   1911         bool operator == ( MessageInfo const& other ) const {
   1912             return sequence == other.sequence;
   1913         }
   1914         bool operator < ( MessageInfo const& other ) const {
   1915             return sequence < other.sequence;
   1916         }
   1917     private:
   1918         static unsigned int globalCount;
   1919     };
   1920 
   1921     struct MessageBuilder {
   1922         MessageBuilder( std::string const& macroName,
   1923                         SourceLineInfo const& lineInfo,
   1924                         ResultWas::OfType type )
   1925         : m_info( macroName, lineInfo, type )
   1926         {}
   1927 
   1928         template<typename T>
   1929         MessageBuilder& operator << ( T const& value ) {
   1930             m_stream << value;
   1931             return *this;
   1932         }
   1933 
   1934         MessageInfo m_info;
   1935         std::ostringstream m_stream;
   1936     };
   1937 
   1938     class ScopedMessage {
   1939     public:
   1940         ScopedMessage( MessageBuilder const& builder );
   1941         ScopedMessage( ScopedMessage const& other );
   1942         ~ScopedMessage();
   1943 
   1944         MessageInfo m_info;
   1945     };
   1946 
   1947 } // end namespace Catch
   1948 
   1949 // #included from: catch_interfaces_capture.h
   1950 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
   1951 
   1952 #include <string>
   1953 
   1954 namespace Catch {
   1955 
   1956     class TestCase;
   1957     class AssertionResult;
   1958     struct AssertionInfo;
   1959     struct SectionInfo;
   1960     struct SectionEndInfo;
   1961     struct MessageInfo;
   1962     class ScopedMessageBuilder;
   1963     struct Counts;
   1964 
   1965     struct IResultCapture {
   1966 
   1967         virtual ~IResultCapture();
   1968 
   1969         virtual void assertionEnded( AssertionResult const& result ) = 0;
   1970         virtual bool sectionStarted(    SectionInfo const& sectionInfo,
   1971                                         Counts& assertions ) = 0;
   1972         virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
   1973         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
   1974         virtual void pushScopedMessage( MessageInfo const& message ) = 0;
   1975         virtual void popScopedMessage( MessageInfo const& message ) = 0;
   1976 
   1977         virtual std::string getCurrentTestName() const = 0;
   1978         virtual const AssertionResult* getLastResult() const = 0;
   1979 
   1980         virtual void handleFatalErrorCondition( std::string const& message ) = 0;
   1981     };
   1982 
   1983     IResultCapture& getResultCapture();
   1984 }
   1985 
   1986 // #included from: catch_debugger.h
   1987 #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
   1988 
   1989 // #included from: catch_platform.h
   1990 #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
   1991 
   1992 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
   1993 #define CATCH_PLATFORM_MAC
   1994 #elif  defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
   1995 #define CATCH_PLATFORM_IPHONE
   1996 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
   1997 #define CATCH_PLATFORM_WINDOWS
   1998 #endif
   1999 
   2000 #include <string>
   2001 
   2002 namespace Catch{
   2003 
   2004     bool isDebuggerActive();
   2005     void writeToDebugConsole( std::string const& text );
   2006 }
   2007 
   2008 #ifdef CATCH_PLATFORM_MAC
   2009 
   2010     // The following code snippet based on:
   2011     // http://cocoawithlove.com/2008/03/break-into-debugger.html
   2012     #ifdef DEBUG
   2013         #if defined(__ppc64__) || defined(__ppc__)
   2014             #define CATCH_BREAK_INTO_DEBUGGER() \
   2015                 if( Catch::isDebuggerActive() ) { \
   2016                     __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
   2017                     : : : "memory","r0","r3","r4" ); \
   2018                 }
   2019         #else
   2020             #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
   2021         #endif
   2022     #endif
   2023 
   2024 #elif defined(_MSC_VER)
   2025     #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
   2026 #elif defined(__MINGW32__)
   2027     extern "C" __declspec(dllimport) void __stdcall DebugBreak();
   2028     #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
   2029 #endif
   2030 
   2031 #ifndef CATCH_BREAK_INTO_DEBUGGER
   2032 #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
   2033 #endif
   2034 
   2035 // #included from: catch_interfaces_runner.h
   2036 #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
   2037 
   2038 namespace Catch {
   2039     class TestCase;
   2040 
   2041     struct IRunner {
   2042         virtual ~IRunner();
   2043         virtual bool aborting() const = 0;
   2044     };
   2045 }
   2046 
   2047 ///////////////////////////////////////////////////////////////////////////////
   2048 // In the event of a failure works out if the debugger needs to be invoked
   2049 // and/or an exception thrown and takes appropriate action.
   2050 // This needs to be done as a macro so the debugger will stop in the user
   2051 // source code rather than in Catch library code
   2052 #define INTERNAL_CATCH_REACT( resultBuilder ) \
   2053     if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
   2054     resultBuilder.react();
   2055 
   2056 ///////////////////////////////////////////////////////////////////////////////
   2057 #define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
   2058     do { \
   2059         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
   2060         try { \
   2061             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
   2062             ( __catchResult <= expr ).endExpression(); \
   2063         } \
   2064         catch( ... ) { \
   2065             __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
   2066         } \
   2067         INTERNAL_CATCH_REACT( __catchResult ) \
   2068     } while( Catch::isTrue( false && static_cast<bool>(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
   2069 
   2070 ///////////////////////////////////////////////////////////////////////////////
   2071 #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
   2072     INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
   2073     if( Catch::getResultCapture().getLastResult()->succeeded() )
   2074 
   2075 ///////////////////////////////////////////////////////////////////////////////
   2076 #define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
   2077     INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
   2078     if( !Catch::getResultCapture().getLastResult()->succeeded() )
   2079 
   2080 ///////////////////////////////////////////////////////////////////////////////
   2081 #define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
   2082     do { \
   2083         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
   2084         try { \
   2085             expr; \
   2086             __catchResult.captureResult( Catch::ResultWas::Ok ); \
   2087         } \
   2088         catch( ... ) { \
   2089             __catchResult.useActiveException( resultDisposition ); \
   2090         } \
   2091         INTERNAL_CATCH_REACT( __catchResult ) \
   2092     } while( Catch::alwaysFalse() )
   2093 
   2094 ///////////////////////////////////////////////////////////////////////////////
   2095 #define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
   2096     do { \
   2097         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
   2098         if( __catchResult.allowThrows() ) \
   2099             try { \
   2100                 expr; \
   2101                 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
   2102             } \
   2103             catch( ... ) { \
   2104                 __catchResult.captureExpectedException( matcher ); \
   2105             } \
   2106         else \
   2107             __catchResult.captureResult( Catch::ResultWas::Ok ); \
   2108         INTERNAL_CATCH_REACT( __catchResult ) \
   2109     } while( Catch::alwaysFalse() )
   2110 
   2111 ///////////////////////////////////////////////////////////////////////////////
   2112 #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
   2113     do { \
   2114         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
   2115         if( __catchResult.allowThrows() ) \
   2116             try { \
   2117                 expr; \
   2118                 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
   2119             } \
   2120             catch( exceptionType ) { \
   2121                 __catchResult.captureResult( Catch::ResultWas::Ok ); \
   2122             } \
   2123             catch( ... ) { \
   2124                 __catchResult.useActiveException( resultDisposition ); \
   2125             } \
   2126         else \
   2127             __catchResult.captureResult( Catch::ResultWas::Ok ); \
   2128         INTERNAL_CATCH_REACT( __catchResult ) \
   2129     } while( Catch::alwaysFalse() )
   2130 
   2131 ///////////////////////////////////////////////////////////////////////////////
   2132 #ifdef CATCH_CONFIG_VARIADIC_MACROS
   2133     #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
   2134         do { \
   2135             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
   2136             __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
   2137             __catchResult.captureResult( messageType ); \
   2138             INTERNAL_CATCH_REACT( __catchResult ) \
   2139         } while( Catch::alwaysFalse() )
   2140 #else
   2141     #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
   2142         do { \
   2143             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
   2144             __catchResult << log + ::Catch::StreamEndStop(); \
   2145             __catchResult.captureResult( messageType ); \
   2146             INTERNAL_CATCH_REACT( __catchResult ) \
   2147         } while( Catch::alwaysFalse() )
   2148 #endif
   2149 
   2150 ///////////////////////////////////////////////////////////////////////////////
   2151 #define INTERNAL_CATCH_INFO( log, macroName ) \
   2152     Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
   2153 
   2154 ///////////////////////////////////////////////////////////////////////////////
   2155 #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
   2156     do { \
   2157         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
   2158         try { \
   2159             std::string matcherAsString = (matcher).toString(); \
   2160             __catchResult \
   2161                 .setLhs( Catch::toString( arg ) ) \
   2162                 .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
   2163                 .setOp( "matches" ) \
   2164                 .setResultType( (matcher).match( arg ) ); \
   2165             __catchResult.captureExpression(); \
   2166         } catch( ... ) { \
   2167             __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
   2168         } \
   2169         INTERNAL_CATCH_REACT( __catchResult ) \
   2170     } while( Catch::alwaysFalse() )
   2171 
   2172 // #included from: internal/catch_section.h
   2173 #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
   2174 
   2175 // #included from: catch_section_info.h
   2176 #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
   2177 
   2178 // #included from: catch_totals.hpp
   2179 #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
   2180 
   2181 #include <cstddef>
   2182 
   2183 namespace Catch {
   2184 
   2185     struct Counts {
   2186         Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
   2187 
   2188         Counts operator - ( Counts const& other ) const {
   2189             Counts diff;
   2190             diff.passed = passed - other.passed;
   2191             diff.failed = failed - other.failed;
   2192             diff.failedButOk = failedButOk - other.failedButOk;
   2193             return diff;
   2194         }
   2195         Counts& operator += ( Counts const& other ) {
   2196             passed += other.passed;
   2197             failed += other.failed;
   2198             failedButOk += other.failedButOk;
   2199             return *this;
   2200         }
   2201 
   2202         std::size_t total() const {
   2203             return passed + failed + failedButOk;
   2204         }
   2205         bool allPassed() const {
   2206             return failed == 0 && failedButOk == 0;
   2207         }
   2208         bool allOk() const {
   2209             return failed == 0;
   2210         }
   2211 
   2212         std::size_t passed;
   2213         std::size_t failed;
   2214         std::size_t failedButOk;
   2215     };
   2216 
   2217     struct Totals {
   2218 
   2219         Totals operator - ( Totals const& other ) const {
   2220             Totals diff;
   2221             diff.assertions = assertions - other.assertions;
   2222             diff.testCases = testCases - other.testCases;
   2223             return diff;
   2224         }
   2225 
   2226         Totals delta( Totals const& prevTotals ) const {
   2227             Totals diff = *this - prevTotals;
   2228             if( diff.assertions.failed > 0 )
   2229                 ++diff.testCases.failed;
   2230             else if( diff.assertions.failedButOk > 0 )
   2231                 ++diff.testCases.failedButOk;
   2232             else
   2233                 ++diff.testCases.passed;
   2234             return diff;
   2235         }
   2236 
   2237         Totals& operator += ( Totals const& other ) {
   2238             assertions += other.assertions;
   2239             testCases += other.testCases;
   2240             return *this;
   2241         }
   2242 
   2243         Counts assertions;
   2244         Counts testCases;
   2245     };
   2246 }
   2247 
   2248 namespace Catch {
   2249 
   2250     struct SectionInfo {
   2251         SectionInfo
   2252             (   SourceLineInfo const& _lineInfo,
   2253                 std::string const& _name,
   2254                 std::string const& _description = std::string() );
   2255 
   2256         std::string name;
   2257         std::string description;
   2258         SourceLineInfo lineInfo;
   2259     };
   2260 
   2261     struct SectionEndInfo {
   2262         SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
   2263         : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
   2264         {}
   2265 
   2266         SectionInfo sectionInfo;
   2267         Counts prevAssertions;
   2268         double durationInSeconds;
   2269     };
   2270 
   2271 } // end namespace Catch
   2272 
   2273 // #included from: catch_timer.h
   2274 #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
   2275 
   2276 #ifdef CATCH_PLATFORM_WINDOWS
   2277 typedef unsigned long long uint64_t;
   2278 #else
   2279 #include <stdint.h>
   2280 #endif
   2281 
   2282 namespace Catch {
   2283 
   2284     class Timer {
   2285     public:
   2286         Timer() : m_ticks( 0 ) {}
   2287         void start();
   2288         unsigned int getElapsedMicroseconds() const;
   2289         unsigned int getElapsedMilliseconds() const;
   2290         double getElapsedSeconds() const;
   2291 
   2292     private:
   2293         uint64_t m_ticks;
   2294     };
   2295 
   2296 } // namespace Catch
   2297 
   2298 #include <string>
   2299 
   2300 namespace Catch {
   2301 
   2302     class Section : NonCopyable {
   2303     public:
   2304         Section( SectionInfo const& info );
   2305         ~Section();
   2306 
   2307         // This indicates whether the section should be executed or not
   2308         operator bool() const;
   2309 
   2310     private:
   2311         SectionInfo m_info;
   2312 
   2313         std::string m_name;
   2314         Counts m_assertions;
   2315         bool m_sectionIncluded;
   2316         Timer m_timer;
   2317     };
   2318 
   2319 } // end namespace Catch
   2320 
   2321 #ifdef CATCH_CONFIG_VARIADIC_MACROS
   2322     #define INTERNAL_CATCH_SECTION( ... ) \
   2323         if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
   2324 #else
   2325     #define INTERNAL_CATCH_SECTION( name, desc ) \
   2326         if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
   2327 #endif
   2328 
   2329 // #included from: internal/catch_generators.hpp
   2330 #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
   2331 
   2332 #include <iterator>
   2333 #include <vector>
   2334 #include <string>
   2335 #include <stdlib.h>
   2336 
   2337 namespace Catch {
   2338 
   2339 template<typename T>
   2340 struct IGenerator {
   2341     virtual ~IGenerator() {}
   2342     virtual T getValue( std::size_t index ) const = 0;
   2343     virtual std::size_t size () const = 0;
   2344 };
   2345 
   2346 template<typename T>
   2347 class BetweenGenerator : public IGenerator<T> {
   2348 public:
   2349     BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
   2350 
   2351     virtual T getValue( std::size_t index ) const {
   2352         return m_from+static_cast<int>( index );
   2353     }
   2354 
   2355     virtual std::size_t size() const {
   2356         return static_cast<std::size_t>( 1+m_to-m_from );
   2357     }
   2358 
   2359 private:
   2360 
   2361     T m_from;
   2362     T m_to;
   2363 };
   2364 
   2365 template<typename T>
   2366 class ValuesGenerator : public IGenerator<T> {
   2367 public:
   2368     ValuesGenerator(){}
   2369 
   2370     void add( T value ) {
   2371         m_values.push_back( value );
   2372     }
   2373 
   2374     virtual T getValue( std::size_t index ) const {
   2375         return m_values[index];
   2376     }
   2377 
   2378     virtual std::size_t size() const {
   2379         return m_values.size();
   2380     }
   2381 
   2382 private:
   2383     std::vector<T> m_values;
   2384 };
   2385 
   2386 template<typename T>
   2387 class CompositeGenerator {
   2388 public:
   2389     CompositeGenerator() : m_totalSize( 0 ) {}
   2390 
   2391     // *** Move semantics, similar to auto_ptr ***
   2392     CompositeGenerator( CompositeGenerator& other )
   2393     :   m_fileInfo( other.m_fileInfo ),
   2394         m_totalSize( 0 )
   2395     {
   2396         move( other );
   2397     }
   2398 
   2399     CompositeGenerator& setFileInfo( const char* fileInfo ) {
   2400         m_fileInfo = fileInfo;
   2401         return *this;
   2402     }
   2403 
   2404     ~CompositeGenerator() {
   2405         deleteAll( m_composed );
   2406     }
   2407 
   2408     operator T () const {
   2409         size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
   2410 
   2411         typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
   2412         typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
   2413         for( size_t index = 0; it != itEnd; ++it )
   2414         {
   2415             const IGenerator<T>* generator = *it;
   2416             if( overallIndex >= index && overallIndex < index + generator->size() )
   2417             {
   2418                 return generator->getValue( overallIndex-index );
   2419             }
   2420             index += generator->size();
   2421         }
   2422         CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
   2423         return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
   2424     }
   2425 
   2426     void add( const IGenerator<T>* generator ) {
   2427         m_totalSize += generator->size();
   2428         m_composed.push_back( generator );
   2429     }
   2430 
   2431     CompositeGenerator& then( CompositeGenerator& other ) {
   2432         move( other );
   2433         return *this;
   2434     }
   2435 
   2436     CompositeGenerator& then( T value ) {
   2437         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
   2438         valuesGen->add( value );
   2439         add( valuesGen );
   2440         return *this;
   2441     }
   2442 
   2443 private:
   2444 
   2445     void move( CompositeGenerator& other ) {
   2446         std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
   2447         m_totalSize += other.m_totalSize;
   2448         other.m_composed.clear();
   2449     }
   2450 
   2451     std::vector<const IGenerator<T>*> m_composed;
   2452     std::string m_fileInfo;
   2453     size_t m_totalSize;
   2454 };
   2455 
   2456 namespace Generators
   2457 {
   2458     template<typename T>
   2459     CompositeGenerator<T> between( T from, T to ) {
   2460         CompositeGenerator<T> generators;
   2461         generators.add( new BetweenGenerator<T>( from, to ) );
   2462         return generators;
   2463     }
   2464 
   2465     template<typename T>
   2466     CompositeGenerator<T> values( T val1, T val2 ) {
   2467         CompositeGenerator<T> generators;
   2468         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
   2469         valuesGen->add( val1 );
   2470         valuesGen->add( val2 );
   2471         generators.add( valuesGen );
   2472         return generators;
   2473     }
   2474 
   2475     template<typename T>
   2476     CompositeGenerator<T> values( T val1, T val2, T val3 ){
   2477         CompositeGenerator<T> generators;
   2478         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
   2479         valuesGen->add( val1 );
   2480         valuesGen->add( val2 );
   2481         valuesGen->add( val3 );
   2482         generators.add( valuesGen );
   2483         return generators;
   2484     }
   2485 
   2486     template<typename T>
   2487     CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
   2488         CompositeGenerator<T> generators;
   2489         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
   2490         valuesGen->add( val1 );
   2491         valuesGen->add( val2 );
   2492         valuesGen->add( val3 );
   2493         valuesGen->add( val4 );
   2494         generators.add( valuesGen );
   2495         return generators;
   2496     }
   2497 
   2498 } // end namespace Generators
   2499 
   2500 using namespace Generators;
   2501 
   2502 } // end namespace Catch
   2503 
   2504 #define INTERNAL_CATCH_LINESTR2( line ) #line
   2505 #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
   2506 
   2507 #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
   2508 
   2509 // #included from: internal/catch_interfaces_exception.h
   2510 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
   2511 
   2512 #include <string>
   2513 #include <vector>
   2514 
   2515 // #included from: catch_interfaces_registry_hub.h
   2516 #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
   2517 
   2518 #include <string>
   2519 
   2520 namespace Catch {
   2521 
   2522     class TestCase;
   2523     struct ITestCaseRegistry;
   2524     struct IExceptionTranslatorRegistry;
   2525     struct IExceptionTranslator;
   2526     struct IReporterRegistry;
   2527     struct IReporterFactory;
   2528 
   2529     struct IRegistryHub {
   2530         virtual ~IRegistryHub();
   2531 
   2532         virtual IReporterRegistry const& getReporterRegistry() const = 0;
   2533         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
   2534         virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
   2535     };
   2536 
   2537     struct IMutableRegistryHub {
   2538         virtual ~IMutableRegistryHub();
   2539         virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
   2540         virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
   2541         virtual void registerTest( TestCase const& testInfo ) = 0;
   2542         virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
   2543     };
   2544 
   2545     IRegistryHub& getRegistryHub();
   2546     IMutableRegistryHub& getMutableRegistryHub();
   2547     void cleanUp();
   2548     std::string translateActiveException();
   2549 
   2550 }
   2551 
   2552 namespace Catch {
   2553 
   2554     typedef std::string(*exceptionTranslateFunction)();
   2555 
   2556     struct IExceptionTranslator;
   2557     typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
   2558 
   2559     struct IExceptionTranslator {
   2560         virtual ~IExceptionTranslator();
   2561         virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
   2562     };
   2563 
   2564     struct IExceptionTranslatorRegistry {
   2565         virtual ~IExceptionTranslatorRegistry();
   2566 
   2567         virtual std::string translateActiveException() const = 0;
   2568     };
   2569 
   2570     class ExceptionTranslatorRegistrar {
   2571         template<typename T>
   2572         class ExceptionTranslator : public IExceptionTranslator {
   2573         public:
   2574 
   2575             ExceptionTranslator( std::string(*translateFunction)( T& ) )
   2576             : m_translateFunction( translateFunction )
   2577             {}
   2578 
   2579             virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
   2580                 try {
   2581                     if( it == itEnd )
   2582                         throw;
   2583                     else
   2584                         return (*it)->translate( it+1, itEnd );
   2585                 }
   2586                 catch( T& ex ) {
   2587                     return m_translateFunction( ex );
   2588                 }
   2589             }
   2590 
   2591         protected:
   2592             std::string(*m_translateFunction)( T& );
   2593         };
   2594 
   2595     public:
   2596         template<typename T>
   2597         ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
   2598             getMutableRegistryHub().registerTranslator
   2599                 ( new ExceptionTranslator<T>( translateFunction ) );
   2600         }
   2601     };
   2602 }
   2603 
   2604 ///////////////////////////////////////////////////////////////////////////////
   2605 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
   2606     static std::string translatorName( signature ); \
   2607     namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
   2608     static std::string translatorName( signature )
   2609 
   2610 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
   2611 
   2612 // #included from: internal/catch_approx.hpp
   2613 #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
   2614 
   2615 #include <cmath>
   2616 #include <limits>
   2617 
   2618 namespace Catch {
   2619 namespace Detail {
   2620 
   2621     class Approx {
   2622     public:
   2623         explicit Approx ( double value )
   2624         :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
   2625             m_scale( 1.0 ),
   2626             m_value( value )
   2627         {}
   2628 
   2629         Approx( Approx const& other )
   2630         :   m_epsilon( other.m_epsilon ),
   2631             m_scale( other.m_scale ),
   2632             m_value( other.m_value )
   2633         {}
   2634 
   2635         static Approx custom() {
   2636             return Approx( 0 );
   2637         }
   2638 
   2639         Approx operator()( double value ) {
   2640             Approx approx( value );
   2641             approx.epsilon( m_epsilon );
   2642             approx.scale( m_scale );
   2643             return approx;
   2644         }
   2645 
   2646         friend bool operator == ( double lhs, Approx const& rhs ) {
   2647             // Thanks to Richard Harris for his help refining this formula
   2648             return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
   2649         }
   2650 
   2651         friend bool operator == ( Approx const& lhs, double rhs ) {
   2652             return operator==( rhs, lhs );
   2653         }
   2654 
   2655         friend bool operator != ( double lhs, Approx const& rhs ) {
   2656             return !operator==( lhs, rhs );
   2657         }
   2658 
   2659         friend bool operator != ( Approx const& lhs, double rhs ) {
   2660             return !operator==( rhs, lhs );
   2661         }
   2662 
   2663         Approx& epsilon( double newEpsilon ) {
   2664             m_epsilon = newEpsilon;
   2665             return *this;
   2666         }
   2667 
   2668         Approx& scale( double newScale ) {
   2669             m_scale = newScale;
   2670             return *this;
   2671         }
   2672 
   2673         std::string toString() const {
   2674             std::ostringstream oss;
   2675             oss << "Approx( " << Catch::toString( m_value ) << " )";
   2676             return oss.str();
   2677         }
   2678 
   2679     private:
   2680         double m_epsilon;
   2681         double m_scale;
   2682         double m_value;
   2683     };
   2684 }
   2685 
   2686 template<>
   2687 inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
   2688     return value.toString();
   2689 }
   2690 
   2691 } // end namespace Catch
   2692 
   2693 // #included from: internal/catch_interfaces_tag_alias_registry.h
   2694 #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
   2695 
   2696 // #included from: catch_tag_alias.h
   2697 #define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
   2698 
   2699 #include <string>
   2700 
   2701 namespace Catch {
   2702 
   2703     struct TagAlias {
   2704         TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
   2705 
   2706         std::string tag;
   2707         SourceLineInfo lineInfo;
   2708     };
   2709 
   2710     struct RegistrarForTagAliases {
   2711         RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
   2712     };
   2713 
   2714 } // end namespace Catch
   2715 
   2716 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
   2717 // #included from: catch_option.hpp
   2718 #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
   2719 
   2720 namespace Catch {
   2721 
   2722     // An optional type
   2723     template<typename T>
   2724     class Option {
   2725     public:
   2726         Option() : nullableValue( CATCH_NULL ) {}
   2727         Option( T const& _value )
   2728         : nullableValue( new( storage ) T( _value ) )
   2729         {}
   2730         Option( Option const& _other )
   2731         : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
   2732         {}
   2733 
   2734         ~Option() {
   2735             reset();
   2736         }
   2737 
   2738         Option& operator= ( Option const& _other ) {
   2739             if( &_other != this ) {
   2740                 reset();
   2741                 if( _other )
   2742                     nullableValue = new( storage ) T( *_other );
   2743             }
   2744             return *this;
   2745         }
   2746         Option& operator = ( T const& _value ) {
   2747             reset();
   2748             nullableValue = new( storage ) T( _value );
   2749             return *this;
   2750         }
   2751 
   2752         void reset() {
   2753             if( nullableValue )
   2754                 nullableValue->~T();
   2755             nullableValue = CATCH_NULL;
   2756         }
   2757 
   2758         T& operator*() { return *nullableValue; }
   2759         T const& operator*() const { return *nullableValue; }
   2760         T* operator->() { return nullableValue; }
   2761         const T* operator->() const { return nullableValue; }
   2762 
   2763         T valueOr( T const& defaultValue ) const {
   2764             return nullableValue ? *nullableValue : defaultValue;
   2765         }
   2766 
   2767         bool some() const { return nullableValue != CATCH_NULL; }
   2768         bool none() const { return nullableValue == CATCH_NULL; }
   2769 
   2770         bool operator !() const { return nullableValue == CATCH_NULL; }
   2771         operator SafeBool::type() const {
   2772             return SafeBool::makeSafe( some() );
   2773         }
   2774 
   2775     private:
   2776         T* nullableValue;
   2777         char storage[sizeof(T)];
   2778     };
   2779 
   2780 } // end namespace Catch
   2781 
   2782 namespace Catch {
   2783 
   2784     struct ITagAliasRegistry {
   2785         virtual ~ITagAliasRegistry();
   2786         virtual Option<TagAlias> find( std::string const& alias ) const = 0;
   2787         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
   2788 
   2789         static ITagAliasRegistry const& get();
   2790     };
   2791 
   2792 } // end namespace Catch
   2793 
   2794 // These files are included here so the single_include script doesn't put them
   2795 // in the conditionally compiled sections
   2796 // #included from: internal/catch_test_case_info.h
   2797 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
   2798 
   2799 #include <string>
   2800 #include <set>
   2801 
   2802 #ifdef __clang__
   2803 #pragma clang diagnostic push
   2804 #pragma clang diagnostic ignored "-Wpadded"
   2805 #endif
   2806 
   2807 namespace Catch {
   2808 
   2809     struct ITestCase;
   2810 
   2811     struct TestCaseInfo {
   2812         enum SpecialProperties{
   2813             None = 0,
   2814             IsHidden = 1 << 1,
   2815             ShouldFail = 1 << 2,
   2816             MayFail = 1 << 3,
   2817             Throws = 1 << 4
   2818         };
   2819 
   2820         TestCaseInfo(   std::string const& _name,
   2821                         std::string const& _className,
   2822                         std::string const& _description,
   2823                         std::set<std::string> const& _tags,
   2824                         SourceLineInfo const& _lineInfo );
   2825 
   2826         TestCaseInfo( TestCaseInfo const& other );
   2827 
   2828         friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
   2829 
   2830         bool isHidden() const;
   2831         bool throws() const;
   2832         bool okToFail() const;
   2833         bool expectedToFail() const;
   2834 
   2835         std::string name;
   2836         std::string className;
   2837         std::string description;
   2838         std::set<std::string> tags;
   2839         std::set<std::string> lcaseTags;
   2840         std::string tagsAsString;
   2841         SourceLineInfo lineInfo;
   2842         SpecialProperties properties;
   2843     };
   2844 
   2845     class TestCase : public TestCaseInfo {
   2846     public:
   2847 
   2848         TestCase( ITestCase* testCase, TestCaseInfo const& info );
   2849         TestCase( TestCase const& other );
   2850 
   2851         TestCase withName( std::string const& _newName ) const;
   2852 
   2853         void invoke() const;
   2854 
   2855         TestCaseInfo const& getTestCaseInfo() const;
   2856 
   2857         void swap( TestCase& other );
   2858         bool operator == ( TestCase const& other ) const;
   2859         bool operator < ( TestCase const& other ) const;
   2860         TestCase& operator = ( TestCase const& other );
   2861 
   2862     private:
   2863         Ptr<ITestCase> test;
   2864     };
   2865 
   2866     TestCase makeTestCase(  ITestCase* testCase,
   2867                             std::string const& className,
   2868                             std::string const& name,
   2869                             std::string const& description,
   2870                             SourceLineInfo const& lineInfo );
   2871 }
   2872 
   2873 #ifdef __clang__
   2874 #pragma clang diagnostic pop
   2875 #endif
   2876 
   2877 
   2878 #ifdef __OBJC__
   2879 // #included from: internal/catch_objc.hpp
   2880 #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
   2881 
   2882 #import <objc/runtime.h>
   2883 
   2884 #include <string>
   2885 
   2886 // NB. Any general catch headers included here must be included
   2887 // in catch.hpp first to make sure they are included by the single
   2888 // header for non obj-usage
   2889 
   2890 ///////////////////////////////////////////////////////////////////////////////
   2891 // This protocol is really only here for (self) documenting purposes, since
   2892 // all its methods are optional.
   2893 @protocol OcFixture
   2894 
   2895 @optional
   2896 
   2897 -(void) setUp;
   2898 -(void) tearDown;
   2899 
   2900 @end
   2901 
   2902 namespace Catch {
   2903 
   2904     class OcMethod : public SharedImpl<ITestCase> {
   2905 
   2906     public:
   2907         OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
   2908 
   2909         virtual void invoke() const {
   2910             id obj = [[m_cls alloc] init];
   2911 
   2912             performOptionalSelector( obj, @selector(setUp)  );
   2913             performOptionalSelector( obj, m_sel );
   2914             performOptionalSelector( obj, @selector(tearDown)  );
   2915 
   2916             arcSafeRelease( obj );
   2917         }
   2918     private:
   2919         virtual ~OcMethod() {}
   2920 
   2921         Class m_cls;
   2922         SEL m_sel;
   2923     };
   2924 
   2925     namespace Detail{
   2926 
   2927         inline std::string getAnnotation(   Class cls,
   2928                                             std::string const& annotationName,
   2929                                             std::string const& testCaseName ) {
   2930             NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
   2931             SEL sel = NSSelectorFromString( selStr );
   2932             arcSafeRelease( selStr );
   2933             id value = performOptionalSelector( cls, sel );
   2934             if( value )
   2935                 return [(NSString*)value UTF8String];
   2936             return "";
   2937         }
   2938     }
   2939 
   2940     inline size_t registerTestMethods() {
   2941         size_t noTestMethods = 0;
   2942         int noClasses = objc_getClassList( CATCH_NULL, 0 );
   2943 
   2944         Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
   2945         objc_getClassList( classes, noClasses );
   2946 
   2947         for( int c = 0; c < noClasses; c++ ) {
   2948             Class cls = classes[c];
   2949             {
   2950                 u_int count;
   2951                 Method* methods = class_copyMethodList( cls, &count );
   2952                 for( u_int m = 0; m < count ; m++ ) {
   2953                     SEL selector = method_getName(methods[m]);
   2954                     std::string methodName = sel_getName(selector);
   2955                     if( startsWith( methodName, "Catch_TestCase_" ) ) {
   2956                         std::string testCaseName = methodName.substr( 15 );
   2957                         std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
   2958                         std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
   2959                         const char* className = class_getName( cls );
   2960 
   2961                         getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
   2962                         noTestMethods++;
   2963                     }
   2964                 }
   2965                 free(methods);
   2966             }
   2967         }
   2968         return noTestMethods;
   2969     }
   2970 
   2971     namespace Matchers {
   2972         namespace Impl {
   2973         namespace NSStringMatchers {
   2974 
   2975             template<typename MatcherT>
   2976             struct StringHolder : MatcherImpl<MatcherT, NSString*>{
   2977                 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
   2978                 StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
   2979                 StringHolder() {
   2980                     arcSafeRelease( m_substr );
   2981                 }
   2982 
   2983                 NSString* m_substr;
   2984             };
   2985 
   2986             struct Equals : StringHolder<Equals> {
   2987                 Equals( NSString* substr ) : StringHolder( substr ){}
   2988 
   2989                 virtual bool match( ExpressionType const& str ) const {
   2990                     return  (str != nil || m_substr == nil ) &&
   2991                             [str isEqualToString:m_substr];
   2992                 }
   2993 
   2994                 virtual std::string toString() const {
   2995                     return "equals string: " + Catch::toString( m_substr );
   2996                 }
   2997             };
   2998 
   2999             struct Contains : StringHolder<Contains> {
   3000                 Contains( NSString* substr ) : StringHolder( substr ){}
   3001 
   3002                 virtual bool match( ExpressionType const& str ) const {
   3003                     return  (str != nil || m_substr == nil ) &&
   3004                             [str rangeOfString:m_substr].location != NSNotFound;
   3005                 }
   3006 
   3007                 virtual std::string toString() const {
   3008                     return "contains string: " + Catch::toString( m_substr );
   3009                 }
   3010             };
   3011 
   3012             struct StartsWith : StringHolder<StartsWith> {
   3013                 StartsWith( NSString* substr ) : StringHolder( substr ){}
   3014 
   3015                 virtual bool match( ExpressionType const& str ) const {
   3016                     return  (str != nil || m_substr == nil ) &&
   3017                             [str rangeOfString:m_substr].location == 0;
   3018                 }
   3019 
   3020                 virtual std::string toString() const {
   3021                     return "starts with: " + Catch::toString( m_substr );
   3022                 }
   3023             };
   3024             struct EndsWith : StringHolder<EndsWith> {
   3025                 EndsWith( NSString* substr ) : StringHolder( substr ){}
   3026 
   3027                 virtual bool match( ExpressionType const& str ) const {
   3028                     return  (str != nil || m_substr == nil ) &&
   3029                             [str rangeOfString:m_substr].location == [str length] - [m_substr length];
   3030                 }
   3031 
   3032                 virtual std::string toString() const {
   3033                     return "ends with: " + Catch::toString( m_substr );
   3034                 }
   3035             };
   3036 
   3037         } // namespace NSStringMatchers
   3038         } // namespace Impl
   3039 
   3040         inline Impl::NSStringMatchers::Equals
   3041             Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
   3042 
   3043         inline Impl::NSStringMatchers::Contains
   3044             Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
   3045 
   3046         inline Impl::NSStringMatchers::StartsWith
   3047             StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
   3048 
   3049         inline Impl::NSStringMatchers::EndsWith
   3050             EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
   3051 
   3052     } // namespace Matchers
   3053 
   3054     using namespace Matchers;
   3055 
   3056 } // namespace Catch
   3057 
   3058 ///////////////////////////////////////////////////////////////////////////////
   3059 #define OC_TEST_CASE( name, desc )\
   3060 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
   3061 {\
   3062 return @ name; \
   3063 }\
   3064 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
   3065 { \
   3066 return @ desc; \
   3067 } \
   3068 -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
   3069 
   3070 #endif
   3071 
   3072 #ifdef CATCH_IMPL
   3073 // #included from: internal/catch_impl.hpp
   3074 #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
   3075 
   3076 // Collect all the implementation files together here
   3077 // These are the equivalent of what would usually be cpp files
   3078 
   3079 #ifdef __clang__
   3080 #pragma clang diagnostic push
   3081 #pragma clang diagnostic ignored "-Wweak-vtables"
   3082 #endif
   3083 
   3084 // #included from: ../catch_session.hpp
   3085 #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
   3086 
   3087 // #included from: internal/catch_commandline.hpp
   3088 #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
   3089 
   3090 // #included from: catch_config.hpp
   3091 #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
   3092 
   3093 // #included from: catch_test_spec_parser.hpp
   3094 #define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
   3095 
   3096 #ifdef __clang__
   3097 #pragma clang diagnostic push
   3098 #pragma clang diagnostic ignored "-Wpadded"
   3099 #endif
   3100 
   3101 // #included from: catch_test_spec.hpp
   3102 #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
   3103 
   3104 #ifdef __clang__
   3105 #pragma clang diagnostic push
   3106 #pragma clang diagnostic ignored "-Wpadded"
   3107 #endif
   3108 
   3109 // #included from: catch_wildcard_pattern.hpp
   3110 #define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
   3111 
   3112 namespace Catch
   3113 {
   3114     class WildcardPattern {
   3115         enum WildcardPosition {
   3116             NoWildcard = 0,
   3117             WildcardAtStart = 1,
   3118             WildcardAtEnd = 2,
   3119             WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
   3120         };
   3121 
   3122     public:
   3123 
   3124         WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
   3125         :   m_caseSensitivity( caseSensitivity ),
   3126             m_wildcard( NoWildcard ),
   3127             m_pattern( adjustCase( pattern ) )
   3128         {
   3129             if( startsWith( m_pattern, "*" ) ) {
   3130                 m_pattern = m_pattern.substr( 1 );
   3131                 m_wildcard = WildcardAtStart;
   3132             }
   3133             if( endsWith( m_pattern, "*" ) ) {
   3134                 m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
   3135                 m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
   3136             }
   3137         }
   3138         virtual ~WildcardPattern();
   3139         virtual bool matches( std::string const& str ) const {
   3140             switch( m_wildcard ) {
   3141                 case NoWildcard:
   3142                     return m_pattern == adjustCase( str );
   3143                 case WildcardAtStart:
   3144                     return endsWith( adjustCase( str ), m_pattern );
   3145                 case WildcardAtEnd:
   3146                     return startsWith( adjustCase( str ), m_pattern );
   3147                 case WildcardAtBothEnds:
   3148                     return contains( adjustCase( str ), m_pattern );
   3149             }
   3150 
   3151 #ifdef __clang__
   3152 #pragma clang diagnostic push
   3153 #pragma clang diagnostic ignored "-Wunreachable-code"
   3154 #endif
   3155             throw std::logic_error( "Unknown enum" );
   3156 #ifdef __clang__
   3157 #pragma clang diagnostic pop
   3158 #endif
   3159         }
   3160     private:
   3161         std::string adjustCase( std::string const& str ) const {
   3162             return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
   3163         }
   3164         CaseSensitive::Choice m_caseSensitivity;
   3165         WildcardPosition m_wildcard;
   3166         std::string m_pattern;
   3167     };
   3168 }
   3169 
   3170 #include <string>
   3171 #include <vector>
   3172 
   3173 namespace Catch {
   3174 
   3175     class TestSpec {
   3176         struct Pattern : SharedImpl<> {
   3177             virtual ~Pattern();
   3178             virtual bool matches( TestCaseInfo const& testCase ) const = 0;
   3179         };
   3180         class NamePattern : public Pattern {
   3181         public:
   3182             NamePattern( std::string const& name )
   3183             : m_wildcardPattern( toLower( name ), CaseSensitive::No )
   3184             {}
   3185             virtual ~NamePattern();
   3186             virtual bool matches( TestCaseInfo const& testCase ) const {
   3187                 return m_wildcardPattern.matches( toLower( testCase.name ) );
   3188             }
   3189         private:
   3190             WildcardPattern m_wildcardPattern;
   3191         };
   3192 
   3193         class TagPattern : public Pattern {
   3194         public:
   3195             TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
   3196             virtual ~TagPattern();
   3197             virtual bool matches( TestCaseInfo const& testCase ) const {
   3198                 return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
   3199             }
   3200         private:
   3201             std::string m_tag;
   3202         };
   3203 
   3204         class ExcludedPattern : public Pattern {
   3205         public:
   3206             ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
   3207             virtual ~ExcludedPattern();
   3208             virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
   3209         private:
   3210             Ptr<Pattern> m_underlyingPattern;
   3211         };
   3212 
   3213         struct Filter {
   3214             std::vector<Ptr<Pattern> > m_patterns;
   3215 
   3216             bool matches( TestCaseInfo const& testCase ) const {
   3217                 // All patterns in a filter must match for the filter to be a match
   3218                 for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
   3219                     if( !(*it)->matches( testCase ) )
   3220                         return false;
   3221                     return true;
   3222             }
   3223         };
   3224 
   3225     public:
   3226         bool hasFilters() const {
   3227             return !m_filters.empty();
   3228         }
   3229         bool matches( TestCaseInfo const& testCase ) const {
   3230             // A TestSpec matches if any filter matches
   3231             for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
   3232                 if( it->matches( testCase ) )
   3233                     return true;
   3234             return false;
   3235         }
   3236 
   3237     private:
   3238         std::vector<Filter> m_filters;
   3239 
   3240         friend class TestSpecParser;
   3241     };
   3242 }
   3243 
   3244 #ifdef __clang__
   3245 #pragma clang diagnostic pop
   3246 #endif
   3247 
   3248 namespace Catch {
   3249 
   3250     class TestSpecParser {
   3251         enum Mode{ None, Name, QuotedName, Tag };
   3252         Mode m_mode;
   3253         bool m_exclusion;
   3254         std::size_t m_start, m_pos;
   3255         std::string m_arg;
   3256         TestSpec::Filter m_currentFilter;
   3257         TestSpec m_testSpec;
   3258         ITagAliasRegistry const* m_tagAliases;
   3259 
   3260     public:
   3261         TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
   3262 
   3263         TestSpecParser& parse( std::string const& arg ) {
   3264             m_mode = None;
   3265             m_exclusion = false;
   3266             m_start = std::string::npos;
   3267             m_arg = m_tagAliases->expandAliases( arg );
   3268             for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
   3269                 visitChar( m_arg[m_pos] );
   3270             if( m_mode == Name )
   3271                 addPattern<TestSpec::NamePattern>();
   3272             return *this;
   3273         }
   3274         TestSpec testSpec() {
   3275             addFilter();
   3276             return m_testSpec;
   3277         }
   3278     private:
   3279         void visitChar( char c ) {
   3280             if( m_mode == None ) {
   3281                 switch( c ) {
   3282                 case ' ': return;
   3283                 case '~': m_exclusion = true; return;
   3284                 case '[': return startNewMode( Tag, ++m_pos );
   3285                 case '"': return startNewMode( QuotedName, ++m_pos );
   3286                 default: startNewMode( Name, m_pos ); break;
   3287                 }
   3288             }
   3289             if( m_mode == Name ) {
   3290                 if( c == ',' ) {
   3291                     addPattern<TestSpec::NamePattern>();
   3292                     addFilter();
   3293                 }
   3294                 else if( c == '[' ) {
   3295                     if( subString() == "exclude:" )
   3296                         m_exclusion = true;
   3297                     else
   3298                         addPattern<TestSpec::NamePattern>();
   3299                     startNewMode( Tag, ++m_pos );
   3300                 }
   3301             }
   3302             else if( m_mode == QuotedName && c == '"' )
   3303                 addPattern<TestSpec::NamePattern>();
   3304             else if( m_mode == Tag && c == ']' )
   3305                 addPattern<TestSpec::TagPattern>();
   3306         }
   3307         void startNewMode( Mode mode, std::size_t start ) {
   3308             m_mode = mode;
   3309             m_start = start;
   3310         }
   3311         std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
   3312         template<typename T>
   3313         void addPattern() {
   3314             std::string token = subString();
   3315             if( startsWith( token, "exclude:" ) ) {
   3316                 m_exclusion = true;
   3317                 token = token.substr( 8 );
   3318             }
   3319             if( !token.empty() ) {
   3320                 Ptr<TestSpec::Pattern> pattern = new T( token );
   3321                 if( m_exclusion )
   3322                     pattern = new TestSpec::ExcludedPattern( pattern );
   3323                 m_currentFilter.m_patterns.push_back( pattern );
   3324             }
   3325             m_exclusion = false;
   3326             m_mode = None;
   3327         }
   3328         void addFilter() {
   3329             if( !m_currentFilter.m_patterns.empty() ) {
   3330                 m_testSpec.m_filters.push_back( m_currentFilter );
   3331                 m_currentFilter = TestSpec::Filter();
   3332             }
   3333         }
   3334     };
   3335     inline TestSpec parseTestSpec( std::string const& arg ) {
   3336         return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
   3337     }
   3338 
   3339 } // namespace Catch
   3340 
   3341 #ifdef __clang__
   3342 #pragma clang diagnostic pop
   3343 #endif
   3344 
   3345 // #included from: catch_interfaces_config.h
   3346 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
   3347 
   3348 #include <iostream>
   3349 #include <string>
   3350 #include <vector>
   3351 
   3352 namespace Catch {
   3353 
   3354     struct Verbosity { enum Level {
   3355         NoOutput = 0,
   3356         Quiet,
   3357         Normal
   3358     }; };
   3359 
   3360     struct WarnAbout { enum What {
   3361         Nothing = 0x00,
   3362         NoAssertions = 0x01
   3363     }; };
   3364 
   3365     struct ShowDurations { enum OrNot {
   3366         DefaultForReporter,
   3367         Always,
   3368         Never
   3369     }; };
   3370     struct RunTests { enum InWhatOrder {
   3371         InDeclarationOrder,
   3372         InLexicographicalOrder,
   3373         InRandomOrder
   3374     }; };
   3375     struct UseColour { enum YesOrNo {
   3376         Auto,
   3377         Yes,
   3378         No
   3379     }; };
   3380 
   3381     class TestSpec;
   3382 
   3383     struct IConfig : IShared {
   3384 
   3385         virtual ~IConfig();
   3386 
   3387         virtual bool allowThrows() const = 0;
   3388         virtual std::ostream& stream() const = 0;
   3389         virtual std::string name() const = 0;
   3390         virtual bool includeSuccessfulResults() const = 0;
   3391         virtual bool shouldDebugBreak() const = 0;
   3392         virtual bool warnAboutMissingAssertions() const = 0;
   3393         virtual int abortAfter() const = 0;
   3394         virtual bool showInvisibles() const = 0;
   3395         virtual ShowDurations::OrNot showDurations() const = 0;
   3396         virtual TestSpec const& testSpec() const = 0;
   3397         virtual RunTests::InWhatOrder runOrder() const = 0;
   3398         virtual unsigned int rngSeed() const = 0;
   3399         virtual UseColour::YesOrNo useColour() const = 0;
   3400     };
   3401 }
   3402 
   3403 // #included from: catch_stream.h
   3404 #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
   3405 
   3406 // #included from: catch_streambuf.h
   3407 #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
   3408 
   3409 #include <streambuf>
   3410 
   3411 namespace Catch {
   3412 
   3413     class StreamBufBase : public std::streambuf {
   3414     public:
   3415         virtual ~StreamBufBase() CATCH_NOEXCEPT;
   3416     };
   3417 }
   3418 
   3419 #include <streambuf>
   3420 #include <ostream>
   3421 #include <fstream>
   3422 
   3423 namespace Catch {
   3424 
   3425     std::ostream& cout();
   3426     std::ostream& cerr();
   3427 
   3428     struct IStream {
   3429         virtual ~IStream() CATCH_NOEXCEPT;
   3430         virtual std::ostream& stream() const = 0;
   3431     };
   3432 
   3433     class FileStream : public IStream {
   3434         mutable std::ofstream m_ofs;
   3435     public:
   3436         FileStream( std::string const& filename );
   3437         virtual ~FileStream() CATCH_NOEXCEPT;
   3438     public: // IStream
   3439         virtual std::ostream& stream() const CATCH_OVERRIDE;
   3440     };
   3441 
   3442     class CoutStream : public IStream {
   3443         mutable std::ostream m_os;
   3444     public:
   3445         CoutStream();
   3446         virtual ~CoutStream() CATCH_NOEXCEPT;
   3447 
   3448     public: // IStream
   3449         virtual std::ostream& stream() const CATCH_OVERRIDE;
   3450     };
   3451 
   3452     class DebugOutStream : public IStream {
   3453         std::auto_ptr<StreamBufBase> m_streamBuf;
   3454         mutable std::ostream m_os;
   3455     public:
   3456         DebugOutStream();
   3457         virtual ~DebugOutStream() CATCH_NOEXCEPT;
   3458 
   3459     public: // IStream
   3460         virtual std::ostream& stream() const CATCH_OVERRIDE;
   3461     };
   3462 }
   3463 
   3464 #include <memory>
   3465 #include <vector>
   3466 #include <string>
   3467 #include <iostream>
   3468 #include <ctime>
   3469 
   3470 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
   3471 #define CATCH_CONFIG_CONSOLE_WIDTH 80
   3472 #endif
   3473 
   3474 namespace Catch {
   3475 
   3476     struct ConfigData {
   3477 
   3478         ConfigData()
   3479         :   listTests( false ),
   3480             listTags( false ),
   3481             listReporters( false ),
   3482             listTestNamesOnly( false ),
   3483             showSuccessfulTests( false ),
   3484             shouldDebugBreak( false ),
   3485             noThrow( false ),
   3486             showHelp( false ),
   3487             showInvisibles( false ),
   3488             filenamesAsTags( false ),
   3489             abortAfter( -1 ),
   3490             rngSeed( 0 ),
   3491             verbosity( Verbosity::Normal ),
   3492             warnings( WarnAbout::Nothing ),
   3493             showDurations( ShowDurations::DefaultForReporter ),
   3494             runOrder( RunTests::InDeclarationOrder ),
   3495             useColour( UseColour::Auto )
   3496         {}
   3497 
   3498         bool listTests;
   3499         bool listTags;
   3500         bool listReporters;
   3501         bool listTestNamesOnly;
   3502 
   3503         bool showSuccessfulTests;
   3504         bool shouldDebugBreak;
   3505         bool noThrow;
   3506         bool showHelp;
   3507         bool showInvisibles;
   3508         bool filenamesAsTags;
   3509 
   3510         int abortAfter;
   3511         unsigned int rngSeed;
   3512 
   3513         Verbosity::Level verbosity;
   3514         WarnAbout::What warnings;
   3515         ShowDurations::OrNot showDurations;
   3516         RunTests::InWhatOrder runOrder;
   3517         UseColour::YesOrNo useColour;
   3518 
   3519         std::string outputFilename;
   3520         std::string name;
   3521         std::string processName;
   3522 
   3523         std::vector<std::string> reporterNames;
   3524         std::vector<std::string> testsOrTags;
   3525     };
   3526 
   3527     class Config : public SharedImpl<IConfig> {
   3528     private:
   3529         Config( Config const& other );
   3530         Config& operator = ( Config const& other );
   3531         virtual void dummy();
   3532     public:
   3533 
   3534         Config()
   3535         {}
   3536 
   3537         Config( ConfigData const& data )
   3538         :   m_data( data ),
   3539             m_stream( openStream() )
   3540         {
   3541             if( !data.testsOrTags.empty() ) {
   3542                 TestSpecParser parser( ITagAliasRegistry::get() );
   3543                 for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
   3544                     parser.parse( data.testsOrTags[i] );
   3545                 m_testSpec = parser.testSpec();
   3546             }
   3547         }
   3548 
   3549         virtual ~Config() {
   3550         }
   3551 
   3552         std::string const& getFilename() const {
   3553             return m_data.outputFilename ;
   3554         }
   3555 
   3556         bool listTests() const { return m_data.listTests; }
   3557         bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
   3558         bool listTags() const { return m_data.listTags; }
   3559         bool listReporters() const { return m_data.listReporters; }
   3560 
   3561         std::string getProcessName() const { return m_data.processName; }
   3562 
   3563         bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
   3564 
   3565         std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
   3566 
   3567         int abortAfter() const { return m_data.abortAfter; }
   3568 
   3569         TestSpec const& testSpec() const { return m_testSpec; }
   3570 
   3571         bool showHelp() const { return m_data.showHelp; }
   3572         bool showInvisibles() const { return m_data.showInvisibles; }
   3573 
   3574         // IConfig interface
   3575         virtual bool allowThrows() const        { return !m_data.noThrow; }
   3576         virtual std::ostream& stream() const    { return m_stream->stream(); }
   3577         virtual std::string name() const        { return m_data.name.empty() ? m_data.processName : m_data.name; }
   3578         virtual bool includeSuccessfulResults() const   { return m_data.showSuccessfulTests; }
   3579         virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
   3580         virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
   3581         virtual RunTests::InWhatOrder runOrder() const  { return m_data.runOrder; }
   3582         virtual unsigned int rngSeed() const    { return m_data.rngSeed; }
   3583         virtual UseColour::YesOrNo useColour() const { return m_data.useColour; }
   3584 
   3585     private:
   3586 
   3587         IStream const* openStream() {
   3588             if( m_data.outputFilename.empty() )
   3589                 return new CoutStream();
   3590             else if( m_data.outputFilename[0] == '%' ) {
   3591                 if( m_data.outputFilename == "%debug" )
   3592                     return new DebugOutStream();
   3593                 else
   3594                     throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
   3595             }
   3596             else
   3597                 return new FileStream( m_data.outputFilename );
   3598         }
   3599         ConfigData m_data;
   3600 
   3601         std::auto_ptr<IStream const> m_stream;
   3602         TestSpec m_testSpec;
   3603     };
   3604 
   3605 } // end namespace Catch
   3606 
   3607 // #included from: catch_clara.h
   3608 #define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
   3609 
   3610 // Use Catch's value for console width (store Clara's off to the side, if present)
   3611 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
   3612 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
   3613 #undef CLARA_CONFIG_CONSOLE_WIDTH
   3614 #endif
   3615 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
   3616 
   3617 // Declare Clara inside the Catch namespace
   3618 #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
   3619 // #included from: ../external/clara.h
   3620 
   3621 // Version 0.0.1.1
   3622 
   3623 // Only use header guard if we are not using an outer namespace
   3624 #if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
   3625 
   3626 #ifndef STITCH_CLARA_OPEN_NAMESPACE
   3627 #define TWOBLUECUBES_CLARA_H_INCLUDED
   3628 #define STITCH_CLARA_OPEN_NAMESPACE
   3629 #define STITCH_CLARA_CLOSE_NAMESPACE
   3630 #else
   3631 #define STITCH_CLARA_CLOSE_NAMESPACE }
   3632 #endif
   3633 
   3634 #define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
   3635 
   3636 // ----------- #included from tbc_text_format.h -----------
   3637 
   3638 // Only use header guard if we are not using an outer namespace
   3639 #if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
   3640 #ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
   3641 #define TBC_TEXT_FORMAT_H_INCLUDED
   3642 #endif
   3643 
   3644 #include <string>
   3645 #include <vector>
   3646 #include <sstream>
   3647 #include <algorithm>
   3648 
   3649 // Use optional outer namespace
   3650 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
   3651 namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
   3652 #endif
   3653 
   3654 namespace Tbc {
   3655 
   3656 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
   3657     const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
   3658 #else
   3659     const unsigned int consoleWidth = 80;
   3660 #endif
   3661 
   3662     struct TextAttributes {
   3663         TextAttributes()
   3664         :   initialIndent( std::string::npos ),
   3665             indent( 0 ),
   3666             width( consoleWidth-1 ),
   3667             tabChar( '\t' )
   3668         {}
   3669 
   3670         TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
   3671         TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
   3672         TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
   3673         TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }
   3674 
   3675         std::size_t initialIndent;  // indent of first line, or npos
   3676         std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
   3677         std::size_t width;          // maximum width of text, including indent. Longer text will wrap
   3678         char tabChar;               // If this char is seen the indent is changed to current pos
   3679     };
   3680 
   3681     class Text {
   3682     public:
   3683         Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
   3684         : attr( _attr )
   3685         {
   3686             std::string wrappableChars = " [({.,/|\\-";
   3687             std::size_t indent = _attr.initialIndent != std::string::npos
   3688                 ? _attr.initialIndent
   3689                 : _attr.indent;
   3690             std::string remainder = _str;
   3691 
   3692             while( !remainder.empty() ) {
   3693                 if( lines.size() >= 1000 ) {
   3694                     lines.push_back( "... message truncated due to excessive size" );
   3695                     return;
   3696                 }
   3697                 std::size_t tabPos = std::string::npos;
   3698                 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
   3699                 std::size_t pos = remainder.find_first_of( '\n' );
   3700                 if( pos <= width ) {
   3701                     width = pos;
   3702                 }
   3703                 pos = remainder.find_last_of( _attr.tabChar, width );
   3704                 if( pos != std::string::npos ) {
   3705                     tabPos = pos;
   3706                     if( remainder[width] == '\n' )
   3707                         width--;
   3708                     remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
   3709                 }
   3710 
   3711                 if( width == remainder.size() ) {
   3712                     spliceLine( indent, remainder, width );
   3713                 }
   3714                 else if( remainder[width] == '\n' ) {
   3715                     spliceLine( indent, remainder, width );
   3716                     if( width <= 1 || remainder.size() != 1 )
   3717                         remainder = remainder.substr( 1 );
   3718                     indent = _attr.indent;
   3719                 }
   3720                 else {
   3721                     pos = remainder.find_last_of( wrappableChars, width );
   3722                     if( pos != std::string::npos && pos > 0 ) {
   3723                         spliceLine( indent, remainder, pos );
   3724                         if( remainder[0] == ' ' )
   3725                             remainder = remainder.substr( 1 );
   3726                     }
   3727                     else {
   3728                         spliceLine( indent, remainder, width-1 );
   3729                         lines.back() += "-";
   3730                     }
   3731                     if( lines.size() == 1 )
   3732                         indent = _attr.indent;
   3733                     if( tabPos != std::string::npos )
   3734                         indent += tabPos;
   3735                 }
   3736             }
   3737         }
   3738 
   3739         void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
   3740             lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
   3741             _remainder = _remainder.substr( _pos );
   3742         }
   3743 
   3744         typedef std::vector<std::string>::const_iterator const_iterator;
   3745 
   3746         const_iterator begin() const { return lines.begin(); }
   3747         const_iterator end() const { return lines.end(); }
   3748         std::string const& last() const { return lines.back(); }
   3749         std::size_t size() const { return lines.size(); }
   3750         std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
   3751         std::string toString() const {
   3752             std::ostringstream oss;
   3753             oss << *this;
   3754             return oss.str();
   3755         }
   3756 
   3757         inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
   3758             for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
   3759                 it != itEnd; ++it ) {
   3760                 if( it != _text.begin() )
   3761                     _stream << "\n";
   3762                 _stream << *it;
   3763             }
   3764             return _stream;
   3765         }
   3766 
   3767     private:
   3768         std::string str;
   3769         TextAttributes attr;
   3770         std::vector<std::string> lines;
   3771     };
   3772 
   3773 } // end namespace Tbc
   3774 
   3775 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
   3776 } // end outer namespace
   3777 #endif
   3778 
   3779 #endif // TBC_TEXT_FORMAT_H_INCLUDED
   3780 
   3781 // ----------- end of #include from tbc_text_format.h -----------
   3782 // ........... back in clara.h
   3783 
   3784 #undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
   3785 
   3786 // ----------- #included from clara_compilers.h -----------
   3787 
   3788 #ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
   3789 #define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
   3790 
   3791 // Detect a number of compiler features - mostly C++11/14 conformance - by compiler
   3792 // The following features are defined:
   3793 //
   3794 // CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported?
   3795 // CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
   3796 // CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
   3797 // CLARA_CONFIG_CPP11_OVERRIDE : is override supported?
   3798 // CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
   3799 
   3800 // CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
   3801 
   3802 // CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported?
   3803 
   3804 // In general each macro has a _NO_<feature name> form
   3805 // (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
   3806 // Many features, at point of detection, define an _INTERNAL_ macro, so they
   3807 // can be combined, en-mass, with the _NO_ forms later.
   3808 
   3809 // All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11
   3810 
   3811 #ifdef __clang__
   3812 
   3813 #if __has_feature(cxx_nullptr)
   3814 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
   3815 #endif
   3816 
   3817 #if __has_feature(cxx_noexcept)
   3818 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
   3819 #endif
   3820 
   3821 #endif // __clang__
   3822 
   3823 ////////////////////////////////////////////////////////////////////////////////
   3824 // GCC
   3825 #ifdef __GNUC__
   3826 
   3827 #if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
   3828 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
   3829 #endif
   3830 
   3831 // - otherwise more recent versions define __cplusplus >= 201103L
   3832 // and will get picked up below
   3833 
   3834 #endif // __GNUC__
   3835 
   3836 ////////////////////////////////////////////////////////////////////////////////
   3837 // Visual C++
   3838 #ifdef _MSC_VER
   3839 
   3840 #if (_MSC_VER >= 1600)
   3841 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
   3842 #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
   3843 #endif
   3844 
   3845 #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
   3846 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
   3847 #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
   3848 #endif
   3849 
   3850 #endif // _MSC_VER
   3851 
   3852 ////////////////////////////////////////////////////////////////////////////////
   3853 // C++ language feature support
   3854 
   3855 // catch all support for C++11
   3856 #if defined(__cplusplus) && __cplusplus >= 201103L
   3857 
   3858 #define CLARA_CPP11_OR_GREATER
   3859 
   3860 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)
   3861 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
   3862 #endif
   3863 
   3864 #ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
   3865 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
   3866 #endif
   3867 
   3868 #ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
   3869 #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
   3870 #endif
   3871 
   3872 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)
   3873 #define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE
   3874 #endif
   3875 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
   3876 #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
   3877 #endif
   3878 
   3879 #endif // __cplusplus >= 201103L
   3880 
   3881 // Now set the actual defines based on the above + anything the user has configured
   3882 #if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)
   3883 #define CLARA_CONFIG_CPP11_NULLPTR
   3884 #endif
   3885 #if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)
   3886 #define CLARA_CONFIG_CPP11_NOEXCEPT
   3887 #endif
   3888 #if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)
   3889 #define CLARA_CONFIG_CPP11_GENERATED_METHODS
   3890 #endif
   3891 #if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)
   3892 #define CLARA_CONFIG_CPP11_OVERRIDE
   3893 #endif
   3894 #if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)
   3895 #define CLARA_CONFIG_CPP11_UNIQUE_PTR
   3896 #endif
   3897 
   3898 // noexcept support:
   3899 #if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)
   3900 #define CLARA_NOEXCEPT noexcept
   3901 #  define CLARA_NOEXCEPT_IS(x) noexcept(x)
   3902 #else
   3903 #define CLARA_NOEXCEPT throw()
   3904 #  define CLARA_NOEXCEPT_IS(x)
   3905 #endif
   3906 
   3907 // nullptr support
   3908 #ifdef CLARA_CONFIG_CPP11_NULLPTR
   3909 #define CLARA_NULL nullptr
   3910 #else
   3911 #define CLARA_NULL NULL
   3912 #endif
   3913 
   3914 // override support
   3915 #ifdef CLARA_CONFIG_CPP11_OVERRIDE
   3916 #define CLARA_OVERRIDE override
   3917 #else
   3918 #define CLARA_OVERRIDE
   3919 #endif
   3920 
   3921 // unique_ptr support
   3922 #ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR
   3923 #   define CLARA_AUTO_PTR( T ) std::unique_ptr<T>
   3924 #else
   3925 #   define CLARA_AUTO_PTR( T ) std::auto_ptr<T>
   3926 #endif
   3927 
   3928 #endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
   3929 
   3930 // ----------- end of #include from clara_compilers.h -----------
   3931 // ........... back in clara.h
   3932 
   3933 #include <map>
   3934 #include <stdexcept>
   3935 #include <memory>
   3936 
   3937 // Use optional outer namespace
   3938 #ifdef STITCH_CLARA_OPEN_NAMESPACE
   3939 STITCH_CLARA_OPEN_NAMESPACE
   3940 #endif
   3941 
   3942 namespace Clara {
   3943 
   3944     struct UnpositionalTag {};
   3945 
   3946     extern UnpositionalTag _;
   3947 
   3948 #ifdef CLARA_CONFIG_MAIN
   3949     UnpositionalTag _;
   3950 #endif
   3951 
   3952     namespace Detail {
   3953 
   3954 #ifdef CLARA_CONSOLE_WIDTH
   3955     const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
   3956 #else
   3957     const unsigned int consoleWidth = 80;
   3958 #endif
   3959 
   3960         // Use this to try and stop compiler from warning about unreachable code
   3961         inline bool isTrue( bool value ) { return value; }
   3962 
   3963         using namespace Tbc;
   3964 
   3965         inline bool startsWith( std::string const& str, std::string const& prefix ) {
   3966             return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
   3967         }
   3968 
   3969         template<typename T> struct RemoveConstRef{ typedef T type; };
   3970         template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
   3971         template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
   3972         template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
   3973 
   3974         template<typename T>    struct IsBool       { static const bool value = false; };
   3975         template<>              struct IsBool<bool> { static const bool value = true; };
   3976 
   3977         template<typename T>
   3978         void convertInto( std::string const& _source, T& _dest ) {
   3979             std::stringstream ss;
   3980             ss << _source;
   3981             ss >> _dest;
   3982             if( ss.fail() )
   3983                 throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
   3984         }
   3985         inline void convertInto( std::string const& _source, std::string& _dest ) {
   3986             _dest = _source;
   3987         }
   3988         inline void convertInto( std::string const& _source, bool& _dest ) {
   3989             std::string sourceLC = _source;
   3990             std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
   3991             if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
   3992                 _dest = true;
   3993             else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
   3994                 _dest = false;
   3995             else
   3996                 throw std::runtime_error( "Expected a boolean value but did not recognise:\n  '" + _source + "'" );
   3997         }
   3998         inline void convertInto( bool _source, bool& _dest ) {
   3999             _dest = _source;
   4000         }
   4001         template<typename T>
   4002         inline void convertInto( bool, T& ) {
   4003             if( isTrue( true ) )
   4004                 throw std::runtime_error( "Invalid conversion" );
   4005         }
   4006 
   4007         template<typename ConfigT>
   4008         struct IArgFunction {
   4009             virtual ~IArgFunction() {}
   4010 #ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS
   4011             IArgFunction()                      = default;
   4012             IArgFunction( IArgFunction const& ) = default;
   4013 #endif
   4014             virtual void set( ConfigT& config, std::string const& value ) const = 0;
   4015             virtual void setFlag( ConfigT& config ) const = 0;
   4016             virtual bool takesArg() const = 0;
   4017             virtual IArgFunction* clone() const = 0;
   4018         };
   4019 
   4020         template<typename ConfigT>
   4021         class BoundArgFunction {
   4022         public:
   4023             BoundArgFunction() : functionObj( CLARA_NULL ) {}
   4024             BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
   4025             BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
   4026             BoundArgFunction& operator = ( BoundArgFunction const& other ) {
   4027                 IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
   4028                 delete functionObj;
   4029                 functionObj = newFunctionObj;
   4030                 return *this;
   4031             }
   4032             ~BoundArgFunction() { delete functionObj; }
   4033 
   4034             void set( ConfigT& config, std::string const& value ) const {
   4035                 functionObj->set( config, value );
   4036             }
   4037             void setFlag( ConfigT& config ) const {
   4038                 functionObj->setFlag( config );
   4039             }
   4040             bool takesArg() const { return functionObj->takesArg(); }
   4041 
   4042             bool isSet() const {
   4043                 return functionObj != CLARA_NULL;
   4044             }
   4045         private:
   4046             IArgFunction<ConfigT>* functionObj;
   4047         };
   4048 
   4049         template<typename C>
   4050         struct NullBinder : IArgFunction<C>{
   4051             virtual void set( C&, std::string const& ) const {}
   4052             virtual void setFlag( C& ) const {}
   4053             virtual bool takesArg() const { return true; }
   4054             virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
   4055         };
   4056 
   4057         template<typename C, typename M>
   4058         struct BoundDataMember : IArgFunction<C>{
   4059             BoundDataMember( M C::* _member ) : member( _member ) {}
   4060             virtual void set( C& p, std::string const& stringValue ) const {
   4061                 convertInto( stringValue, p.*member );
   4062             }
   4063             virtual void setFlag( C& p ) const {
   4064                 convertInto( true, p.*member );
   4065             }
   4066             virtual bool takesArg() const { return !IsBool<M>::value; }
   4067             virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
   4068             M C::* member;
   4069         };
   4070         template<typename C, typename M>
   4071         struct BoundUnaryMethod : IArgFunction<C>{
   4072             BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
   4073             virtual void set( C& p, std::string const& stringValue ) const {
   4074                 typename RemoveConstRef<M>::type value;
   4075                 convertInto( stringValue, value );
   4076                 (p.*member)( value );
   4077             }
   4078             virtual void setFlag( C& p ) const {
   4079                 typename RemoveConstRef<M>::type value;
   4080                 convertInto( true, value );
   4081                 (p.*member)( value );
   4082             }
   4083             virtual bool takesArg() const { return !IsBool<M>::value; }
   4084             virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
   4085             void (C::*member)( M );
   4086         };
   4087         template<typename C>
   4088         struct BoundNullaryMethod : IArgFunction<C>{
   4089             BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
   4090             virtual void set( C& p, std::string const& stringValue ) const {
   4091                 bool value;
   4092                 convertInto( stringValue, value );
   4093                 if( value )
   4094                     (p.*member)();
   4095             }
   4096             virtual void setFlag( C& p ) const {
   4097                 (p.*member)();
   4098             }
   4099             virtual bool takesArg() const { return false; }
   4100             virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
   4101             void (C::*member)();
   4102         };
   4103 
   4104         template<typename C>
   4105         struct BoundUnaryFunction : IArgFunction<C>{
   4106             BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
   4107             virtual void set( C& obj, std::string const& stringValue ) const {
   4108                 bool value;
   4109                 convertInto( stringValue, value );
   4110                 if( value )
   4111                     function( obj );
   4112             }
   4113             virtual void setFlag( C& p ) const {
   4114                 function( p );
   4115             }
   4116             virtual bool takesArg() const { return false; }
   4117             virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
   4118             void (*function)( C& );
   4119         };
   4120 
   4121         template<typename C, typename T>
   4122         struct BoundBinaryFunction : IArgFunction<C>{
   4123             BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
   4124             virtual void set( C& obj, std::string const& stringValue ) const {
   4125                 typename RemoveConstRef<T>::type value;
   4126                 convertInto( stringValue, value );
   4127                 function( obj, value );
   4128             }
   4129             virtual void setFlag( C& obj ) const {
   4130                 typename RemoveConstRef<T>::type value;
   4131                 convertInto( true, value );
   4132                 function( obj, value );
   4133             }
   4134             virtual bool takesArg() const { return !IsBool<T>::value; }
   4135             virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
   4136             void (*function)( C&, T );
   4137         };
   4138 
   4139     } // namespace Detail
   4140 
   4141     struct Parser {
   4142         Parser() : separators( " \t=:" ) {}
   4143 
   4144         struct Token {
   4145             enum Type { Positional, ShortOpt, LongOpt };
   4146             Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
   4147             Type type;
   4148             std::string data;
   4149         };
   4150 
   4151         void parseIntoTokens( int argc, char const* const argv[], std::vector<Parser::Token>& tokens ) const {
   4152             const std::string doubleDash = "--";
   4153             for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
   4154                 parseIntoTokens( argv[i] , tokens);
   4155         }
   4156         void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
   4157             while( !arg.empty() ) {
   4158                 Parser::Token token( Parser::Token::Positional, arg );
   4159                 arg = "";
   4160                 if( token.data[0] == '-' ) {
   4161                     if( token.data.size() > 1 && token.data[1] == '-' ) {
   4162                         token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
   4163                     }
   4164                     else {
   4165                         token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
   4166                         if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
   4167                             arg = "-" + token.data.substr( 1 );
   4168                             token.data = token.data.substr( 0, 1 );
   4169                         }
   4170                     }
   4171                 }
   4172                 if( token.type != Parser::Token::Positional ) {
   4173                     std::size_t pos = token.data.find_first_of( separators );
   4174                     if( pos != std::string::npos ) {
   4175                         arg = token.data.substr( pos+1 );
   4176                         token.data = token.data.substr( 0, pos );
   4177                     }
   4178                 }
   4179                 tokens.push_back( token );
   4180             }
   4181         }
   4182         std::string separators;
   4183     };
   4184 
   4185     template<typename ConfigT>
   4186     struct CommonArgProperties {
   4187         CommonArgProperties() {}
   4188         CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
   4189 
   4190         Detail::BoundArgFunction<ConfigT> boundField;
   4191         std::string description;
   4192         std::string detail;
   4193         std::string placeholder; // Only value if boundField takes an arg
   4194 
   4195         bool takesArg() const {
   4196             return !placeholder.empty();
   4197         }
   4198         void validate() const {
   4199             if( !boundField.isSet() )
   4200                 throw std::logic_error( "option not bound" );
   4201         }
   4202     };
   4203     struct OptionArgProperties {
   4204         std::vector<std::string> shortNames;
   4205         std::string longName;
   4206 
   4207         bool hasShortName( std::string const& shortName ) const {
   4208             return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
   4209         }
   4210         bool hasLongName( std::string const& _longName ) const {
   4211             return _longName == longName;
   4212         }
   4213     };
   4214     struct PositionalArgProperties {
   4215         PositionalArgProperties() : position( -1 ) {}
   4216         int position; // -1 means non-positional (floating)
   4217 
   4218         bool isFixedPositional() const {
   4219             return position != -1;
   4220         }
   4221     };
   4222 
   4223     template<typename ConfigT>
   4224     class CommandLine {
   4225 
   4226         struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
   4227             Arg() {}
   4228             Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
   4229 
   4230             using CommonArgProperties<ConfigT>::placeholder; // !TBD
   4231 
   4232             std::string dbgName() const {
   4233                 if( !longName.empty() )
   4234                     return "--" + longName;
   4235                 if( !shortNames.empty() )
   4236                     return "-" + shortNames[0];
   4237                 return "positional args";
   4238             }
   4239             std::string commands() const {
   4240                 std::ostringstream oss;
   4241                 bool first = true;
   4242                 std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
   4243                 for(; it != itEnd; ++it ) {
   4244                     if( first )
   4245                         first = false;
   4246                     else
   4247                         oss << ", ";
   4248                     oss << "-" << *it;
   4249                 }
   4250                 if( !longName.empty() ) {
   4251                     if( !first )
   4252                         oss << ", ";
   4253                     oss << "--" << longName;
   4254                 }
   4255                 if( !placeholder.empty() )
   4256                     oss << " <" << placeholder << ">";
   4257                 return oss.str();
   4258             }
   4259         };
   4260 
   4261         typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
   4262 
   4263         friend void addOptName( Arg& arg, std::string const& optName )
   4264         {
   4265             if( optName.empty() )
   4266                 return;
   4267             if( Detail::startsWith( optName, "--" ) ) {
   4268                 if( !arg.longName.empty() )
   4269                     throw std::logic_error( "Only one long opt may be specified. '"
   4270                         + arg.longName
   4271                         + "' already specified, now attempting to add '"
   4272                         + optName + "'" );
   4273                 arg.longName = optName.substr( 2 );
   4274             }
   4275             else if( Detail::startsWith( optName, "-" ) )
   4276                 arg.shortNames.push_back( optName.substr( 1 ) );
   4277             else
   4278                 throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
   4279         }
   4280         friend void setPositionalArg( Arg& arg, int position )
   4281         {
   4282             arg.position = position;
   4283         }
   4284 
   4285         class ArgBuilder {
   4286         public:
   4287             ArgBuilder( Arg* arg ) : m_arg( arg ) {}
   4288 
   4289             // Bind a non-boolean data member (requires placeholder string)
   4290             template<typename C, typename M>
   4291             void bind( M C::* field, std::string const& placeholder ) {
   4292                 m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
   4293                 m_arg->placeholder = placeholder;
   4294             }
   4295             // Bind a boolean data member (no placeholder required)
   4296             template<typename C>
   4297             void bind( bool C::* field ) {
   4298                 m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
   4299             }
   4300 
   4301             // Bind a method taking a single, non-boolean argument (requires a placeholder string)
   4302             template<typename C, typename M>
   4303             void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
   4304                 m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
   4305                 m_arg->placeholder = placeholder;
   4306             }
   4307 
   4308             // Bind a method taking a single, boolean argument (no placeholder string required)
   4309             template<typename C>
   4310             void bind( void (C::* unaryMethod)( bool ) ) {
   4311                 m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
   4312             }
   4313 
   4314             // Bind a method that takes no arguments (will be called if opt is present)
   4315             template<typename C>
   4316             void bind( void (C::* nullaryMethod)() ) {
   4317                 m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
   4318             }
   4319 
   4320             // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
   4321             template<typename C>
   4322             void bind( void (* unaryFunction)( C& ) ) {
   4323                 m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
   4324             }
   4325 
   4326             // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
   4327             template<typename C, typename T>
   4328             void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
   4329                 m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
   4330                 m_arg->placeholder = placeholder;
   4331             }
   4332 
   4333             ArgBuilder& describe( std::string const& description ) {
   4334                 m_arg->description = description;
   4335                 return *this;
   4336             }
   4337             ArgBuilder& detail( std::string const& detail ) {
   4338                 m_arg->detail = detail;
   4339                 return *this;
   4340             }
   4341 
   4342         protected:
   4343             Arg* m_arg;
   4344         };
   4345 
   4346         class OptBuilder : public ArgBuilder {
   4347         public:
   4348             OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
   4349             OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
   4350 
   4351             OptBuilder& operator[]( std::string const& optName ) {
   4352                 addOptName( *ArgBuilder::m_arg, optName );
   4353                 return *this;
   4354             }
   4355         };
   4356 
   4357     public:
   4358 
   4359         CommandLine()
   4360         :   m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
   4361             m_highestSpecifiedArgPosition( 0 ),
   4362             m_throwOnUnrecognisedTokens( false )
   4363         {}
   4364         CommandLine( CommandLine const& other )
   4365         :   m_boundProcessName( other.m_boundProcessName ),
   4366             m_options ( other.m_options ),
   4367             m_positionalArgs( other.m_positionalArgs ),
   4368             m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
   4369             m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
   4370         {
   4371             if( other.m_floatingArg.get() )
   4372                 m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
   4373         }
   4374 
   4375         CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
   4376             m_throwOnUnrecognisedTokens = shouldThrow;
   4377             return *this;
   4378         }
   4379 
   4380         OptBuilder operator[]( std::string const& optName ) {
   4381             m_options.push_back( Arg() );
   4382             addOptName( m_options.back(), optName );
   4383             OptBuilder builder( &m_options.back() );
   4384             return builder;
   4385         }
   4386 
   4387         ArgBuilder operator[]( int position ) {
   4388             m_positionalArgs.insert( std::make_pair( position, Arg() ) );
   4389             if( position > m_highestSpecifiedArgPosition )
   4390                 m_highestSpecifiedArgPosition = position;
   4391             setPositionalArg( m_positionalArgs[position], position );
   4392             ArgBuilder builder( &m_positionalArgs[position] );
   4393             return builder;
   4394         }
   4395 
   4396         // Invoke this with the _ instance
   4397         ArgBuilder operator[]( UnpositionalTag ) {
   4398             if( m_floatingArg.get() )
   4399                 throw std::logic_error( "Only one unpositional argument can be added" );
   4400             m_floatingArg.reset( new Arg() );
   4401             ArgBuilder builder( m_floatingArg.get() );
   4402             return builder;
   4403         }
   4404 
   4405         template<typename C, typename M>
   4406         void bindProcessName( M C::* field ) {
   4407             m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
   4408         }
   4409         template<typename C, typename M>
   4410         void bindProcessName( void (C::*_unaryMethod)( M ) ) {
   4411             m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
   4412         }
   4413 
   4414         void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
   4415             typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
   4416             std::size_t maxWidth = 0;
   4417             for( it = itBegin; it != itEnd; ++it )
   4418                 maxWidth = (std::max)( maxWidth, it->commands().size() );
   4419 
   4420             for( it = itBegin; it != itEnd; ++it ) {
   4421                 Detail::Text usage( it->commands(), Detail::TextAttributes()
   4422                                                         .setWidth( maxWidth+indent )
   4423                                                         .setIndent( indent ) );
   4424                 Detail::Text desc( it->description, Detail::TextAttributes()
   4425                                                         .setWidth( width - maxWidth - 3 ) );
   4426 
   4427                 for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
   4428                     std::string usageCol = i < usage.size() ? usage[i] : "";
   4429                     os << usageCol;
   4430 
   4431                     if( i < desc.size() && !desc[i].empty() )
   4432                         os  << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
   4433                             << desc[i];
   4434                     os << "\n";
   4435                 }
   4436             }
   4437         }
   4438         std::string optUsage() const {
   4439             std::ostringstream oss;
   4440             optUsage( oss );
   4441             return oss.str();
   4442         }
   4443 
   4444         void argSynopsis( std::ostream& os ) const {
   4445             for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
   4446                 if( i > 1 )
   4447                     os << " ";
   4448                 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
   4449                 if( it != m_positionalArgs.end() )
   4450                     os << "<" << it->second.placeholder << ">";
   4451                 else if( m_floatingArg.get() )
   4452                     os << "<" << m_floatingArg->placeholder << ">";
   4453                 else
   4454                     throw std::logic_error( "non consecutive positional arguments with no floating args" );
   4455             }
   4456             // !TBD No indication of mandatory args
   4457             if( m_floatingArg.get() ) {
   4458                 if( m_highestSpecifiedArgPosition > 1 )
   4459                     os << " ";
   4460                 os << "[<" << m_floatingArg->placeholder << "> ...]";
   4461             }
   4462         }
   4463         std::string argSynopsis() const {
   4464             std::ostringstream oss;
   4465             argSynopsis( oss );
   4466             return oss.str();
   4467         }
   4468 
   4469         void usage( std::ostream& os, std::string const& procName ) const {
   4470             validate();
   4471             os << "usage:\n  " << procName << " ";
   4472             argSynopsis( os );
   4473             if( !m_options.empty() ) {
   4474                 os << " [options]\n\nwhere options are: \n";
   4475                 optUsage( os, 2 );
   4476             }
   4477             os << "\n";
   4478         }
   4479         std::string usage( std::string const& procName ) const {
   4480             std::ostringstream oss;
   4481             usage( oss, procName );
   4482             return oss.str();
   4483         }
   4484 
   4485         ConfigT parse( int argc, char const* const argv[] ) const {
   4486             ConfigT config;
   4487             parseInto( argc, argv, config );
   4488             return config;
   4489         }
   4490 
   4491         std::vector<Parser::Token> parseInto( int argc, char const* argv[], ConfigT& config ) const {
   4492             std::string processName = argv[0];
   4493             std::size_t lastSlash = processName.find_last_of( "/\\" );
   4494             if( lastSlash != std::string::npos )
   4495                 processName = processName.substr( lastSlash+1 );
   4496             m_boundProcessName.set( config, processName );
   4497             std::vector<Parser::Token> tokens;
   4498             Parser parser;
   4499             parser.parseIntoTokens( argc, argv, tokens );
   4500             return populate( tokens, config );
   4501         }
   4502 
   4503         std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
   4504             validate();
   4505             std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
   4506             unusedTokens = populateFixedArgs( unusedTokens, config );
   4507             unusedTokens = populateFloatingArgs( unusedTokens, config );
   4508             return unusedTokens;
   4509         }
   4510 
   4511         std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
   4512             std::vector<Parser::Token> unusedTokens;
   4513             std::vector<std::string> errors;
   4514             for( std::size_t i = 0; i < tokens.size(); ++i ) {
   4515                 Parser::Token const& token = tokens[i];
   4516                 typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
   4517                 for(; it != itEnd; ++it ) {
   4518                     Arg const& arg = *it;
   4519 
   4520                     try {
   4521                         if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
   4522                             ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
   4523                             if( arg.takesArg() ) {
   4524                                 if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
   4525                                     errors.push_back( "Expected argument to option: " + token.data );
   4526                                 else
   4527                                     arg.boundField.set( config, tokens[++i].data );
   4528                             }
   4529                             else {
   4530                                 arg.boundField.setFlag( config );
   4531                             }
   4532                             break;
   4533                         }
   4534                     }
   4535                     catch( std::exception& ex ) {
   4536                         errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
   4537                     }
   4538                 }
   4539                 if( it == itEnd ) {
   4540                     if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
   4541                         unusedTokens.push_back( token );
   4542                     else if( errors.empty() && m_throwOnUnrecognisedTokens )
   4543                         errors.push_back( "unrecognised option: " + token.data );
   4544                 }
   4545             }
   4546             if( !errors.empty() ) {
   4547                 std::ostringstream oss;
   4548                 for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
   4549                         it != itEnd;
   4550                         ++it ) {
   4551                     if( it != errors.begin() )
   4552                         oss << "\n";
   4553                     oss << *it;
   4554                 }
   4555                 throw std::runtime_error( oss.str() );
   4556             }
   4557             return unusedTokens;
   4558         }
   4559         std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
   4560             std::vector<Parser::Token> unusedTokens;
   4561             int position = 1;
   4562             for( std::size_t i = 0; i < tokens.size(); ++i ) {
   4563                 Parser::Token const& token = tokens[i];
   4564                 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
   4565                 if( it != m_positionalArgs.end() )
   4566                     it->second.boundField.set( config, token.data );
   4567                 else
   4568                     unusedTokens.push_back( token );
   4569                 if( token.type == Parser::Token::Positional )
   4570                     position++;
   4571             }
   4572             return unusedTokens;
   4573         }
   4574         std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
   4575             if( !m_floatingArg.get() )
   4576                 return tokens;
   4577             std::vector<Parser::Token> unusedTokens;
   4578             for( std::size_t i = 0; i < tokens.size(); ++i ) {
   4579                 Parser::Token const& token = tokens[i];
   4580                 if( token.type == Parser::Token::Positional )
   4581                     m_floatingArg->boundField.set( config, token.data );
   4582                 else
   4583                     unusedTokens.push_back( token );
   4584             }
   4585             return unusedTokens;
   4586         }
   4587 
   4588         void validate() const
   4589         {
   4590             if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
   4591                 throw std::logic_error( "No options or arguments specified" );
   4592 
   4593             for( typename std::vector<Arg>::const_iterator  it = m_options.begin(),
   4594                                                             itEnd = m_options.end();
   4595                     it != itEnd; ++it )
   4596                 it->validate();
   4597         }
   4598 
   4599     private:
   4600         Detail::BoundArgFunction<ConfigT> m_boundProcessName;
   4601         std::vector<Arg> m_options;
   4602         std::map<int, Arg> m_positionalArgs;
   4603         ArgAutoPtr m_floatingArg;
   4604         int m_highestSpecifiedArgPosition;
   4605         bool m_throwOnUnrecognisedTokens;
   4606     };
   4607 
   4608 } // end namespace Clara
   4609 
   4610 STITCH_CLARA_CLOSE_NAMESPACE
   4611 #undef STITCH_CLARA_OPEN_NAMESPACE
   4612 #undef STITCH_CLARA_CLOSE_NAMESPACE
   4613 
   4614 #endif // TWOBLUECUBES_CLARA_H_INCLUDED
   4615 #undef STITCH_CLARA_OPEN_NAMESPACE
   4616 
   4617 // Restore Clara's value for console width, if present
   4618 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
   4619 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
   4620 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
   4621 #endif
   4622 
   4623 #include <fstream>
   4624 
   4625 namespace Catch {
   4626 
   4627     inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
   4628     inline void abortAfterX( ConfigData& config, int x ) {
   4629         if( x < 1 )
   4630             throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
   4631         config.abortAfter = x;
   4632     }
   4633     inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
   4634     inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
   4635 
   4636     inline void addWarning( ConfigData& config, std::string const& _warning ) {
   4637         if( _warning == "NoAssertions" )
   4638             config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
   4639         else
   4640             throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
   4641     }
   4642     inline void setOrder( ConfigData& config, std::string const& order ) {
   4643         if( startsWith( "declared", order ) )
   4644             config.runOrder = RunTests::InDeclarationOrder;
   4645         else if( startsWith( "lexical", order ) )
   4646             config.runOrder = RunTests::InLexicographicalOrder;
   4647         else if( startsWith( "random", order ) )
   4648             config.runOrder = RunTests::InRandomOrder;
   4649         else
   4650             throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
   4651     }
   4652     inline void setRngSeed( ConfigData& config, std::string const& seed ) {
   4653         if( seed == "time" ) {
   4654             config.rngSeed = static_cast<unsigned int>( std::time(0) );
   4655         }
   4656         else {
   4657             std::stringstream ss;
   4658             ss << seed;
   4659             ss >> config.rngSeed;
   4660             if( ss.fail() )
   4661                 throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
   4662         }
   4663     }
   4664     inline void setVerbosity( ConfigData& config, int level ) {
   4665         // !TBD: accept strings?
   4666         config.verbosity = static_cast<Verbosity::Level>( level );
   4667     }
   4668     inline void setShowDurations( ConfigData& config, bool _showDurations ) {
   4669         config.showDurations = _showDurations
   4670             ? ShowDurations::Always
   4671             : ShowDurations::Never;
   4672     }
   4673     inline void setUseColour( ConfigData& config, std::string const& value ) {
   4674         std::string mode = toLower( value );
   4675 
   4676         if( mode == "yes" )
   4677             config.useColour = UseColour::Yes;
   4678         else if( mode == "no" )
   4679             config.useColour = UseColour::No;
   4680         else if( mode == "auto" )
   4681             config.useColour = UseColour::Auto;
   4682         else
   4683             throw std::runtime_error( "colour mode must be one of: auto, yes or no" );
   4684     }
   4685     inline void forceColour( ConfigData& config ) {
   4686         config.useColour = UseColour::Yes;
   4687     }
   4688     inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
   4689         std::ifstream f( _filename.c_str() );
   4690         if( !f.is_open() )
   4691             throw std::domain_error( "Unable to load input file: " + _filename );
   4692 
   4693         std::string line;
   4694         while( std::getline( f, line ) ) {
   4695             line = trim(line);
   4696             if( !line.empty() && !startsWith( line, "#" ) )
   4697                 addTestOrTags( config, "\"" + line + "\"," );
   4698         }
   4699     }
   4700 
   4701     inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
   4702 
   4703         using namespace Clara;
   4704         CommandLine<ConfigData> cli;
   4705 
   4706         cli.bindProcessName( &ConfigData::processName );
   4707 
   4708         cli["-?"]["-h"]["--help"]
   4709             .describe( "display usage information" )
   4710             .bind( &ConfigData::showHelp );
   4711 
   4712         cli["-l"]["--list-tests"]
   4713             .describe( "list all/matching test cases" )
   4714             .bind( &ConfigData::listTests );
   4715 
   4716         cli["-t"]["--list-tags"]
   4717             .describe( "list all/matching tags" )
   4718             .bind( &ConfigData::listTags );
   4719 
   4720         cli["-s"]["--success"]
   4721             .describe( "include successful tests in output" )
   4722             .bind( &ConfigData::showSuccessfulTests );
   4723 
   4724         cli["-b"]["--break"]
   4725             .describe( "break into debugger on failure" )
   4726             .bind( &ConfigData::shouldDebugBreak );
   4727 
   4728         cli["-e"]["--nothrow"]
   4729             .describe( "skip exception tests" )
   4730             .bind( &ConfigData::noThrow );
   4731 
   4732         cli["-i"]["--invisibles"]
   4733             .describe( "show invisibles (tabs, newlines)" )
   4734             .bind( &ConfigData::showInvisibles );
   4735 
   4736         cli["-o"]["--out"]
   4737             .describe( "output filename" )
   4738             .bind( &ConfigData::outputFilename, "filename" );
   4739 
   4740         cli["-r"]["--reporter"]
   4741 //            .placeholder( "name[:filename]" )
   4742             .describe( "reporter to use (defaults to console)" )
   4743             .bind( &addReporterName, "name" );
   4744 
   4745         cli["-n"]["--name"]
   4746             .describe( "suite name" )
   4747             .bind( &ConfigData::name, "name" );
   4748 
   4749         cli["-a"]["--abort"]
   4750             .describe( "abort at first failure" )
   4751             .bind( &abortAfterFirst );
   4752 
   4753         cli["-x"]["--abortx"]
   4754             .describe( "abort after x failures" )
   4755             .bind( &abortAfterX, "no. failures" );
   4756 
   4757         cli["-w"]["--warn"]
   4758             .describe( "enable warnings" )
   4759             .bind( &addWarning, "warning name" );
   4760 
   4761 // - needs updating if reinstated
   4762 //        cli.into( &setVerbosity )
   4763 //            .describe( "level of verbosity (0=no output)" )
   4764 //            .shortOpt( "v")
   4765 //            .longOpt( "verbosity" )
   4766 //            .placeholder( "level" );
   4767 
   4768         cli[_]
   4769             .describe( "which test or tests to use" )
   4770             .bind( &addTestOrTags, "test name, pattern or tags" );
   4771 
   4772         cli["-d"]["--durations"]
   4773             .describe( "show test durations" )
   4774             .bind( &setShowDurations, "yes|no" );
   4775 
   4776         cli["-f"]["--input-file"]
   4777             .describe( "load test names to run from a file" )
   4778             .bind( &loadTestNamesFromFile, "filename" );
   4779 
   4780         cli["-#"]["--filenames-as-tags"]
   4781             .describe( "adds a tag for the filename" )
   4782             .bind( &ConfigData::filenamesAsTags );
   4783 
   4784         // Less common commands which don't have a short form
   4785         cli["--list-test-names-only"]
   4786             .describe( "list all/matching test cases names only" )
   4787             .bind( &ConfigData::listTestNamesOnly );
   4788 
   4789         cli["--list-reporters"]
   4790             .describe( "list all reporters" )
   4791             .bind( &ConfigData::listReporters );
   4792 
   4793         cli["--order"]
   4794             .describe( "test case order (defaults to decl)" )
   4795             .bind( &setOrder, "decl|lex|rand" );
   4796 
   4797         cli["--rng-seed"]
   4798             .describe( "set a specific seed for random numbers" )
   4799             .bind( &setRngSeed, "'time'|number" );
   4800 
   4801         cli["--force-colour"]
   4802             .describe( "force colourised output (deprecated)" )
   4803             .bind( &forceColour );
   4804 
   4805         cli["--use-colour"]
   4806             .describe( "should output be colourised" )
   4807             .bind( &setUseColour, "yes|no" );
   4808 
   4809         return cli;
   4810     }
   4811 
   4812 } // end namespace Catch
   4813 
   4814 // #included from: internal/catch_list.hpp
   4815 #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
   4816 
   4817 // #included from: catch_text.h
   4818 #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
   4819 
   4820 #define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
   4821 
   4822 #define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
   4823 // #included from: ../external/tbc_text_format.h
   4824 // Only use header guard if we are not using an outer namespace
   4825 #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
   4826 # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
   4827 #  ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
   4828 #   define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
   4829 #  endif
   4830 # else
   4831 #  define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
   4832 # endif
   4833 #endif
   4834 #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
   4835 #include <string>
   4836 #include <vector>
   4837 #include <sstream>
   4838 
   4839 // Use optional outer namespace
   4840 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
   4841 namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
   4842 #endif
   4843 
   4844 namespace Tbc {
   4845 
   4846 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
   4847     const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
   4848 #else
   4849     const unsigned int consoleWidth = 80;
   4850 #endif
   4851 
   4852     struct TextAttributes {
   4853         TextAttributes()
   4854         :   initialIndent( std::string::npos ),
   4855             indent( 0 ),
   4856             width( consoleWidth-1 ),
   4857             tabChar( '\t' )
   4858         {}
   4859 
   4860         TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
   4861         TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
   4862         TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
   4863         TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }
   4864 
   4865         std::size_t initialIndent;  // indent of first line, or npos
   4866         std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
   4867         std::size_t width;          // maximum width of text, including indent. Longer text will wrap
   4868         char tabChar;               // If this char is seen the indent is changed to current pos
   4869     };
   4870 
   4871     class Text {
   4872     public:
   4873         Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
   4874         : attr( _attr )
   4875         {
   4876             std::string wrappableChars = " [({.,/|\\-";
   4877             std::size_t indent = _attr.initialIndent != std::string::npos
   4878                 ? _attr.initialIndent
   4879                 : _attr.indent;
   4880             std::string remainder = _str;
   4881 
   4882             while( !remainder.empty() ) {
   4883                 if( lines.size() >= 1000 ) {
   4884                     lines.push_back( "... message truncated due to excessive size" );
   4885                     return;
   4886                 }
   4887                 std::size_t tabPos = std::string::npos;
   4888                 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
   4889                 std::size_t pos = remainder.find_first_of( '\n' );
   4890                 if( pos <= width ) {
   4891                     width = pos;
   4892                 }
   4893                 pos = remainder.find_last_of( _attr.tabChar, width );
   4894                 if( pos != std::string::npos ) {
   4895                     tabPos = pos;
   4896                     if( remainder[width] == '\n' )
   4897                         width--;
   4898                     remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
   4899                 }
   4900 
   4901                 if( width == remainder.size() ) {
   4902                     spliceLine( indent, remainder, width );
   4903                 }
   4904                 else if( remainder[width] == '\n' ) {
   4905                     spliceLine( indent, remainder, width );
   4906                     if( width <= 1 || remainder.size() != 1 )
   4907                         remainder = remainder.substr( 1 );
   4908                     indent = _attr.indent;
   4909                 }
   4910                 else {
   4911                     pos = remainder.find_last_of( wrappableChars, width );
   4912                     if( pos != std::string::npos && pos > 0 ) {
   4913                         spliceLine( indent, remainder, pos );
   4914                         if( remainder[0] == ' ' )
   4915                             remainder = remainder.substr( 1 );
   4916                     }
   4917                     else {
   4918                         spliceLine( indent, remainder, width-1 );
   4919                         lines.back() += "-";
   4920                     }
   4921                     if( lines.size() == 1 )
   4922                         indent = _attr.indent;
   4923                     if( tabPos != std::string::npos )
   4924                         indent += tabPos;
   4925                 }
   4926             }
   4927         }
   4928 
   4929         void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
   4930             lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
   4931             _remainder = _remainder.substr( _pos );
   4932         }
   4933 
   4934         typedef std::vector<std::string>::const_iterator const_iterator;
   4935 
   4936         const_iterator begin() const { return lines.begin(); }
   4937         const_iterator end() const { return lines.end(); }
   4938         std::string const& last() const { return lines.back(); }
   4939         std::size_t size() const { return lines.size(); }
   4940         std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
   4941         std::string toString() const {
   4942             std::ostringstream oss;
   4943             oss << *this;
   4944             return oss.str();
   4945         }
   4946 
   4947         inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
   4948             for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
   4949                 it != itEnd; ++it ) {
   4950                 if( it != _text.begin() )
   4951                     _stream << "\n";
   4952                 _stream << *it;
   4953             }
   4954             return _stream;
   4955         }
   4956 
   4957     private:
   4958         std::string str;
   4959         TextAttributes attr;
   4960         std::vector<std::string> lines;
   4961     };
   4962 
   4963 } // end namespace Tbc
   4964 
   4965 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
   4966 } // end outer namespace
   4967 #endif
   4968 
   4969 #endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
   4970 #undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
   4971 
   4972 namespace Catch {
   4973     using Tbc::Text;
   4974     using Tbc::TextAttributes;
   4975 }
   4976 
   4977 // #included from: catch_console_colour.hpp
   4978 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
   4979 
   4980 namespace Catch {
   4981 
   4982     struct Colour {
   4983         enum Code {
   4984             None = 0,
   4985 
   4986             White,
   4987             Red,
   4988             Green,
   4989             Blue,
   4990             Cyan,
   4991             Yellow,
   4992             Grey,
   4993 
   4994             Bright = 0x10,
   4995 
   4996             BrightRed = Bright | Red,
   4997             BrightGreen = Bright | Green,
   4998             LightGrey = Bright | Grey,
   4999             BrightWhite = Bright | White,
   5000 
   5001             // By intention
   5002             FileName = LightGrey,
   5003             Warning = Yellow,
   5004             ResultError = BrightRed,
   5005             ResultSuccess = BrightGreen,
   5006             ResultExpectedFailure = Warning,
   5007 
   5008             Error = BrightRed,
   5009             Success = Green,
   5010 
   5011             OriginalExpression = Cyan,
   5012             ReconstructedExpression = Yellow,
   5013 
   5014             SecondaryText = LightGrey,
   5015             Headers = White
   5016         };
   5017 
   5018         // Use constructed object for RAII guard
   5019         Colour( Code _colourCode );
   5020         Colour( Colour const& other );
   5021         ~Colour();
   5022 
   5023         // Use static method for one-shot changes
   5024         static void use( Code _colourCode );
   5025 
   5026     private:
   5027         bool m_moved;
   5028     };
   5029 
   5030     inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
   5031 
   5032 } // end namespace Catch
   5033 
   5034 // #included from: catch_interfaces_reporter.h
   5035 #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
   5036 
   5037 #include <string>
   5038 #include <ostream>
   5039 #include <map>
   5040 #include <assert.h>
   5041 
   5042 namespace Catch
   5043 {
   5044     struct ReporterConfig {
   5045         explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
   5046         :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
   5047 
   5048         ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
   5049         :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
   5050 
   5051         std::ostream& stream() const    { return *m_stream; }
   5052         Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
   5053 
   5054     private:
   5055         std::ostream* m_stream;
   5056         Ptr<IConfig const> m_fullConfig;
   5057     };
   5058 
   5059     struct ReporterPreferences {
   5060         ReporterPreferences()
   5061         : shouldRedirectStdOut( false )
   5062         {}
   5063 
   5064         bool shouldRedirectStdOut;
   5065     };
   5066 
   5067     template<typename T>
   5068     struct LazyStat : Option<T> {
   5069         LazyStat() : used( false ) {}
   5070         LazyStat& operator=( T const& _value ) {
   5071             Option<T>::operator=( _value );
   5072             used = false;
   5073             return *this;
   5074         }
   5075         void reset() {
   5076             Option<T>::reset();
   5077             used = false;
   5078         }
   5079         bool used;
   5080     };
   5081 
   5082     struct TestRunInfo {
   5083         TestRunInfo( std::string const& _name ) : name( _name ) {}
   5084         std::string name;
   5085     };
   5086     struct GroupInfo {
   5087         GroupInfo(  std::string const& _name,
   5088                     std::size_t _groupIndex,
   5089                     std::size_t _groupsCount )
   5090         :   name( _name ),
   5091             groupIndex( _groupIndex ),
   5092             groupsCounts( _groupsCount )
   5093         {}
   5094 
   5095         std::string name;
   5096         std::size_t groupIndex;
   5097         std::size_t groupsCounts;
   5098     };
   5099 
   5100     struct AssertionStats {
   5101         AssertionStats( AssertionResult const& _assertionResult,
   5102                         std::vector<MessageInfo> const& _infoMessages,
   5103                         Totals const& _totals )
   5104         :   assertionResult( _assertionResult ),
   5105             infoMessages( _infoMessages ),
   5106             totals( _totals )
   5107         {
   5108             if( assertionResult.hasMessage() ) {
   5109                 // Copy message into messages list.
   5110                 // !TBD This should have been done earlier, somewhere
   5111                 MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
   5112                 builder << assertionResult.getMessage();
   5113                 builder.m_info.message = builder.m_stream.str();
   5114 
   5115                 infoMessages.push_back( builder.m_info );
   5116             }
   5117         }
   5118         virtual ~AssertionStats();
   5119 
   5120 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
   5121         AssertionStats( AssertionStats const& )              = default;
   5122         AssertionStats( AssertionStats && )                  = default;
   5123         AssertionStats& operator = ( AssertionStats const& ) = default;
   5124         AssertionStats& operator = ( AssertionStats && )     = default;
   5125 #  endif
   5126 
   5127         AssertionResult assertionResult;
   5128         std::vector<MessageInfo> infoMessages;
   5129         Totals totals;
   5130     };
   5131 
   5132     struct SectionStats {
   5133         SectionStats(   SectionInfo const& _sectionInfo,
   5134                         Counts const& _assertions,
   5135                         double _durationInSeconds,
   5136                         bool _missingAssertions )
   5137         :   sectionInfo( _sectionInfo ),
   5138             assertions( _assertions ),
   5139             durationInSeconds( _durationInSeconds ),
   5140             missingAssertions( _missingAssertions )
   5141         {}
   5142         virtual ~SectionStats();
   5143 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
   5144         SectionStats( SectionStats const& )              = default;
   5145         SectionStats( SectionStats && )                  = default;
   5146         SectionStats& operator = ( SectionStats const& ) = default;
   5147         SectionStats& operator = ( SectionStats && )     = default;
   5148 #  endif
   5149 
   5150         SectionInfo sectionInfo;
   5151         Counts assertions;
   5152         double durationInSeconds;
   5153         bool missingAssertions;
   5154     };
   5155 
   5156     struct TestCaseStats {
   5157         TestCaseStats(  TestCaseInfo const& _testInfo,
   5158                         Totals const& _totals,
   5159                         std::string const& _stdOut,
   5160                         std::string const& _stdErr,
   5161                         bool _aborting )
   5162         : testInfo( _testInfo ),
   5163             totals( _totals ),
   5164             stdOut( _stdOut ),
   5165             stdErr( _stdErr ),
   5166             aborting( _aborting )
   5167         {}
   5168         virtual ~TestCaseStats();
   5169 
   5170 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
   5171         TestCaseStats( TestCaseStats const& )              = default;
   5172         TestCaseStats( TestCaseStats && )                  = default;
   5173         TestCaseStats& operator = ( TestCaseStats const& ) = default;
   5174         TestCaseStats& operator = ( TestCaseStats && )     = default;
   5175 #  endif
   5176 
   5177         TestCaseInfo testInfo;
   5178         Totals totals;
   5179         std::string stdOut;
   5180         std::string stdErr;
   5181         bool aborting;
   5182     };
   5183 
   5184     struct TestGroupStats {
   5185         TestGroupStats( GroupInfo const& _groupInfo,
   5186                         Totals const& _totals,
   5187                         bool _aborting )
   5188         :   groupInfo( _groupInfo ),
   5189             totals( _totals ),
   5190             aborting( _aborting )
   5191         {}
   5192         TestGroupStats( GroupInfo const& _groupInfo )
   5193         :   groupInfo( _groupInfo ),
   5194             aborting( false )
   5195         {}
   5196         virtual ~TestGroupStats();
   5197 
   5198 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
   5199         TestGroupStats( TestGroupStats const& )              = default;
   5200         TestGroupStats( TestGroupStats && )                  = default;
   5201         TestGroupStats& operator = ( TestGroupStats const& ) = default;
   5202         TestGroupStats& operator = ( TestGroupStats && )     = default;
   5203 #  endif
   5204 
   5205         GroupInfo groupInfo;
   5206         Totals totals;
   5207         bool aborting;
   5208     };
   5209 
   5210     struct TestRunStats {
   5211         TestRunStats(   TestRunInfo const& _runInfo,
   5212                         Totals const& _totals,
   5213                         bool _aborting )
   5214         :   runInfo( _runInfo ),
   5215             totals( _totals ),
   5216             aborting( _aborting )
   5217         {}
   5218         virtual ~TestRunStats();
   5219 
   5220 #  ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
   5221         TestRunStats( TestRunStats const& _other )
   5222         :   runInfo( _other.runInfo ),
   5223             totals( _other.totals ),
   5224             aborting( _other.aborting )
   5225         {}
   5226 #  else
   5227         TestRunStats( TestRunStats const& )              = default;
   5228         TestRunStats( TestRunStats && )                  = default;
   5229         TestRunStats& operator = ( TestRunStats const& ) = default;
   5230         TestRunStats& operator = ( TestRunStats && )     = default;
   5231 #  endif
   5232 
   5233         TestRunInfo runInfo;
   5234         Totals totals;
   5235         bool aborting;
   5236     };
   5237 
   5238     struct IStreamingReporter : IShared {
   5239         virtual ~IStreamingReporter();
   5240 
   5241         // Implementing class must also provide the following static method:
   5242         // static std::string getDescription();
   5243 
   5244         virtual ReporterPreferences getPreferences() const = 0;
   5245 
   5246         virtual void noMatchingTestCases( std::string const& spec ) = 0;
   5247 
   5248         virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
   5249         virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
   5250 
   5251         virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
   5252         virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
   5253 
   5254         virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
   5255 
   5256         // The return value indicates if the messages buffer should be cleared:
   5257         virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
   5258 
   5259         virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
   5260         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
   5261         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
   5262         virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
   5263 
   5264         virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
   5265     };
   5266 
   5267     struct IReporterFactory : IShared {
   5268         virtual ~IReporterFactory();
   5269         virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
   5270         virtual std::string getDescription() const = 0;
   5271     };
   5272 
   5273     struct IReporterRegistry {
   5274         typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
   5275         typedef std::vector<Ptr<IReporterFactory> > Listeners;
   5276 
   5277         virtual ~IReporterRegistry();
   5278         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
   5279         virtual FactoryMap const& getFactories() const = 0;
   5280         virtual Listeners const& getListeners() const = 0;
   5281     };
   5282 
   5283     Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
   5284 
   5285 }
   5286 
   5287 #include <limits>
   5288 #include <algorithm>
   5289 
   5290 namespace Catch {
   5291 
   5292     inline std::size_t listTests( Config const& config ) {
   5293 
   5294         TestSpec testSpec = config.testSpec();
   5295         if( config.testSpec().hasFilters() )
   5296             Catch::cout() << "Matching test cases:\n";
   5297         else {
   5298             Catch::cout() << "All available test cases:\n";
   5299             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
   5300         }
   5301 
   5302         std::size_t matchedTests = 0;
   5303         TextAttributes nameAttr, tagsAttr;
   5304         nameAttr.setInitialIndent( 2 ).setIndent( 4 );
   5305         tagsAttr.setIndent( 6 );
   5306 
   5307         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
   5308         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
   5309                 it != itEnd;
   5310                 ++it ) {
   5311             matchedTests++;
   5312             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
   5313             Colour::Code colour = testCaseInfo.isHidden()
   5314                 ? Colour::SecondaryText
   5315                 : Colour::None;
   5316             Colour colourGuard( colour );
   5317 
   5318             Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
   5319             if( !testCaseInfo.tags.empty() )
   5320                 Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
   5321         }
   5322 
   5323         if( !config.testSpec().hasFilters() )
   5324             Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
   5325         else
   5326             Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
   5327         return matchedTests;
   5328     }
   5329 
   5330     inline std::size_t listTestsNamesOnly( Config const& config ) {
   5331         TestSpec testSpec = config.testSpec();
   5332         if( !config.testSpec().hasFilters() )
   5333             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
   5334         std::size_t matchedTests = 0;
   5335         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
   5336         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
   5337                 it != itEnd;
   5338                 ++it ) {
   5339             matchedTests++;
   5340             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
   5341             Catch::cout() << testCaseInfo.name << std::endl;
   5342         }
   5343         return matchedTests;
   5344     }
   5345 
   5346     struct TagInfo {
   5347         TagInfo() : count ( 0 ) {}
   5348         void add( std::string const& spelling ) {
   5349             ++count;
   5350             spellings.insert( spelling );
   5351         }
   5352         std::string all() const {
   5353             std::string out;
   5354             for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
   5355                         it != itEnd;
   5356                         ++it )
   5357                 out += "[" + *it + "]";
   5358             return out;
   5359         }
   5360         std::set<std::string> spellings;
   5361         std::size_t count;
   5362     };
   5363 
   5364     inline std::size_t listTags( Config const& config ) {
   5365         TestSpec testSpec = config.testSpec();
   5366         if( config.testSpec().hasFilters() )
   5367             Catch::cout() << "Tags for matching test cases:\n";
   5368         else {
   5369             Catch::cout() << "All available tags:\n";
   5370             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
   5371         }
   5372 
   5373         std::map<std::string, TagInfo> tagCounts;
   5374 
   5375         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
   5376         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
   5377                 it != itEnd;
   5378                 ++it ) {
   5379             for( std::set<std::string>::const_iterator  tagIt = it->getTestCaseInfo().tags.begin(),
   5380                                                         tagItEnd = it->getTestCaseInfo().tags.end();
   5381                     tagIt != tagItEnd;
   5382                     ++tagIt ) {
   5383                 std::string tagName = *tagIt;
   5384                 std::string lcaseTagName = toLower( tagName );
   5385                 std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
   5386                 if( countIt == tagCounts.end() )
   5387                     countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
   5388                 countIt->second.add( tagName );
   5389             }
   5390         }
   5391 
   5392         for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
   5393                                                             countItEnd = tagCounts.end();
   5394                 countIt != countItEnd;
   5395                 ++countIt ) {
   5396             std::ostringstream oss;
   5397             oss << "  " << std::setw(2) << countIt->second.count << "  ";
   5398             Text wrapper( countIt->second.all(), TextAttributes()
   5399                                                     .setInitialIndent( 0 )
   5400                                                     .setIndent( oss.str().size() )
   5401                                                     .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
   5402             Catch::cout() << oss.str() << wrapper << "\n";
   5403         }
   5404         Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
   5405         return tagCounts.size();
   5406     }
   5407 
   5408     inline std::size_t listReporters( Config const& /*config*/ ) {
   5409         Catch::cout() << "Available reporters:\n";
   5410         IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
   5411         IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
   5412         std::size_t maxNameLen = 0;
   5413         for(it = itBegin; it != itEnd; ++it )
   5414             maxNameLen = (std::max)( maxNameLen, it->first.size() );
   5415 
   5416         for(it = itBegin; it != itEnd; ++it ) {
   5417             Text wrapper( it->second->getDescription(), TextAttributes()
   5418                                                         .setInitialIndent( 0 )
   5419                                                         .setIndent( 7+maxNameLen )
   5420                                                         .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
   5421             Catch::cout() << "  "
   5422                     << it->first
   5423                     << ":"
   5424                     << std::string( maxNameLen - it->first.size() + 2, ' ' )
   5425                     << wrapper << "\n";
   5426         }
   5427         Catch::cout() << std::endl;
   5428         return factories.size();
   5429     }
   5430 
   5431     inline Option<std::size_t> list( Config const& config ) {
   5432         Option<std::size_t> listedCount;
   5433         if( config.listTests() )
   5434             listedCount = listedCount.valueOr(0) + listTests( config );
   5435         if( config.listTestNamesOnly() )
   5436             listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
   5437         if( config.listTags() )
   5438             listedCount = listedCount.valueOr(0) + listTags( config );
   5439         if( config.listReporters() )
   5440             listedCount = listedCount.valueOr(0) + listReporters( config );
   5441         return listedCount;
   5442     }
   5443 
   5444 } // end namespace Catch
   5445 
   5446 // #included from: internal/catch_run_context.hpp
   5447 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
   5448 
   5449 // #included from: catch_test_case_tracker.hpp
   5450 #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
   5451 
   5452 #include <map>
   5453 #include <string>
   5454 #include <assert.h>
   5455 #include <vector>
   5456 
   5457 namespace Catch {
   5458 namespace TestCaseTracking {
   5459 
   5460     struct ITracker : SharedImpl<> {
   5461         virtual ~ITracker();
   5462 
   5463         // static queries
   5464         virtual std::string name() const = 0;
   5465 
   5466         // dynamic queries
   5467         virtual bool isComplete() const = 0; // Successfully completed or failed
   5468         virtual bool isSuccessfullyCompleted() const = 0;
   5469         virtual bool isOpen() const = 0; // Started but not complete
   5470         virtual bool hasChildren() const = 0;
   5471 
   5472         virtual ITracker& parent() = 0;
   5473 
   5474         // actions
   5475         virtual void close() = 0; // Successfully complete
   5476         virtual void fail() = 0;
   5477         virtual void markAsNeedingAnotherRun() = 0;
   5478 
   5479         virtual void addChild( Ptr<ITracker> const& child ) = 0;
   5480         virtual ITracker* findChild( std::string const& name ) = 0;
   5481         virtual void openChild() = 0;
   5482     };
   5483 
   5484     class TrackerContext {
   5485 
   5486         enum RunState {
   5487             NotStarted,
   5488             Executing,
   5489             CompletedCycle
   5490         };
   5491 
   5492         Ptr<ITracker> m_rootTracker;
   5493         ITracker* m_currentTracker;
   5494         RunState m_runState;
   5495 
   5496     public:
   5497 
   5498         static TrackerContext& instance() {
   5499             static TrackerContext s_instance;
   5500             return s_instance;
   5501         }
   5502 
   5503         TrackerContext()
   5504         :   m_currentTracker( CATCH_NULL ),
   5505             m_runState( NotStarted )
   5506         {}
   5507 
   5508         ITracker& startRun();
   5509 
   5510         void endRun() {
   5511             m_rootTracker.reset();
   5512             m_currentTracker = CATCH_NULL;
   5513             m_runState = NotStarted;
   5514         }
   5515 
   5516         void startCycle() {
   5517             m_currentTracker = m_rootTracker.get();
   5518             m_runState = Executing;
   5519         }
   5520         void completeCycle() {
   5521             m_runState = CompletedCycle;
   5522         }
   5523 
   5524         bool completedCycle() const {
   5525             return m_runState == CompletedCycle;
   5526         }
   5527         ITracker& currentTracker() {
   5528             return *m_currentTracker;
   5529         }
   5530         void setCurrentTracker( ITracker* tracker ) {
   5531             m_currentTracker = tracker;
   5532         }
   5533     };
   5534 
   5535     class TrackerBase : public ITracker {
   5536     protected:
   5537         enum CycleState {
   5538             NotStarted,
   5539             Executing,
   5540             ExecutingChildren,
   5541             NeedsAnotherRun,
   5542             CompletedSuccessfully,
   5543             Failed
   5544         };
   5545         class TrackerHasName {
   5546             std::string m_name;
   5547         public:
   5548             TrackerHasName( std::string const& name ) : m_name( name ) {}
   5549             bool operator ()( Ptr<ITracker> const& tracker ) {
   5550                 return tracker->name() == m_name;
   5551             }
   5552         };
   5553         typedef std::vector<Ptr<ITracker> > Children;
   5554         std::string m_name;
   5555         TrackerContext& m_ctx;
   5556         ITracker* m_parent;
   5557         Children m_children;
   5558         CycleState m_runState;
   5559     public:
   5560         TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )
   5561         :   m_name( name ),
   5562             m_ctx( ctx ),
   5563             m_parent( parent ),
   5564             m_runState( NotStarted )
   5565         {}
   5566         virtual ~TrackerBase();
   5567 
   5568         virtual std::string name() const CATCH_OVERRIDE {
   5569             return m_name;
   5570         }
   5571         virtual bool isComplete() const CATCH_OVERRIDE {
   5572             return m_runState == CompletedSuccessfully || m_runState == Failed;
   5573         }
   5574         virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {
   5575             return m_runState == CompletedSuccessfully;
   5576         }
   5577         virtual bool isOpen() const CATCH_OVERRIDE {
   5578             return m_runState != NotStarted && !isComplete();
   5579         }
   5580         virtual bool hasChildren() const CATCH_OVERRIDE {
   5581             return !m_children.empty();
   5582         }
   5583 
   5584         virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
   5585             m_children.push_back( child );
   5586         }
   5587 
   5588         virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE {
   5589             Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );
   5590             return( it != m_children.end() )
   5591                 ? it->get()
   5592                 : CATCH_NULL;
   5593         }
   5594         virtual ITracker& parent() CATCH_OVERRIDE {
   5595             assert( m_parent ); // Should always be non-null except for root
   5596             return *m_parent;
   5597         }
   5598 
   5599         virtual void openChild() CATCH_OVERRIDE {
   5600             if( m_runState != ExecutingChildren ) {
   5601                 m_runState = ExecutingChildren;
   5602                 if( m_parent )
   5603                     m_parent->openChild();
   5604             }
   5605         }
   5606         void open() {
   5607             m_runState = Executing;
   5608             moveToThis();
   5609             if( m_parent )
   5610                 m_parent->openChild();
   5611         }
   5612 
   5613         virtual void close() CATCH_OVERRIDE {
   5614 
   5615             // Close any still open children (e.g. generators)
   5616             while( &m_ctx.currentTracker() != this )
   5617                 m_ctx.currentTracker().close();
   5618 
   5619             switch( m_runState ) {
   5620                 case NotStarted:
   5621                 case CompletedSuccessfully:
   5622                 case Failed:
   5623                     throw std::logic_error( "Illogical state" );
   5624 
   5625                 case NeedsAnotherRun:
   5626                     break;;
   5627 
   5628                 case Executing:
   5629                     m_runState = CompletedSuccessfully;
   5630                     break;
   5631                 case ExecutingChildren:
   5632                     if( m_children.empty() || m_children.back()->isComplete() )
   5633                         m_runState = CompletedSuccessfully;
   5634                     break;
   5635 
   5636                 default:
   5637                     throw std::logic_error( "Unexpected state" );
   5638             }
   5639             moveToParent();
   5640             m_ctx.completeCycle();
   5641         }
   5642         virtual void fail() CATCH_OVERRIDE {
   5643             m_runState = Failed;
   5644             if( m_parent )
   5645                 m_parent->markAsNeedingAnotherRun();
   5646             moveToParent();
   5647             m_ctx.completeCycle();
   5648         }
   5649         virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
   5650             m_runState = NeedsAnotherRun;
   5651         }
   5652     private:
   5653         void moveToParent() {
   5654             assert( m_parent );
   5655             m_ctx.setCurrentTracker( m_parent );
   5656         }
   5657         void moveToThis() {
   5658             m_ctx.setCurrentTracker( this );
   5659         }
   5660     };
   5661 
   5662     class SectionTracker : public TrackerBase {
   5663     public:
   5664         SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )
   5665         :   TrackerBase( name, ctx, parent )
   5666         {}
   5667         virtual ~SectionTracker();
   5668 
   5669         static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
   5670             SectionTracker* section = CATCH_NULL;
   5671 
   5672             ITracker& currentTracker = ctx.currentTracker();
   5673             if( ITracker* childTracker = currentTracker.findChild( name ) ) {
   5674                 section = dynamic_cast<SectionTracker*>( childTracker );
   5675                 assert( section );
   5676             }
   5677             else {
   5678                 section = new SectionTracker( name, ctx, &currentTracker );
   5679                 currentTracker.addChild( section );
   5680             }
   5681             if( !ctx.completedCycle() && !section->isComplete() ) {
   5682 
   5683                 section->open();
   5684             }
   5685             return *section;
   5686         }
   5687     };
   5688 
   5689     class IndexTracker : public TrackerBase {
   5690         int m_size;
   5691         int m_index;
   5692     public:
   5693         IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size )
   5694         :   TrackerBase( name, ctx, parent ),
   5695             m_size( size ),
   5696             m_index( -1 )
   5697         {}
   5698         virtual ~IndexTracker();
   5699 
   5700         static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
   5701             IndexTracker* tracker = CATCH_NULL;
   5702 
   5703             ITracker& currentTracker = ctx.currentTracker();
   5704             if( ITracker* childTracker = currentTracker.findChild( name ) ) {
   5705                 tracker = dynamic_cast<IndexTracker*>( childTracker );
   5706                 assert( tracker );
   5707             }
   5708             else {
   5709                 tracker = new IndexTracker( name, ctx, &currentTracker, size );
   5710                 currentTracker.addChild( tracker );
   5711             }
   5712 
   5713             if( !ctx.completedCycle() && !tracker->isComplete() ) {
   5714                 if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
   5715                     tracker->moveNext();
   5716                 tracker->open();
   5717             }
   5718 
   5719             return *tracker;
   5720         }
   5721 
   5722         int index() const { return m_index; }
   5723 
   5724         void moveNext() {
   5725             m_index++;
   5726             m_children.clear();
   5727         }
   5728 
   5729         virtual void close() CATCH_OVERRIDE {
   5730             TrackerBase::close();
   5731             if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
   5732                 m_runState = Executing;
   5733         }
   5734     };
   5735 
   5736     inline ITracker& TrackerContext::startRun() {
   5737         m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL );
   5738         m_currentTracker = CATCH_NULL;
   5739         m_runState = Executing;
   5740         return *m_rootTracker;
   5741     }
   5742 
   5743 } // namespace TestCaseTracking
   5744 
   5745 using TestCaseTracking::ITracker;
   5746 using TestCaseTracking::TrackerContext;
   5747 using TestCaseTracking::SectionTracker;
   5748 using TestCaseTracking::IndexTracker;
   5749 
   5750 } // namespace Catch
   5751 
   5752 // #included from: catch_fatal_condition.hpp
   5753 #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
   5754 
   5755 namespace Catch {
   5756 
   5757     // Report the error condition then exit the process
   5758     inline void fatal( std::string const& message, int exitCode ) {
   5759         IContext& context = Catch::getCurrentContext();
   5760         IResultCapture* resultCapture = context.getResultCapture();
   5761         resultCapture->handleFatalErrorCondition( message );
   5762 
   5763 		if( Catch::alwaysTrue() ) // avoids "no return" warnings
   5764             exit( exitCode );
   5765     }
   5766 
   5767 } // namespace Catch
   5768 
   5769 #if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
   5770 
   5771 namespace Catch {
   5772 
   5773     struct FatalConditionHandler {
   5774 		void reset() {}
   5775 	};
   5776 
   5777 } // namespace Catch
   5778 
   5779 #else // Not Windows - assumed to be POSIX compatible //////////////////////////
   5780 
   5781 #include <signal.h>
   5782 
   5783 namespace Catch {
   5784 
   5785     struct SignalDefs { int id; const char* name; };
   5786     extern SignalDefs signalDefs[];
   5787     SignalDefs signalDefs[] = {
   5788             { SIGINT,  "SIGINT - Terminal interrupt signal" },
   5789             { SIGILL,  "SIGILL - Illegal instruction signal" },
   5790             { SIGFPE,  "SIGFPE - Floating point error signal" },
   5791             { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
   5792             { SIGTERM, "SIGTERM - Termination request signal" },
   5793             { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
   5794         };
   5795 
   5796     struct FatalConditionHandler {
   5797 
   5798         static void handleSignal( int sig ) {
   5799             for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
   5800                 if( sig == signalDefs[i].id )
   5801                     fatal( signalDefs[i].name, -sig );
   5802             fatal( "<unknown signal>", -sig );
   5803         }
   5804 
   5805         FatalConditionHandler() : m_isSet( true ) {
   5806             for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
   5807                 signal( signalDefs[i].id, handleSignal );
   5808         }
   5809         ~FatalConditionHandler() {
   5810             reset();
   5811         }
   5812         void reset() {
   5813             if( m_isSet ) {
   5814                 for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
   5815                     signal( signalDefs[i].id, SIG_DFL );
   5816                 m_isSet = false;
   5817             }
   5818         }
   5819 
   5820         bool m_isSet;
   5821     };
   5822 
   5823 } // namespace Catch
   5824 
   5825 #endif // not Windows
   5826 
   5827 #include <set>
   5828 #include <string>
   5829 
   5830 namespace Catch {
   5831 
   5832     class StreamRedirect {
   5833 
   5834     public:
   5835         StreamRedirect( std::ostream& stream, std::string& targetString )
   5836         :   m_stream( stream ),
   5837             m_prevBuf( stream.rdbuf() ),
   5838             m_targetString( targetString )
   5839         {
   5840             stream.rdbuf( m_oss.rdbuf() );
   5841         }
   5842 
   5843         ~StreamRedirect() {
   5844             m_targetString += m_oss.str();
   5845             m_stream.rdbuf( m_prevBuf );
   5846         }
   5847 
   5848     private:
   5849         std::ostream& m_stream;
   5850         std::streambuf* m_prevBuf;
   5851         std::ostringstream m_oss;
   5852         std::string& m_targetString;
   5853     };
   5854 
   5855     ///////////////////////////////////////////////////////////////////////////
   5856 
   5857     class RunContext : public IResultCapture, public IRunner {
   5858 
   5859         RunContext( RunContext const& );
   5860         void operator =( RunContext const& );
   5861 
   5862     public:
   5863 
   5864         explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )
   5865         :   m_runInfo( _config->name() ),
   5866             m_context( getCurrentMutableContext() ),
   5867             m_activeTestCase( CATCH_NULL ),
   5868             m_config( _config ),
   5869             m_reporter( reporter )
   5870         {
   5871             m_context.setRunner( this );
   5872             m_context.setConfig( m_config );
   5873             m_context.setResultCapture( this );
   5874             m_reporter->testRunStarting( m_runInfo );
   5875         }
   5876 
   5877         virtual ~RunContext() {
   5878             m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
   5879         }
   5880 
   5881         void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
   5882             m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
   5883         }
   5884         void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
   5885             m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
   5886         }
   5887 
   5888         Totals runTest( TestCase const& testCase ) {
   5889             Totals prevTotals = m_totals;
   5890 
   5891             std::string redirectedCout;
   5892             std::string redirectedCerr;
   5893 
   5894             TestCaseInfo testInfo = testCase.getTestCaseInfo();
   5895 
   5896             m_reporter->testCaseStarting( testInfo );
   5897 
   5898             m_activeTestCase = &testCase;
   5899 
   5900             do {
   5901                 m_trackerContext.startRun();
   5902                 do {
   5903                     m_trackerContext.startCycle();
   5904                     m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );
   5905                     runCurrentTest( redirectedCout, redirectedCerr );
   5906                 }
   5907                 while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
   5908             }
   5909             // !TBD: deprecated - this will be replaced by indexed trackers
   5910             while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
   5911 
   5912             Totals deltaTotals = m_totals.delta( prevTotals );
   5913             if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {
   5914                 deltaTotals.assertions.failed++;
   5915                 deltaTotals.testCases.passed--;
   5916                 deltaTotals.testCases.failed++;
   5917             }
   5918             m_totals.testCases += deltaTotals.testCases;
   5919             m_reporter->testCaseEnded( TestCaseStats(   testInfo,
   5920                                                         deltaTotals,
   5921                                                         redirectedCout,
   5922                                                         redirectedCerr,
   5923                                                         aborting() ) );
   5924 
   5925             m_activeTestCase = CATCH_NULL;
   5926             m_testCaseTracker = CATCH_NULL;
   5927 
   5928             return deltaTotals;
   5929         }
   5930 
   5931         Ptr<IConfig const> config() const {
   5932             return m_config;
   5933         }
   5934 
   5935     private: // IResultCapture
   5936 
   5937         virtual void assertionEnded( AssertionResult const& result ) {
   5938             if( result.getResultType() == ResultWas::Ok ) {
   5939                 m_totals.assertions.passed++;
   5940             }
   5941             else if( !result.isOk() ) {
   5942                 m_totals.assertions.failed++;
   5943             }
   5944 
   5945             if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
   5946                 m_messages.clear();
   5947 
   5948             // Reset working state
   5949             m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
   5950             m_lastResult = result;
   5951         }
   5952 
   5953         virtual bool sectionStarted (
   5954             SectionInfo const& sectionInfo,
   5955             Counts& assertions
   5956         )
   5957         {
   5958             std::ostringstream oss;
   5959             oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
   5960 
   5961             ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );
   5962             if( !sectionTracker.isOpen() )
   5963                 return false;
   5964             m_activeSections.push_back( &sectionTracker );
   5965 
   5966             m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
   5967 
   5968             m_reporter->sectionStarting( sectionInfo );
   5969 
   5970             assertions = m_totals.assertions;
   5971 
   5972             return true;
   5973         }
   5974         bool testForMissingAssertions( Counts& assertions ) {
   5975             if( assertions.total() != 0 )
   5976                 return false;
   5977             if( !m_config->warnAboutMissingAssertions() )
   5978                 return false;
   5979             if( m_trackerContext.currentTracker().hasChildren() )
   5980                 return false;
   5981             m_totals.assertions.failed++;
   5982             assertions.failed++;
   5983             return true;
   5984         }
   5985 
   5986         virtual void sectionEnded( SectionEndInfo const& endInfo ) {
   5987             Counts assertions = m_totals.assertions - endInfo.prevAssertions;
   5988             bool missingAssertions = testForMissingAssertions( assertions );
   5989 
   5990             if( !m_activeSections.empty() ) {
   5991                 m_activeSections.back()->close();
   5992                 m_activeSections.pop_back();
   5993             }
   5994 
   5995             m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
   5996             m_messages.clear();
   5997         }
   5998 
   5999         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
   6000             if( m_unfinishedSections.empty() )
   6001                 m_activeSections.back()->fail();
   6002             else
   6003                 m_activeSections.back()->close();
   6004             m_activeSections.pop_back();
   6005 
   6006             m_unfinishedSections.push_back( endInfo );
   6007         }
   6008 
   6009         virtual void pushScopedMessage( MessageInfo const& message ) {
   6010             m_messages.push_back( message );
   6011         }
   6012 
   6013         virtual void popScopedMessage( MessageInfo const& message ) {
   6014             m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
   6015         }
   6016 
   6017         virtual std::string getCurrentTestName() const {
   6018             return m_activeTestCase
   6019                 ? m_activeTestCase->getTestCaseInfo().name
   6020                 : "";
   6021         }
   6022 
   6023         virtual const AssertionResult* getLastResult() const {
   6024             return &m_lastResult;
   6025         }
   6026 
   6027         virtual void handleFatalErrorCondition( std::string const& message ) {
   6028             ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
   6029             resultBuilder.setResultType( ResultWas::FatalErrorCondition );
   6030             resultBuilder << message;
   6031             resultBuilder.captureExpression();
   6032 
   6033             handleUnfinishedSections();
   6034 
   6035             // Recreate section for test case (as we will lose the one that was in scope)
   6036             TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
   6037             SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
   6038 
   6039             Counts assertions;
   6040             assertions.failed = 1;
   6041             SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
   6042             m_reporter->sectionEnded( testCaseSectionStats );
   6043 
   6044             TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
   6045 
   6046             Totals deltaTotals;
   6047             deltaTotals.testCases.failed = 1;
   6048             m_reporter->testCaseEnded( TestCaseStats(   testInfo,
   6049                                                         deltaTotals,
   6050                                                         "",
   6051                                                         "",
   6052                                                         false ) );
   6053             m_totals.testCases.failed++;
   6054             testGroupEnded( "", m_totals, 1, 1 );
   6055             m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
   6056         }
   6057 
   6058     public:
   6059         // !TBD We need to do this another way!
   6060         bool aborting() const {
   6061             return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
   6062         }
   6063 
   6064     private:
   6065 
   6066         void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
   6067             TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
   6068             SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
   6069             m_reporter->sectionStarting( testCaseSection );
   6070             Counts prevAssertions = m_totals.assertions;
   6071             double duration = 0;
   6072             try {
   6073                 m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
   6074 
   6075                 seedRng( *m_config );
   6076 
   6077                 Timer timer;
   6078                 timer.start();
   6079                 if( m_reporter->getPreferences().shouldRedirectStdOut ) {
   6080                     StreamRedirect coutRedir( Catch::cout(), redirectedCout );
   6081                     StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
   6082                     invokeActiveTestCase();
   6083                 }
   6084                 else {
   6085                     invokeActiveTestCase();
   6086                 }
   6087                 duration = timer.getElapsedSeconds();
   6088             }
   6089             catch( TestFailureException& ) {
   6090                 // This just means the test was aborted due to failure
   6091             }
   6092             catch(...) {
   6093                 makeUnexpectedResultBuilder().useActiveException();
   6094             }
   6095             m_testCaseTracker->close();
   6096             handleUnfinishedSections();
   6097             m_messages.clear();
   6098 
   6099             Counts assertions = m_totals.assertions - prevAssertions;
   6100             bool missingAssertions = testForMissingAssertions( assertions );
   6101 
   6102             if( testCaseInfo.okToFail() ) {
   6103                 std::swap( assertions.failedButOk, assertions.failed );
   6104                 m_totals.assertions.failed -= assertions.failedButOk;
   6105                 m_totals.assertions.failedButOk += assertions.failedButOk;
   6106             }
   6107 
   6108             SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
   6109             m_reporter->sectionEnded( testCaseSectionStats );
   6110         }
   6111 
   6112         void invokeActiveTestCase() {
   6113             FatalConditionHandler fatalConditionHandler; // Handle signals
   6114             m_activeTestCase->invoke();
   6115             fatalConditionHandler.reset();
   6116         }
   6117 
   6118     private:
   6119 
   6120         ResultBuilder makeUnexpectedResultBuilder() const {
   6121             return ResultBuilder(   m_lastAssertionInfo.macroName.c_str(),
   6122                                     m_lastAssertionInfo.lineInfo,
   6123                                     m_lastAssertionInfo.capturedExpression.c_str(),
   6124                                     m_lastAssertionInfo.resultDisposition );
   6125         }
   6126 
   6127         void handleUnfinishedSections() {
   6128             // If sections ended prematurely due to an exception we stored their
   6129             // infos here so we can tear them down outside the unwind process.
   6130             for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
   6131                         itEnd = m_unfinishedSections.rend();
   6132                     it != itEnd;
   6133                     ++it )
   6134                 sectionEnded( *it );
   6135             m_unfinishedSections.clear();
   6136         }
   6137 
   6138         TestRunInfo m_runInfo;
   6139         IMutableContext& m_context;
   6140         TestCase const* m_activeTestCase;
   6141         ITracker* m_testCaseTracker;
   6142         ITracker* m_currentSectionTracker;
   6143         AssertionResult m_lastResult;
   6144 
   6145         Ptr<IConfig const> m_config;
   6146         Totals m_totals;
   6147         Ptr<IStreamingReporter> m_reporter;
   6148         std::vector<MessageInfo> m_messages;
   6149         AssertionInfo m_lastAssertionInfo;
   6150         std::vector<SectionEndInfo> m_unfinishedSections;
   6151         std::vector<ITracker*> m_activeSections;
   6152         TrackerContext m_trackerContext;
   6153     };
   6154 
   6155     IResultCapture& getResultCapture() {
   6156         if( IResultCapture* capture = getCurrentContext().getResultCapture() )
   6157             return *capture;
   6158         else
   6159             throw std::logic_error( "No result capture instance" );
   6160     }
   6161 
   6162 } // end namespace Catch
   6163 
   6164 // #included from: internal/catch_version.h
   6165 #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
   6166 
   6167 namespace Catch {
   6168 
   6169     // Versioning information
   6170     struct Version {
   6171         Version(    unsigned int _majorVersion,
   6172                     unsigned int _minorVersion,
   6173                     unsigned int _patchNumber,
   6174                     std::string const& _branchName,
   6175                     unsigned int _buildNumber );
   6176 
   6177         unsigned int const majorVersion;
   6178         unsigned int const minorVersion;
   6179         unsigned int const patchNumber;
   6180 
   6181         // buildNumber is only used if branchName is not null
   6182         std::string const branchName;
   6183         unsigned int const buildNumber;
   6184 
   6185         friend std::ostream& operator << ( std::ostream& os, Version const& version );
   6186 
   6187     private:
   6188         void operator=( Version const& );
   6189     };
   6190 
   6191     extern Version libraryVersion;
   6192 }
   6193 
   6194 #include <fstream>
   6195 #include <stdlib.h>
   6196 #include <limits>
   6197 
   6198 namespace Catch {
   6199 
   6200     Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
   6201         Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
   6202         if( !reporter ) {
   6203             std::ostringstream oss;
   6204             oss << "No reporter registered with name: '" << reporterName << "'";
   6205             throw std::domain_error( oss.str() );
   6206         }
   6207         return reporter;
   6208     }
   6209 
   6210     Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
   6211         std::vector<std::string> reporters = config->getReporterNames();
   6212         if( reporters.empty() )
   6213             reporters.push_back( "console" );
   6214 
   6215         Ptr<IStreamingReporter> reporter;
   6216         for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
   6217                 it != itEnd;
   6218                 ++it )
   6219             reporter = addReporter( reporter, createReporter( *it, config ) );
   6220         return reporter;
   6221     }
   6222     Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
   6223         IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
   6224         for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
   6225                 it != itEnd;
   6226                 ++it )
   6227             reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
   6228         return reporters;
   6229     }
   6230 
   6231     Totals runTests( Ptr<Config> const& config ) {
   6232 
   6233         Ptr<IConfig const> iconfig = config.get();
   6234 
   6235         Ptr<IStreamingReporter> reporter = makeReporter( config );
   6236         reporter = addListeners( iconfig, reporter );
   6237 
   6238         RunContext context( iconfig, reporter );
   6239 
   6240         Totals totals;
   6241 
   6242         context.testGroupStarting( config->name(), 1, 1 );
   6243 
   6244         TestSpec testSpec = config->testSpec();
   6245         if( !testSpec.hasFilters() )
   6246             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
   6247 
   6248         std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
   6249         for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
   6250                 it != itEnd;
   6251                 ++it ) {
   6252             if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
   6253                 totals += context.runTest( *it );
   6254             else
   6255                 reporter->skipTest( *it );
   6256         }
   6257 
   6258         context.testGroupEnded( iconfig->name(), totals, 1, 1 );
   6259         return totals;
   6260     }
   6261 
   6262     void applyFilenamesAsTags( IConfig const& config ) {
   6263         std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
   6264         for(std::size_t i = 0; i < tests.size(); ++i ) {
   6265             TestCase& test = const_cast<TestCase&>( tests[i] );
   6266             std::set<std::string> tags = test.tags;
   6267 
   6268             std::string filename = test.lineInfo.file;
   6269             std::string::size_type lastSlash = filename.find_last_of( "\\/" );
   6270             if( lastSlash != std::string::npos )
   6271                 filename = filename.substr( lastSlash+1 );
   6272 
   6273             std::string::size_type lastDot = filename.find_last_of( "." );
   6274             if( lastDot != std::string::npos )
   6275                 filename = filename.substr( 0, lastDot );
   6276 
   6277             tags.insert( "#" + filename );
   6278             setTags( test, tags );
   6279         }
   6280     }
   6281 
   6282     class Session : NonCopyable {
   6283         static bool alreadyInstantiated;
   6284 
   6285     public:
   6286 
   6287         struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
   6288 
   6289         Session()
   6290         : m_cli( makeCommandLineParser() ) {
   6291             if( alreadyInstantiated ) {
   6292                 std::string msg = "Only one instance of Catch::Session can ever be used";
   6293                 Catch::cerr() << msg << std::endl;
   6294                 throw std::logic_error( msg );
   6295             }
   6296             alreadyInstantiated = true;
   6297         }
   6298         ~Session() {
   6299             Catch::cleanUp();
   6300         }
   6301 
   6302         void showHelp( std::string const& processName ) {
   6303             Catch::cout() << "\nCatch v" << libraryVersion << "\n";
   6304 
   6305             m_cli.usage( Catch::cout(), processName );
   6306             Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
   6307         }
   6308 
   6309         int applyCommandLine( int argc, char const* argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
   6310             try {
   6311                 m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
   6312                 m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
   6313                 if( m_configData.showHelp )
   6314                     showHelp( m_configData.processName );
   6315                 m_config.reset();
   6316             }
   6317             catch( std::exception& ex ) {
   6318                 {
   6319                     Colour colourGuard( Colour::Red );
   6320                     Catch::cerr()
   6321                         << "\nError(s) in input:\n"
   6322                         << Text( ex.what(), TextAttributes().setIndent(2) )
   6323                         << "\n\n";
   6324                 }
   6325                 m_cli.usage( Catch::cout(), m_configData.processName );
   6326                 return (std::numeric_limits<int>::max)();
   6327             }
   6328             return 0;
   6329         }
   6330 
   6331         void useConfigData( ConfigData const& _configData ) {
   6332             m_configData = _configData;
   6333             m_config.reset();
   6334         }
   6335 
   6336         int run( int argc, char const* argv[] ) {
   6337 
   6338             int returnCode = applyCommandLine( argc, argv );
   6339             if( returnCode == 0 )
   6340                 returnCode = run();
   6341             return returnCode;
   6342         }
   6343         int run( int argc, char* argv[] ) {
   6344             return run( argc, const_cast<char const**>( argv ) );
   6345         }
   6346 
   6347         int run() {
   6348             if( m_configData.showHelp )
   6349                 return 0;
   6350 
   6351             try
   6352             {
   6353                 config(); // Force config to be constructed
   6354 
   6355                 seedRng( *m_config );
   6356 
   6357                 if( m_configData.filenamesAsTags )
   6358                     applyFilenamesAsTags( *m_config );
   6359 
   6360                 // Handle list request
   6361                 if( Option<std::size_t> listed = list( config() ) )
   6362                     return static_cast<int>( *listed );
   6363 
   6364                 return static_cast<int>( runTests( m_config ).assertions.failed );
   6365             }
   6366             catch( std::exception& ex ) {
   6367                 Catch::cerr() << ex.what() << std::endl;
   6368                 return (std::numeric_limits<int>::max)();
   6369             }
   6370         }
   6371 
   6372         Clara::CommandLine<ConfigData> const& cli() const {
   6373             return m_cli;
   6374         }
   6375         std::vector<Clara::Parser::Token> const& unusedTokens() const {
   6376             return m_unusedTokens;
   6377         }
   6378         ConfigData& configData() {
   6379             return m_configData;
   6380         }
   6381         Config& config() {
   6382             if( !m_config )
   6383                 m_config = new Config( m_configData );
   6384             return *m_config;
   6385         }
   6386     private:
   6387         Clara::CommandLine<ConfigData> m_cli;
   6388         std::vector<Clara::Parser::Token> m_unusedTokens;
   6389         ConfigData m_configData;
   6390         Ptr<Config> m_config;
   6391     };
   6392 
   6393     bool Session::alreadyInstantiated = false;
   6394 
   6395 } // end namespace Catch
   6396 
   6397 // #included from: catch_registry_hub.hpp
   6398 #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
   6399 
   6400 // #included from: catch_test_case_registry_impl.hpp
   6401 #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
   6402 
   6403 #include <vector>
   6404 #include <set>
   6405 #include <sstream>
   6406 #include <iostream>
   6407 #include <algorithm>
   6408 
   6409 namespace Catch {
   6410 
   6411     struct LexSort {
   6412         bool operator() (TestCase i,TestCase j) const { return (i<j);}
   6413     };
   6414     struct RandomNumberGenerator {
   6415         int operator()( int n ) const { return std::rand() % n; }
   6416     };
   6417 
   6418     inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
   6419 
   6420         std::vector<TestCase> sorted = unsortedTestCases;
   6421 
   6422         switch( config.runOrder() ) {
   6423             case RunTests::InLexicographicalOrder:
   6424                 std::sort( sorted.begin(), sorted.end(), LexSort() );
   6425                 break;
   6426             case RunTests::InRandomOrder:
   6427                 {
   6428                     seedRng( config );
   6429 
   6430                     RandomNumberGenerator rng;
   6431                     std::random_shuffle( sorted.begin(), sorted.end(), rng );
   6432                 }
   6433                 break;
   6434             case RunTests::InDeclarationOrder:
   6435                 // already in declaration order
   6436                 break;
   6437         }
   6438         return sorted;
   6439     }
   6440     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
   6441         return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
   6442     }
   6443 
   6444     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
   6445         std::set<TestCase> seenFunctions;
   6446         for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
   6447             it != itEnd;
   6448             ++it ) {
   6449             std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
   6450             if( !prev.second ){
   6451                 Catch::cerr()
   6452                 << Colour( Colour::Red )
   6453                 << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
   6454                 << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
   6455                 << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
   6456                 exit(1);
   6457             }
   6458         }
   6459     }
   6460 
   6461     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
   6462         std::vector<TestCase> filtered;
   6463         filtered.reserve( testCases.size() );
   6464         for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
   6465                 it != itEnd;
   6466                 ++it )
   6467             if( matchTest( *it, testSpec, config ) )
   6468                 filtered.push_back( *it );
   6469         return filtered;
   6470     }
   6471     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
   6472         return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
   6473     }
   6474 
   6475     class TestRegistry : public ITestCaseRegistry {
   6476     public:
   6477         TestRegistry()
   6478         :   m_currentSortOrder( RunTests::InDeclarationOrder ),
   6479             m_unnamedCount( 0 )
   6480         {}
   6481         virtual ~TestRegistry();
   6482 
   6483         virtual void registerTest( TestCase const& testCase ) {
   6484             std::string name = testCase.getTestCaseInfo().name;
   6485             if( name == "" ) {
   6486                 std::ostringstream oss;
   6487                 oss << "Anonymous test case " << ++m_unnamedCount;
   6488                 return registerTest( testCase.withName( oss.str() ) );
   6489             }
   6490             m_functions.push_back( testCase );
   6491         }
   6492 
   6493         virtual std::vector<TestCase> const& getAllTests() const {
   6494             return m_functions;
   6495         }
   6496         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
   6497             if( m_sortedFunctions.empty() )
   6498                 enforceNoDuplicateTestCases( m_functions );
   6499 
   6500             if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
   6501                 m_sortedFunctions = sortTests( config, m_functions );
   6502                 m_currentSortOrder = config.runOrder();
   6503             }
   6504             return m_sortedFunctions;
   6505         }
   6506 
   6507     private:
   6508         std::vector<TestCase> m_functions;
   6509         mutable RunTests::InWhatOrder m_currentSortOrder;
   6510         mutable std::vector<TestCase> m_sortedFunctions;
   6511         size_t m_unnamedCount;
   6512         std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
   6513     };
   6514 
   6515     ///////////////////////////////////////////////////////////////////////////
   6516 
   6517     class FreeFunctionTestCase : public SharedImpl<ITestCase> {
   6518     public:
   6519 
   6520         FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
   6521 
   6522         virtual void invoke() const {
   6523             m_fun();
   6524         }
   6525 
   6526     private:
   6527         virtual ~FreeFunctionTestCase();
   6528 
   6529         TestFunction m_fun;
   6530     };
   6531 
   6532     inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
   6533         std::string className = classOrQualifiedMethodName;
   6534         if( startsWith( className, "&" ) )
   6535         {
   6536             std::size_t lastColons = className.rfind( "::" );
   6537             std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
   6538             if( penultimateColons == std::string::npos )
   6539                 penultimateColons = 1;
   6540             className = className.substr( penultimateColons, lastColons-penultimateColons );
   6541         }
   6542         return className;
   6543     }
   6544 
   6545     void registerTestCase
   6546         (   ITestCase* testCase,
   6547             char const* classOrQualifiedMethodName,
   6548             NameAndDesc const& nameAndDesc,
   6549             SourceLineInfo const& lineInfo ) {
   6550 
   6551         getMutableRegistryHub().registerTest
   6552             ( makeTestCase
   6553                 (   testCase,
   6554                     extractClassName( classOrQualifiedMethodName ),
   6555                     nameAndDesc.name,
   6556                     nameAndDesc.description,
   6557                     lineInfo ) );
   6558     }
   6559     void registerTestCaseFunction
   6560         (   TestFunction function,
   6561             SourceLineInfo const& lineInfo,
   6562             NameAndDesc const& nameAndDesc ) {
   6563         registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
   6564     }
   6565 
   6566     ///////////////////////////////////////////////////////////////////////////
   6567 
   6568     AutoReg::AutoReg
   6569         (   TestFunction function,
   6570             SourceLineInfo const& lineInfo,
   6571             NameAndDesc const& nameAndDesc ) {
   6572         registerTestCaseFunction( function, lineInfo, nameAndDesc );
   6573     }
   6574 
   6575     AutoReg::~AutoReg() {}
   6576 
   6577 } // end namespace Catch
   6578 
   6579 // #included from: catch_reporter_registry.hpp
   6580 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
   6581 
   6582 #include <map>
   6583 
   6584 namespace Catch {
   6585 
   6586     class ReporterRegistry : public IReporterRegistry {
   6587 
   6588     public:
   6589 
   6590         virtual ~ReporterRegistry() CATCH_OVERRIDE {}
   6591 
   6592         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
   6593             FactoryMap::const_iterator it =  m_factories.find( name );
   6594             if( it == m_factories.end() )
   6595                 return CATCH_NULL;
   6596             return it->second->create( ReporterConfig( config ) );
   6597         }
   6598 
   6599         void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
   6600             m_factories.insert( std::make_pair( name, factory ) );
   6601         }
   6602         void registerListener( Ptr<IReporterFactory> const& factory ) {
   6603             m_listeners.push_back( factory );
   6604         }
   6605 
   6606         virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {
   6607             return m_factories;
   6608         }
   6609         virtual Listeners const& getListeners() const CATCH_OVERRIDE {
   6610             return m_listeners;
   6611         }
   6612 
   6613     private:
   6614         FactoryMap m_factories;
   6615         Listeners m_listeners;
   6616     };
   6617 }
   6618 
   6619 // #included from: catch_exception_translator_registry.hpp
   6620 #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
   6621 
   6622 #ifdef __OBJC__
   6623 #import "Foundation/Foundation.h"
   6624 #endif
   6625 
   6626 namespace Catch {
   6627 
   6628     class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
   6629     public:
   6630         ~ExceptionTranslatorRegistry() {
   6631             deleteAll( m_translators );
   6632         }
   6633 
   6634         virtual void registerTranslator( const IExceptionTranslator* translator ) {
   6635             m_translators.push_back( translator );
   6636         }
   6637 
   6638         virtual std::string translateActiveException() const {
   6639             try {
   6640 #ifdef __OBJC__
   6641                 // In Objective-C try objective-c exceptions first
   6642                 @try {
   6643                     return tryTranslators();
   6644                 }
   6645                 @catch (NSException *exception) {
   6646                     return Catch::toString( [exception description] );
   6647                 }
   6648 #else
   6649                 return tryTranslators();
   6650 #endif
   6651             }
   6652             catch( TestFailureException& ) {
   6653                 throw;
   6654             }
   6655             catch( std::exception& ex ) {
   6656                 return ex.what();
   6657             }
   6658             catch( std::string& msg ) {
   6659                 return msg;
   6660             }
   6661             catch( const char* msg ) {
   6662                 return msg;
   6663             }
   6664             catch(...) {
   6665                 return "Unknown exception";
   6666             }
   6667         }
   6668 
   6669         std::string tryTranslators() const {
   6670             if( m_translators.empty() )
   6671                 throw;
   6672             else
   6673                 return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
   6674         }
   6675 
   6676     private:
   6677         std::vector<const IExceptionTranslator*> m_translators;
   6678     };
   6679 }
   6680 
   6681 namespace Catch {
   6682 
   6683     namespace {
   6684 
   6685         class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
   6686 
   6687             RegistryHub( RegistryHub const& );
   6688             void operator=( RegistryHub const& );
   6689 
   6690         public: // IRegistryHub
   6691             RegistryHub() {
   6692             }
   6693             virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {
   6694                 return m_reporterRegistry;
   6695             }
   6696             virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {
   6697                 return m_testCaseRegistry;
   6698             }
   6699             virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
   6700                 return m_exceptionTranslatorRegistry;
   6701             }
   6702 
   6703         public: // IMutableRegistryHub
   6704             virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
   6705                 m_reporterRegistry.registerReporter( name, factory );
   6706             }
   6707             virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
   6708                 m_reporterRegistry.registerListener( factory );
   6709             }
   6710             virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {
   6711                 m_testCaseRegistry.registerTest( testInfo );
   6712             }
   6713             virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
   6714                 m_exceptionTranslatorRegistry.registerTranslator( translator );
   6715             }
   6716 
   6717         private:
   6718             TestRegistry m_testCaseRegistry;
   6719             ReporterRegistry m_reporterRegistry;
   6720             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
   6721         };
   6722 
   6723         // Single, global, instance
   6724         inline RegistryHub*& getTheRegistryHub() {
   6725             static RegistryHub* theRegistryHub = CATCH_NULL;
   6726             if( !theRegistryHub )
   6727                 theRegistryHub = new RegistryHub();
   6728             return theRegistryHub;
   6729         }
   6730     }
   6731 
   6732     IRegistryHub& getRegistryHub() {
   6733         return *getTheRegistryHub();
   6734     }
   6735     IMutableRegistryHub& getMutableRegistryHub() {
   6736         return *getTheRegistryHub();
   6737     }
   6738     void cleanUp() {
   6739         delete getTheRegistryHub();
   6740         getTheRegistryHub() = CATCH_NULL;
   6741         cleanUpContext();
   6742     }
   6743     std::string translateActiveException() {
   6744         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
   6745     }
   6746 
   6747 } // end namespace Catch
   6748 
   6749 // #included from: catch_notimplemented_exception.hpp
   6750 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
   6751 
   6752 #include <ostream>
   6753 
   6754 namespace Catch {
   6755 
   6756     NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
   6757     :   m_lineInfo( lineInfo ) {
   6758         std::ostringstream oss;
   6759         oss << lineInfo << ": function ";
   6760         oss << "not implemented";
   6761         m_what = oss.str();
   6762     }
   6763 
   6764     const char* NotImplementedException::what() const CATCH_NOEXCEPT {
   6765         return m_what.c_str();
   6766     }
   6767 
   6768 } // end namespace Catch
   6769 
   6770 // #included from: catch_context_impl.hpp
   6771 #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
   6772 
   6773 // #included from: catch_stream.hpp
   6774 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
   6775 
   6776 #include <stdexcept>
   6777 #include <cstdio>
   6778 #include <iostream>
   6779 
   6780 namespace Catch {
   6781 
   6782     template<typename WriterF, size_t bufferSize=256>
   6783     class StreamBufImpl : public StreamBufBase {
   6784         char data[bufferSize];
   6785         WriterF m_writer;
   6786 
   6787     public:
   6788         StreamBufImpl() {
   6789             setp( data, data + sizeof(data) );
   6790         }
   6791 
   6792         ~StreamBufImpl() CATCH_NOEXCEPT {
   6793             sync();
   6794         }
   6795 
   6796     private:
   6797         int overflow( int c ) {
   6798             sync();
   6799 
   6800             if( c != EOF ) {
   6801                 if( pbase() == epptr() )
   6802                     m_writer( std::string( 1, static_cast<char>( c ) ) );
   6803                 else
   6804                     sputc( static_cast<char>( c ) );
   6805             }
   6806             return 0;
   6807         }
   6808 
   6809         int sync() {
   6810             if( pbase() != pptr() ) {
   6811                 m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
   6812                 setp( pbase(), epptr() );
   6813             }
   6814             return 0;
   6815         }
   6816     };
   6817 
   6818     ///////////////////////////////////////////////////////////////////////////
   6819 
   6820     FileStream::FileStream( std::string const& filename ) {
   6821         m_ofs.open( filename.c_str() );
   6822         if( m_ofs.fail() ) {
   6823             std::ostringstream oss;
   6824             oss << "Unable to open file: '" << filename << "'";
   6825             throw std::domain_error( oss.str() );
   6826         }
   6827     }
   6828 
   6829     std::ostream& FileStream::stream() const {
   6830         return m_ofs;
   6831     }
   6832 
   6833     struct OutputDebugWriter {
   6834 
   6835         void operator()( std::string const&str ) {
   6836             writeToDebugConsole( str );
   6837         }
   6838     };
   6839 
   6840     DebugOutStream::DebugOutStream()
   6841     :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
   6842         m_os( m_streamBuf.get() )
   6843     {}
   6844 
   6845     std::ostream& DebugOutStream::stream() const {
   6846         return m_os;
   6847     }
   6848 
   6849     // Store the streambuf from cout up-front because
   6850     // cout may get redirected when running tests
   6851     CoutStream::CoutStream()
   6852     :   m_os( Catch::cout().rdbuf() )
   6853     {}
   6854 
   6855     std::ostream& CoutStream::stream() const {
   6856         return m_os;
   6857     }
   6858 
   6859 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
   6860     std::ostream& cout() {
   6861         return std::cout;
   6862     }
   6863     std::ostream& cerr() {
   6864         return std::cerr;
   6865     }
   6866 #endif
   6867 }
   6868 
   6869 namespace Catch {
   6870 
   6871     class Context : public IMutableContext {
   6872 
   6873         Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
   6874         Context( Context const& );
   6875         void operator=( Context const& );
   6876 
   6877     public: // IContext
   6878         virtual IResultCapture* getResultCapture() {
   6879             return m_resultCapture;
   6880         }
   6881         virtual IRunner* getRunner() {
   6882             return m_runner;
   6883         }
   6884         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
   6885             return getGeneratorsForCurrentTest()
   6886             .getGeneratorInfo( fileInfo, totalSize )
   6887             .getCurrentIndex();
   6888         }
   6889         virtual bool advanceGeneratorsForCurrentTest() {
   6890             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
   6891             return generators && generators->moveNext();
   6892         }
   6893 
   6894         virtual Ptr<IConfig const> getConfig() const {
   6895             return m_config;
   6896         }
   6897 
   6898     public: // IMutableContext
   6899         virtual void setResultCapture( IResultCapture* resultCapture ) {
   6900             m_resultCapture = resultCapture;
   6901         }
   6902         virtual void setRunner( IRunner* runner ) {
   6903             m_runner = runner;
   6904         }
   6905         virtual void setConfig( Ptr<IConfig const> const& config ) {
   6906             m_config = config;
   6907         }
   6908 
   6909         friend IMutableContext& getCurrentMutableContext();
   6910 
   6911     private:
   6912         IGeneratorsForTest* findGeneratorsForCurrentTest() {
   6913             std::string testName = getResultCapture()->getCurrentTestName();
   6914 
   6915             std::map<std::string, IGeneratorsForTest*>::const_iterator it =
   6916                 m_generatorsByTestName.find( testName );
   6917             return it != m_generatorsByTestName.end()
   6918                 ? it->second
   6919                 : CATCH_NULL;
   6920         }
   6921 
   6922         IGeneratorsForTest& getGeneratorsForCurrentTest() {
   6923             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
   6924             if( !generators ) {
   6925                 std::string testName = getResultCapture()->getCurrentTestName();
   6926                 generators = createGeneratorsForTest();
   6927                 m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
   6928             }
   6929             return *generators;
   6930         }
   6931 
   6932     private:
   6933         Ptr<IConfig const> m_config;
   6934         IRunner* m_runner;
   6935         IResultCapture* m_resultCapture;
   6936         std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
   6937     };
   6938 
   6939     namespace {
   6940         Context* currentContext = CATCH_NULL;
   6941     }
   6942     IMutableContext& getCurrentMutableContext() {
   6943         if( !currentContext )
   6944             currentContext = new Context();
   6945         return *currentContext;
   6946     }
   6947     IContext& getCurrentContext() {
   6948         return getCurrentMutableContext();
   6949     }
   6950 
   6951     void cleanUpContext() {
   6952         delete currentContext;
   6953         currentContext = CATCH_NULL;
   6954     }
   6955 }
   6956 
   6957 // #included from: catch_console_colour_impl.hpp
   6958 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
   6959 
   6960 namespace Catch {
   6961     namespace {
   6962 
   6963         struct IColourImpl {
   6964             virtual ~IColourImpl() {}
   6965             virtual void use( Colour::Code _colourCode ) = 0;
   6966         };
   6967 
   6968         struct NoColourImpl : IColourImpl {
   6969             void use( Colour::Code ) {}
   6970 
   6971             static IColourImpl* instance() {
   6972                 static NoColourImpl s_instance;
   6973                 return &s_instance;
   6974             }
   6975         };
   6976 
   6977     } // anon namespace
   6978 } // namespace Catch
   6979 
   6980 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
   6981 #   ifdef CATCH_PLATFORM_WINDOWS
   6982 #       define CATCH_CONFIG_COLOUR_WINDOWS
   6983 #   else
   6984 #       define CATCH_CONFIG_COLOUR_ANSI
   6985 #   endif
   6986 #endif
   6987 
   6988 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
   6989 
   6990 #ifndef NOMINMAX
   6991 #define NOMINMAX
   6992 #endif
   6993 
   6994 #ifdef __AFXDLL
   6995 #include <AfxWin.h>
   6996 #else
   6997 #include <windows.h>
   6998 #endif
   6999 
   7000 namespace Catch {
   7001 namespace {
   7002 
   7003     class Win32ColourImpl : public IColourImpl {
   7004     public:
   7005         Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
   7006         {
   7007             CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
   7008             GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
   7009             originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
   7010             originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
   7011         }
   7012 
   7013         virtual void use( Colour::Code _colourCode ) {
   7014             switch( _colourCode ) {
   7015                 case Colour::None:      return setTextAttribute( originalForegroundAttributes );
   7016                 case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
   7017                 case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
   7018                 case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
   7019                 case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
   7020                 case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
   7021                 case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
   7022                 case Colour::Grey:      return setTextAttribute( 0 );
   7023 
   7024                 case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
   7025                 case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
   7026                 case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
   7027                 case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
   7028 
   7029                 case Colour::Bright: throw std::logic_error( "not a colour" );
   7030             }
   7031         }
   7032 
   7033     private:
   7034         void setTextAttribute( WORD _textAttribute ) {
   7035             SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
   7036         }
   7037         HANDLE stdoutHandle;
   7038         WORD originalForegroundAttributes;
   7039         WORD originalBackgroundAttributes;
   7040     };
   7041 
   7042     IColourImpl* platformColourInstance() {
   7043         static Win32ColourImpl s_instance;
   7044 
   7045         Ptr<IConfig const> config = getCurrentContext().getConfig();
   7046         UseColour::YesOrNo colourMode = config
   7047             ? config->useColour()
   7048             : UseColour::Auto;
   7049         if( colourMode == UseColour::Auto )
   7050             colourMode = !isDebuggerActive()
   7051                 ? UseColour::Yes
   7052                 : UseColour::No;
   7053         return colourMode == UseColour::Yes
   7054             ? &s_instance
   7055             : NoColourImpl::instance();
   7056     }
   7057 
   7058 } // end anon namespace
   7059 } // end namespace Catch
   7060 
   7061 #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
   7062 
   7063 #include <unistd.h>
   7064 
   7065 namespace Catch {
   7066 namespace {
   7067 
   7068     // use POSIX/ ANSI console terminal codes
   7069     // Thanks to Adam Strzelecki for original contribution
   7070     // (http://github.com/nanoant)
   7071     // https://github.com/philsquared/Catch/pull/131
   7072     class PosixColourImpl : public IColourImpl {
   7073     public:
   7074         virtual void use( Colour::Code _colourCode ) {
   7075             switch( _colourCode ) {
   7076                 case Colour::None:
   7077                 case Colour::White:     return setColour( "[0m" );
   7078                 case Colour::Red:       return setColour( "[0;31m" );
   7079                 case Colour::Green:     return setColour( "[0;32m" );
   7080                 case Colour::Blue:      return setColour( "[0:34m" );
   7081                 case Colour::Cyan:      return setColour( "[0;36m" );
   7082                 case Colour::Yellow:    return setColour( "[0;33m" );
   7083                 case Colour::Grey:      return setColour( "[1;30m" );
   7084 
   7085                 case Colour::LightGrey:     return setColour( "[0;37m" );
   7086                 case Colour::BrightRed:     return setColour( "[1;31m" );
   7087                 case Colour::BrightGreen:   return setColour( "[1;32m" );
   7088                 case Colour::BrightWhite:   return setColour( "[1;37m" );
   7089 
   7090                 case Colour::Bright: throw std::logic_error( "not a colour" );
   7091             }
   7092         }
   7093         static IColourImpl* instance() {
   7094             static PosixColourImpl s_instance;
   7095             return &s_instance;
   7096         }
   7097 
   7098     private:
   7099         void setColour( const char* _escapeCode ) {
   7100             Catch::cout() << '\033' << _escapeCode;
   7101         }
   7102     };
   7103 
   7104     IColourImpl* platformColourInstance() {
   7105         Ptr<IConfig const> config = getCurrentContext().getConfig();
   7106         UseColour::YesOrNo colourMode = config
   7107             ? config->useColour()
   7108             : UseColour::Auto;
   7109         if( colourMode == UseColour::Auto )
   7110             colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )
   7111                 ? UseColour::Yes
   7112                 : UseColour::No;
   7113         return colourMode == UseColour::Yes
   7114             ? PosixColourImpl::instance()
   7115             : NoColourImpl::instance();
   7116     }
   7117 
   7118 } // end anon namespace
   7119 } // end namespace Catch
   7120 
   7121 #else  // not Windows or ANSI ///////////////////////////////////////////////
   7122 
   7123 namespace Catch {
   7124 
   7125     static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
   7126 
   7127 } // end namespace Catch
   7128 
   7129 #endif // Windows/ ANSI/ None
   7130 
   7131 namespace Catch {
   7132 
   7133     Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
   7134     Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
   7135     Colour::~Colour(){ if( !m_moved ) use( None ); }
   7136 
   7137     void Colour::use( Code _colourCode ) {
   7138         static IColourImpl* impl = platformColourInstance();
   7139         impl->use( _colourCode );
   7140     }
   7141 
   7142 } // end namespace Catch
   7143 
   7144 // #included from: catch_generators_impl.hpp
   7145 #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
   7146 
   7147 #include <vector>
   7148 #include <string>
   7149 #include <map>
   7150 
   7151 namespace Catch {
   7152 
   7153     struct GeneratorInfo : IGeneratorInfo {
   7154 
   7155         GeneratorInfo( std::size_t size )
   7156         :   m_size( size ),
   7157             m_currentIndex( 0 )
   7158         {}
   7159 
   7160         bool moveNext() {
   7161             if( ++m_currentIndex == m_size ) {
   7162                 m_currentIndex = 0;
   7163                 return false;
   7164             }
   7165             return true;
   7166         }
   7167 
   7168         std::size_t getCurrentIndex() const {
   7169             return m_currentIndex;
   7170         }
   7171 
   7172         std::size_t m_size;
   7173         std::size_t m_currentIndex;
   7174     };
   7175 
   7176     ///////////////////////////////////////////////////////////////////////////
   7177 
   7178     class GeneratorsForTest : public IGeneratorsForTest {
   7179 
   7180     public:
   7181         ~GeneratorsForTest() {
   7182             deleteAll( m_generatorsInOrder );
   7183         }
   7184 
   7185         IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
   7186             std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
   7187             if( it == m_generatorsByName.end() ) {
   7188                 IGeneratorInfo* info = new GeneratorInfo( size );
   7189                 m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
   7190                 m_generatorsInOrder.push_back( info );
   7191                 return *info;
   7192             }
   7193             return *it->second;
   7194         }
   7195 
   7196         bool moveNext() {
   7197             std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
   7198             std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
   7199             for(; it != itEnd; ++it ) {
   7200                 if( (*it)->moveNext() )
   7201                     return true;
   7202             }
   7203             return false;
   7204         }
   7205 
   7206     private:
   7207         std::map<std::string, IGeneratorInfo*> m_generatorsByName;
   7208         std::vector<IGeneratorInfo*> m_generatorsInOrder;
   7209     };
   7210 
   7211     IGeneratorsForTest* createGeneratorsForTest()
   7212     {
   7213         return new GeneratorsForTest();
   7214     }
   7215 
   7216 } // end namespace Catch
   7217 
   7218 // #included from: catch_assertionresult.hpp
   7219 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
   7220 
   7221 namespace Catch {
   7222 
   7223     AssertionInfo::AssertionInfo(   std::string const& _macroName,
   7224                                     SourceLineInfo const& _lineInfo,
   7225                                     std::string const& _capturedExpression,
   7226                                     ResultDisposition::Flags _resultDisposition )
   7227     :   macroName( _macroName ),
   7228         lineInfo( _lineInfo ),
   7229         capturedExpression( _capturedExpression ),
   7230         resultDisposition( _resultDisposition )
   7231     {}
   7232 
   7233     AssertionResult::AssertionResult() {}
   7234 
   7235     AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
   7236     :   m_info( info ),
   7237         m_resultData( data )
   7238     {}
   7239 
   7240     AssertionResult::~AssertionResult() {}
   7241 
   7242     // Result was a success
   7243     bool AssertionResult::succeeded() const {
   7244         return Catch::isOk( m_resultData.resultType );
   7245     }
   7246 
   7247     // Result was a success, or failure is suppressed
   7248     bool AssertionResult::isOk() const {
   7249         return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
   7250     }
   7251 
   7252     ResultWas::OfType AssertionResult::getResultType() const {
   7253         return m_resultData.resultType;
   7254     }
   7255 
   7256     bool AssertionResult::hasExpression() const {
   7257         return !m_info.capturedExpression.empty();
   7258     }
   7259 
   7260     bool AssertionResult::hasMessage() const {
   7261         return !m_resultData.message.empty();
   7262     }
   7263 
   7264     std::string AssertionResult::getExpression() const {
   7265         if( isFalseTest( m_info.resultDisposition ) )
   7266             return "!" + m_info.capturedExpression;
   7267         else
   7268             return m_info.capturedExpression;
   7269     }
   7270     std::string AssertionResult::getExpressionInMacro() const {
   7271         if( m_info.macroName.empty() )
   7272             return m_info.capturedExpression;
   7273         else
   7274             return m_info.macroName + "( " + m_info.capturedExpression + " )";
   7275     }
   7276 
   7277     bool AssertionResult::hasExpandedExpression() const {
   7278         return hasExpression() && getExpandedExpression() != getExpression();
   7279     }
   7280 
   7281     std::string AssertionResult::getExpandedExpression() const {
   7282         return m_resultData.reconstructedExpression;
   7283     }
   7284 
   7285     std::string AssertionResult::getMessage() const {
   7286         return m_resultData.message;
   7287     }
   7288     SourceLineInfo AssertionResult::getSourceInfo() const {
   7289         return m_info.lineInfo;
   7290     }
   7291 
   7292     std::string AssertionResult::getTestMacroName() const {
   7293         return m_info.macroName;
   7294     }
   7295 
   7296 } // end namespace Catch
   7297 
   7298 // #included from: catch_test_case_info.hpp
   7299 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
   7300 
   7301 namespace Catch {
   7302 
   7303     inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
   7304         if( startsWith( tag, "." ) ||
   7305             tag == "hide" ||
   7306             tag == "!hide" )
   7307             return TestCaseInfo::IsHidden;
   7308         else if( tag == "!throws" )
   7309             return TestCaseInfo::Throws;
   7310         else if( tag == "!shouldfail" )
   7311             return TestCaseInfo::ShouldFail;
   7312         else if( tag == "!mayfail" )
   7313             return TestCaseInfo::MayFail;
   7314         else
   7315             return TestCaseInfo::None;
   7316     }
   7317     inline bool isReservedTag( std::string const& tag ) {
   7318         return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
   7319     }
   7320     inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
   7321         if( isReservedTag( tag ) ) {
   7322             {
   7323                 Colour colourGuard( Colour::Red );
   7324                 Catch::cerr()
   7325                     << "Tag name [" << tag << "] not allowed.\n"
   7326                     << "Tag names starting with non alpha-numeric characters are reserved\n";
   7327             }
   7328             {
   7329                 Colour colourGuard( Colour::FileName );
   7330                 Catch::cerr() << _lineInfo << std::endl;
   7331             }
   7332             exit(1);
   7333         }
   7334     }
   7335 
   7336     TestCase makeTestCase(  ITestCase* _testCase,
   7337                             std::string const& _className,
   7338                             std::string const& _name,
   7339                             std::string const& _descOrTags,
   7340                             SourceLineInfo const& _lineInfo )
   7341     {
   7342         bool isHidden( startsWith( _name, "./" ) ); // Legacy support
   7343 
   7344         // Parse out tags
   7345         std::set<std::string> tags;
   7346         std::string desc, tag;
   7347         bool inTag = false;
   7348         for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
   7349             char c = _descOrTags[i];
   7350             if( !inTag ) {
   7351                 if( c == '[' )
   7352                     inTag = true;
   7353                 else
   7354                     desc += c;
   7355             }
   7356             else {
   7357                 if( c == ']' ) {
   7358                     TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
   7359                     if( prop == TestCaseInfo::IsHidden )
   7360                         isHidden = true;
   7361                     else if( prop == TestCaseInfo::None )
   7362                         enforceNotReservedTag( tag, _lineInfo );
   7363 
   7364                     tags.insert( tag );
   7365                     tag.clear();
   7366                     inTag = false;
   7367                 }
   7368                 else
   7369                     tag += c;
   7370             }
   7371         }
   7372         if( isHidden ) {
   7373             tags.insert( "hide" );
   7374             tags.insert( "." );
   7375         }
   7376 
   7377         TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
   7378         return TestCase( _testCase, info );
   7379     }
   7380 
   7381     void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )
   7382     {
   7383         testCaseInfo.tags = tags;
   7384         testCaseInfo.lcaseTags.clear();
   7385 
   7386         std::ostringstream oss;
   7387         for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
   7388             oss << "[" << *it << "]";
   7389             std::string lcaseTag = toLower( *it );
   7390             testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
   7391             testCaseInfo.lcaseTags.insert( lcaseTag );
   7392         }
   7393         testCaseInfo.tagsAsString = oss.str();
   7394     }
   7395 
   7396     TestCaseInfo::TestCaseInfo( std::string const& _name,
   7397                                 std::string const& _className,
   7398                                 std::string const& _description,
   7399                                 std::set<std::string> const& _tags,
   7400                                 SourceLineInfo const& _lineInfo )
   7401     :   name( _name ),
   7402         className( _className ),
   7403         description( _description ),
   7404         lineInfo( _lineInfo ),
   7405         properties( None )
   7406     {
   7407         setTags( *this, _tags );
   7408     }
   7409 
   7410     TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
   7411     :   name( other.name ),
   7412         className( other.className ),
   7413         description( other.description ),
   7414         tags( other.tags ),
   7415         lcaseTags( other.lcaseTags ),
   7416         tagsAsString( other.tagsAsString ),
   7417         lineInfo( other.lineInfo ),
   7418         properties( other.properties )
   7419     {}
   7420 
   7421     bool TestCaseInfo::isHidden() const {
   7422         return ( properties & IsHidden ) != 0;
   7423     }
   7424     bool TestCaseInfo::throws() const {
   7425         return ( properties & Throws ) != 0;
   7426     }
   7427     bool TestCaseInfo::okToFail() const {
   7428         return ( properties & (ShouldFail | MayFail ) ) != 0;
   7429     }
   7430     bool TestCaseInfo::expectedToFail() const {
   7431         return ( properties & (ShouldFail ) ) != 0;
   7432     }
   7433 
   7434     TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
   7435 
   7436     TestCase::TestCase( TestCase const& other )
   7437     :   TestCaseInfo( other ),
   7438         test( other.test )
   7439     {}
   7440 
   7441     TestCase TestCase::withName( std::string const& _newName ) const {
   7442         TestCase other( *this );
   7443         other.name = _newName;
   7444         return other;
   7445     }
   7446 
   7447     void TestCase::swap( TestCase& other ) {
   7448         test.swap( other.test );
   7449         name.swap( other.name );
   7450         className.swap( other.className );
   7451         description.swap( other.description );
   7452         tags.swap( other.tags );
   7453         lcaseTags.swap( other.lcaseTags );
   7454         tagsAsString.swap( other.tagsAsString );
   7455         std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
   7456         std::swap( lineInfo, other.lineInfo );
   7457     }
   7458 
   7459     void TestCase::invoke() const {
   7460         test->invoke();
   7461     }
   7462 
   7463     bool TestCase::operator == ( TestCase const& other ) const {
   7464         return  test.get() == other.test.get() &&
   7465                 name == other.name &&
   7466                 className == other.className;
   7467     }
   7468 
   7469     bool TestCase::operator < ( TestCase const& other ) const {
   7470         return name < other.name;
   7471     }
   7472     TestCase& TestCase::operator = ( TestCase const& other ) {
   7473         TestCase temp( other );
   7474         swap( temp );
   7475         return *this;
   7476     }
   7477 
   7478     TestCaseInfo const& TestCase::getTestCaseInfo() const
   7479     {
   7480         return *this;
   7481     }
   7482 
   7483 } // end namespace Catch
   7484 
   7485 // #included from: catch_version.hpp
   7486 #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
   7487 
   7488 namespace Catch {
   7489 
   7490     Version::Version
   7491         (   unsigned int _majorVersion,
   7492             unsigned int _minorVersion,
   7493             unsigned int _patchNumber,
   7494             std::string const& _branchName,
   7495             unsigned int _buildNumber )
   7496     :   majorVersion( _majorVersion ),
   7497         minorVersion( _minorVersion ),
   7498         patchNumber( _patchNumber ),
   7499         branchName( _branchName ),
   7500         buildNumber( _buildNumber )
   7501     {}
   7502 
   7503     std::ostream& operator << ( std::ostream& os, Version const& version ) {
   7504         os  << version.majorVersion << "."
   7505             << version.minorVersion << "."
   7506             << version.patchNumber;
   7507 
   7508         if( !version.branchName.empty() ) {
   7509             os  << "-" << version.branchName
   7510                 << "." << version.buildNumber;
   7511         }
   7512         return os;
   7513     }
   7514 
   7515     Version libraryVersion( 1, 4, 0, "", 0 );
   7516 
   7517 }
   7518 
   7519 // #included from: catch_message.hpp
   7520 #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
   7521 
   7522 namespace Catch {
   7523 
   7524     MessageInfo::MessageInfo(   std::string const& _macroName,
   7525                                 SourceLineInfo const& _lineInfo,
   7526                                 ResultWas::OfType _type )
   7527     :   macroName( _macroName ),
   7528         lineInfo( _lineInfo ),
   7529         type( _type ),
   7530         sequence( ++globalCount )
   7531     {}
   7532 
   7533     // This may need protecting if threading support is added
   7534     unsigned int MessageInfo::globalCount = 0;
   7535 
   7536     ////////////////////////////////////////////////////////////////////////////
   7537 
   7538     ScopedMessage::ScopedMessage( MessageBuilder const& builder )
   7539     : m_info( builder.m_info )
   7540     {
   7541         m_info.message = builder.m_stream.str();
   7542         getResultCapture().pushScopedMessage( m_info );
   7543     }
   7544     ScopedMessage::ScopedMessage( ScopedMessage const& other )
   7545     : m_info( other.m_info )
   7546     {}
   7547 
   7548     ScopedMessage::~ScopedMessage() {
   7549         getResultCapture().popScopedMessage( m_info );
   7550     }
   7551 
   7552 } // end namespace Catch
   7553 
   7554 // #included from: catch_legacy_reporter_adapter.hpp
   7555 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
   7556 
   7557 // #included from: catch_legacy_reporter_adapter.h
   7558 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
   7559 
   7560 namespace Catch
   7561 {
   7562     // Deprecated
   7563     struct IReporter : IShared {
   7564         virtual ~IReporter();
   7565 
   7566         virtual bool shouldRedirectStdout() const = 0;
   7567 
   7568         virtual void StartTesting() = 0;
   7569         virtual void EndTesting( Totals const& totals ) = 0;
   7570         virtual void StartGroup( std::string const& groupName ) = 0;
   7571         virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
   7572         virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
   7573         virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
   7574         virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
   7575         virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
   7576         virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
   7577         virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
   7578         virtual void Aborted() = 0;
   7579         virtual void Result( AssertionResult const& result ) = 0;
   7580     };
   7581 
   7582     class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
   7583     {
   7584     public:
   7585         LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
   7586         virtual ~LegacyReporterAdapter();
   7587 
   7588         virtual ReporterPreferences getPreferences() const;
   7589         virtual void noMatchingTestCases( std::string const& );
   7590         virtual void testRunStarting( TestRunInfo const& );
   7591         virtual void testGroupStarting( GroupInfo const& groupInfo );
   7592         virtual void testCaseStarting( TestCaseInfo const& testInfo );
   7593         virtual void sectionStarting( SectionInfo const& sectionInfo );
   7594         virtual void assertionStarting( AssertionInfo const& );
   7595         virtual bool assertionEnded( AssertionStats const& assertionStats );
   7596         virtual void sectionEnded( SectionStats const& sectionStats );
   7597         virtual void testCaseEnded( TestCaseStats const& testCaseStats );
   7598         virtual void testGroupEnded( TestGroupStats const& testGroupStats );
   7599         virtual void testRunEnded( TestRunStats const& testRunStats );
   7600         virtual void skipTest( TestCaseInfo const& );
   7601 
   7602     private:
   7603         Ptr<IReporter> m_legacyReporter;
   7604     };
   7605 }
   7606 
   7607 namespace Catch
   7608 {
   7609     LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
   7610     :   m_legacyReporter( legacyReporter )
   7611     {}
   7612     LegacyReporterAdapter::~LegacyReporterAdapter() {}
   7613 
   7614     ReporterPreferences LegacyReporterAdapter::getPreferences() const {
   7615         ReporterPreferences prefs;
   7616         prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
   7617         return prefs;
   7618     }
   7619 
   7620     void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
   7621     void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
   7622         m_legacyReporter->StartTesting();
   7623     }
   7624     void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
   7625         m_legacyReporter->StartGroup( groupInfo.name );
   7626     }
   7627     void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
   7628         m_legacyReporter->StartTestCase( testInfo );
   7629     }
   7630     void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
   7631         m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
   7632     }
   7633     void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
   7634         // Not on legacy interface
   7635     }
   7636 
   7637     bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
   7638         if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
   7639             for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
   7640                     it != itEnd;
   7641                     ++it ) {
   7642                 if( it->type == ResultWas::Info ) {
   7643                     ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
   7644                     rb << it->message;
   7645                     rb.setResultType( ResultWas::Info );
   7646                     AssertionResult result = rb.build();
   7647                     m_legacyReporter->Result( result );
   7648                 }
   7649             }
   7650         }
   7651         m_legacyReporter->Result( assertionStats.assertionResult );
   7652         return true;
   7653     }
   7654     void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
   7655         if( sectionStats.missingAssertions )
   7656             m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
   7657         m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
   7658     }
   7659     void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
   7660         m_legacyReporter->EndTestCase
   7661             (   testCaseStats.testInfo,
   7662                 testCaseStats.totals,
   7663                 testCaseStats.stdOut,
   7664                 testCaseStats.stdErr );
   7665     }
   7666     void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
   7667         if( testGroupStats.aborting )
   7668             m_legacyReporter->Aborted();
   7669         m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
   7670     }
   7671     void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
   7672         m_legacyReporter->EndTesting( testRunStats.totals );
   7673     }
   7674     void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
   7675     }
   7676 }
   7677 
   7678 // #included from: catch_timer.hpp
   7679 
   7680 #ifdef __clang__
   7681 #pragma clang diagnostic push
   7682 #pragma clang diagnostic ignored "-Wc++11-long-long"
   7683 #endif
   7684 
   7685 #ifdef CATCH_PLATFORM_WINDOWS
   7686 #include <windows.h>
   7687 #else
   7688 #include <sys/time.h>
   7689 #endif
   7690 
   7691 namespace Catch {
   7692 
   7693     namespace {
   7694 #ifdef CATCH_PLATFORM_WINDOWS
   7695         uint64_t getCurrentTicks() {
   7696             static uint64_t hz=0, hzo=0;
   7697             if (!hz) {
   7698                 QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
   7699                 QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
   7700             }
   7701             uint64_t t;
   7702             QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
   7703             return ((t-hzo)*1000000)/hz;
   7704         }
   7705 #else
   7706         uint64_t getCurrentTicks() {
   7707             timeval t;
   7708             gettimeofday(&t,CATCH_NULL);
   7709             return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
   7710         }
   7711 #endif
   7712     }
   7713 
   7714     void Timer::start() {
   7715         m_ticks = getCurrentTicks();
   7716     }
   7717     unsigned int Timer::getElapsedMicroseconds() const {
   7718         return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
   7719     }
   7720     unsigned int Timer::getElapsedMilliseconds() const {
   7721         return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
   7722     }
   7723     double Timer::getElapsedSeconds() const {
   7724         return getElapsedMicroseconds()/1000000.0;
   7725     }
   7726 
   7727 } // namespace Catch
   7728 
   7729 #ifdef __clang__
   7730 #pragma clang diagnostic pop
   7731 #endif
   7732 // #included from: catch_common.hpp
   7733 #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
   7734 
   7735 namespace Catch {
   7736 
   7737     bool startsWith( std::string const& s, std::string const& prefix ) {
   7738         return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
   7739     }
   7740     bool endsWith( std::string const& s, std::string const& suffix ) {
   7741         return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
   7742     }
   7743     bool contains( std::string const& s, std::string const& infix ) {
   7744         return s.find( infix ) != std::string::npos;
   7745     }
   7746     void toLowerInPlace( std::string& s ) {
   7747         std::transform( s.begin(), s.end(), s.begin(), ::tolower );
   7748     }
   7749     std::string toLower( std::string const& s ) {
   7750         std::string lc = s;
   7751         toLowerInPlace( lc );
   7752         return lc;
   7753     }
   7754     std::string trim( std::string const& str ) {
   7755         static char const* whitespaceChars = "\n\r\t ";
   7756         std::string::size_type start = str.find_first_not_of( whitespaceChars );
   7757         std::string::size_type end = str.find_last_not_of( whitespaceChars );
   7758 
   7759         return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
   7760     }
   7761 
   7762     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
   7763         bool replaced = false;
   7764         std::size_t i = str.find( replaceThis );
   7765         while( i != std::string::npos ) {
   7766             replaced = true;
   7767             str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
   7768             if( i < str.size()-withThis.size() )
   7769                 i = str.find( replaceThis, i+withThis.size() );
   7770             else
   7771                 i = std::string::npos;
   7772         }
   7773         return replaced;
   7774     }
   7775 
   7776     pluralise::pluralise( std::size_t count, std::string const& label )
   7777     :   m_count( count ),
   7778         m_label( label )
   7779     {}
   7780 
   7781     std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
   7782         os << pluraliser.m_count << " " << pluraliser.m_label;
   7783         if( pluraliser.m_count != 1 )
   7784             os << "s";
   7785         return os;
   7786     }
   7787 
   7788     SourceLineInfo::SourceLineInfo() : line( 0 ){}
   7789     SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
   7790     :   file( _file ),
   7791         line( _line )
   7792     {}
   7793     SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
   7794     :   file( other.file ),
   7795         line( other.line )
   7796     {}
   7797     bool SourceLineInfo::empty() const {
   7798         return file.empty();
   7799     }
   7800     bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
   7801         return line == other.line && file == other.file;
   7802     }
   7803     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
   7804         return line < other.line || ( line == other.line  && file < other.file );
   7805     }
   7806 
   7807     void seedRng( IConfig const& config ) {
   7808         if( config.rngSeed() != 0 )
   7809             std::srand( config.rngSeed() );
   7810     }
   7811     unsigned int rngSeed() {
   7812         return getCurrentContext().getConfig()->rngSeed();
   7813     }
   7814 
   7815     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
   7816 #ifndef __GNUG__
   7817         os << info.file << "(" << info.line << ")";
   7818 #else
   7819         os << info.file << ":" << info.line;
   7820 #endif
   7821         return os;
   7822     }
   7823 
   7824     void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
   7825         std::ostringstream oss;
   7826         oss << locationInfo << ": Internal Catch error: '" << message << "'";
   7827         if( alwaysTrue() )
   7828             throw std::logic_error( oss.str() );
   7829     }
   7830 }
   7831 
   7832 // #included from: catch_section.hpp
   7833 #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
   7834 
   7835 namespace Catch {
   7836 
   7837     SectionInfo::SectionInfo
   7838         (   SourceLineInfo const& _lineInfo,
   7839             std::string const& _name,
   7840             std::string const& _description )
   7841     :   name( _name ),
   7842         description( _description ),
   7843         lineInfo( _lineInfo )
   7844     {}
   7845 
   7846     Section::Section( SectionInfo const& info )
   7847     :   m_info( info ),
   7848         m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
   7849     {
   7850         m_timer.start();
   7851     }
   7852 
   7853     Section::~Section() {
   7854         if( m_sectionIncluded ) {
   7855             SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
   7856             if( std::uncaught_exception() )
   7857                 getResultCapture().sectionEndedEarly( endInfo );
   7858             else
   7859                 getResultCapture().sectionEnded( endInfo );
   7860         }
   7861     }
   7862 
   7863     // This indicates whether the section should be executed or not
   7864     Section::operator bool() const {
   7865         return m_sectionIncluded;
   7866     }
   7867 
   7868 } // end namespace Catch
   7869 
   7870 // #included from: catch_debugger.hpp
   7871 #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
   7872 
   7873 #include <iostream>
   7874 
   7875 #ifdef CATCH_PLATFORM_MAC
   7876 
   7877     #include <assert.h>
   7878     #include <stdbool.h>
   7879     #include <sys/types.h>
   7880     #include <unistd.h>
   7881     #include <sys/sysctl.h>
   7882 
   7883     namespace Catch{
   7884 
   7885         // The following function is taken directly from the following technical note:
   7886         // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
   7887 
   7888         // Returns true if the current process is being debugged (either
   7889         // running under the debugger or has a debugger attached post facto).
   7890         bool isDebuggerActive(){
   7891 
   7892             int                 mib[4];
   7893             struct kinfo_proc   info;
   7894             size_t              size;
   7895 
   7896             // Initialize the flags so that, if sysctl fails for some bizarre
   7897             // reason, we get a predictable result.
   7898 
   7899             info.kp_proc.p_flag = 0;
   7900 
   7901             // Initialize mib, which tells sysctl the info we want, in this case
   7902             // we're looking for information about a specific process ID.
   7903 
   7904             mib[0] = CTL_KERN;
   7905             mib[1] = KERN_PROC;
   7906             mib[2] = KERN_PROC_PID;
   7907             mib[3] = getpid();
   7908 
   7909             // Call sysctl.
   7910 
   7911             size = sizeof(info);
   7912             if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
   7913                 Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
   7914                 return false;
   7915             }
   7916 
   7917             // We're being debugged if the P_TRACED flag is set.
   7918 
   7919             return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
   7920         }
   7921     } // namespace Catch
   7922 
   7923 #elif defined(_MSC_VER)
   7924     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
   7925     namespace Catch {
   7926         bool isDebuggerActive() {
   7927             return IsDebuggerPresent() != 0;
   7928         }
   7929     }
   7930 #elif defined(__MINGW32__)
   7931     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
   7932     namespace Catch {
   7933         bool isDebuggerActive() {
   7934             return IsDebuggerPresent() != 0;
   7935         }
   7936     }
   7937 #else
   7938     namespace Catch {
   7939        inline bool isDebuggerActive() { return false; }
   7940     }
   7941 #endif // Platform
   7942 
   7943 #ifdef CATCH_PLATFORM_WINDOWS
   7944     extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
   7945     namespace Catch {
   7946         void writeToDebugConsole( std::string const& text ) {
   7947             ::OutputDebugStringA( text.c_str() );
   7948         }
   7949     }
   7950 #else
   7951     namespace Catch {
   7952         void writeToDebugConsole( std::string const& text ) {
   7953             // !TBD: Need a version for Mac/ XCode and other IDEs
   7954             Catch::cout() << text;
   7955         }
   7956     }
   7957 #endif // Platform
   7958 
   7959 // #included from: catch_tostring.hpp
   7960 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
   7961 
   7962 namespace Catch {
   7963 
   7964 namespace Detail {
   7965 
   7966     const std::string unprintableString = "{?}";
   7967 
   7968     namespace {
   7969         const int hexThreshold = 255;
   7970 
   7971         struct Endianness {
   7972             enum Arch { Big, Little };
   7973 
   7974             static Arch which() {
   7975                 union _{
   7976                     int asInt;
   7977                     char asChar[sizeof (int)];
   7978                 } u;
   7979 
   7980                 u.asInt = 1;
   7981                 return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
   7982             }
   7983         };
   7984     }
   7985 
   7986     std::string rawMemoryToString( const void *object, std::size_t size )
   7987     {
   7988         // Reverse order for little endian architectures
   7989         int i = 0, end = static_cast<int>( size ), inc = 1;
   7990         if( Endianness::which() == Endianness::Little ) {
   7991             i = end-1;
   7992             end = inc = -1;
   7993         }
   7994 
   7995         unsigned char const *bytes = static_cast<unsigned char const *>(object);
   7996         std::ostringstream os;
   7997         os << "0x" << std::setfill('0') << std::hex;
   7998         for( ; i != end; i += inc )
   7999              os << std::setw(2) << static_cast<unsigned>(bytes[i]);
   8000        return os.str();
   8001     }
   8002 }
   8003 
   8004 std::string toString( std::string const& value ) {
   8005     std::string s = value;
   8006     if( getCurrentContext().getConfig()->showInvisibles() ) {
   8007         for(size_t i = 0; i < s.size(); ++i ) {
   8008             std::string subs;
   8009             switch( s[i] ) {
   8010             case '\n': subs = "\\n"; break;
   8011             case '\t': subs = "\\t"; break;
   8012             default: break;
   8013             }
   8014             if( !subs.empty() ) {
   8015                 s = s.substr( 0, i ) + subs + s.substr( i+1 );
   8016                 ++i;
   8017             }
   8018         }
   8019     }
   8020     return "\"" + s + "\"";
   8021 }
   8022 std::string toString( std::wstring const& value ) {
   8023 
   8024     std::string s;
   8025     s.reserve( value.size() );
   8026     for(size_t i = 0; i < value.size(); ++i )
   8027         s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
   8028     return Catch::toString( s );
   8029 }
   8030 
   8031 std::string toString( const char* const value ) {
   8032     return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
   8033 }
   8034 
   8035 std::string toString( char* const value ) {
   8036     return Catch::toString( static_cast<const char*>( value ) );
   8037 }
   8038 
   8039 std::string toString( const wchar_t* const value )
   8040 {
   8041 	return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
   8042 }
   8043 
   8044 std::string toString( wchar_t* const value )
   8045 {
   8046 	return Catch::toString( static_cast<const wchar_t*>( value ) );
   8047 }
   8048 
   8049 std::string toString( int value ) {
   8050     std::ostringstream oss;
   8051     oss << value;
   8052     if( value > Detail::hexThreshold )
   8053         oss << " (0x" << std::hex << value << ")";
   8054     return oss.str();
   8055 }
   8056 
   8057 std::string toString( unsigned long value ) {
   8058     std::ostringstream oss;
   8059     oss << value;
   8060     if( value > Detail::hexThreshold )
   8061         oss << " (0x" << std::hex << value << ")";
   8062     return oss.str();
   8063 }
   8064 
   8065 std::string toString( unsigned int value ) {
   8066     return Catch::toString( static_cast<unsigned long>( value ) );
   8067 }
   8068 
   8069 template<typename T>
   8070 std::string fpToString( T value, int precision ) {
   8071     std::ostringstream oss;
   8072     oss << std::setprecision( precision )
   8073         << std::fixed
   8074         << value;
   8075     std::string d = oss.str();
   8076     std::size_t i = d.find_last_not_of( '0' );
   8077     if( i != std::string::npos && i != d.size()-1 ) {
   8078         if( d[i] == '.' )
   8079             i++;
   8080         d = d.substr( 0, i+1 );
   8081     }
   8082     return d;
   8083 }
   8084 
   8085 std::string toString( const double value ) {
   8086     return fpToString( value, 10 );
   8087 }
   8088 std::string toString( const float value ) {
   8089     return fpToString( value, 5 ) + "f";
   8090 }
   8091 
   8092 std::string toString( bool value ) {
   8093     return value ? "true" : "false";
   8094 }
   8095 
   8096 std::string toString( char value ) {
   8097     return value < ' '
   8098         ? toString( static_cast<unsigned int>( value ) )
   8099         : Detail::makeString( value );
   8100 }
   8101 
   8102 std::string toString( signed char value ) {
   8103     return toString( static_cast<char>( value ) );
   8104 }
   8105 
   8106 std::string toString( unsigned char value ) {
   8107     return toString( static_cast<char>( value ) );
   8108 }
   8109 
   8110 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
   8111 std::string toString( long long value ) {
   8112     std::ostringstream oss;
   8113     oss << value;
   8114     if( value > Detail::hexThreshold )
   8115         oss << " (0x" << std::hex << value << ")";
   8116     return oss.str();
   8117 }
   8118 std::string toString( unsigned long long value ) {
   8119     std::ostringstream oss;
   8120     oss << value;
   8121     if( value > Detail::hexThreshold )
   8122         oss << " (0x" << std::hex << value << ")";
   8123     return oss.str();
   8124 }
   8125 #endif
   8126 
   8127 #ifdef CATCH_CONFIG_CPP11_NULLPTR
   8128 std::string toString( std::nullptr_t ) {
   8129     return "nullptr";
   8130 }
   8131 #endif
   8132 
   8133 #ifdef __OBJC__
   8134     std::string toString( NSString const * const& nsstring ) {
   8135         if( !nsstring )
   8136             return "nil";
   8137         return "@" + toString([nsstring UTF8String]);
   8138     }
   8139     std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
   8140         if( !nsstring )
   8141             return "nil";
   8142         return "@" + toString([nsstring UTF8String]);
   8143     }
   8144     std::string toString( NSObject* const& nsObject ) {
   8145         return toString( [nsObject description] );
   8146     }
   8147 #endif
   8148 
   8149 } // end namespace Catch
   8150 
   8151 // #included from: catch_result_builder.hpp
   8152 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
   8153 
   8154 namespace Catch {
   8155 
   8156     std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) {
   8157         return secondArg.empty() || secondArg == "\"\""
   8158             ? capturedExpression
   8159             : capturedExpression + ", " + secondArg;
   8160     }
   8161     ResultBuilder::ResultBuilder(   char const* macroName,
   8162                                     SourceLineInfo const& lineInfo,
   8163                                     char const* capturedExpression,
   8164                                     ResultDisposition::Flags resultDisposition,
   8165                                     char const* secondArg )
   8166     :   m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),
   8167         m_shouldDebugBreak( false ),
   8168         m_shouldThrow( false )
   8169     {}
   8170 
   8171     ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
   8172         m_data.resultType = result;
   8173         return *this;
   8174     }
   8175     ResultBuilder& ResultBuilder::setResultType( bool result ) {
   8176         m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
   8177         return *this;
   8178     }
   8179     ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
   8180         m_exprComponents.lhs = lhs;
   8181         return *this;
   8182     }
   8183     ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
   8184         m_exprComponents.rhs = rhs;
   8185         return *this;
   8186     }
   8187     ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
   8188         m_exprComponents.op = op;
   8189         return *this;
   8190     }
   8191 
   8192     void ResultBuilder::endExpression() {
   8193         m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
   8194         captureExpression();
   8195     }
   8196 
   8197     void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
   8198         m_assertionInfo.resultDisposition = resultDisposition;
   8199         m_stream.oss << Catch::translateActiveException();
   8200         captureResult( ResultWas::ThrewException );
   8201     }
   8202 
   8203     void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
   8204         setResultType( resultType );
   8205         captureExpression();
   8206     }
   8207     void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
   8208         if( expectedMessage.empty() )
   8209             captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );
   8210         else
   8211             captureExpectedException( Matchers::Equals( expectedMessage ) );
   8212     }
   8213 
   8214     void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
   8215 
   8216         assert( m_exprComponents.testFalse == false );
   8217         AssertionResultData data = m_data;
   8218         data.resultType = ResultWas::Ok;
   8219         data.reconstructedExpression = m_assertionInfo.capturedExpression;
   8220 
   8221         std::string actualMessage = Catch::translateActiveException();
   8222         if( !matcher.match( actualMessage ) ) {
   8223             data.resultType = ResultWas::ExpressionFailed;
   8224             data.reconstructedExpression = actualMessage;
   8225         }
   8226         AssertionResult result( m_assertionInfo, data );
   8227         handleResult( result );
   8228     }
   8229 
   8230     void ResultBuilder::captureExpression() {
   8231         AssertionResult result = build();
   8232         handleResult( result );
   8233     }
   8234     void ResultBuilder::handleResult( AssertionResult const& result )
   8235     {
   8236         getResultCapture().assertionEnded( result );
   8237 
   8238         if( !result.isOk() ) {
   8239             if( getCurrentContext().getConfig()->shouldDebugBreak() )
   8240                 m_shouldDebugBreak = true;
   8241             if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
   8242                 m_shouldThrow = true;
   8243         }
   8244     }
   8245     void ResultBuilder::react() {
   8246         if( m_shouldThrow )
   8247             throw Catch::TestFailureException();
   8248     }
   8249 
   8250     bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
   8251     bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
   8252 
   8253     AssertionResult ResultBuilder::build() const
   8254     {
   8255         assert( m_data.resultType != ResultWas::Unknown );
   8256 
   8257         AssertionResultData data = m_data;
   8258 
   8259         // Flip bool results if testFalse is set
   8260         if( m_exprComponents.testFalse ) {
   8261             if( data.resultType == ResultWas::Ok )
   8262                 data.resultType = ResultWas::ExpressionFailed;
   8263             else if( data.resultType == ResultWas::ExpressionFailed )
   8264                 data.resultType = ResultWas::Ok;
   8265         }
   8266 
   8267         data.message = m_stream.oss.str();
   8268         data.reconstructedExpression = reconstructExpression();
   8269         if( m_exprComponents.testFalse ) {
   8270             if( m_exprComponents.op == "" )
   8271                 data.reconstructedExpression = "!" + data.reconstructedExpression;
   8272             else
   8273                 data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
   8274         }
   8275         return AssertionResult( m_assertionInfo, data );
   8276     }
   8277     std::string ResultBuilder::reconstructExpression() const {
   8278         if( m_exprComponents.op == "" )
   8279             return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
   8280         else if( m_exprComponents.op == "matches" )
   8281             return m_exprComponents.lhs + " " + m_exprComponents.rhs;
   8282         else if( m_exprComponents.op != "!" ) {
   8283             if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
   8284                 m_exprComponents.lhs.find("\n") == std::string::npos &&
   8285                 m_exprComponents.rhs.find("\n") == std::string::npos )
   8286                 return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
   8287             else
   8288                 return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
   8289         }
   8290         else
   8291             return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
   8292     }
   8293 
   8294 } // end namespace Catch
   8295 
   8296 // #included from: catch_tag_alias_registry.hpp
   8297 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
   8298 
   8299 // #included from: catch_tag_alias_registry.h
   8300 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
   8301 
   8302 #include <map>
   8303 
   8304 namespace Catch {
   8305 
   8306     class TagAliasRegistry : public ITagAliasRegistry {
   8307     public:
   8308         virtual ~TagAliasRegistry();
   8309         virtual Option<TagAlias> find( std::string const& alias ) const;
   8310         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
   8311         void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
   8312         static TagAliasRegistry& get();
   8313 
   8314     private:
   8315         std::map<std::string, TagAlias> m_registry;
   8316     };
   8317 
   8318 } // end namespace Catch
   8319 
   8320 #include <map>
   8321 #include <iostream>
   8322 
   8323 namespace Catch {
   8324 
   8325     TagAliasRegistry::~TagAliasRegistry() {}
   8326 
   8327     Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
   8328         std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
   8329         if( it != m_registry.end() )
   8330             return it->second;
   8331         else
   8332             return Option<TagAlias>();
   8333     }
   8334 
   8335     std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
   8336         std::string expandedTestSpec = unexpandedTestSpec;
   8337         for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
   8338                 it != itEnd;
   8339                 ++it ) {
   8340             std::size_t pos = expandedTestSpec.find( it->first );
   8341             if( pos != std::string::npos ) {
   8342                 expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
   8343                                     it->second.tag +
   8344                                     expandedTestSpec.substr( pos + it->first.size() );
   8345             }
   8346         }
   8347         return expandedTestSpec;
   8348     }
   8349 
   8350     void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
   8351 
   8352         if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
   8353             std::ostringstream oss;
   8354             oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
   8355             throw std::domain_error( oss.str().c_str() );
   8356         }
   8357         if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
   8358             std::ostringstream oss;
   8359             oss << "error: tag alias, \"" << alias << "\" already registered.\n"
   8360                 << "\tFirst seen at " << find(alias)->lineInfo << "\n"
   8361                 << "\tRedefined at " << lineInfo;
   8362             throw std::domain_error( oss.str().c_str() );
   8363         }
   8364     }
   8365 
   8366     TagAliasRegistry& TagAliasRegistry::get() {
   8367         static TagAliasRegistry instance;
   8368         return instance;
   8369 
   8370     }
   8371 
   8372     ITagAliasRegistry::~ITagAliasRegistry() {}
   8373     ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
   8374 
   8375     RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
   8376         try {
   8377             TagAliasRegistry::get().add( alias, tag, lineInfo );
   8378         }
   8379         catch( std::exception& ex ) {
   8380             Colour colourGuard( Colour::Red );
   8381             Catch::cerr() << ex.what() << std::endl;
   8382             exit(1);
   8383         }
   8384     }
   8385 
   8386 } // end namespace Catch
   8387 
   8388 // #included from: ../reporters/catch_reporter_multi.hpp
   8389 #define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
   8390 
   8391 namespace Catch {
   8392 
   8393 class MultipleReporters : public SharedImpl<IStreamingReporter> {
   8394     typedef std::vector<Ptr<IStreamingReporter> > Reporters;
   8395     Reporters m_reporters;
   8396 
   8397 public:
   8398     void add( Ptr<IStreamingReporter> const& reporter ) {
   8399         m_reporters.push_back( reporter );
   8400     }
   8401 
   8402 public: // IStreamingReporter
   8403 
   8404     virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
   8405         return m_reporters[0]->getPreferences();
   8406     }
   8407 
   8408     virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
   8409         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
   8410                 it != itEnd;
   8411                 ++it )
   8412             (*it)->noMatchingTestCases( spec );
   8413     }
   8414 
   8415     virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
   8416         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
   8417                 it != itEnd;
   8418                 ++it )
   8419             (*it)->testRunStarting( testRunInfo );
   8420     }
   8421 
   8422     virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
   8423         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
   8424                 it != itEnd;
   8425                 ++it )
   8426             (*it)->testGroupStarting( groupInfo );
   8427     }
   8428 
   8429     virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
   8430         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
   8431                 it != itEnd;
   8432                 ++it )
   8433             (*it)->testCaseStarting( testInfo );
   8434     }
   8435 
   8436     virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
   8437         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
   8438                 it != itEnd;
   8439                 ++it )
   8440             (*it)->sectionStarting( sectionInfo );
   8441     }
   8442 
   8443     virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
   8444         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
   8445                 it != itEnd;
   8446                 ++it )
   8447             (*it)->assertionStarting( assertionInfo );
   8448     }
   8449 
   8450     // The return value indicates if the messages buffer should be cleared:
   8451     virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
   8452         bool clearBuffer = false;
   8453         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
   8454                 it != itEnd;
   8455                 ++it )
   8456             clearBuffer |= (*it)->assertionEnded( assertionStats );
   8457         return clearBuffer;
   8458     }
   8459 
   8460     virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
   8461         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
   8462                 it != itEnd;
   8463                 ++it )
   8464             (*it)->sectionEnded( sectionStats );
   8465     }
   8466 
   8467     virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
   8468         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
   8469                 it != itEnd;
   8470                 ++it )
   8471             (*it)->testCaseEnded( testCaseStats );
   8472     }
   8473 
   8474     virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
   8475         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
   8476                 it != itEnd;
   8477                 ++it )
   8478             (*it)->testGroupEnded( testGroupStats );
   8479     }
   8480 
   8481     virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
   8482         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
   8483                 it != itEnd;
   8484                 ++it )
   8485             (*it)->testRunEnded( testRunStats );
   8486     }
   8487 
   8488     virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
   8489         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
   8490                 it != itEnd;
   8491                 ++it )
   8492             (*it)->skipTest( testInfo );
   8493     }
   8494 };
   8495 
   8496 Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
   8497     Ptr<IStreamingReporter> resultingReporter;
   8498 
   8499     if( existingReporter ) {
   8500         MultipleReporters* multi = dynamic_cast<MultipleReporters*>( existingReporter.get() );
   8501         if( !multi ) {
   8502             multi = new MultipleReporters;
   8503             resultingReporter = Ptr<IStreamingReporter>( multi );
   8504             if( existingReporter )
   8505                 multi->add( existingReporter );
   8506         }
   8507         else
   8508             resultingReporter = existingReporter;
   8509         multi->add( additionalReporter );
   8510     }
   8511     else
   8512         resultingReporter = additionalReporter;
   8513 
   8514     return resultingReporter;
   8515 }
   8516 
   8517 } // end namespace Catch
   8518 
   8519 // #included from: ../reporters/catch_reporter_xml.hpp
   8520 #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
   8521 
   8522 // #included from: catch_reporter_bases.hpp
   8523 #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
   8524 
   8525 #include <cstring>
   8526 
   8527 namespace Catch {
   8528 
   8529     struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
   8530 
   8531         StreamingReporterBase( ReporterConfig const& _config )
   8532         :   m_config( _config.fullConfig() ),
   8533             stream( _config.stream() )
   8534         {
   8535             m_reporterPrefs.shouldRedirectStdOut = false;
   8536         }
   8537 
   8538         virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
   8539             return m_reporterPrefs;
   8540         }
   8541 
   8542         virtual ~StreamingReporterBase() CATCH_OVERRIDE;
   8543 
   8544         virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
   8545 
   8546         virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {
   8547             currentTestRunInfo = _testRunInfo;
   8548         }
   8549         virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {
   8550             currentGroupInfo = _groupInfo;
   8551         }
   8552 
   8553         virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
   8554             currentTestCaseInfo = _testInfo;
   8555         }
   8556         virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
   8557             m_sectionStack.push_back( _sectionInfo );
   8558         }
   8559 
   8560         virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {
   8561             m_sectionStack.pop_back();
   8562         }
   8563         virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {
   8564             currentTestCaseInfo.reset();
   8565         }
   8566         virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {
   8567             currentGroupInfo.reset();
   8568         }
   8569         virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {
   8570             currentTestCaseInfo.reset();
   8571             currentGroupInfo.reset();
   8572             currentTestRunInfo.reset();
   8573         }
   8574 
   8575         virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {
   8576             // Don't do anything with this by default.
   8577             // It can optionally be overridden in the derived class.
   8578         }
   8579 
   8580         Ptr<IConfig const> m_config;
   8581         std::ostream& stream;
   8582 
   8583         LazyStat<TestRunInfo> currentTestRunInfo;
   8584         LazyStat<GroupInfo> currentGroupInfo;
   8585         LazyStat<TestCaseInfo> currentTestCaseInfo;
   8586 
   8587         std::vector<SectionInfo> m_sectionStack;
   8588         ReporterPreferences m_reporterPrefs;
   8589     };
   8590 
   8591     struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
   8592         template<typename T, typename ChildNodeT>
   8593         struct Node : SharedImpl<> {
   8594             explicit Node( T const& _value ) : value( _value ) {}
   8595             virtual ~Node() {}
   8596 
   8597             typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
   8598             T value;
   8599             ChildNodes children;
   8600         };
   8601         struct SectionNode : SharedImpl<> {
   8602             explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
   8603             virtual ~SectionNode();
   8604 
   8605             bool operator == ( SectionNode const& other ) const {
   8606                 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
   8607             }
   8608             bool operator == ( Ptr<SectionNode> const& other ) const {
   8609                 return operator==( *other );
   8610             }
   8611 
   8612             SectionStats stats;
   8613             typedef std::vector<Ptr<SectionNode> > ChildSections;
   8614             typedef std::vector<AssertionStats> Assertions;
   8615             ChildSections childSections;
   8616             Assertions assertions;
   8617             std::string stdOut;
   8618             std::string stdErr;
   8619         };
   8620 
   8621         struct BySectionInfo {
   8622             BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
   8623 			BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
   8624             bool operator() ( Ptr<SectionNode> const& node ) const {
   8625                 return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
   8626             }
   8627         private:
   8628 			void operator=( BySectionInfo const& );
   8629             SectionInfo const& m_other;
   8630         };
   8631 
   8632         typedef Node<TestCaseStats, SectionNode> TestCaseNode;
   8633         typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
   8634         typedef Node<TestRunStats, TestGroupNode> TestRunNode;
   8635 
   8636         CumulativeReporterBase( ReporterConfig const& _config )
   8637         :   m_config( _config.fullConfig() ),
   8638             stream( _config.stream() )
   8639         {
   8640             m_reporterPrefs.shouldRedirectStdOut = false;
   8641         }
   8642         ~CumulativeReporterBase();
   8643 
   8644         virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
   8645             return m_reporterPrefs;
   8646         }
   8647 
   8648         virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}
   8649         virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}
   8650 
   8651         virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}
   8652 
   8653         virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
   8654             SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
   8655             Ptr<SectionNode> node;
   8656             if( m_sectionStack.empty() ) {
   8657                 if( !m_rootSection )
   8658                     m_rootSection = new SectionNode( incompleteStats );
   8659                 node = m_rootSection;
   8660             }
   8661             else {
   8662                 SectionNode& parentNode = *m_sectionStack.back();
   8663                 SectionNode::ChildSections::const_iterator it =
   8664                     std::find_if(   parentNode.childSections.begin(),
   8665                                     parentNode.childSections.end(),
   8666                                     BySectionInfo( sectionInfo ) );
   8667                 if( it == parentNode.childSections.end() ) {
   8668                     node = new SectionNode( incompleteStats );
   8669                     parentNode.childSections.push_back( node );
   8670                 }
   8671                 else
   8672                     node = *it;
   8673             }
   8674             m_sectionStack.push_back( node );
   8675             m_deepestSection = node;
   8676         }
   8677 
   8678         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
   8679 
   8680         virtual bool assertionEnded( AssertionStats const& assertionStats ) {
   8681             assert( !m_sectionStack.empty() );
   8682             SectionNode& sectionNode = *m_sectionStack.back();
   8683             sectionNode.assertions.push_back( assertionStats );
   8684             return true;
   8685         }
   8686         virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
   8687             assert( !m_sectionStack.empty() );
   8688             SectionNode& node = *m_sectionStack.back();
   8689             node.stats = sectionStats;
   8690             m_sectionStack.pop_back();
   8691         }
   8692         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
   8693             Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
   8694             assert( m_sectionStack.size() == 0 );
   8695             node->children.push_back( m_rootSection );
   8696             m_testCases.push_back( node );
   8697             m_rootSection.reset();
   8698 
   8699             assert( m_deepestSection );
   8700             m_deepestSection->stdOut = testCaseStats.stdOut;
   8701             m_deepestSection->stdErr = testCaseStats.stdErr;
   8702         }
   8703         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
   8704             Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
   8705             node->children.swap( m_testCases );
   8706             m_testGroups.push_back( node );
   8707         }
   8708         virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
   8709             Ptr<TestRunNode> node = new TestRunNode( testRunStats );
   8710             node->children.swap( m_testGroups );
   8711             m_testRuns.push_back( node );
   8712             testRunEndedCumulative();
   8713         }
   8714         virtual void testRunEndedCumulative() = 0;
   8715 
   8716         virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
   8717 
   8718         Ptr<IConfig const> m_config;
   8719         std::ostream& stream;
   8720         std::vector<AssertionStats> m_assertions;
   8721         std::vector<std::vector<Ptr<SectionNode> > > m_sections;
   8722         std::vector<Ptr<TestCaseNode> > m_testCases;
   8723         std::vector<Ptr<TestGroupNode> > m_testGroups;
   8724 
   8725         std::vector<Ptr<TestRunNode> > m_testRuns;
   8726 
   8727         Ptr<SectionNode> m_rootSection;
   8728         Ptr<SectionNode> m_deepestSection;
   8729         std::vector<Ptr<SectionNode> > m_sectionStack;
   8730         ReporterPreferences m_reporterPrefs;
   8731 
   8732     };
   8733 
   8734     template<char C>
   8735     char const* getLineOfChars() {
   8736         static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
   8737         if( !*line ) {
   8738             memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
   8739             line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
   8740         }
   8741         return line;
   8742     }
   8743 
   8744     struct TestEventListenerBase : StreamingReporterBase {
   8745         TestEventListenerBase( ReporterConfig const& _config )
   8746         :   StreamingReporterBase( _config )
   8747         {}
   8748 
   8749         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
   8750         virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {
   8751             return false;
   8752         }
   8753     };
   8754 
   8755 } // end namespace Catch
   8756 
   8757 // #included from: ../internal/catch_reporter_registrars.hpp
   8758 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
   8759 
   8760 namespace Catch {
   8761 
   8762     template<typename T>
   8763     class LegacyReporterRegistrar {
   8764 
   8765         class ReporterFactory : public IReporterFactory {
   8766             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
   8767                 return new LegacyReporterAdapter( new T( config ) );
   8768             }
   8769 
   8770             virtual std::string getDescription() const {
   8771                 return T::getDescription();
   8772             }
   8773         };
   8774 
   8775     public:
   8776 
   8777         LegacyReporterRegistrar( std::string const& name ) {
   8778             getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
   8779         }
   8780     };
   8781 
   8782     template<typename T>
   8783     class ReporterRegistrar {
   8784 
   8785         class ReporterFactory : public SharedImpl<IReporterFactory> {
   8786 
   8787             // *** Please Note ***:
   8788             // - If you end up here looking at a compiler error because it's trying to register
   8789             // your custom reporter class be aware that the native reporter interface has changed
   8790             // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
   8791             // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
   8792             // However please consider updating to the new interface as the old one is now
   8793             // deprecated and will probably be removed quite soon!
   8794             // Please contact me via github if you have any questions at all about this.
   8795             // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
   8796             // no idea who is actually using custom reporters at all (possibly no-one!).
   8797             // The new interface is designed to minimise exposure to interface changes in the future.
   8798             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
   8799                 return new T( config );
   8800             }
   8801 
   8802             virtual std::string getDescription() const {
   8803                 return T::getDescription();
   8804             }
   8805         };
   8806 
   8807     public:
   8808 
   8809         ReporterRegistrar( std::string const& name ) {
   8810             getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
   8811         }
   8812     };
   8813 
   8814     template<typename T>
   8815     class ListenerRegistrar {
   8816 
   8817         class ListenerFactory : public SharedImpl<IReporterFactory> {
   8818 
   8819             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
   8820                 return new T( config );
   8821             }
   8822             virtual std::string getDescription() const {
   8823                 return "";
   8824             }
   8825         };
   8826 
   8827     public:
   8828 
   8829         ListenerRegistrar() {
   8830             getMutableRegistryHub().registerListener( new ListenerFactory() );
   8831         }
   8832     };
   8833 }
   8834 
   8835 #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
   8836     namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
   8837 
   8838 #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
   8839     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
   8840 
   8841 #define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
   8842     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
   8843 
   8844 // #included from: ../internal/catch_xmlwriter.hpp
   8845 #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
   8846 
   8847 #include <sstream>
   8848 #include <string>
   8849 #include <vector>
   8850 #include <iomanip>
   8851 
   8852 namespace Catch {
   8853 
   8854     class XmlEncode {
   8855     public:
   8856         enum ForWhat { ForTextNodes, ForAttributes };
   8857 
   8858         XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
   8859         :   m_str( str ),
   8860             m_forWhat( forWhat )
   8861         {}
   8862 
   8863         void encodeTo( std::ostream& os ) const {
   8864 
   8865             // Apostrophe escaping not necessary if we always use " to write attributes
   8866             // (see: http://www.w3.org/TR/xml/#syntax)
   8867 
   8868             for( std::size_t i = 0; i < m_str.size(); ++ i ) {
   8869                 char c = m_str[i];
   8870                 switch( c ) {
   8871                     case '<':   os << "&lt;"; break;
   8872                     case '&':   os << "&amp;"; break;
   8873 
   8874                     case '>':
   8875                         // See: http://www.w3.org/TR/xml/#syntax
   8876                         if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
   8877                             os << "&gt;";
   8878                         else
   8879                             os << c;
   8880                         break;
   8881 
   8882                     case '\"':
   8883                         if( m_forWhat == ForAttributes )
   8884                             os << "&quot;";
   8885                         else
   8886                             os << c;
   8887                         break;
   8888 
   8889                     default:
   8890                         // Escape control chars - based on contribution by @espenalb in PR #465
   8891                         if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
   8892                             os << "&#x" << std::uppercase << std::hex << static_cast<int>( c );
   8893                         else
   8894                             os << c;
   8895                 }
   8896             }
   8897         }
   8898 
   8899         friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
   8900             xmlEncode.encodeTo( os );
   8901             return os;
   8902         }
   8903 
   8904     private:
   8905         std::string m_str;
   8906         ForWhat m_forWhat;
   8907     };
   8908 
   8909     class XmlWriter {
   8910     public:
   8911 
   8912         class ScopedElement {
   8913         public:
   8914             ScopedElement( XmlWriter* writer )
   8915             :   m_writer( writer )
   8916             {}
   8917 
   8918             ScopedElement( ScopedElement const& other )
   8919             :   m_writer( other.m_writer ){
   8920                 other.m_writer = CATCH_NULL;
   8921             }
   8922 
   8923             ~ScopedElement() {
   8924                 if( m_writer )
   8925                     m_writer->endElement();
   8926             }
   8927 
   8928             ScopedElement& writeText( std::string const& text, bool indent = true ) {
   8929                 m_writer->writeText( text, indent );
   8930                 return *this;
   8931             }
   8932 
   8933             template<typename T>
   8934             ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
   8935                 m_writer->writeAttribute( name, attribute );
   8936                 return *this;
   8937             }
   8938 
   8939         private:
   8940             mutable XmlWriter* m_writer;
   8941         };
   8942 
   8943         XmlWriter()
   8944         :   m_tagIsOpen( false ),
   8945             m_needsNewline( false ),
   8946             m_os( &Catch::cout() )
   8947         {}
   8948 
   8949         XmlWriter( std::ostream& os )
   8950         :   m_tagIsOpen( false ),
   8951             m_needsNewline( false ),
   8952             m_os( &os )
   8953         {}
   8954 
   8955         ~XmlWriter() {
   8956             while( !m_tags.empty() )
   8957                 endElement();
   8958         }
   8959 
   8960         XmlWriter& startElement( std::string const& name ) {
   8961             ensureTagClosed();
   8962             newlineIfNecessary();
   8963             stream() << m_indent << "<" << name;
   8964             m_tags.push_back( name );
   8965             m_indent += "  ";
   8966             m_tagIsOpen = true;
   8967             return *this;
   8968         }
   8969 
   8970         ScopedElement scopedElement( std::string const& name ) {
   8971             ScopedElement scoped( this );
   8972             startElement( name );
   8973             return scoped;
   8974         }
   8975 
   8976         XmlWriter& endElement() {
   8977             newlineIfNecessary();
   8978             m_indent = m_indent.substr( 0, m_indent.size()-2 );
   8979             if( m_tagIsOpen ) {
   8980                 stream() << "/>\n";
   8981                 m_tagIsOpen = false;
   8982             }
   8983             else {
   8984                 stream() << m_indent << "</" << m_tags.back() << ">\n";
   8985             }
   8986             m_tags.pop_back();
   8987             return *this;
   8988         }
   8989 
   8990         XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
   8991             if( !name.empty() && !attribute.empty() )
   8992                 stream() << " " << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << "\"";
   8993             return *this;
   8994         }
   8995 
   8996         XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
   8997             stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
   8998             return *this;
   8999         }
   9000 
   9001         template<typename T>
   9002         XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
   9003             std::ostringstream oss;
   9004             oss << attribute;
   9005             return writeAttribute( name, oss.str() );
   9006         }
   9007 
   9008         XmlWriter& writeText( std::string const& text, bool indent = true ) {
   9009             if( !text.empty() ){
   9010                 bool tagWasOpen = m_tagIsOpen;
   9011                 ensureTagClosed();
   9012                 if( tagWasOpen && indent )
   9013                     stream() << m_indent;
   9014                 stream() << XmlEncode( text );
   9015                 m_needsNewline = true;
   9016             }
   9017             return *this;
   9018         }
   9019 
   9020         XmlWriter& writeComment( std::string const& text ) {
   9021             ensureTagClosed();
   9022             stream() << m_indent << "<!--" << text << "-->";
   9023             m_needsNewline = true;
   9024             return *this;
   9025         }
   9026 
   9027         XmlWriter& writeBlankLine() {
   9028             ensureTagClosed();
   9029             stream() << "\n";
   9030             return *this;
   9031         }
   9032 
   9033         void setStream( std::ostream& os ) {
   9034             m_os = &os;
   9035         }
   9036 
   9037     private:
   9038         XmlWriter( XmlWriter const& );
   9039         void operator=( XmlWriter const& );
   9040 
   9041         std::ostream& stream() {
   9042             return *m_os;
   9043         }
   9044 
   9045         void ensureTagClosed() {
   9046             if( m_tagIsOpen ) {
   9047                 stream() << ">\n";
   9048                 m_tagIsOpen = false;
   9049             }
   9050         }
   9051 
   9052         void newlineIfNecessary() {
   9053             if( m_needsNewline ) {
   9054                 stream() << "\n";
   9055                 m_needsNewline = false;
   9056             }
   9057         }
   9058 
   9059         bool m_tagIsOpen;
   9060         bool m_needsNewline;
   9061         std::vector<std::string> m_tags;
   9062         std::string m_indent;
   9063         std::ostream* m_os;
   9064     };
   9065 
   9066 }
   9067 // #included from: catch_reenable_warnings.h
   9068 
   9069 #define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
   9070 
   9071 #ifdef __clang__
   9072 #    ifdef __ICC // icpc defines the __clang__ macro
   9073 #        pragma warning(pop)
   9074 #    else
   9075 #        pragma clang diagnostic pop
   9076 #    endif
   9077 #elif defined __GNUC__
   9078 #    pragma GCC diagnostic pop
   9079 #endif
   9080 
   9081 
   9082 namespace Catch {
   9083     class XmlReporter : public StreamingReporterBase {
   9084     public:
   9085         XmlReporter( ReporterConfig const& _config )
   9086         :   StreamingReporterBase( _config ),
   9087             m_sectionDepth( 0 )
   9088         {
   9089             m_reporterPrefs.shouldRedirectStdOut = true;
   9090         }
   9091 
   9092         virtual ~XmlReporter() CATCH_OVERRIDE;
   9093 
   9094         static std::string getDescription() {
   9095             return "Reports test results as an XML document";
   9096         }
   9097 
   9098     public: // StreamingReporterBase
   9099 
   9100         virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
   9101             StreamingReporterBase::noMatchingTestCases( s );
   9102         }
   9103 
   9104         virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
   9105             StreamingReporterBase::testRunStarting( testInfo );
   9106             m_xml.setStream( stream );
   9107             m_xml.startElement( "Catch" );
   9108             if( !m_config->name().empty() )
   9109                 m_xml.writeAttribute( "name", m_config->name() );
   9110         }
   9111 
   9112         virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
   9113             StreamingReporterBase::testGroupStarting( groupInfo );
   9114             m_xml.startElement( "Group" )
   9115                 .writeAttribute( "name", groupInfo.name );
   9116         }
   9117 
   9118         virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
   9119             StreamingReporterBase::testCaseStarting(testInfo);
   9120             m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
   9121 
   9122             if ( m_config->showDurations() == ShowDurations::Always )
   9123                 m_testCaseTimer.start();
   9124         }
   9125 
   9126         virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
   9127             StreamingReporterBase::sectionStarting( sectionInfo );
   9128             if( m_sectionDepth++ > 0 ) {
   9129                 m_xml.startElement( "Section" )
   9130                     .writeAttribute( "name", trim( sectionInfo.name ) )
   9131                     .writeAttribute( "description", sectionInfo.description );
   9132             }
   9133         }
   9134 
   9135         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
   9136 
   9137         virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
   9138             const AssertionResult& assertionResult = assertionStats.assertionResult;
   9139 
   9140             // Print any info messages in <Info> tags.
   9141             if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
   9142                 for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
   9143                         it != itEnd;
   9144                         ++it ) {
   9145                     if( it->type == ResultWas::Info ) {
   9146                         m_xml.scopedElement( "Info" )
   9147                             .writeText( it->message );
   9148                     } else if ( it->type == ResultWas::Warning ) {
   9149                         m_xml.scopedElement( "Warning" )
   9150                             .writeText( it->message );
   9151                     }
   9152                 }
   9153             }
   9154 
   9155             // Drop out if result was successful but we're not printing them.
   9156             if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
   9157                 return true;
   9158 
   9159             // Print the expression if there is one.
   9160             if( assertionResult.hasExpression() ) {
   9161                 m_xml.startElement( "Expression" )
   9162                     .writeAttribute( "success", assertionResult.succeeded() )
   9163 					.writeAttribute( "type", assertionResult.getTestMacroName() )
   9164                     .writeAttribute( "filename", assertionResult.getSourceInfo().file )
   9165                     .writeAttribute( "line", assertionResult.getSourceInfo().line );
   9166 
   9167                 m_xml.scopedElement( "Original" )
   9168                     .writeText( assertionResult.getExpression() );
   9169                 m_xml.scopedElement( "Expanded" )
   9170                     .writeText( assertionResult.getExpandedExpression() );
   9171             }
   9172 
   9173             // And... Print a result applicable to each result type.
   9174             switch( assertionResult.getResultType() ) {
   9175                 case ResultWas::ThrewException:
   9176                     m_xml.scopedElement( "Exception" )
   9177                         .writeAttribute( "filename", assertionResult.getSourceInfo().file )
   9178                         .writeAttribute( "line", assertionResult.getSourceInfo().line )
   9179                         .writeText( assertionResult.getMessage() );
   9180                     break;
   9181                 case ResultWas::FatalErrorCondition:
   9182                     m_xml.scopedElement( "Fatal Error Condition" )
   9183                         .writeAttribute( "filename", assertionResult.getSourceInfo().file )
   9184                         .writeAttribute( "line", assertionResult.getSourceInfo().line )
   9185                         .writeText( assertionResult.getMessage() );
   9186                     break;
   9187                 case ResultWas::Info:
   9188                     m_xml.scopedElement( "Info" )
   9189                         .writeText( assertionResult.getMessage() );
   9190                     break;
   9191                 case ResultWas::Warning:
   9192                     // Warning will already have been written
   9193                     break;
   9194                 case ResultWas::ExplicitFailure:
   9195                     m_xml.scopedElement( "Failure" )
   9196                         .writeText( assertionResult.getMessage() );
   9197                     break;
   9198                 default:
   9199                     break;
   9200             }
   9201 
   9202             if( assertionResult.hasExpression() )
   9203                 m_xml.endElement();
   9204 
   9205             return true;
   9206         }
   9207 
   9208         virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
   9209             StreamingReporterBase::sectionEnded( sectionStats );
   9210             if( --m_sectionDepth > 0 ) {
   9211                 XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
   9212                 e.writeAttribute( "successes", sectionStats.assertions.passed );
   9213                 e.writeAttribute( "failures", sectionStats.assertions.failed );
   9214                 e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
   9215 
   9216                 if ( m_config->showDurations() == ShowDurations::Always )
   9217                     e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
   9218 
   9219                 m_xml.endElement();
   9220             }
   9221         }
   9222 
   9223         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
   9224             StreamingReporterBase::testCaseEnded( testCaseStats );
   9225             XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
   9226             e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
   9227 
   9228             if ( m_config->showDurations() == ShowDurations::Always )
   9229                 e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
   9230 
   9231             m_xml.endElement();
   9232         }
   9233 
   9234         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
   9235             StreamingReporterBase::testGroupEnded( testGroupStats );
   9236             // TODO: Check testGroupStats.aborting and act accordingly.
   9237             m_xml.scopedElement( "OverallResults" )
   9238                 .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
   9239                 .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
   9240                 .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
   9241             m_xml.endElement();
   9242         }
   9243 
   9244         virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
   9245             StreamingReporterBase::testRunEnded( testRunStats );
   9246             m_xml.scopedElement( "OverallResults" )
   9247                 .writeAttribute( "successes", testRunStats.totals.assertions.passed )
   9248                 .writeAttribute( "failures", testRunStats.totals.assertions.failed )
   9249                 .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
   9250             m_xml.endElement();
   9251         }
   9252 
   9253     private:
   9254         Timer m_testCaseTimer;
   9255         XmlWriter m_xml;
   9256         int m_sectionDepth;
   9257     };
   9258 
   9259      INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
   9260 
   9261 } // end namespace Catch
   9262 
   9263 // #included from: ../reporters/catch_reporter_junit.hpp
   9264 #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
   9265 
   9266 #include <assert.h>
   9267 
   9268 namespace Catch {
   9269 
   9270     class JunitReporter : public CumulativeReporterBase {
   9271     public:
   9272         JunitReporter( ReporterConfig const& _config )
   9273         :   CumulativeReporterBase( _config ),
   9274             xml( _config.stream() )
   9275         {
   9276             m_reporterPrefs.shouldRedirectStdOut = true;
   9277         }
   9278 
   9279         virtual ~JunitReporter() CATCH_OVERRIDE;
   9280 
   9281         static std::string getDescription() {
   9282             return "Reports test results in an XML format that looks like Ant's junitreport target";
   9283         }
   9284 
   9285         virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}
   9286 
   9287         virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {
   9288             CumulativeReporterBase::testRunStarting( runInfo );
   9289             xml.startElement( "testsuites" );
   9290         }
   9291 
   9292         virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
   9293             suiteTimer.start();
   9294             stdOutForSuite.str("");
   9295             stdErrForSuite.str("");
   9296             unexpectedExceptions = 0;
   9297             CumulativeReporterBase::testGroupStarting( groupInfo );
   9298         }
   9299 
   9300         virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
   9301             if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
   9302                 unexpectedExceptions++;
   9303             return CumulativeReporterBase::assertionEnded( assertionStats );
   9304         }
   9305 
   9306         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
   9307             stdOutForSuite << testCaseStats.stdOut;
   9308             stdErrForSuite << testCaseStats.stdErr;
   9309             CumulativeReporterBase::testCaseEnded( testCaseStats );
   9310         }
   9311 
   9312         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
   9313             double suiteTime = suiteTimer.getElapsedSeconds();
   9314             CumulativeReporterBase::testGroupEnded( testGroupStats );
   9315             writeGroup( *m_testGroups.back(), suiteTime );
   9316         }
   9317 
   9318         virtual void testRunEndedCumulative() CATCH_OVERRIDE {
   9319             xml.endElement();
   9320         }
   9321 
   9322         void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
   9323             XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
   9324             TestGroupStats const& stats = groupNode.value;
   9325             xml.writeAttribute( "name", stats.groupInfo.name );
   9326             xml.writeAttribute( "errors", unexpectedExceptions );
   9327             xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
   9328             xml.writeAttribute( "tests", stats.totals.assertions.total() );
   9329             xml.writeAttribute( "hostname", "tbd" ); // !TBD
   9330             if( m_config->showDurations() == ShowDurations::Never )
   9331                 xml.writeAttribute( "time", "" );
   9332             else
   9333                 xml.writeAttribute( "time", suiteTime );
   9334             xml.writeAttribute( "timestamp", "tbd" ); // !TBD
   9335 
   9336             // Write test cases
   9337             for( TestGroupNode::ChildNodes::const_iterator
   9338                     it = groupNode.children.begin(), itEnd = groupNode.children.end();
   9339                     it != itEnd;
   9340                     ++it )
   9341                 writeTestCase( **it );
   9342 
   9343             xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
   9344             xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
   9345         }
   9346 
   9347         void writeTestCase( TestCaseNode const& testCaseNode ) {
   9348             TestCaseStats const& stats = testCaseNode.value;
   9349 
   9350             // All test cases have exactly one section - which represents the
   9351             // test case itself. That section may have 0-n nested sections
   9352             assert( testCaseNode.children.size() == 1 );
   9353             SectionNode const& rootSection = *testCaseNode.children.front();
   9354 
   9355             std::string className = stats.testInfo.className;
   9356 
   9357             if( className.empty() ) {
   9358                 if( rootSection.childSections.empty() )
   9359                     className = "global";
   9360             }
   9361             writeSection( className, "", rootSection );
   9362         }
   9363 
   9364         void writeSection(  std::string const& className,
   9365                             std::string const& rootName,
   9366                             SectionNode const& sectionNode ) {
   9367             std::string name = trim( sectionNode.stats.sectionInfo.name );
   9368             if( !rootName.empty() )
   9369                 name = rootName + "/" + name;
   9370 
   9371             if( !sectionNode.assertions.empty() ||
   9372                 !sectionNode.stdOut.empty() ||
   9373                 !sectionNode.stdErr.empty() ) {
   9374                 XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
   9375                 if( className.empty() ) {
   9376                     xml.writeAttribute( "classname", name );
   9377                     xml.writeAttribute( "name", "root" );
   9378                 }
   9379                 else {
   9380                     xml.writeAttribute( "classname", className );
   9381                     xml.writeAttribute( "name", name );
   9382                 }
   9383                 xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
   9384 
   9385                 writeAssertions( sectionNode );
   9386 
   9387                 if( !sectionNode.stdOut.empty() )
   9388                     xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
   9389                 if( !sectionNode.stdErr.empty() )
   9390                     xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
   9391             }
   9392             for( SectionNode::ChildSections::const_iterator
   9393                     it = sectionNode.childSections.begin(),
   9394                     itEnd = sectionNode.childSections.end();
   9395                     it != itEnd;
   9396                     ++it )
   9397                 if( className.empty() )
   9398                     writeSection( name, "", **it );
   9399                 else
   9400                     writeSection( className, name, **it );
   9401         }
   9402 
   9403         void writeAssertions( SectionNode const& sectionNode ) {
   9404             for( SectionNode::Assertions::const_iterator
   9405                     it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
   9406                     it != itEnd;
   9407                     ++it )
   9408                 writeAssertion( *it );
   9409         }
   9410         void writeAssertion( AssertionStats const& stats ) {
   9411             AssertionResult const& result = stats.assertionResult;
   9412             if( !result.isOk() ) {
   9413                 std::string elementName;
   9414                 switch( result.getResultType() ) {
   9415                     case ResultWas::ThrewException:
   9416                     case ResultWas::FatalErrorCondition:
   9417                         elementName = "error";
   9418                         break;
   9419                     case ResultWas::ExplicitFailure:
   9420                         elementName = "failure";
   9421                         break;
   9422                     case ResultWas::ExpressionFailed:
   9423                         elementName = "failure";
   9424                         break;
   9425                     case ResultWas::DidntThrowException:
   9426                         elementName = "failure";
   9427                         break;
   9428 
   9429                     // We should never see these here:
   9430                     case ResultWas::Info:
   9431                     case ResultWas::Warning:
   9432                     case ResultWas::Ok:
   9433                     case ResultWas::Unknown:
   9434                     case ResultWas::FailureBit:
   9435                     case ResultWas::Exception:
   9436                         elementName = "internalError";
   9437                         break;
   9438                 }
   9439 
   9440                 XmlWriter::ScopedElement e = xml.scopedElement( elementName );
   9441 
   9442                 xml.writeAttribute( "message", result.getExpandedExpression() );
   9443                 xml.writeAttribute( "type", result.getTestMacroName() );
   9444 
   9445                 std::ostringstream oss;
   9446                 if( !result.getMessage().empty() )
   9447                     oss << result.getMessage() << "\n";
   9448                 for( std::vector<MessageInfo>::const_iterator
   9449                         it = stats.infoMessages.begin(),
   9450                         itEnd = stats.infoMessages.end();
   9451                             it != itEnd;
   9452                             ++it )
   9453                     if( it->type == ResultWas::Info )
   9454                         oss << it->message << "\n";
   9455 
   9456                 oss << "at " << result.getSourceInfo();
   9457                 xml.writeText( oss.str(), false );
   9458             }
   9459         }
   9460 
   9461         XmlWriter xml;
   9462         Timer suiteTimer;
   9463         std::ostringstream stdOutForSuite;
   9464         std::ostringstream stdErrForSuite;
   9465         unsigned int unexpectedExceptions;
   9466     };
   9467 
   9468     INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
   9469 
   9470 } // end namespace Catch
   9471 
   9472 // #included from: ../reporters/catch_reporter_console.hpp
   9473 #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
   9474 
   9475 namespace Catch {
   9476 
   9477     struct ConsoleReporter : StreamingReporterBase {
   9478         ConsoleReporter( ReporterConfig const& _config )
   9479         :   StreamingReporterBase( _config ),
   9480             m_headerPrinted( false )
   9481         {}
   9482 
   9483         virtual ~ConsoleReporter() CATCH_OVERRIDE;
   9484         static std::string getDescription() {
   9485             return "Reports test results as plain lines of text";
   9486         }
   9487 
   9488         virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
   9489             stream << "No test cases matched '" << spec << "'" << std::endl;
   9490         }
   9491 
   9492         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
   9493         }
   9494 
   9495         virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
   9496             AssertionResult const& result = _assertionStats.assertionResult;
   9497 
   9498             bool printInfoMessages = true;
   9499 
   9500             // Drop out if result was successful and we're not printing those
   9501             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
   9502                 if( result.getResultType() != ResultWas::Warning )
   9503                     return false;
   9504                 printInfoMessages = false;
   9505             }
   9506 
   9507             lazyPrint();
   9508 
   9509             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
   9510             printer.print();
   9511             stream << std::endl;
   9512             return true;
   9513         }
   9514 
   9515         virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
   9516             m_headerPrinted = false;
   9517             StreamingReporterBase::sectionStarting( _sectionInfo );
   9518         }
   9519         virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
   9520             if( _sectionStats.missingAssertions ) {
   9521                 lazyPrint();
   9522                 Colour colour( Colour::ResultError );
   9523                 if( m_sectionStack.size() > 1 )
   9524                     stream << "\nNo assertions in section";
   9525                 else
   9526                     stream << "\nNo assertions in test case";
   9527                 stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
   9528             }
   9529             if( m_headerPrinted ) {
   9530                 if( m_config->showDurations() == ShowDurations::Always )
   9531                     stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
   9532                 m_headerPrinted = false;
   9533             }
   9534             else {
   9535                 if( m_config->showDurations() == ShowDurations::Always )
   9536                     stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
   9537             }
   9538             StreamingReporterBase::sectionEnded( _sectionStats );
   9539         }
   9540 
   9541         virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
   9542             StreamingReporterBase::testCaseEnded( _testCaseStats );
   9543             m_headerPrinted = false;
   9544         }
   9545         virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
   9546             if( currentGroupInfo.used ) {
   9547                 printSummaryDivider();
   9548                 stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
   9549                 printTotals( _testGroupStats.totals );
   9550                 stream << "\n" << std::endl;
   9551             }
   9552             StreamingReporterBase::testGroupEnded( _testGroupStats );
   9553         }
   9554         virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
   9555             printTotalsDivider( _testRunStats.totals );
   9556             printTotals( _testRunStats.totals );
   9557             stream << std::endl;
   9558             StreamingReporterBase::testRunEnded( _testRunStats );
   9559         }
   9560 
   9561     private:
   9562 
   9563         class AssertionPrinter {
   9564             void operator= ( AssertionPrinter const& );
   9565         public:
   9566             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
   9567             :   stream( _stream ),
   9568                 stats( _stats ),
   9569                 result( _stats.assertionResult ),
   9570                 colour( Colour::None ),
   9571                 message( result.getMessage() ),
   9572                 messages( _stats.infoMessages ),
   9573                 printInfoMessages( _printInfoMessages )
   9574             {
   9575                 switch( result.getResultType() ) {
   9576                     case ResultWas::Ok:
   9577                         colour = Colour::Success;
   9578                         passOrFail = "PASSED";
   9579                         //if( result.hasMessage() )
   9580                         if( _stats.infoMessages.size() == 1 )
   9581                             messageLabel = "with message";
   9582                         if( _stats.infoMessages.size() > 1 )
   9583                             messageLabel = "with messages";
   9584                         break;
   9585                     case ResultWas::ExpressionFailed:
   9586                         if( result.isOk() ) {
   9587                             colour = Colour::Success;
   9588                             passOrFail = "FAILED - but was ok";
   9589                         }
   9590                         else {
   9591                             colour = Colour::Error;
   9592                             passOrFail = "FAILED";
   9593                         }
   9594                         if( _stats.infoMessages.size() == 1 )
   9595                             messageLabel = "with message";
   9596                         if( _stats.infoMessages.size() > 1 )
   9597                             messageLabel = "with messages";
   9598                         break;
   9599                     case ResultWas::ThrewException:
   9600                         colour = Colour::Error;
   9601                         passOrFail = "FAILED";
   9602                         messageLabel = "due to unexpected exception with message";
   9603                         break;
   9604                     case ResultWas::FatalErrorCondition:
   9605                         colour = Colour::Error;
   9606                         passOrFail = "FAILED";
   9607                         messageLabel = "due to a fatal error condition";
   9608                         break;
   9609                     case ResultWas::DidntThrowException:
   9610                         colour = Colour::Error;
   9611                         passOrFail = "FAILED";
   9612                         messageLabel = "because no exception was thrown where one was expected";
   9613                         break;
   9614                     case ResultWas::Info:
   9615                         messageLabel = "info";
   9616                         break;
   9617                     case ResultWas::Warning:
   9618                         messageLabel = "warning";
   9619                         break;
   9620                     case ResultWas::ExplicitFailure:
   9621                         passOrFail = "FAILED";
   9622                         colour = Colour::Error;
   9623                         if( _stats.infoMessages.size() == 1 )
   9624                             messageLabel = "explicitly with message";
   9625                         if( _stats.infoMessages.size() > 1 )
   9626                             messageLabel = "explicitly with messages";
   9627                         break;
   9628                     // These cases are here to prevent compiler warnings
   9629                     case ResultWas::Unknown:
   9630                     case ResultWas::FailureBit:
   9631                     case ResultWas::Exception:
   9632                         passOrFail = "** internal error **";
   9633                         colour = Colour::Error;
   9634                         break;
   9635                 }
   9636             }
   9637 
   9638             void print() const {
   9639                 printSourceInfo();
   9640                 if( stats.totals.assertions.total() > 0 ) {
   9641                     if( result.isOk() )
   9642                         stream << "\n";
   9643                     printResultType();
   9644                     printOriginalExpression();
   9645                     printReconstructedExpression();
   9646                 }
   9647                 else {
   9648                     stream << "\n";
   9649                 }
   9650                 printMessage();
   9651             }
   9652 
   9653         private:
   9654             void printResultType() const {
   9655                 if( !passOrFail.empty() ) {
   9656                     Colour colourGuard( colour );
   9657                     stream << passOrFail << ":\n";
   9658                 }
   9659             }
   9660             void printOriginalExpression() const {
   9661                 if( result.hasExpression() ) {
   9662                     Colour colourGuard( Colour::OriginalExpression );
   9663                     stream  << "  ";
   9664                     stream << result.getExpressionInMacro();
   9665                     stream << "\n";
   9666                 }
   9667             }
   9668             void printReconstructedExpression() const {
   9669                 if( result.hasExpandedExpression() ) {
   9670                     stream << "with expansion:\n";
   9671                     Colour colourGuard( Colour::ReconstructedExpression );
   9672                     stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
   9673                 }
   9674             }
   9675             void printMessage() const {
   9676                 if( !messageLabel.empty() )
   9677                     stream << messageLabel << ":" << "\n";
   9678                 for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
   9679                         it != itEnd;
   9680                         ++it ) {
   9681                     // If this assertion is a warning ignore any INFO messages
   9682                     if( printInfoMessages || it->type != ResultWas::Info )
   9683                         stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
   9684                 }
   9685             }
   9686             void printSourceInfo() const {
   9687                 Colour colourGuard( Colour::FileName );
   9688                 stream << result.getSourceInfo() << ": ";
   9689             }
   9690 
   9691             std::ostream& stream;
   9692             AssertionStats const& stats;
   9693             AssertionResult const& result;
   9694             Colour::Code colour;
   9695             std::string passOrFail;
   9696             std::string messageLabel;
   9697             std::string message;
   9698             std::vector<MessageInfo> messages;
   9699             bool printInfoMessages;
   9700         };
   9701 
   9702         void lazyPrint() {
   9703 
   9704             if( !currentTestRunInfo.used )
   9705                 lazyPrintRunInfo();
   9706             if( !currentGroupInfo.used )
   9707                 lazyPrintGroupInfo();
   9708 
   9709             if( !m_headerPrinted ) {
   9710                 printTestCaseAndSectionHeader();
   9711                 m_headerPrinted = true;
   9712             }
   9713         }
   9714         void lazyPrintRunInfo() {
   9715             stream  << "\n" << getLineOfChars<'~'>() << "\n";
   9716             Colour colour( Colour::SecondaryText );
   9717             stream  << currentTestRunInfo->name
   9718                     << " is a Catch v"  << libraryVersion << " host application.\n"
   9719                     << "Run with -? for options\n\n";
   9720 
   9721             if( m_config->rngSeed() != 0 )
   9722                 stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
   9723 
   9724             currentTestRunInfo.used = true;
   9725         }
   9726         void lazyPrintGroupInfo() {
   9727             if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
   9728                 printClosedHeader( "Group: " + currentGroupInfo->name );
   9729                 currentGroupInfo.used = true;
   9730             }
   9731         }
   9732         void printTestCaseAndSectionHeader() {
   9733             assert( !m_sectionStack.empty() );
   9734             printOpenHeader( currentTestCaseInfo->name );
   9735 
   9736             if( m_sectionStack.size() > 1 ) {
   9737                 Colour colourGuard( Colour::Headers );
   9738 
   9739                 std::vector<SectionInfo>::const_iterator
   9740                     it = m_sectionStack.begin()+1, // Skip first section (test case)
   9741                     itEnd = m_sectionStack.end();
   9742                 for( ; it != itEnd; ++it )
   9743                     printHeaderString( it->name, 2 );
   9744             }
   9745 
   9746             SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
   9747 
   9748             if( !lineInfo.empty() ){
   9749                 stream << getLineOfChars<'-'>() << "\n";
   9750                 Colour colourGuard( Colour::FileName );
   9751                 stream << lineInfo << "\n";
   9752             }
   9753             stream << getLineOfChars<'.'>() << "\n" << std::endl;
   9754         }
   9755 
   9756         void printClosedHeader( std::string const& _name ) {
   9757             printOpenHeader( _name );
   9758             stream << getLineOfChars<'.'>() << "\n";
   9759         }
   9760         void printOpenHeader( std::string const& _name ) {
   9761             stream  << getLineOfChars<'-'>() << "\n";
   9762             {
   9763                 Colour colourGuard( Colour::Headers );
   9764                 printHeaderString( _name );
   9765             }
   9766         }
   9767 
   9768         // if string has a : in first line will set indent to follow it on
   9769         // subsequent lines
   9770         void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
   9771             std::size_t i = _string.find( ": " );
   9772             if( i != std::string::npos )
   9773                 i+=2;
   9774             else
   9775                 i = 0;
   9776             stream << Text( _string, TextAttributes()
   9777                                         .setIndent( indent+i)
   9778                                         .setInitialIndent( indent ) ) << "\n";
   9779         }
   9780 
   9781         struct SummaryColumn {
   9782 
   9783             SummaryColumn( std::string const& _label, Colour::Code _colour )
   9784             :   label( _label ),
   9785                 colour( _colour )
   9786             {}
   9787             SummaryColumn addRow( std::size_t count ) {
   9788                 std::ostringstream oss;
   9789                 oss << count;
   9790                 std::string row = oss.str();
   9791                 for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
   9792                     while( it->size() < row.size() )
   9793                         *it = " " + *it;
   9794                     while( it->size() > row.size() )
   9795                         row = " " + row;
   9796                 }
   9797                 rows.push_back( row );
   9798                 return *this;
   9799             }
   9800 
   9801             std::string label;
   9802             Colour::Code colour;
   9803             std::vector<std::string> rows;
   9804 
   9805         };
   9806 
   9807         void printTotals( Totals const& totals ) {
   9808             if( totals.testCases.total() == 0 ) {
   9809                 stream << Colour( Colour::Warning ) << "No tests ran\n";
   9810             }
   9811             else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
   9812                 stream << Colour( Colour::ResultSuccess ) << "All tests passed";
   9813                 stream << " ("
   9814                         << pluralise( totals.assertions.passed, "assertion" ) << " in "
   9815                         << pluralise( totals.testCases.passed, "test case" ) << ")"
   9816                         << "\n";
   9817             }
   9818             else {
   9819 
   9820                 std::vector<SummaryColumn> columns;
   9821                 columns.push_back( SummaryColumn( "", Colour::None )
   9822                                         .addRow( totals.testCases.total() )
   9823                                         .addRow( totals.assertions.total() ) );
   9824                 columns.push_back( SummaryColumn( "passed", Colour::Success )
   9825                                         .addRow( totals.testCases.passed )
   9826                                         .addRow( totals.assertions.passed ) );
   9827                 columns.push_back( SummaryColumn( "failed", Colour::ResultError )
   9828                                         .addRow( totals.testCases.failed )
   9829                                         .addRow( totals.assertions.failed ) );
   9830                 columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
   9831                                         .addRow( totals.testCases.failedButOk )
   9832                                         .addRow( totals.assertions.failedButOk ) );
   9833 
   9834                 printSummaryRow( "test cases", columns, 0 );
   9835                 printSummaryRow( "assertions", columns, 1 );
   9836             }
   9837         }
   9838         void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
   9839             for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
   9840                 std::string value = it->rows[row];
   9841                 if( it->label.empty() ) {
   9842                     stream << label << ": ";
   9843                     if( value != "0" )
   9844                         stream << value;
   9845                     else
   9846                         stream << Colour( Colour::Warning ) << "- none -";
   9847                 }
   9848                 else if( value != "0" ) {
   9849                     stream  << Colour( Colour::LightGrey ) << " | ";
   9850                     stream  << Colour( it->colour )
   9851                             << value << " " << it->label;
   9852                 }
   9853             }
   9854             stream << "\n";
   9855         }
   9856 
   9857         static std::size_t makeRatio( std::size_t number, std::size_t total ) {
   9858             std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
   9859             return ( ratio == 0 && number > 0 ) ? 1 : ratio;
   9860         }
   9861         static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
   9862             if( i > j && i > k )
   9863                 return i;
   9864             else if( j > k )
   9865                 return j;
   9866             else
   9867                 return k;
   9868         }
   9869 
   9870         void printTotalsDivider( Totals const& totals ) {
   9871             if( totals.testCases.total() > 0 ) {
   9872                 std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
   9873                 std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
   9874                 std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
   9875                 while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
   9876                     findMax( failedRatio, failedButOkRatio, passedRatio )++;
   9877                 while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
   9878                     findMax( failedRatio, failedButOkRatio, passedRatio )--;
   9879 
   9880                 stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
   9881                 stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
   9882                 if( totals.testCases.allPassed() )
   9883                     stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
   9884                 else
   9885                     stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
   9886             }
   9887             else {
   9888                 stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
   9889             }
   9890             stream << "\n";
   9891         }
   9892         void printSummaryDivider() {
   9893             stream << getLineOfChars<'-'>() << "\n";
   9894         }
   9895 
   9896     private:
   9897         bool m_headerPrinted;
   9898     };
   9899 
   9900     INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
   9901 
   9902 } // end namespace Catch
   9903 
   9904 // #included from: ../reporters/catch_reporter_compact.hpp
   9905 #define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
   9906 
   9907 namespace Catch {
   9908 
   9909     struct CompactReporter : StreamingReporterBase {
   9910 
   9911         CompactReporter( ReporterConfig const& _config )
   9912         : StreamingReporterBase( _config )
   9913         {}
   9914 
   9915         virtual ~CompactReporter();
   9916 
   9917         static std::string getDescription() {
   9918             return "Reports test results on a single line, suitable for IDEs";
   9919         }
   9920 
   9921         virtual ReporterPreferences getPreferences() const {
   9922             ReporterPreferences prefs;
   9923             prefs.shouldRedirectStdOut = false;
   9924             return prefs;
   9925         }
   9926 
   9927         virtual void noMatchingTestCases( std::string const& spec ) {
   9928             stream << "No test cases matched '" << spec << "'" << std::endl;
   9929         }
   9930 
   9931         virtual void assertionStarting( AssertionInfo const& ) {
   9932         }
   9933 
   9934         virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
   9935             AssertionResult const& result = _assertionStats.assertionResult;
   9936 
   9937             bool printInfoMessages = true;
   9938 
   9939             // Drop out if result was successful and we're not printing those
   9940             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
   9941                 if( result.getResultType() != ResultWas::Warning )
   9942                     return false;
   9943                 printInfoMessages = false;
   9944             }
   9945 
   9946             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
   9947             printer.print();
   9948 
   9949             stream << std::endl;
   9950             return true;
   9951         }
   9952 
   9953         virtual void testRunEnded( TestRunStats const& _testRunStats ) {
   9954             printTotals( _testRunStats.totals );
   9955             stream << "\n" << std::endl;
   9956             StreamingReporterBase::testRunEnded( _testRunStats );
   9957         }
   9958 
   9959     private:
   9960         class AssertionPrinter {
   9961             void operator= ( AssertionPrinter const& );
   9962         public:
   9963             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
   9964             : stream( _stream )
   9965             , stats( _stats )
   9966             , result( _stats.assertionResult )
   9967             , messages( _stats.infoMessages )
   9968             , itMessage( _stats.infoMessages.begin() )
   9969             , printInfoMessages( _printInfoMessages )
   9970             {}
   9971 
   9972             void print() {
   9973                 printSourceInfo();
   9974 
   9975                 itMessage = messages.begin();
   9976 
   9977                 switch( result.getResultType() ) {
   9978                     case ResultWas::Ok:
   9979                         printResultType( Colour::ResultSuccess, passedString() );
   9980                         printOriginalExpression();
   9981                         printReconstructedExpression();
   9982                         if ( ! result.hasExpression() )
   9983                             printRemainingMessages( Colour::None );
   9984                         else
   9985                             printRemainingMessages();
   9986                         break;
   9987                     case ResultWas::ExpressionFailed:
   9988                         if( result.isOk() )
   9989                             printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
   9990                         else
   9991                             printResultType( Colour::Error, failedString() );
   9992                         printOriginalExpression();
   9993                         printReconstructedExpression();
   9994                         printRemainingMessages();
   9995                         break;
   9996                     case ResultWas::ThrewException:
   9997                         printResultType( Colour::Error, failedString() );
   9998                         printIssue( "unexpected exception with message:" );
   9999                         printMessage();
   10000                         printExpressionWas();
   10001                         printRemainingMessages();
   10002                         break;
   10003                     case ResultWas::FatalErrorCondition:
   10004                         printResultType( Colour::Error, failedString() );
   10005                         printIssue( "fatal error condition with message:" );
   10006                         printMessage();
   10007                         printExpressionWas();
   10008                         printRemainingMessages();
   10009                         break;
   10010                     case ResultWas::DidntThrowException:
   10011                         printResultType( Colour::Error, failedString() );
   10012                         printIssue( "expected exception, got none" );
   10013                         printExpressionWas();
   10014                         printRemainingMessages();
   10015                         break;
   10016                     case ResultWas::Info:
   10017                         printResultType( Colour::None, "info" );
   10018                         printMessage();
   10019                         printRemainingMessages();
   10020                         break;
   10021                     case ResultWas::Warning:
   10022                         printResultType( Colour::None, "warning" );
   10023                         printMessage();
   10024                         printRemainingMessages();
   10025                         break;
   10026                     case ResultWas::ExplicitFailure:
   10027                         printResultType( Colour::Error, failedString() );
   10028                         printIssue( "explicitly" );
   10029                         printRemainingMessages( Colour::None );
   10030                         break;
   10031                     // These cases are here to prevent compiler warnings
   10032                     case ResultWas::Unknown:
   10033                     case ResultWas::FailureBit:
   10034                     case ResultWas::Exception:
   10035                         printResultType( Colour::Error, "** internal error **" );
   10036                         break;
   10037                 }
   10038             }
   10039 
   10040         private:
   10041             // Colour::LightGrey
   10042 
   10043             static Colour::Code dimColour() { return Colour::FileName; }
   10044 
   10045 #ifdef CATCH_PLATFORM_MAC
   10046             static const char* failedString() { return "FAILED"; }
   10047             static const char* passedString() { return "PASSED"; }
   10048 #else
   10049             static const char* failedString() { return "failed"; }
   10050             static const char* passedString() { return "passed"; }
   10051 #endif
   10052 
   10053             void printSourceInfo() const {
   10054                 Colour colourGuard( Colour::FileName );
   10055                 stream << result.getSourceInfo() << ":";
   10056             }
   10057 
   10058             void printResultType( Colour::Code colour, std::string passOrFail ) const {
   10059                 if( !passOrFail.empty() ) {
   10060                     {
   10061                         Colour colourGuard( colour );
   10062                         stream << " " << passOrFail;
   10063                     }
   10064                     stream << ":";
   10065                 }
   10066             }
   10067 
   10068             void printIssue( std::string issue ) const {
   10069                 stream << " " << issue;
   10070             }
   10071 
   10072             void printExpressionWas() {
   10073                 if( result.hasExpression() ) {
   10074                     stream << ";";
   10075                     {
   10076                         Colour colour( dimColour() );
   10077                         stream << " expression was:";
   10078                     }
   10079                     printOriginalExpression();
   10080                 }
   10081             }
   10082 
   10083             void printOriginalExpression() const {
   10084                 if( result.hasExpression() ) {
   10085                     stream << " " << result.getExpression();
   10086                 }
   10087             }
   10088 
   10089             void printReconstructedExpression() const {
   10090                 if( result.hasExpandedExpression() ) {
   10091                     {
   10092                         Colour colour( dimColour() );
   10093                         stream << " for: ";
   10094                     }
   10095                     stream << result.getExpandedExpression();
   10096                 }
   10097             }
   10098 
   10099             void printMessage() {
   10100                 if ( itMessage != messages.end() ) {
   10101                     stream << " '" << itMessage->message << "'";
   10102                     ++itMessage;
   10103                 }
   10104             }
   10105 
   10106             void printRemainingMessages( Colour::Code colour = dimColour() ) {
   10107                 if ( itMessage == messages.end() )
   10108                     return;
   10109 
   10110                 // using messages.end() directly yields compilation error:
   10111                 std::vector<MessageInfo>::const_iterator itEnd = messages.end();
   10112                 const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
   10113 
   10114                 {
   10115                     Colour colourGuard( colour );
   10116                     stream << " with " << pluralise( N, "message" ) << ":";
   10117                 }
   10118 
   10119                 for(; itMessage != itEnd; ) {
   10120                     // If this assertion is a warning ignore any INFO messages
   10121                     if( printInfoMessages || itMessage->type != ResultWas::Info ) {
   10122                         stream << " '" << itMessage->message << "'";
   10123                         if ( ++itMessage != itEnd ) {
   10124                             Colour colourGuard( dimColour() );
   10125                             stream << " and";
   10126                         }
   10127                     }
   10128                 }
   10129             }
   10130 
   10131         private:
   10132             std::ostream& stream;
   10133             AssertionStats const& stats;
   10134             AssertionResult const& result;
   10135             std::vector<MessageInfo> messages;
   10136             std::vector<MessageInfo>::const_iterator itMessage;
   10137             bool printInfoMessages;
   10138         };
   10139 
   10140         // Colour, message variants:
   10141         // - white: No tests ran.
   10142         // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
   10143         // - white: Passed [both/all] N test cases (no assertions).
   10144         // -   red: Failed N tests cases, failed M assertions.
   10145         // - green: Passed [both/all] N tests cases with M assertions.
   10146 
   10147         std::string bothOrAll( std::size_t count ) const {
   10148             return count == 1 ? "" : count == 2 ? "both " : "all " ;
   10149         }
   10150 
   10151         void printTotals( const Totals& totals ) const {
   10152             if( totals.testCases.total() == 0 ) {
   10153                 stream << "No tests ran.";
   10154             }
   10155             else if( totals.testCases.failed == totals.testCases.total() ) {
   10156                 Colour colour( Colour::ResultError );
   10157                 const std::string qualify_assertions_failed =
   10158                     totals.assertions.failed == totals.assertions.total() ?
   10159                         bothOrAll( totals.assertions.failed ) : "";
   10160                 stream <<
   10161                     "Failed " << bothOrAll( totals.testCases.failed )
   10162                               << pluralise( totals.testCases.failed, "test case"  ) << ", "
   10163                     "failed " << qualify_assertions_failed <<
   10164                                  pluralise( totals.assertions.failed, "assertion" ) << ".";
   10165             }
   10166             else if( totals.assertions.total() == 0 ) {
   10167                 stream <<
   10168                     "Passed " << bothOrAll( totals.testCases.total() )
   10169                               << pluralise( totals.testCases.total(), "test case" )
   10170                               << " (no assertions).";
   10171             }
   10172             else if( totals.assertions.failed ) {
   10173                 Colour colour( Colour::ResultError );
   10174                 stream <<
   10175                     "Failed " << pluralise( totals.testCases.failed, "test case"  ) << ", "
   10176                     "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
   10177             }
   10178             else {
   10179                 Colour colour( Colour::ResultSuccess );
   10180                 stream <<
   10181                     "Passed " << bothOrAll( totals.testCases.passed )
   10182                               << pluralise( totals.testCases.passed, "test case"  ) <<
   10183                     " with "  << pluralise( totals.assertions.passed, "assertion" ) << ".";
   10184             }
   10185         }
   10186     };
   10187 
   10188     INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
   10189 
   10190 } // end namespace Catch
   10191 
   10192 namespace Catch {
   10193     // These are all here to avoid warnings about not having any out of line
   10194     // virtual methods
   10195     NonCopyable::~NonCopyable() {}
   10196     IShared::~IShared() {}
   10197     IStream::~IStream() CATCH_NOEXCEPT {}
   10198     FileStream::~FileStream() CATCH_NOEXCEPT {}
   10199     CoutStream::~CoutStream() CATCH_NOEXCEPT {}
   10200     DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
   10201     StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
   10202     IContext::~IContext() {}
   10203     IResultCapture::~IResultCapture() {}
   10204     ITestCase::~ITestCase() {}
   10205     ITestCaseRegistry::~ITestCaseRegistry() {}
   10206     IRegistryHub::~IRegistryHub() {}
   10207     IMutableRegistryHub::~IMutableRegistryHub() {}
   10208     IExceptionTranslator::~IExceptionTranslator() {}
   10209     IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
   10210     IReporter::~IReporter() {}
   10211     IReporterFactory::~IReporterFactory() {}
   10212     IReporterRegistry::~IReporterRegistry() {}
   10213     IStreamingReporter::~IStreamingReporter() {}
   10214     AssertionStats::~AssertionStats() {}
   10215     SectionStats::~SectionStats() {}
   10216     TestCaseStats::~TestCaseStats() {}
   10217     TestGroupStats::~TestGroupStats() {}
   10218     TestRunStats::~TestRunStats() {}
   10219     CumulativeReporterBase::SectionNode::~SectionNode() {}
   10220     CumulativeReporterBase::~CumulativeReporterBase() {}
   10221 
   10222     StreamingReporterBase::~StreamingReporterBase() {}
   10223     ConsoleReporter::~ConsoleReporter() {}
   10224     CompactReporter::~CompactReporter() {}
   10225     IRunner::~IRunner() {}
   10226     IMutableContext::~IMutableContext() {}
   10227     IConfig::~IConfig() {}
   10228     XmlReporter::~XmlReporter() {}
   10229     JunitReporter::~JunitReporter() {}
   10230     TestRegistry::~TestRegistry() {}
   10231     FreeFunctionTestCase::~FreeFunctionTestCase() {}
   10232     IGeneratorInfo::~IGeneratorInfo() {}
   10233     IGeneratorsForTest::~IGeneratorsForTest() {}
   10234     WildcardPattern::~WildcardPattern() {}
   10235     TestSpec::Pattern::~Pattern() {}
   10236     TestSpec::NamePattern::~NamePattern() {}
   10237     TestSpec::TagPattern::~TagPattern() {}
   10238     TestSpec::ExcludedPattern::~ExcludedPattern() {}
   10239 
   10240     Matchers::Impl::StdString::Equals::~Equals() {}
   10241     Matchers::Impl::StdString::Contains::~Contains() {}
   10242     Matchers::Impl::StdString::StartsWith::~StartsWith() {}
   10243     Matchers::Impl::StdString::EndsWith::~EndsWith() {}
   10244 
   10245     void Config::dummy() {}
   10246 
   10247     namespace TestCaseTracking {
   10248         ITracker::~ITracker() {}
   10249         TrackerBase::~TrackerBase() {}
   10250         SectionTracker::~SectionTracker() {}
   10251         IndexTracker::~IndexTracker() {}
   10252     }
   10253 }
   10254 
   10255 #ifdef __clang__
   10256 #pragma clang diagnostic pop
   10257 #endif
   10258 
   10259 #endif
   10260 
   10261 #ifdef CATCH_CONFIG_MAIN
   10262 // #included from: internal/catch_default_main.hpp
   10263 #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
   10264 
   10265 #ifndef __OBJC__
   10266 
   10267 // Standard C/C++ main entry point
   10268 int main (int argc, char * argv[]) {
   10269     return Catch::Session().run( argc, argv );
   10270 }
   10271 
   10272 #else // __OBJC__
   10273 
   10274 // Objective-C entry point
   10275 int main (int argc, char * const argv[]) {
   10276 #if !CATCH_ARC_ENABLED
   10277     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   10278 #endif
   10279 
   10280     Catch::registerTestMethods();
   10281     int result = Catch::Session().run( argc, (char* const*)argv );
   10282 
   10283 #if !CATCH_ARC_ENABLED
   10284     [pool drain];
   10285 #endif
   10286 
   10287     return result;
   10288 }
   10289 
   10290 #endif // __OBJC__
   10291 
   10292 #endif
   10293 
   10294 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
   10295 #  undef CLARA_CONFIG_MAIN
   10296 #endif
   10297 
   10298 //////
   10299 
   10300 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
   10301 #ifdef CATCH_CONFIG_PREFIX_ALL
   10302 
   10303 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
   10304 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
   10305 
   10306 #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" )
   10307 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
   10308 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" )
   10309 #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
   10310 
   10311 #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
   10312 #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
   10313 #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
   10314 #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
   10315 #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
   10316 
   10317 #define CATCH_CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
   10318 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
   10319 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" )
   10320 #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
   10321 
   10322 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
   10323 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
   10324 
   10325 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
   10326 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
   10327 #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
   10328 #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
   10329 #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
   10330 
   10331 #ifdef CATCH_CONFIG_VARIADIC_MACROS
   10332     #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
   10333     #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
   10334     #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
   10335     #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
   10336     #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
   10337     #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
   10338     #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
   10339 #else
   10340     #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
   10341     #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
   10342     #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
   10343     #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
   10344     #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
   10345     #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
   10346     #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
   10347 #endif
   10348 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
   10349 
   10350 #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
   10351 #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
   10352 
   10353 #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
   10354 
   10355 // "BDD-style" convenience wrappers
   10356 #ifdef CATCH_CONFIG_VARIADIC_MACROS
   10357 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
   10358 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
   10359 #else
   10360 #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
   10361 #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
   10362 #endif
   10363 #define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc, "" )
   10364 #define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc, "" )
   10365 #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
   10366 #define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc, "" )
   10367 #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
   10368 
   10369 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
   10370 #else
   10371 
   10372 #define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
   10373 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
   10374 
   10375 #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" )
   10376 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
   10377 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" )
   10378 #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
   10379 
   10380 #define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
   10381 #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
   10382 #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
   10383 #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
   10384 #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
   10385 
   10386 #define CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" )
   10387 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
   10388 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" )
   10389 #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
   10390 
   10391 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
   10392 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
   10393 
   10394 #define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
   10395 #define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
   10396 #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
   10397 #define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
   10398 #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
   10399 
   10400 #ifdef CATCH_CONFIG_VARIADIC_MACROS
   10401     #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
   10402     #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
   10403     #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
   10404     #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
   10405     #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
   10406     #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
   10407     #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
   10408 #else
   10409     #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
   10410     #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
   10411     #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
   10412     #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
   10413     #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
   10414     #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
   10415     #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
   10416 #endif
   10417 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
   10418 
   10419 #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
   10420 #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
   10421 
   10422 #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
   10423 
   10424 #endif
   10425 
   10426 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
   10427 
   10428 // "BDD-style" convenience wrappers
   10429 #ifdef CATCH_CONFIG_VARIADIC_MACROS
   10430 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
   10431 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
   10432 #else
   10433 #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
   10434 #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
   10435 #endif
   10436 #define GIVEN( desc )    SECTION( std::string("   Given: ") + desc, "" )
   10437 #define WHEN( desc )     SECTION( std::string("    When: ") + desc, "" )
   10438 #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
   10439 #define THEN( desc )     SECTION( std::string("    Then: ") + desc, "" )
   10440 #define AND_THEN( desc ) SECTION( std::string("     And: ") + desc, "" )
   10441 
   10442 using Catch::Detail::Approx;
   10443 
   10444 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
   10445