catch.hpp
Go to the documentation of this file.
00001 /*
00002  *  Catch v1.2.1
00003  *  Generated: 2015-06-30 18:23:27.961086
00004  *  ----------------------------------------------------------
00005  *  This file has been merged from multiple headers. Please don't edit it directly
00006  *  Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
00007  *
00008  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
00009  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00010  */
00011 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
00012 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
00013 
00014 #define TWOBLUECUBES_CATCH_HPP_INCLUDED
00015 
00016 #ifdef __clang__
00017 #    pragma clang system_header
00018 #elif defined __GNUC__
00019 #    pragma GCC system_header
00020 #endif
00021 
00022 // #included from: internal/catch_suppress_warnings.h
00023 
00024 #define TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED
00025 
00026 #ifdef __clang__
00027 #   ifdef __ICC // icpc defines the __clang__ macro
00028 #       pragma warning(push)
00029 #       pragma warning(disable: 161 1682)
00030 #   else // __ICC
00031 #       pragma clang diagnostic ignored "-Wglobal-constructors"
00032 #       pragma clang diagnostic ignored "-Wvariadic-macros"
00033 #       pragma clang diagnostic ignored "-Wc99-extensions"
00034 #       pragma clang diagnostic ignored "-Wunused-variable"
00035 #       pragma clang diagnostic push
00036 #       pragma clang diagnostic ignored "-Wpadded"
00037 #       pragma clang diagnostic ignored "-Wc++98-compat"
00038 #       pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
00039 #       pragma clang diagnostic ignored "-Wswitch-enum"
00040 #    endif
00041 #elif defined __GNUC__
00042 #    pragma GCC diagnostic ignored "-Wvariadic-macros"
00043 #    pragma GCC diagnostic ignored "-Wunused-variable"
00044 #    pragma GCC diagnostic push
00045 #    pragma GCC diagnostic ignored "-Wpadded"
00046 #endif
00047 
00048 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
00049 #  define CATCH_IMPL
00050 #endif
00051 
00052 #ifdef CATCH_IMPL
00053 #  ifndef CLARA_CONFIG_MAIN
00054 #    define CLARA_CONFIG_MAIN_NOT_DEFINED
00055 #    define CLARA_CONFIG_MAIN
00056 #  endif
00057 #endif
00058 
00059 // #included from: internal/catch_notimplemented_exception.h
00060 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
00061 
00062 // #included from: catch_common.h
00063 #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
00064 
00065 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
00066 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
00067 #define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
00068 
00069 #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
00070 #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
00071 
00072 #include <sstream>
00073 #include <stdexcept>
00074 #include <algorithm>
00075 
00076 // #included from: catch_compiler_capabilities.h
00077 #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
00078 
00079 // Detect a number of compiler features - mostly C++11/14 conformance - by compiler
00080 // The following features are defined:
00081 //
00082 // CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
00083 // CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
00084 // CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
00085 // CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
00086 // CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
00087 
00088 // CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
00089 
00090 // CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
00091 
00092 // In general each macro has a _NO_<feature name> form
00093 // (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
00094 // Many features, at point of detection, define an _INTERNAL_ macro, so they
00095 // can be combined, en-mass, with the _NO_ forms later.
00096 
00097 // All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
00098 
00099 #ifdef __clang__
00100 
00101 #  if __has_feature(cxx_nullptr)
00102 #    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
00103 #  endif
00104 
00105 #  if __has_feature(cxx_noexcept)
00106 #    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
00107 #  endif
00108 
00109 #endif // __clang__
00110 
00112 // Borland
00113 #ifdef __BORLANDC__
00114 
00115 #endif // __BORLANDC__
00116 
00118 // EDG
00119 #ifdef __EDG_VERSION__
00120 
00121 #endif // __EDG_VERSION__
00122 
00124 // Digital Mars
00125 #ifdef __DMC__
00126 
00127 #endif // __DMC__
00128 
00130 // GCC
00131 #ifdef __GNUC__
00132 
00133 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) )
00134 #   define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
00135 #endif
00136 
00137 #endif // __GNUC__
00138 
00140 // Visual C++
00141 #ifdef _MSC_VER
00142 
00143 #if (_MSC_VER >= 1600)
00144 #   define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
00145 #endif
00146 
00147 #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
00148 #define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
00149 #define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
00150 #endif
00151 
00152 #endif // _MSC_VER
00153 
00154 // Use variadic macros if the compiler supports them
00155 #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
00156     ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
00157     ( defined __GNUC__ && __GNUC__ >= 3 ) || \
00158     ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
00159 
00160 #define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
00161 
00162 #endif
00163 
00165 // C++ language feature support
00166 
00167 // catch all support for C++11
00168 #if (__cplusplus >= 201103L)
00169 
00170 #  define CATCH_CPP11_OR_GREATER
00171 
00172 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
00173 #    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
00174 #  endif
00175 
00176 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
00177 #    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
00178 #  endif
00179 
00180 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
00181 #    define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
00182 #  endif
00183 
00184 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
00185 #    define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
00186 #  endif
00187 
00188 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
00189 #    define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
00190 #  endif
00191 
00192 #  ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
00193 #    define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
00194 #  endif
00195 
00196 #endif // __cplusplus >= 201103L
00197 
00198 // Now set the actual defines based on the above + anything the user has configured
00199 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
00200 #   define CATCH_CONFIG_CPP11_NULLPTR
00201 #endif
00202 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
00203 #   define CATCH_CONFIG_CPP11_NOEXCEPT
00204 #endif
00205 #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)
00206 #   define CATCH_CONFIG_CPP11_GENERATED_METHODS
00207 #endif
00208 #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)
00209 #   define CATCH_CONFIG_CPP11_IS_ENUM
00210 #endif
00211 #if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
00212 #   define CATCH_CONFIG_CPP11_TUPLE
00213 #endif
00214 #if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
00215 #define CATCH_CONFIG_VARIADIC_MACROS
00216 #endif
00217 
00218 // noexcept support:
00219 #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
00220 #  define CATCH_NOEXCEPT noexcept
00221 #  define CATCH_NOEXCEPT_IS(x) noexcept(x)
00222 #else
00223 #  define CATCH_NOEXCEPT throw()
00224 #  define CATCH_NOEXCEPT_IS(x)
00225 #endif
00226 
00227 namespace Catch {
00228 
00229     class NonCopyable {
00230 #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
00231         NonCopyable( NonCopyable const& )              = delete;
00232         NonCopyable( NonCopyable && )                  = delete;
00233         NonCopyable& operator = ( NonCopyable const& ) = delete;
00234         NonCopyable& operator = ( NonCopyable && )     = delete;
00235 #else
00236         NonCopyable( NonCopyable const& info );
00237         NonCopyable& operator = ( NonCopyable const& );
00238 #endif
00239 
00240     protected:
00241         NonCopyable() {}
00242         virtual ~NonCopyable();
00243     };
00244 
00245     class SafeBool {
00246     public:
00247         typedef void (SafeBool::*type)() const;
00248 
00249         static type makeSafe( bool value ) {
00250             return value ? &SafeBool::trueValue : 0;
00251         }
00252     private:
00253         void trueValue() const {}
00254     };
00255 
00256     template<typename ContainerT>
00257     inline void deleteAll( ContainerT& container ) {
00258         typename ContainerT::const_iterator it = container.begin();
00259         typename ContainerT::const_iterator itEnd = container.end();
00260         for(; it != itEnd; ++it )
00261             delete *it;
00262     }
00263     template<typename AssociativeContainerT>
00264     inline void deleteAllValues( AssociativeContainerT& container ) {
00265         typename AssociativeContainerT::const_iterator it = container.begin();
00266         typename AssociativeContainerT::const_iterator itEnd = container.end();
00267         for(; it != itEnd; ++it )
00268             delete it->second;
00269     }
00270 
00271     bool startsWith( std::string const& s, std::string const& prefix );
00272     bool endsWith( std::string const& s, std::string const& suffix );
00273     bool contains( std::string const& s, std::string const& infix );
00274     void toLowerInPlace( std::string& s );
00275     std::string toLower( std::string const& s );
00276     std::string trim( std::string const& str );
00277     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
00278 
00279     struct pluralise {
00280         pluralise( std::size_t count, std::string const& label );
00281 
00282         friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
00283 
00284         std::size_t m_count;
00285         std::string m_label;
00286     };
00287 
00288     struct SourceLineInfo {
00289 
00290         SourceLineInfo();
00291         SourceLineInfo( char const* _file, std::size_t _line );
00292         SourceLineInfo( SourceLineInfo const& other );
00293 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
00294         SourceLineInfo( SourceLineInfo && )                  = default;
00295         SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
00296         SourceLineInfo& operator = ( SourceLineInfo && )     = default;
00297 #  endif
00298         bool empty() const;
00299         bool operator == ( SourceLineInfo const& other ) const;
00300         bool operator < ( SourceLineInfo const& other ) const;
00301 
00302         std::string file;
00303         std::size_t line;
00304     };
00305 
00306     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
00307 
00308     // This is just here to avoid compiler warnings with macro constants and boolean literals
00309     inline bool isTrue( bool value ){ return value; }
00310     inline bool alwaysTrue() { return true; }
00311     inline bool alwaysFalse() { return false; }
00312 
00313     void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
00314 
00315     // Use this in variadic streaming macros to allow
00316     //    >> +StreamEndStop
00317     // as well as
00318     //    >> stuff +StreamEndStop
00319     struct StreamEndStop {
00320         std::string operator+() {
00321             return std::string();
00322         }
00323     };
00324     template<typename T>
00325     T const& operator + ( T const& value, StreamEndStop ) {
00326         return value;
00327     }
00328 }
00329 
00330 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
00331 #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
00332 
00333 #include <ostream>
00334 
00335 namespace Catch {
00336 
00337     class NotImplementedException : public std::exception
00338     {
00339     public:
00340         NotImplementedException( SourceLineInfo const& lineInfo );
00341         NotImplementedException( NotImplementedException const& ) {}
00342 
00343         virtual ~NotImplementedException() CATCH_NOEXCEPT {}
00344 
00345         virtual const char* what() const CATCH_NOEXCEPT;
00346 
00347     private:
00348         std::string m_what;
00349         SourceLineInfo m_lineInfo;
00350     };
00351 
00352 } // end namespace Catch
00353 
00355 #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
00356 
00357 // #included from: internal/catch_context.h
00358 #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
00359 
00360 // #included from: catch_interfaces_generators.h
00361 #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
00362 
00363 #include <string>
00364 
00365 namespace Catch {
00366 
00367     struct IGeneratorInfo {
00368         virtual ~IGeneratorInfo();
00369         virtual bool moveNext() = 0;
00370         virtual std::size_t getCurrentIndex() const = 0;
00371     };
00372 
00373     struct IGeneratorsForTest {
00374         virtual ~IGeneratorsForTest();
00375 
00376         virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
00377         virtual bool moveNext() = 0;
00378     };
00379 
00380     IGeneratorsForTest* createGeneratorsForTest();
00381 
00382 } // end namespace Catch
00383 
00384 // #included from: catch_ptr.hpp
00385 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
00386 
00387 #ifdef __clang__
00388 #pragma clang diagnostic push
00389 #pragma clang diagnostic ignored "-Wpadded"
00390 #endif
00391 
00392 namespace Catch {
00393 
00394     // An intrusive reference counting smart pointer.
00395     // T must implement addRef() and release() methods
00396     // typically implementing the IShared interface
00397     template<typename T>
00398     class Ptr {
00399     public:
00400         Ptr() : m_p( NULL ){}
00401         Ptr( T* p ) : m_p( p ){
00402             if( m_p )
00403                 m_p->addRef();
00404         }
00405         Ptr( Ptr const& other ) : m_p( other.m_p ){
00406             if( m_p )
00407                 m_p->addRef();
00408         }
00409         ~Ptr(){
00410             if( m_p )
00411                 m_p->release();
00412         }
00413         void reset() {
00414             if( m_p )
00415                 m_p->release();
00416             m_p = NULL;
00417         }
00418         Ptr& operator = ( T* p ){
00419             Ptr temp( p );
00420             swap( temp );
00421             return *this;
00422         }
00423         Ptr& operator = ( Ptr const& other ){
00424             Ptr temp( other );
00425             swap( temp );
00426             return *this;
00427         }
00428         void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
00429         T* get() { return m_p; }
00430         const T* get() const{ return m_p; }
00431         T& operator*() const { return *m_p; }
00432         T* operator->() const { return m_p; }
00433         bool operator !() const { return m_p == NULL; }
00434         operator SafeBool::type() const { return SafeBool::makeSafe( m_p != NULL ); }
00435 
00436     private:
00437         T* m_p;
00438     };
00439 
00440     struct IShared : NonCopyable {
00441         virtual ~IShared();
00442         virtual void addRef() const = 0;
00443         virtual void release() const = 0;
00444     };
00445 
00446     template<typename T = IShared>
00447     struct SharedImpl : T {
00448 
00449         SharedImpl() : m_rc( 0 ){}
00450 
00451         virtual void addRef() const {
00452             ++m_rc;
00453         }
00454         virtual void release() const {
00455             if( --m_rc == 0 )
00456                 delete this;
00457         }
00458 
00459         mutable unsigned int m_rc;
00460     };
00461 
00462 } // end namespace Catch
00463 
00464 #ifdef __clang__
00465 #pragma clang diagnostic pop
00466 #endif
00467 
00468 #include <memory>
00469 #include <vector>
00470 #include <stdlib.h>
00471 
00472 namespace Catch {
00473 
00474     class TestCase;
00475     class Stream;
00476     struct IResultCapture;
00477     struct IRunner;
00478     struct IGeneratorsForTest;
00479     struct IConfig;
00480 
00481     struct IContext
00482     {
00483         virtual ~IContext();
00484 
00485         virtual IResultCapture* getResultCapture() = 0;
00486         virtual IRunner* getRunner() = 0;
00487         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
00488         virtual bool advanceGeneratorsForCurrentTest() = 0;
00489         virtual Ptr<IConfig const> getConfig() const = 0;
00490     };
00491 
00492     struct IMutableContext : IContext
00493     {
00494         virtual ~IMutableContext();
00495         virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
00496         virtual void setRunner( IRunner* runner ) = 0;
00497         virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
00498     };
00499 
00500     IContext& getCurrentContext();
00501     IMutableContext& getCurrentMutableContext();
00502     void cleanUpContext();
00503     Stream createStream( std::string const& streamName );
00504 
00505 }
00506 
00507 // #included from: internal/catch_test_registry.hpp
00508 #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
00509 
00510 // #included from: catch_interfaces_testcase.h
00511 #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
00512 
00513 #include <vector>
00514 
00515 namespace Catch {
00516 
00517     class TestSpec;
00518 
00519     struct ITestCase : IShared {
00520         virtual void invoke () const = 0;
00521     protected:
00522         virtual ~ITestCase();
00523     };
00524 
00525     class TestCase;
00526     struct IConfig;
00527 
00528     struct ITestCaseRegistry {
00529         virtual ~ITestCaseRegistry();
00530         virtual std::vector<TestCase> const& getAllTests() const = 0;
00531         virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const = 0;
00532 
00533     };
00534 }
00535 
00536 namespace Catch {
00537 
00538 template<typename C>
00539 class MethodTestCase : public SharedImpl<ITestCase> {
00540 
00541 public:
00542     MethodTestCase( void (C::*method)() ) : m_method( method ) {}
00543 
00544     virtual void invoke() const {
00545         C obj;
00546         (obj.*m_method)();
00547     }
00548 
00549 private:
00550     virtual ~MethodTestCase() {}
00551 
00552     void (C::*m_method)();
00553 };
00554 
00555 typedef void(*TestFunction)();
00556 
00557 struct NameAndDesc {
00558     NameAndDesc( const char* _name = "", const char* _description= "" )
00559     : name( _name ), description( _description )
00560     {}
00561 
00562     const char* name;
00563     const char* description;
00564 };
00565 
00566 struct AutoReg {
00567 
00568     AutoReg(    TestFunction function,
00569                 SourceLineInfo const& lineInfo,
00570                 NameAndDesc const& nameAndDesc );
00571 
00572     template<typename C>
00573     AutoReg(    void (C::*method)(),
00574                 char const* className,
00575                 NameAndDesc const& nameAndDesc,
00576                 SourceLineInfo const& lineInfo ) {
00577         registerTestCase(   new MethodTestCase<C>( method ),
00578                             className,
00579                             nameAndDesc,
00580                             lineInfo );
00581     }
00582 
00583     void registerTestCase(  ITestCase* testCase,
00584                             char const* className,
00585                             NameAndDesc const& nameAndDesc,
00586                             SourceLineInfo const& lineInfo );
00587 
00588     ~AutoReg();
00589 
00590 private:
00591     AutoReg( AutoReg const& );
00592     void operator= ( AutoReg const& );
00593 };
00594 
00595 } // end namespace Catch
00596 
00597 #ifdef CATCH_CONFIG_VARIADIC_MACROS
00598 
00599     #define INTERNAL_CATCH_TESTCASE( ... ) \
00600         static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
00601         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME(  ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
00602         static void INTERNAL_CATCH_UNIQUE_NAME(  ____C_A_T_C_H____T_E_S_T____ )()
00603 
00605     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
00606         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
00607 
00609     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
00610         namespace{ \
00611             struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
00612                 void test(); \
00613             }; \
00614             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
00615         } \
00616         void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
00617 
00618 #else
00619 
00620     #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
00621         static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
00622         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME(  ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
00623         static void INTERNAL_CATCH_UNIQUE_NAME(  ____C_A_T_C_H____T_E_S_T____ )()
00624 
00626     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
00627         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
00628 
00630     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
00631         namespace{ \
00632             struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
00633                 void test(); \
00634             }; \
00635             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
00636         } \
00637         void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
00638 
00639 #endif
00640 
00641 // #included from: internal/catch_capture.hpp
00642 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
00643 
00644 // #included from: catch_result_builder.h
00645 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
00646 
00647 // #included from: catch_result_type.h
00648 #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
00649 
00650 namespace Catch {
00651 
00652     // ResultWas::OfType enum
00653     struct ResultWas { enum OfType {
00654         Unknown = -1,
00655         Ok = 0,
00656         Info = 1,
00657         Warning = 2,
00658 
00659         FailureBit = 0x10,
00660 
00661         ExpressionFailed = FailureBit | 1,
00662         ExplicitFailure = FailureBit | 2,
00663 
00664         Exception = 0x100 | FailureBit,
00665 
00666         ThrewException = Exception | 1,
00667         DidntThrowException = Exception | 2,
00668 
00669         FatalErrorCondition = 0x200 | FailureBit
00670 
00671     }; };
00672 
00673     inline bool isOk( ResultWas::OfType resultType ) {
00674         return ( resultType & ResultWas::FailureBit ) == 0;
00675     }
00676     inline bool isJustInfo( int flags ) {
00677         return flags == ResultWas::Info;
00678     }
00679 
00680     // ResultDisposition::Flags enum
00681     struct ResultDisposition { enum Flags {
00682         Normal = 0x01,
00683 
00684         ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
00685         FalseTest = 0x04,           // Prefix expression with !
00686         SuppressFail = 0x08         // Failures are reported but do not fail the test
00687     }; };
00688 
00689     inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
00690         return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
00691     }
00692 
00693     inline bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
00694     inline bool isFalseTest( int flags )                { return ( flags & ResultDisposition::FalseTest ) != 0; }
00695     inline bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
00696 
00697 } // end namespace Catch
00698 
00699 // #included from: catch_assertionresult.h
00700 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
00701 
00702 #include <string>
00703 
00704 namespace Catch {
00705 
00706     struct AssertionInfo
00707     {
00708         AssertionInfo() {}
00709         AssertionInfo(  std::string const& _macroName,
00710                         SourceLineInfo const& _lineInfo,
00711                         std::string const& _capturedExpression,
00712                         ResultDisposition::Flags _resultDisposition );
00713 
00714         std::string macroName;
00715         SourceLineInfo lineInfo;
00716         std::string capturedExpression;
00717         ResultDisposition::Flags resultDisposition;
00718     };
00719 
00720     struct AssertionResultData
00721     {
00722         AssertionResultData() : resultType( ResultWas::Unknown ) {}
00723 
00724         std::string reconstructedExpression;
00725         std::string message;
00726         ResultWas::OfType resultType;
00727     };
00728 
00729     class AssertionResult {
00730     public:
00731         AssertionResult();
00732         AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
00733         ~AssertionResult();
00734 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
00735          AssertionResult( AssertionResult const& )              = default;
00736          AssertionResult( AssertionResult && )                  = default;
00737          AssertionResult& operator = ( AssertionResult const& ) = default;
00738          AssertionResult& operator = ( AssertionResult && )     = default;
00739 #  endif
00740 
00741         bool isOk() const;
00742         bool succeeded() const;
00743         ResultWas::OfType getResultType() const;
00744         bool hasExpression() const;
00745         bool hasMessage() const;
00746         std::string getExpression() const;
00747         std::string getExpressionInMacro() const;
00748         bool hasExpandedExpression() const;
00749         std::string getExpandedExpression() const;
00750         std::string getMessage() const;
00751         SourceLineInfo getSourceInfo() const;
00752         std::string getTestMacroName() const;
00753 
00754     protected:
00755         AssertionInfo m_info;
00756         AssertionResultData m_resultData;
00757     };
00758 
00759 } // end namespace Catch
00760 
00761 namespace Catch {
00762 
00763     struct TestFailureException{};
00764 
00765     template<typename T> class ExpressionLhs;
00766 
00767     struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
00768 
00769     struct CopyableStream {
00770         CopyableStream() {}
00771         CopyableStream( CopyableStream const& other ) {
00772             oss << other.oss.str();
00773         }
00774         CopyableStream& operator=( CopyableStream const& other ) {
00775             oss.str("");
00776             oss << other.oss.str();
00777             return *this;
00778         }
00779         std::ostringstream oss;
00780     };
00781 
00782     class ResultBuilder {
00783     public:
00784         ResultBuilder(  char const* macroName,
00785                         SourceLineInfo const& lineInfo,
00786                         char const* capturedExpression,
00787                         ResultDisposition::Flags resultDisposition );
00788 
00789         template<typename T>
00790         ExpressionLhs<T const&> operator <= ( T const& operand );
00791         ExpressionLhs<bool> operator <= ( bool value );
00792 
00793         template<typename T>
00794         ResultBuilder& operator << ( T const& value ) {
00795             m_stream.oss << value;
00796             return *this;
00797         }
00798 
00799         template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
00800         template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
00801 
00802         ResultBuilder& setResultType( ResultWas::OfType result );
00803         ResultBuilder& setResultType( bool result );
00804         ResultBuilder& setLhs( std::string const& lhs );
00805         ResultBuilder& setRhs( std::string const& rhs );
00806         ResultBuilder& setOp( std::string const& op );
00807 
00808         void endExpression();
00809 
00810         std::string reconstructExpression() const;
00811         AssertionResult build() const;
00812 
00813         void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
00814         void captureResult( ResultWas::OfType resultType );
00815         void captureExpression();
00816         void react();
00817         bool shouldDebugBreak() const;
00818         bool allowThrows() const;
00819 
00820     private:
00821         AssertionInfo m_assertionInfo;
00822         AssertionResultData m_data;
00823         struct ExprComponents {
00824             ExprComponents() : testFalse( false ) {}
00825             bool testFalse;
00826             std::string lhs, rhs, op;
00827         } m_exprComponents;
00828         CopyableStream m_stream;
00829 
00830         bool m_shouldDebugBreak;
00831         bool m_shouldThrow;
00832     };
00833 
00834 } // namespace Catch
00835 
00836 // Include after due to circular dependency:
00837 // #included from: catch_expression_lhs.hpp
00838 #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
00839 
00840 // #included from: catch_evaluate.hpp
00841 #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
00842 
00843 #ifdef _MSC_VER
00844 #pragma warning(push)
00845 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
00846 #endif
00847 
00848 #include <cstddef>
00849 
00850 namespace Catch {
00851 namespace Internal {
00852 
00853     enum Operator {
00854         IsEqualTo,
00855         IsNotEqualTo,
00856         IsLessThan,
00857         IsGreaterThan,
00858         IsLessThanOrEqualTo,
00859         IsGreaterThanOrEqualTo
00860     };
00861 
00862     template<Operator Op> struct OperatorTraits             { static const char* getName(){ return "*error*"; } };
00863     template<> struct OperatorTraits<IsEqualTo>             { static const char* getName(){ return "=="; } };
00864     template<> struct OperatorTraits<IsNotEqualTo>          { static const char* getName(){ return "!="; } };
00865     template<> struct OperatorTraits<IsLessThan>            { static const char* getName(){ return "<"; } };
00866     template<> struct OperatorTraits<IsGreaterThan>         { static const char* getName(){ return ">"; } };
00867     template<> struct OperatorTraits<IsLessThanOrEqualTo>   { static const char* getName(){ return "<="; } };
00868     template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
00869 
00870     template<typename T>
00871     inline T& opCast(T const& t) { return const_cast<T&>(t); }
00872 
00873 // nullptr_t support based on pull request #154 from Konstantin Baumann
00874 #ifdef CATCH_CONFIG_CPP11_NULLPTR
00875     inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
00876 #endif // CATCH_CONFIG_CPP11_NULLPTR
00877 
00878     // So the compare overloads can be operator agnostic we convey the operator as a template
00879     // enum, which is used to specialise an Evaluator for doing the comparison.
00880     template<typename T1, typename T2, Operator Op>
00881     class Evaluator{};
00882 
00883     template<typename T1, typename T2>
00884     struct Evaluator<T1, T2, IsEqualTo> {
00885         static bool evaluate( T1 const& lhs, T2 const& rhs) {
00886             return opCast( lhs ) ==  opCast( rhs );
00887         }
00888     };
00889     template<typename T1, typename T2>
00890     struct Evaluator<T1, T2, IsNotEqualTo> {
00891         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
00892             return opCast( lhs ) != opCast( rhs );
00893         }
00894     };
00895     template<typename T1, typename T2>
00896     struct Evaluator<T1, T2, IsLessThan> {
00897         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
00898             return opCast( lhs ) < opCast( rhs );
00899         }
00900     };
00901     template<typename T1, typename T2>
00902     struct Evaluator<T1, T2, IsGreaterThan> {
00903         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
00904             return opCast( lhs ) > opCast( rhs );
00905         }
00906     };
00907     template<typename T1, typename T2>
00908     struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
00909         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
00910             return opCast( lhs ) >= opCast( rhs );
00911         }
00912     };
00913     template<typename T1, typename T2>
00914     struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
00915         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
00916             return opCast( lhs ) <= opCast( rhs );
00917         }
00918     };
00919 
00920     template<Operator Op, typename T1, typename T2>
00921     bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
00922         return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
00923     }
00924 
00925     // This level of indirection allows us to specialise for integer types
00926     // to avoid signed/ unsigned warnings
00927 
00928     // "base" overload
00929     template<Operator Op, typename T1, typename T2>
00930     bool compare( T1 const& lhs, T2 const& rhs ) {
00931         return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
00932     }
00933 
00934     // unsigned X to int
00935     template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
00936         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
00937     }
00938     template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
00939         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
00940     }
00941     template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
00942         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
00943     }
00944 
00945     // unsigned X to long
00946     template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
00947         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
00948     }
00949     template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
00950         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
00951     }
00952     template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
00953         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
00954     }
00955 
00956     // int to unsigned X
00957     template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
00958         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
00959     }
00960     template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
00961         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
00962     }
00963     template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
00964         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
00965     }
00966 
00967     // long to unsigned X
00968     template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
00969         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
00970     }
00971     template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
00972         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
00973     }
00974     template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
00975         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
00976     }
00977 
00978     // pointer to long (when comparing against NULL)
00979     template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
00980         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
00981     }
00982     template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
00983         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
00984     }
00985 
00986     // pointer to int (when comparing against NULL)
00987     template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
00988         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
00989     }
00990     template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
00991         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
00992     }
00993 
00994 #ifdef CATCH_CONFIG_CPP11_NULLPTR
00995     // pointer to nullptr_t (when comparing against nullptr)
00996     template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
00997         return Evaluator<T*, T*, Op>::evaluate( NULL, rhs );
00998     }
00999     template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
01000         return Evaluator<T*, T*, Op>::evaluate( lhs, NULL );
01001     }
01002 #endif // CATCH_CONFIG_CPP11_NULLPTR
01003 
01004 } // end of namespace Internal
01005 } // end of namespace Catch
01006 
01007 #ifdef _MSC_VER
01008 #pragma warning(pop)
01009 #endif
01010 
01011 // #included from: catch_tostring.h
01012 #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
01013 
01014 #include <sstream>
01015 #include <iomanip>
01016 #include <limits>
01017 #include <vector>
01018 #include <cstddef>
01019 
01020 #ifdef __OBJC__
01021 // #included from: catch_objc_arc.hpp
01022 #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
01023 
01024 #import <Foundation/Foundation.h>
01025 
01026 #ifdef __has_feature
01027 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
01028 #else
01029 #define CATCH_ARC_ENABLED 0
01030 #endif
01031 
01032 void arcSafeRelease( NSObject* obj );
01033 id performOptionalSelector( id obj, SEL sel );
01034 
01035 #if !CATCH_ARC_ENABLED
01036 inline void arcSafeRelease( NSObject* obj ) {
01037     [obj release];
01038 }
01039 inline id performOptionalSelector( id obj, SEL sel ) {
01040     if( [obj respondsToSelector: sel] )
01041         return [obj performSelector: sel];
01042     return nil;
01043 }
01044 #define CATCH_UNSAFE_UNRETAINED
01045 #define CATCH_ARC_STRONG
01046 #else
01047 inline void arcSafeRelease( NSObject* ){}
01048 inline id performOptionalSelector( id obj, SEL sel ) {
01049 #ifdef __clang__
01050 #pragma clang diagnostic push
01051 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
01052 #endif
01053     if( [obj respondsToSelector: sel] )
01054         return [obj performSelector: sel];
01055 #ifdef __clang__
01056 #pragma clang diagnostic pop
01057 #endif
01058     return nil;
01059 }
01060 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
01061 #define CATCH_ARC_STRONG __strong
01062 #endif
01063 
01064 #endif
01065 
01066 #ifdef CATCH_CONFIG_CPP11_TUPLE
01067 #include <tuple>
01068 #endif
01069 
01070 #ifdef CATCH_CONFIG_CPP11_IS_ENUM
01071 #include <type_traits>
01072 #endif
01073 
01074 namespace Catch {
01075 
01076 // Why we're here.
01077 template<typename T>
01078 std::string toString( T const& value );
01079 
01080 // Built in overloads
01081 
01082 std::string toString( std::string const& value );
01083 std::string toString( std::wstring const& value );
01084 std::string toString( const char* const value );
01085 std::string toString( char* const value );
01086 std::string toString( const wchar_t* const value );
01087 std::string toString( wchar_t* const value );
01088 std::string toString( int value );
01089 std::string toString( unsigned long value );
01090 std::string toString( unsigned int value );
01091 std::string toString( const double value );
01092 std::string toString( const float value );
01093 std::string toString( bool value );
01094 std::string toString( char value );
01095 std::string toString( signed char value );
01096 std::string toString( unsigned char value );
01097 
01098 #ifdef CATCH_CONFIG_CPP11_NULLPTR
01099 std::string toString( std::nullptr_t );
01100 #endif
01101 
01102 #ifdef __OBJC__
01103     std::string toString( NSString const * const& nsstring );
01104     std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
01105     std::string toString( NSObject* const& nsObject );
01106 #endif
01107 
01108 namespace Detail {
01109 
01110     extern std::string unprintableString;
01111 
01112     struct BorgType {
01113         template<typename T> BorgType( T const& );
01114     };
01115 
01116     struct TrueType { char sizer[1]; };
01117     struct FalseType { char sizer[2]; };
01118 
01119     TrueType& testStreamable( std::ostream& );
01120     FalseType testStreamable( FalseType );
01121 
01122     FalseType operator<<( std::ostream const&, BorgType const& );
01123 
01124     template<typename T>
01125     struct IsStreamInsertable {
01126         static std::ostream &s;
01127         static T  const&t;
01128         enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
01129     };
01130 
01131 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
01132     template<typename T,
01133              bool IsEnum = std::is_enum<T>::value
01134              >
01135     struct EnumStringMaker
01136     {
01137         static std::string convert( T const& ) { return unprintableString; }
01138     };
01139 
01140     template<typename T>
01141     struct EnumStringMaker<T,true>
01142     {
01143         static std::string convert( T const& v )
01144         {
01145             return ::Catch::toString(
01146                 static_cast<typename std::underlying_type<T>::type>(v)
01147                 );
01148         }
01149     };
01150 #endif
01151     template<bool C>
01152     struct StringMakerBase {
01153 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
01154         template<typename T>
01155         static std::string convert( T const& v )
01156         {
01157             return EnumStringMaker<T>::convert( v );
01158         }
01159 #else
01160         template<typename T>
01161         static std::string convert( T const& ) { return unprintableString; }
01162 #endif
01163     };
01164 
01165     template<>
01166     struct StringMakerBase<true> {
01167         template<typename T>
01168         static std::string convert( T const& _value ) {
01169             std::ostringstream oss;
01170             oss << _value;
01171             return oss.str();
01172         }
01173     };
01174 
01175     std::string rawMemoryToString( const void *object, std::size_t size );
01176 
01177     template<typename T>
01178     inline std::string rawMemoryToString( const T& object ) {
01179       return rawMemoryToString( &object, sizeof(object) );
01180     }
01181 
01182 } // end namespace Detail
01183 
01184 template<typename T>
01185 struct StringMaker :
01186     Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
01187 
01188 template<typename T>
01189 struct StringMaker<T*> {
01190     template<typename U>
01191     static std::string convert( U* p ) {
01192         if( !p )
01193             return INTERNAL_CATCH_STRINGIFY( NULL );
01194         else
01195             return Detail::rawMemoryToString( p );
01196     }
01197 };
01198 
01199 template<typename R, typename C>
01200 struct StringMaker<R C::*> {
01201     static std::string convert( R C::* p ) {
01202         if( !p )
01203             return INTERNAL_CATCH_STRINGIFY( NULL );
01204         else
01205             return Detail::rawMemoryToString( p );
01206     }
01207 };
01208 
01209 namespace Detail {
01210     template<typename InputIterator>
01211     std::string rangeToString( InputIterator first, InputIterator last );
01212 }
01213 
01214 //template<typename T, typename Allocator>
01215 //struct StringMaker<std::vector<T, Allocator> > {
01216 //    static std::string convert( std::vector<T,Allocator> const& v ) {
01217 //        return Detail::rangeToString( v.begin(), v.end() );
01218 //    }
01219 //};
01220 
01221 template<typename T, typename Allocator>
01222 std::string toString( std::vector<T,Allocator> const& v ) {
01223     return Detail::rangeToString( v.begin(), v.end() );
01224 }
01225 
01226 #ifdef CATCH_CONFIG_CPP11_TUPLE
01227 
01228 // toString for tuples
01229 namespace TupleDetail {
01230   template<
01231       typename Tuple,
01232       std::size_t N = 0,
01233       bool = (N < std::tuple_size<Tuple>::value)
01234       >
01235   struct ElementPrinter {
01236       static void print( const Tuple& tuple, std::ostream& os )
01237       {
01238           os << ( N ? ", " : " " )
01239              << Catch::toString(std::get<N>(tuple));
01240           ElementPrinter<Tuple,N+1>::print(tuple,os);
01241       }
01242   };
01243 
01244   template<
01245       typename Tuple,
01246       std::size_t N
01247       >
01248   struct ElementPrinter<Tuple,N,false> {
01249       static void print( const Tuple&, std::ostream& ) {}
01250   };
01251 
01252 }
01253 
01254 template<typename ...Types>
01255 struct StringMaker<std::tuple<Types...>> {
01256 
01257     static std::string convert( const std::tuple<Types...>& tuple )
01258     {
01259         std::ostringstream os;
01260         os << '{';
01261         TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
01262         os << " }";
01263         return os.str();
01264     }
01265 };
01266 #endif // CATCH_CONFIG_CPP11_TUPLE
01267 
01268 namespace Detail {
01269     template<typename T>
01270     std::string makeString( T const& value ) {
01271         return StringMaker<T>::convert( value );
01272     }
01273 } // end namespace Detail
01274 
01282 template<typename T>
01283 std::string toString( T const& value ) {
01284     return StringMaker<T>::convert( value );
01285 }
01286 
01287     namespace Detail {
01288     template<typename InputIterator>
01289     std::string rangeToString( InputIterator first, InputIterator last ) {
01290         std::ostringstream oss;
01291         oss << "{ ";
01292         if( first != last ) {
01293             oss << Catch::toString( *first );
01294             for( ++first ; first != last ; ++first )
01295                 oss << ", " << Catch::toString( *first );
01296         }
01297         oss << " }";
01298         return oss.str();
01299     }
01300 }
01301 
01302 } // end namespace Catch
01303 
01304 namespace Catch {
01305 
01306 // Wraps the LHS of an expression and captures the operator and RHS (if any) -
01307 // wrapping them all in a ResultBuilder object
01308 template<typename T>
01309 class ExpressionLhs {
01310     ExpressionLhs& operator = ( ExpressionLhs const& );
01311 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
01312     ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
01313 #  endif
01314 
01315 public:
01316     ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
01317 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
01318     ExpressionLhs( ExpressionLhs const& ) = default;
01319     ExpressionLhs( ExpressionLhs && )     = default;
01320 #  endif
01321 
01322     template<typename RhsT>
01323     ResultBuilder& operator == ( RhsT const& rhs ) {
01324         return captureExpression<Internal::IsEqualTo>( rhs );
01325     }
01326 
01327     template<typename RhsT>
01328     ResultBuilder& operator != ( RhsT const& rhs ) {
01329         return captureExpression<Internal::IsNotEqualTo>( rhs );
01330     }
01331 
01332     template<typename RhsT>
01333     ResultBuilder& operator < ( RhsT const& rhs ) {
01334         return captureExpression<Internal::IsLessThan>( rhs );
01335     }
01336 
01337     template<typename RhsT>
01338     ResultBuilder& operator > ( RhsT const& rhs ) {
01339         return captureExpression<Internal::IsGreaterThan>( rhs );
01340     }
01341 
01342     template<typename RhsT>
01343     ResultBuilder& operator <= ( RhsT const& rhs ) {
01344         return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
01345     }
01346 
01347     template<typename RhsT>
01348     ResultBuilder& operator >= ( RhsT const& rhs ) {
01349         return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
01350     }
01351 
01352     ResultBuilder& operator == ( bool rhs ) {
01353         return captureExpression<Internal::IsEqualTo>( rhs );
01354     }
01355 
01356     ResultBuilder& operator != ( bool rhs ) {
01357         return captureExpression<Internal::IsNotEqualTo>( rhs );
01358     }
01359 
01360     void endExpression() {
01361         bool value = m_lhs ? true : false;
01362         m_rb
01363             .setLhs( Catch::toString( value ) )
01364             .setResultType( value )
01365             .endExpression();
01366     }
01367 
01368     // Only simple binary expressions are allowed on the LHS.
01369     // If more complex compositions are required then place the sub expression in parentheses
01370     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
01371     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
01372     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
01373     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
01374     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
01375     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
01376 
01377 private:
01378     template<Internal::Operator Op, typename RhsT>
01379     ResultBuilder& captureExpression( RhsT const& rhs ) {
01380         return m_rb
01381             .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
01382             .setLhs( Catch::toString( m_lhs ) )
01383             .setRhs( Catch::toString( rhs ) )
01384             .setOp( Internal::OperatorTraits<Op>::getName() );
01385     }
01386 
01387 private:
01388     ResultBuilder& m_rb;
01389     T m_lhs;
01390 };
01391 
01392 } // end namespace Catch
01393 
01394 
01395 namespace Catch {
01396 
01397     template<typename T>
01398     inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
01399         return ExpressionLhs<T const&>( *this, operand );
01400     }
01401 
01402     inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
01403         return ExpressionLhs<bool>( *this, value );
01404     }
01405 
01406 } // namespace Catch
01407 
01408 // #included from: catch_message.h
01409 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
01410 
01411 #include <string>
01412 
01413 namespace Catch {
01414 
01415     struct MessageInfo {
01416         MessageInfo(    std::string const& _macroName,
01417                         SourceLineInfo const& _lineInfo,
01418                         ResultWas::OfType _type );
01419 
01420         std::string macroName;
01421         SourceLineInfo lineInfo;
01422         ResultWas::OfType type;
01423         std::string message;
01424         unsigned int sequence;
01425 
01426         bool operator == ( MessageInfo const& other ) const {
01427             return sequence == other.sequence;
01428         }
01429         bool operator < ( MessageInfo const& other ) const {
01430             return sequence < other.sequence;
01431         }
01432     private:
01433         static unsigned int globalCount;
01434     };
01435 
01436     struct MessageBuilder {
01437         MessageBuilder( std::string const& macroName,
01438                         SourceLineInfo const& lineInfo,
01439                         ResultWas::OfType type )
01440         : m_info( macroName, lineInfo, type )
01441         {}
01442 
01443         template<typename T>
01444         MessageBuilder& operator << ( T const& value ) {
01445             m_stream << value;
01446             return *this;
01447         }
01448 
01449         MessageInfo m_info;
01450         std::ostringstream m_stream;
01451     };
01452 
01453     class ScopedMessage {
01454     public:
01455         ScopedMessage( MessageBuilder const& builder );
01456         ScopedMessage( ScopedMessage const& other );
01457         ~ScopedMessage();
01458 
01459         MessageInfo m_info;
01460     };
01461 
01462 } // end namespace Catch
01463 
01464 // #included from: catch_interfaces_capture.h
01465 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
01466 
01467 #include <string>
01468 
01469 namespace Catch {
01470 
01471     class TestCase;
01472     class AssertionResult;
01473     struct AssertionInfo;
01474     struct SectionInfo;
01475     struct MessageInfo;
01476     class ScopedMessageBuilder;
01477     struct Counts;
01478 
01479     struct IResultCapture {
01480 
01481         virtual ~IResultCapture();
01482 
01483         virtual void assertionEnded( AssertionResult const& result ) = 0;
01484         virtual bool sectionStarted(    SectionInfo const& sectionInfo,
01485                                         Counts& assertions ) = 0;
01486         virtual void sectionEnded( SectionInfo const& name, Counts const& assertions, double _durationInSeconds ) = 0;
01487         virtual void pushScopedMessage( MessageInfo const& message ) = 0;
01488         virtual void popScopedMessage( MessageInfo const& message ) = 0;
01489 
01490         virtual std::string getCurrentTestName() const = 0;
01491         virtual const AssertionResult* getLastResult() const = 0;
01492 
01493         virtual void handleFatalErrorCondition( std::string const& message ) = 0;
01494     };
01495 
01496     IResultCapture& getResultCapture();
01497 }
01498 
01499 // #included from: catch_debugger.h
01500 #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
01501 
01502 // #included from: catch_platform.h
01503 #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
01504 
01505 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
01506 #define CATCH_PLATFORM_MAC
01507 #elif  defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
01508 #define CATCH_PLATFORM_IPHONE
01509 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
01510 #define CATCH_PLATFORM_WINDOWS
01511 #endif
01512 
01513 #include <string>
01514 
01515 namespace Catch{
01516 
01517     bool isDebuggerActive();
01518     void writeToDebugConsole( std::string const& text );
01519 }
01520 
01521 #ifdef CATCH_PLATFORM_MAC
01522 
01523     // The following code snippet based on:
01524     // http://cocoawithlove.com/2008/03/break-into-debugger.html
01525     #ifdef DEBUG
01526         #if defined(__ppc64__) || defined(__ppc__)
01527             #define CATCH_BREAK_INTO_DEBUGGER() \
01528                 if( Catch::isDebuggerActive() ) { \
01529                     __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
01530                     : : : "memory","r0","r3","r4" ); \
01531                 }
01532         #else
01533             #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
01534         #endif
01535     #endif
01536 
01537 #elif defined(_MSC_VER)
01538     #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
01539 #elif defined(__MINGW32__)
01540     extern "C" __declspec(dllimport) void __stdcall DebugBreak();
01541     #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
01542 #endif
01543 
01544 #ifndef CATCH_BREAK_INTO_DEBUGGER
01545 #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
01546 #endif
01547 
01548 // #included from: catch_interfaces_runner.h
01549 #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
01550 
01551 namespace Catch {
01552     class TestCase;
01553 
01554     struct IRunner {
01555         virtual ~IRunner();
01556         virtual bool aborting() const = 0;
01557     };
01558 }
01559 
01561 // In the event of a failure works out if the debugger needs to be invoked
01562 // and/or an exception thrown and takes appropriate action.
01563 // This needs to be done as a macro so the debugger will stop in the user
01564 // source code rather than in Catch library code
01565 #define INTERNAL_CATCH_REACT( resultBuilder ) \
01566     if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
01567     resultBuilder.react();
01568 
01570 #define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
01571     do { \
01572         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
01573         try { \
01574             ( __catchResult <= expr ).endExpression(); \
01575         } \
01576         catch( ... ) { \
01577             __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
01578         } \
01579         INTERNAL_CATCH_REACT( __catchResult ) \
01580     } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
01581 
01583 #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
01584     INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
01585     if( Catch::getResultCapture().getLastResult()->succeeded() )
01586 
01588 #define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
01589     INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
01590     if( !Catch::getResultCapture().getLastResult()->succeeded() )
01591 
01593 #define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
01594     do { \
01595         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
01596         try { \
01597             expr; \
01598             __catchResult.captureResult( Catch::ResultWas::Ok ); \
01599         } \
01600         catch( ... ) { \
01601             __catchResult.useActiveException( resultDisposition ); \
01602         } \
01603         INTERNAL_CATCH_REACT( __catchResult ) \
01604     } while( Catch::alwaysFalse() )
01605 
01607 #define INTERNAL_CATCH_THROWS( expr, resultDisposition, macroName ) \
01608     do { \
01609         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
01610         if( __catchResult.allowThrows() ) \
01611             try { \
01612                 expr; \
01613                 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
01614             } \
01615             catch( ... ) { \
01616                 __catchResult.captureResult( Catch::ResultWas::Ok ); \
01617             } \
01618         else \
01619             __catchResult.captureResult( Catch::ResultWas::Ok ); \
01620         INTERNAL_CATCH_REACT( __catchResult ) \
01621     } while( Catch::alwaysFalse() )
01622 
01624 #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
01625     do { \
01626         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
01627         if( __catchResult.allowThrows() ) \
01628             try { \
01629                 expr; \
01630                 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
01631             } \
01632             catch( exceptionType ) { \
01633                 __catchResult.captureResult( Catch::ResultWas::Ok ); \
01634             } \
01635             catch( ... ) { \
01636                 __catchResult.useActiveException( resultDisposition ); \
01637             } \
01638         else \
01639             __catchResult.captureResult( Catch::ResultWas::Ok ); \
01640         INTERNAL_CATCH_REACT( __catchResult ) \
01641     } while( Catch::alwaysFalse() )
01642 
01644 #ifdef CATCH_CONFIG_VARIADIC_MACROS
01645     #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
01646         do { \
01647             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
01648             __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
01649             __catchResult.captureResult( messageType ); \
01650             INTERNAL_CATCH_REACT( __catchResult ) \
01651         } while( Catch::alwaysFalse() )
01652 #else
01653     #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
01654         do { \
01655             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
01656             __catchResult << log + ::Catch::StreamEndStop(); \
01657             __catchResult.captureResult( messageType ); \
01658             INTERNAL_CATCH_REACT( __catchResult ) \
01659         } while( Catch::alwaysFalse() )
01660 #endif
01661 
01663 #define INTERNAL_CATCH_INFO( log, macroName ) \
01664     Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
01665 
01667 #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
01668     do { \
01669         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \
01670         try { \
01671             std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \
01672             __catchResult \
01673                 .setLhs( Catch::toString( arg ) ) \
01674                 .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
01675                 .setOp( "matches" ) \
01676                 .setResultType( ::Catch::Matchers::matcher.match( arg ) ); \
01677             __catchResult.captureExpression(); \
01678         } catch( ... ) { \
01679             __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
01680         } \
01681         INTERNAL_CATCH_REACT( __catchResult ) \
01682     } while( Catch::alwaysFalse() )
01683 
01684 // #included from: internal/catch_section.h
01685 #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
01686 
01687 // #included from: catch_section_info.h
01688 #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
01689 
01690 namespace Catch {
01691 
01692     struct SectionInfo {
01693         SectionInfo
01694             (   SourceLineInfo const& _lineInfo,
01695                 std::string const& _name,
01696                 std::string const& _description = std::string() );
01697 
01698         std::string name;
01699         std::string description;
01700         SourceLineInfo lineInfo;
01701     };
01702 
01703 } // end namespace Catch
01704 
01705 // #included from: catch_totals.hpp
01706 #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
01707 
01708 #include <cstddef>
01709 
01710 namespace Catch {
01711 
01712     struct Counts {
01713         Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
01714 
01715         Counts operator - ( Counts const& other ) const {
01716             Counts diff;
01717             diff.passed = passed - other.passed;
01718             diff.failed = failed - other.failed;
01719             diff.failedButOk = failedButOk - other.failedButOk;
01720             return diff;
01721         }
01722         Counts& operator += ( Counts const& other ) {
01723             passed += other.passed;
01724             failed += other.failed;
01725             failedButOk += other.failedButOk;
01726             return *this;
01727         }
01728 
01729         std::size_t total() const {
01730             return passed + failed + failedButOk;
01731         }
01732         bool allPassed() const {
01733             return failed == 0 && failedButOk == 0;
01734         }
01735         bool allOk() const {
01736             return failed == 0;
01737         }
01738 
01739         std::size_t passed;
01740         std::size_t failed;
01741         std::size_t failedButOk;
01742     };
01743 
01744     struct Totals {
01745 
01746         Totals operator - ( Totals const& other ) const {
01747             Totals diff;
01748             diff.assertions = assertions - other.assertions;
01749             diff.testCases = testCases - other.testCases;
01750             return diff;
01751         }
01752 
01753         Totals delta( Totals const& prevTotals ) const {
01754             Totals diff = *this - prevTotals;
01755             if( diff.assertions.failed > 0 )
01756                 ++diff.testCases.failed;
01757             else if( diff.assertions.failedButOk > 0 )
01758                 ++diff.testCases.failedButOk;
01759             else
01760                 ++diff.testCases.passed;
01761             return diff;
01762         }
01763 
01764         Totals& operator += ( Totals const& other ) {
01765             assertions += other.assertions;
01766             testCases += other.testCases;
01767             return *this;
01768         }
01769 
01770         Counts assertions;
01771         Counts testCases;
01772     };
01773 }
01774 
01775 // #included from: catch_timer.h
01776 #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
01777 
01778 #ifdef CATCH_PLATFORM_WINDOWS
01779 typedef unsigned long long uint64_t;
01780 #else
01781 #include <stdint.h>
01782 #endif
01783 
01784 namespace Catch {
01785 
01786     class Timer {
01787     public:
01788         Timer() : m_ticks( 0 ) {}
01789         void start();
01790         unsigned int getElapsedMicroseconds() const;
01791         unsigned int getElapsedMilliseconds() const;
01792         double getElapsedSeconds() const;
01793 
01794     private:
01795         uint64_t m_ticks;
01796     };
01797 
01798 } // namespace Catch
01799 
01800 #include <string>
01801 
01802 namespace Catch {
01803 
01804     class Section : NonCopyable {
01805     public:
01806         Section( SectionInfo const& info );
01807         ~Section();
01808 
01809         // This indicates whether the section should be executed or not
01810         operator bool() const;
01811 
01812     private:
01813         SectionInfo m_info;
01814 
01815         std::string m_name;
01816         Counts m_assertions;
01817         bool m_sectionIncluded;
01818         Timer m_timer;
01819     };
01820 
01821 } // end namespace Catch
01822 
01823 #ifdef CATCH_CONFIG_VARIADIC_MACROS
01824     #define INTERNAL_CATCH_SECTION( ... ) \
01825         if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
01826 #else
01827     #define INTERNAL_CATCH_SECTION( name, desc ) \
01828         if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
01829 #endif
01830 
01831 // #included from: internal/catch_generators.hpp
01832 #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
01833 
01834 #include <iterator>
01835 #include <vector>
01836 #include <string>
01837 #include <stdlib.h>
01838 
01839 namespace Catch {
01840 
01841 template<typename T>
01842 struct IGenerator {
01843     virtual ~IGenerator() {}
01844     virtual T getValue( std::size_t index ) const = 0;
01845     virtual std::size_t size () const = 0;
01846 };
01847 
01848 template<typename T>
01849 class BetweenGenerator : public IGenerator<T> {
01850 public:
01851     BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
01852 
01853     virtual T getValue( std::size_t index ) const {
01854         return m_from+static_cast<int>( index );
01855     }
01856 
01857     virtual std::size_t size() const {
01858         return static_cast<std::size_t>( 1+m_to-m_from );
01859     }
01860 
01861 private:
01862 
01863     T m_from;
01864     T m_to;
01865 };
01866 
01867 template<typename T>
01868 class ValuesGenerator : public IGenerator<T> {
01869 public:
01870     ValuesGenerator(){}
01871 
01872     void add( T value ) {
01873         m_values.push_back( value );
01874     }
01875 
01876     virtual T getValue( std::size_t index ) const {
01877         return m_values[index];
01878     }
01879 
01880     virtual std::size_t size() const {
01881         return m_values.size();
01882     }
01883 
01884 private:
01885     std::vector<T> m_values;
01886 };
01887 
01888 template<typename T>
01889 class CompositeGenerator {
01890 public:
01891     CompositeGenerator() : m_totalSize( 0 ) {}
01892 
01893     // *** Move semantics, similar to auto_ptr ***
01894     CompositeGenerator( CompositeGenerator& other )
01895     :   m_fileInfo( other.m_fileInfo ),
01896         m_totalSize( 0 )
01897     {
01898         move( other );
01899     }
01900 
01901     CompositeGenerator& setFileInfo( const char* fileInfo ) {
01902         m_fileInfo = fileInfo;
01903         return *this;
01904     }
01905 
01906     ~CompositeGenerator() {
01907         deleteAll( m_composed );
01908     }
01909 
01910     operator T () const {
01911         size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
01912 
01913         typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
01914         typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
01915         for( size_t index = 0; it != itEnd; ++it )
01916         {
01917             const IGenerator<T>* generator = *it;
01918             if( overallIndex >= index && overallIndex < index + generator->size() )
01919             {
01920                 return generator->getValue( overallIndex-index );
01921             }
01922             index += generator->size();
01923         }
01924         CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
01925         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
01926     }
01927 
01928     void add( const IGenerator<T>* generator ) {
01929         m_totalSize += generator->size();
01930         m_composed.push_back( generator );
01931     }
01932 
01933     CompositeGenerator& then( CompositeGenerator& other ) {
01934         move( other );
01935         return *this;
01936     }
01937 
01938     CompositeGenerator& then( T value ) {
01939         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
01940         valuesGen->add( value );
01941         add( valuesGen );
01942         return *this;
01943     }
01944 
01945 private:
01946 
01947     void move( CompositeGenerator& other ) {
01948         std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
01949         m_totalSize += other.m_totalSize;
01950         other.m_composed.clear();
01951     }
01952 
01953     std::vector<const IGenerator<T>*> m_composed;
01954     std::string m_fileInfo;
01955     size_t m_totalSize;
01956 };
01957 
01958 namespace Generators
01959 {
01960     template<typename T>
01961     CompositeGenerator<T> between( T from, T to ) {
01962         CompositeGenerator<T> generators;
01963         generators.add( new BetweenGenerator<T>( from, to ) );
01964         return generators;
01965     }
01966 
01967     template<typename T>
01968     CompositeGenerator<T> values( T val1, T val2 ) {
01969         CompositeGenerator<T> generators;
01970         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
01971         valuesGen->add( val1 );
01972         valuesGen->add( val2 );
01973         generators.add( valuesGen );
01974         return generators;
01975     }
01976 
01977     template<typename T>
01978     CompositeGenerator<T> values( T val1, T val2, T val3 ){
01979         CompositeGenerator<T> generators;
01980         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
01981         valuesGen->add( val1 );
01982         valuesGen->add( val2 );
01983         valuesGen->add( val3 );
01984         generators.add( valuesGen );
01985         return generators;
01986     }
01987 
01988     template<typename T>
01989     CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
01990         CompositeGenerator<T> generators;
01991         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
01992         valuesGen->add( val1 );
01993         valuesGen->add( val2 );
01994         valuesGen->add( val3 );
01995         valuesGen->add( val4 );
01996         generators.add( valuesGen );
01997         return generators;
01998     }
01999 
02000 } // end namespace Generators
02001 
02002 using namespace Generators;
02003 
02004 } // end namespace Catch
02005 
02006 #define INTERNAL_CATCH_LINESTR2( line ) #line
02007 #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
02008 
02009 #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
02010 
02011 // #included from: internal/catch_interfaces_exception.h
02012 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
02013 
02014 #include <string>
02015 // #included from: catch_interfaces_registry_hub.h
02016 #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
02017 
02018 #include <string>
02019 
02020 namespace Catch {
02021 
02022     class TestCase;
02023     struct ITestCaseRegistry;
02024     struct IExceptionTranslatorRegistry;
02025     struct IExceptionTranslator;
02026     struct IReporterRegistry;
02027     struct IReporterFactory;
02028 
02029     struct IRegistryHub {
02030         virtual ~IRegistryHub();
02031 
02032         virtual IReporterRegistry const& getReporterRegistry() const = 0;
02033         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
02034         virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
02035     };
02036 
02037     struct IMutableRegistryHub {
02038         virtual ~IMutableRegistryHub();
02039         virtual void registerReporter( std::string const& name, IReporterFactory* factory ) = 0;
02040         virtual void registerTest( TestCase const& testInfo ) = 0;
02041         virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
02042     };
02043 
02044     IRegistryHub& getRegistryHub();
02045     IMutableRegistryHub& getMutableRegistryHub();
02046     void cleanUp();
02047     std::string translateActiveException();
02048 
02049 }
02050 
02051 
02052 namespace Catch {
02053 
02054     typedef std::string(*exceptionTranslateFunction)();
02055 
02056     struct IExceptionTranslator {
02057         virtual ~IExceptionTranslator();
02058         virtual std::string translate() const = 0;
02059     };
02060 
02061     struct IExceptionTranslatorRegistry {
02062         virtual ~IExceptionTranslatorRegistry();
02063 
02064         virtual std::string translateActiveException() const = 0;
02065     };
02066 
02067     class ExceptionTranslatorRegistrar {
02068         template<typename T>
02069         class ExceptionTranslator : public IExceptionTranslator {
02070         public:
02071 
02072             ExceptionTranslator( std::string(*translateFunction)( T& ) )
02073             : m_translateFunction( translateFunction )
02074             {}
02075 
02076             virtual std::string translate() const {
02077                 try {
02078                     throw;
02079                 }
02080                 catch( T& ex ) {
02081                     return m_translateFunction( ex );
02082                 }
02083             }
02084 
02085         protected:
02086             std::string(*m_translateFunction)( T& );
02087         };
02088 
02089     public:
02090         template<typename T>
02091         ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
02092             getMutableRegistryHub().registerTranslator
02093                 ( new ExceptionTranslator<T>( translateFunction ) );
02094         }
02095     };
02096 }
02097 
02099 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
02100     static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
02101     namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
02102     static std::string INTERNAL_CATCH_UNIQUE_NAME(  catch_internal_ExceptionTranslator )( signature )
02103 
02104 // #included from: internal/catch_approx.hpp
02105 #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
02106 
02107 #include <cmath>
02108 #include <limits>
02109 
02110 namespace Catch {
02111 namespace Detail {
02112 
02113     class Approx {
02114     public:
02115         explicit Approx ( double value )
02116         :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
02117             m_scale( 1.0 ),
02118             m_value( value )
02119         {}
02120 
02121         Approx( Approx const& other )
02122         :   m_epsilon( other.m_epsilon ),
02123             m_scale( other.m_scale ),
02124             m_value( other.m_value )
02125         {}
02126 
02127         static Approx custom() {
02128             return Approx( 0 );
02129         }
02130 
02131         Approx operator()( double value ) {
02132             Approx approx( value );
02133             approx.epsilon( m_epsilon );
02134             approx.scale( m_scale );
02135             return approx;
02136         }
02137 
02138         friend bool operator == ( double lhs, Approx const& rhs ) {
02139             // Thanks to Richard Harris for his help refining this formula
02140             return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
02141         }
02142 
02143         friend bool operator == ( Approx const& lhs, double rhs ) {
02144             return operator==( rhs, lhs );
02145         }
02146 
02147         friend bool operator != ( double lhs, Approx const& rhs ) {
02148             return !operator==( lhs, rhs );
02149         }
02150 
02151         friend bool operator != ( Approx const& lhs, double rhs ) {
02152             return !operator==( rhs, lhs );
02153         }
02154 
02155         Approx& epsilon( double newEpsilon ) {
02156             m_epsilon = newEpsilon;
02157             return *this;
02158         }
02159 
02160         Approx& scale( double newScale ) {
02161             m_scale = newScale;
02162             return *this;
02163         }
02164 
02165         std::string toString() const {
02166             std::ostringstream oss;
02167             oss << "Approx( " << Catch::toString( m_value ) << " )";
02168             return oss.str();
02169         }
02170 
02171     private:
02172         double m_epsilon;
02173         double m_scale;
02174         double m_value;
02175     };
02176 }
02177 
02178 template<>
02179 inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
02180     return value.toString();
02181 }
02182 
02183 } // end namespace Catch
02184 
02185 // #included from: internal/catch_matchers.hpp
02186 #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
02187 
02188 namespace Catch {
02189 namespace Matchers {
02190     namespace Impl {
02191 
02192     template<typename ExpressionT>
02193     struct Matcher : SharedImpl<IShared>
02194     {
02195         typedef ExpressionT ExpressionType;
02196 
02197         virtual ~Matcher() {}
02198         virtual Ptr<Matcher> clone() const = 0;
02199         virtual bool match( ExpressionT const& expr ) const = 0;
02200         virtual std::string toString() const = 0;
02201     };
02202 
02203     template<typename DerivedT, typename ExpressionT>
02204     struct MatcherImpl : Matcher<ExpressionT> {
02205 
02206         virtual Ptr<Matcher<ExpressionT> > clone() const {
02207             return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
02208         }
02209     };
02210 
02211     namespace Generic {
02212 
02213         template<typename ExpressionT>
02214         class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
02215         public:
02216 
02217             AllOf() {}
02218             AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
02219 
02220             AllOf& add( Matcher<ExpressionT> const& matcher ) {
02221                 m_matchers.push_back( matcher.clone() );
02222                 return *this;
02223             }
02224             virtual bool match( ExpressionT const& expr ) const
02225             {
02226                 for( std::size_t i = 0; i < m_matchers.size(); ++i )
02227                     if( !m_matchers[i]->match( expr ) )
02228                         return false;
02229                 return true;
02230             }
02231             virtual std::string toString() const {
02232                 std::ostringstream oss;
02233                 oss << "( ";
02234                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
02235                     if( i != 0 )
02236                         oss << " and ";
02237                     oss << m_matchers[i]->toString();
02238                 }
02239                 oss << " )";
02240                 return oss.str();
02241             }
02242 
02243         private:
02244             std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
02245         };
02246 
02247         template<typename ExpressionT>
02248         class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
02249         public:
02250 
02251             AnyOf() {}
02252             AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
02253 
02254             AnyOf& add( Matcher<ExpressionT> const& matcher ) {
02255                 m_matchers.push_back( matcher.clone() );
02256                 return *this;
02257             }
02258             virtual bool match( ExpressionT const& expr ) const
02259             {
02260                 for( std::size_t i = 0; i < m_matchers.size(); ++i )
02261                     if( m_matchers[i]->match( expr ) )
02262                         return true;
02263                 return false;
02264             }
02265             virtual std::string toString() const {
02266                 std::ostringstream oss;
02267                 oss << "( ";
02268                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
02269                     if( i != 0 )
02270                         oss << " or ";
02271                     oss << m_matchers[i]->toString();
02272                 }
02273                 oss << " )";
02274                 return oss.str();
02275             }
02276 
02277         private:
02278             std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
02279         };
02280 
02281     }
02282 
02283     namespace StdString {
02284 
02285         inline std::string makeString( std::string const& str ) { return str; }
02286         inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
02287 
02288         struct Equals : MatcherImpl<Equals, std::string> {
02289             Equals( std::string const& str ) : m_str( str ){}
02290             Equals( Equals const& other ) : m_str( other.m_str ){}
02291 
02292             virtual ~Equals();
02293 
02294             virtual bool match( std::string const& expr ) const {
02295                 return m_str == expr;
02296             }
02297             virtual std::string toString() const {
02298                 return "equals: \"" + m_str + "\"";
02299             }
02300 
02301             std::string m_str;
02302         };
02303 
02304         struct Contains : MatcherImpl<Contains, std::string> {
02305             Contains( std::string const& substr ) : m_substr( substr ){}
02306             Contains( Contains const& other ) : m_substr( other.m_substr ){}
02307 
02308             virtual ~Contains();
02309 
02310             virtual bool match( std::string const& expr ) const {
02311                 return expr.find( m_substr ) != std::string::npos;
02312             }
02313             virtual std::string toString() const {
02314                 return "contains: \"" + m_substr + "\"";
02315             }
02316 
02317             std::string m_substr;
02318         };
02319 
02320         struct StartsWith : MatcherImpl<StartsWith, std::string> {
02321             StartsWith( std::string const& substr ) : m_substr( substr ){}
02322             StartsWith( StartsWith const& other ) : m_substr( other.m_substr ){}
02323 
02324             virtual ~StartsWith();
02325 
02326             virtual bool match( std::string const& expr ) const {
02327                 return expr.find( m_substr ) == 0;
02328             }
02329             virtual std::string toString() const {
02330                 return "starts with: \"" + m_substr + "\"";
02331             }
02332 
02333             std::string m_substr;
02334         };
02335 
02336         struct EndsWith : MatcherImpl<EndsWith, std::string> {
02337             EndsWith( std::string const& substr ) : m_substr( substr ){}
02338             EndsWith( EndsWith const& other ) : m_substr( other.m_substr ){}
02339 
02340             virtual ~EndsWith();
02341 
02342             virtual bool match( std::string const& expr ) const {
02343                 return expr.find( m_substr ) == expr.size() - m_substr.size();
02344             }
02345             virtual std::string toString() const {
02346                 return "ends with: \"" + m_substr + "\"";
02347             }
02348 
02349             std::string m_substr;
02350         };
02351     } // namespace StdString
02352     } // namespace Impl
02353 
02354     // The following functions create the actual matcher objects.
02355     // This allows the types to be inferred
02356     template<typename ExpressionT>
02357     inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
02358                                                     Impl::Matcher<ExpressionT> const& m2 ) {
02359         return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
02360     }
02361     template<typename ExpressionT>
02362     inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
02363                                                     Impl::Matcher<ExpressionT> const& m2,
02364                                                     Impl::Matcher<ExpressionT> const& m3 ) {
02365         return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
02366     }
02367     template<typename ExpressionT>
02368     inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
02369                                                     Impl::Matcher<ExpressionT> const& m2 ) {
02370         return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
02371     }
02372     template<typename ExpressionT>
02373     inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
02374                                                     Impl::Matcher<ExpressionT> const& m2,
02375                                                     Impl::Matcher<ExpressionT> const& m3 ) {
02376         return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
02377     }
02378 
02379     inline Impl::StdString::Equals      Equals( std::string const& str ) {
02380         return Impl::StdString::Equals( str );
02381     }
02382     inline Impl::StdString::Equals      Equals( const char* str ) {
02383         return Impl::StdString::Equals( Impl::StdString::makeString( str ) );
02384     }
02385     inline Impl::StdString::Contains    Contains( std::string const& substr ) {
02386         return Impl::StdString::Contains( substr );
02387     }
02388     inline Impl::StdString::Contains    Contains( const char* substr ) {
02389         return Impl::StdString::Contains( Impl::StdString::makeString( substr ) );
02390     }
02391     inline Impl::StdString::StartsWith  StartsWith( std::string const& substr ) {
02392         return Impl::StdString::StartsWith( substr );
02393     }
02394     inline Impl::StdString::StartsWith  StartsWith( const char* substr ) {
02395         return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
02396     }
02397     inline Impl::StdString::EndsWith    EndsWith( std::string const& substr ) {
02398         return Impl::StdString::EndsWith( substr );
02399     }
02400     inline Impl::StdString::EndsWith    EndsWith( const char* substr ) {
02401         return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
02402     }
02403 
02404 } // namespace Matchers
02405 
02406 using namespace Matchers;
02407 
02408 } // namespace Catch
02409 
02410 // #included from: internal/catch_interfaces_tag_alias_registry.h
02411 #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
02412 
02413 // #included from: catch_tag_alias.h
02414 #define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
02415 
02416 #include <string>
02417 
02418 namespace Catch {
02419 
02420     struct TagAlias {
02421         TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
02422 
02423         std::string tag;
02424         SourceLineInfo lineInfo;
02425     };
02426 
02427     struct RegistrarForTagAliases {
02428         RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
02429     };
02430 
02431 } // end namespace Catch
02432 
02433 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
02434 // #included from: catch_option.hpp
02435 #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
02436 
02437 namespace Catch {
02438 
02439     // An optional type
02440     template<typename T>
02441     class Option {
02442     public:
02443         Option() : nullableValue( NULL ) {}
02444         Option( T const& _value )
02445         : nullableValue( new( storage ) T( _value ) )
02446         {}
02447         Option( Option const& _other )
02448         : nullableValue( _other ? new( storage ) T( *_other ) : NULL )
02449         {}
02450 
02451         ~Option() {
02452             reset();
02453         }
02454 
02455         Option& operator= ( Option const& _other ) {
02456             if( &_other != this ) {
02457                 reset();
02458                 if( _other )
02459                     nullableValue = new( storage ) T( *_other );
02460             }
02461             return *this;
02462         }
02463         Option& operator = ( T const& _value ) {
02464             reset();
02465             nullableValue = new( storage ) T( _value );
02466             return *this;
02467         }
02468 
02469         void reset() {
02470             if( nullableValue )
02471                 nullableValue->~T();
02472             nullableValue = NULL;
02473         }
02474 
02475         T& operator*() { return *nullableValue; }
02476         T const& operator*() const { return *nullableValue; }
02477         T* operator->() { return nullableValue; }
02478         const T* operator->() const { return nullableValue; }
02479 
02480         T valueOr( T const& defaultValue ) const {
02481             return nullableValue ? *nullableValue : defaultValue;
02482         }
02483 
02484         bool some() const { return nullableValue != NULL; }
02485         bool none() const { return nullableValue == NULL; }
02486 
02487         bool operator !() const { return nullableValue == NULL; }
02488         operator SafeBool::type() const {
02489             return SafeBool::makeSafe( some() );
02490         }
02491 
02492     private:
02493         T* nullableValue;
02494         char storage[sizeof(T)];
02495     };
02496 
02497 } // end namespace Catch
02498 
02499 namespace Catch {
02500 
02501     struct ITagAliasRegistry {
02502         virtual ~ITagAliasRegistry();
02503         virtual Option<TagAlias> find( std::string const& alias ) const = 0;
02504         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
02505 
02506         static ITagAliasRegistry const& get();
02507     };
02508 
02509 } // end namespace Catch
02510 
02511 // These files are included here so the single_include script doesn't put them
02512 // in the conditionally compiled sections
02513 // #included from: internal/catch_test_case_info.h
02514 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
02515 
02516 #include <string>
02517 #include <set>
02518 
02519 #ifdef __clang__
02520 #pragma clang diagnostic push
02521 #pragma clang diagnostic ignored "-Wpadded"
02522 #endif
02523 
02524 namespace Catch {
02525 
02526     struct ITestCase;
02527 
02528     struct TestCaseInfo {
02529         enum SpecialProperties{
02530             None = 0,
02531             IsHidden = 1 << 1,
02532             ShouldFail = 1 << 2,
02533             MayFail = 1 << 3,
02534             Throws = 1 << 4
02535         };
02536 
02537         TestCaseInfo(   std::string const& _name,
02538                         std::string const& _className,
02539                         std::string const& _description,
02540                         std::set<std::string> const& _tags,
02541                         SourceLineInfo const& _lineInfo );
02542 
02543         TestCaseInfo( TestCaseInfo const& other );
02544 
02545         bool isHidden() const;
02546         bool throws() const;
02547         bool okToFail() const;
02548         bool expectedToFail() const;
02549 
02550         std::string name;
02551         std::string className;
02552         std::string description;
02553         std::set<std::string> tags;
02554         std::set<std::string> lcaseTags;
02555         std::string tagsAsString;
02556         SourceLineInfo lineInfo;
02557         SpecialProperties properties;
02558     };
02559 
02560     class TestCase : public TestCaseInfo {
02561     public:
02562 
02563         TestCase( ITestCase* testCase, TestCaseInfo const& info );
02564         TestCase( TestCase const& other );
02565 
02566         TestCase withName( std::string const& _newName ) const;
02567 
02568         void invoke() const;
02569 
02570         TestCaseInfo const& getTestCaseInfo() const;
02571 
02572         void swap( TestCase& other );
02573         bool operator == ( TestCase const& other ) const;
02574         bool operator < ( TestCase const& other ) const;
02575         TestCase& operator = ( TestCase const& other );
02576 
02577     private:
02578         Ptr<ITestCase> test;
02579     };
02580 
02581     TestCase makeTestCase(  ITestCase* testCase,
02582                             std::string const& className,
02583                             std::string const& name,
02584                             std::string const& description,
02585                             SourceLineInfo const& lineInfo );
02586 }
02587 
02588 #ifdef __clang__
02589 #pragma clang diagnostic pop
02590 #endif
02591 
02592 
02593 #ifdef __OBJC__
02594 // #included from: internal/catch_objc.hpp
02595 #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
02596 
02597 #import <objc/runtime.h>
02598 
02599 #include <string>
02600 
02601 // NB. Any general catch headers included here must be included
02602 // in catch.hpp first to make sure they are included by the single
02603 // header for non obj-usage
02604 
02606 // This protocol is really only here for (self) documenting purposes, since
02607 // all its methods are optional.
02608 @protocol OcFixture
02609 
02610 @optional
02611 
02612 -(void) setUp;
02613 -(void) tearDown;
02614 
02615 @end
02616 
02617 namespace Catch {
02618 
02619     class OcMethod : public SharedImpl<ITestCase> {
02620 
02621     public:
02622         OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
02623 
02624         virtual void invoke() const {
02625             id obj = [[m_cls alloc] init];
02626 
02627             performOptionalSelector( obj, @selector(setUp)  );
02628             performOptionalSelector( obj, m_sel );
02629             performOptionalSelector( obj, @selector(tearDown)  );
02630 
02631             arcSafeRelease( obj );
02632         }
02633     private:
02634         virtual ~OcMethod() {}
02635 
02636         Class m_cls;
02637         SEL m_sel;
02638     };
02639 
02640     namespace Detail{
02641 
02642         inline std::string getAnnotation(   Class cls,
02643                                             std::string const& annotationName,
02644                                             std::string const& testCaseName ) {
02645             NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
02646             SEL sel = NSSelectorFromString( selStr );
02647             arcSafeRelease( selStr );
02648             id value = performOptionalSelector( cls, sel );
02649             if( value )
02650                 return [(NSString*)value UTF8String];
02651             return "";
02652         }
02653     }
02654 
02655     inline size_t registerTestMethods() {
02656         size_t noTestMethods = 0;
02657         int noClasses = objc_getClassList( NULL, 0 );
02658 
02659         Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
02660         objc_getClassList( classes, noClasses );
02661 
02662         for( int c = 0; c < noClasses; c++ ) {
02663             Class cls = classes[c];
02664             {
02665                 u_int count;
02666                 Method* methods = class_copyMethodList( cls, &count );
02667                 for( u_int m = 0; m < count ; m++ ) {
02668                     SEL selector = method_getName(methods[m]);
02669                     std::string methodName = sel_getName(selector);
02670                     if( startsWith( methodName, "Catch_TestCase_" ) ) {
02671                         std::string testCaseName = methodName.substr( 15 );
02672                         std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
02673                         std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
02674                         const char* className = class_getName( cls );
02675 
02676                         getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
02677                         noTestMethods++;
02678                     }
02679                 }
02680                 free(methods);
02681             }
02682         }
02683         return noTestMethods;
02684     }
02685 
02686     namespace Matchers {
02687         namespace Impl {
02688         namespace NSStringMatchers {
02689 
02690             template<typename MatcherT>
02691             struct StringHolder : MatcherImpl<MatcherT, NSString*>{
02692                 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
02693                 StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
02694                 StringHolder() {
02695                     arcSafeRelease( m_substr );
02696                 }
02697 
02698                 NSString* m_substr;
02699             };
02700 
02701             struct Equals : StringHolder<Equals> {
02702                 Equals( NSString* substr ) : StringHolder( substr ){}
02703 
02704                 virtual bool match( ExpressionType const& str ) const {
02705                     return  (str != nil || m_substr == nil ) &&
02706                             [str isEqualToString:m_substr];
02707                 }
02708 
02709                 virtual std::string toString() const {
02710                     return "equals string: " + Catch::toString( m_substr );
02711                 }
02712             };
02713 
02714             struct Contains : StringHolder<Contains> {
02715                 Contains( NSString* substr ) : StringHolder( substr ){}
02716 
02717                 virtual bool match( ExpressionType const& str ) const {
02718                     return  (str != nil || m_substr == nil ) &&
02719                             [str rangeOfString:m_substr].location != NSNotFound;
02720                 }
02721 
02722                 virtual std::string toString() const {
02723                     return "contains string: " + Catch::toString( m_substr );
02724                 }
02725             };
02726 
02727             struct StartsWith : StringHolder<StartsWith> {
02728                 StartsWith( NSString* substr ) : StringHolder( substr ){}
02729 
02730                 virtual bool match( ExpressionType const& str ) const {
02731                     return  (str != nil || m_substr == nil ) &&
02732                             [str rangeOfString:m_substr].location == 0;
02733                 }
02734 
02735                 virtual std::string toString() const {
02736                     return "starts with: " + Catch::toString( m_substr );
02737                 }
02738             };
02739             struct EndsWith : StringHolder<EndsWith> {
02740                 EndsWith( NSString* substr ) : StringHolder( substr ){}
02741 
02742                 virtual bool match( ExpressionType const& str ) const {
02743                     return  (str != nil || m_substr == nil ) &&
02744                             [str rangeOfString:m_substr].location == [str length] - [m_substr length];
02745                 }
02746 
02747                 virtual std::string toString() const {
02748                     return "ends with: " + Catch::toString( m_substr );
02749                 }
02750             };
02751 
02752         } // namespace NSStringMatchers
02753         } // namespace Impl
02754 
02755         inline Impl::NSStringMatchers::Equals
02756             Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
02757 
02758         inline Impl::NSStringMatchers::Contains
02759             Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
02760 
02761         inline Impl::NSStringMatchers::StartsWith
02762             StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
02763 
02764         inline Impl::NSStringMatchers::EndsWith
02765             EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
02766 
02767     } // namespace Matchers
02768 
02769     using namespace Matchers;
02770 
02771 } // namespace Catch
02772 
02774 #define OC_TEST_CASE( name, desc )\
02775 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
02776 {\
02777 return @ name; \
02778 }\
02779 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
02780 { \
02781 return @ desc; \
02782 } \
02783 -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
02784 
02785 #endif
02786 
02787 #ifdef CATCH_IMPL
02788 // #included from: internal/catch_impl.hpp
02789 #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
02790 
02791 // Collect all the implementation files together here
02792 // These are the equivalent of what would usually be cpp files
02793 
02794 #ifdef __clang__
02795 #pragma clang diagnostic push
02796 #pragma clang diagnostic ignored "-Wweak-vtables"
02797 #endif
02798 
02799 // #included from: ../catch_runner.hpp
02800 #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
02801 
02802 // #included from: internal/catch_commandline.hpp
02803 #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
02804 
02805 // #included from: catch_config.hpp
02806 #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
02807 
02808 // #included from: catch_test_spec_parser.hpp
02809 #define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
02810 
02811 #ifdef __clang__
02812 #pragma clang diagnostic push
02813 #pragma clang diagnostic ignored "-Wpadded"
02814 #endif
02815 
02816 // #included from: catch_test_spec.hpp
02817 #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
02818 
02819 #ifdef __clang__
02820 #pragma clang diagnostic push
02821 #pragma clang diagnostic ignored "-Wpadded"
02822 #endif
02823 
02824 #include <string>
02825 #include <vector>
02826 
02827 namespace Catch {
02828 
02829     class TestSpec {
02830         struct Pattern : SharedImpl<> {
02831             virtual ~Pattern();
02832             virtual bool matches( TestCaseInfo const& testCase ) const = 0;
02833         };
02834         class NamePattern : public Pattern {
02835             enum WildcardPosition {
02836                 NoWildcard = 0,
02837                 WildcardAtStart = 1,
02838                 WildcardAtEnd = 2,
02839                 WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
02840             };
02841 
02842         public:
02843             NamePattern( std::string const& name ) : m_name( toLower( name ) ), m_wildcard( NoWildcard ) {
02844                 if( startsWith( m_name, "*" ) ) {
02845                     m_name = m_name.substr( 1 );
02846                     m_wildcard = WildcardAtStart;
02847                 }
02848                 if( endsWith( m_name, "*" ) ) {
02849                     m_name = m_name.substr( 0, m_name.size()-1 );
02850                     m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
02851                 }
02852             }
02853             virtual ~NamePattern();
02854             virtual bool matches( TestCaseInfo const& testCase ) const {
02855                 switch( m_wildcard ) {
02856                     case NoWildcard:
02857                         return m_name == toLower( testCase.name );
02858                     case WildcardAtStart:
02859                         return endsWith( toLower( testCase.name ), m_name );
02860                     case WildcardAtEnd:
02861                         return startsWith( toLower( testCase.name ), m_name );
02862                     case WildcardAtBothEnds:
02863                         return contains( toLower( testCase.name ), m_name );
02864                 }
02865 
02866 #ifdef __clang__
02867 #pragma clang diagnostic push
02868 #pragma clang diagnostic ignored "-Wunreachable-code"
02869 #endif
02870                 throw std::logic_error( "Unknown enum" );
02871 #ifdef __clang__
02872 #pragma clang diagnostic pop
02873 #endif
02874             }
02875         private:
02876             std::string m_name;
02877             WildcardPosition m_wildcard;
02878         };
02879         class TagPattern : public Pattern {
02880         public:
02881             TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
02882             virtual ~TagPattern();
02883             virtual bool matches( TestCaseInfo const& testCase ) const {
02884                 return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
02885             }
02886         private:
02887             std::string m_tag;
02888         };
02889         class ExcludedPattern : public Pattern {
02890         public:
02891             ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
02892             virtual ~ExcludedPattern();
02893             virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
02894         private:
02895             Ptr<Pattern> m_underlyingPattern;
02896         };
02897 
02898         struct Filter {
02899             std::vector<Ptr<Pattern> > m_patterns;
02900 
02901             bool matches( TestCaseInfo const& testCase ) const {
02902                 // All patterns in a filter must match for the filter to be a match
02903                 for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
02904                     if( !(*it)->matches( testCase ) )
02905                         return false;
02906                     return true;
02907             }
02908         };
02909 
02910     public:
02911         bool hasFilters() const {
02912             return !m_filters.empty();
02913         }
02914         bool matches( TestCaseInfo const& testCase ) const {
02915             // A TestSpec matches if any filter matches
02916             for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
02917                 if( it->matches( testCase ) )
02918                     return true;
02919             return false;
02920         }
02921 
02922     private:
02923         std::vector<Filter> m_filters;
02924 
02925         friend class TestSpecParser;
02926     };
02927 }
02928 
02929 #ifdef __clang__
02930 #pragma clang diagnostic pop
02931 #endif
02932 
02933 namespace Catch {
02934 
02935     class TestSpecParser {
02936         enum Mode{ None, Name, QuotedName, Tag };
02937         Mode m_mode;
02938         bool m_exclusion;
02939         std::size_t m_start, m_pos;
02940         std::string m_arg;
02941         TestSpec::Filter m_currentFilter;
02942         TestSpec m_testSpec;
02943         ITagAliasRegistry const* m_tagAliases;
02944 
02945     public:
02946         TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
02947 
02948         TestSpecParser& parse( std::string const& arg ) {
02949             m_mode = None;
02950             m_exclusion = false;
02951             m_start = std::string::npos;
02952             m_arg = m_tagAliases->expandAliases( arg );
02953             for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
02954                 visitChar( m_arg[m_pos] );
02955             if( m_mode == Name )
02956                 addPattern<TestSpec::NamePattern>();
02957             return *this;
02958         }
02959         TestSpec testSpec() {
02960             addFilter();
02961             return m_testSpec;
02962         }
02963     private:
02964         void visitChar( char c ) {
02965             if( m_mode == None ) {
02966                 switch( c ) {
02967                 case ' ': return;
02968                 case '~': m_exclusion = true; return;
02969                 case '[': return startNewMode( Tag, ++m_pos );
02970                 case '"': return startNewMode( QuotedName, ++m_pos );
02971                 default: startNewMode( Name, m_pos ); break;
02972                 }
02973             }
02974             if( m_mode == Name ) {
02975                 if( c == ',' ) {
02976                     addPattern<TestSpec::NamePattern>();
02977                     addFilter();
02978                 }
02979                 else if( c == '[' ) {
02980                     if( subString() == "exclude:" )
02981                         m_exclusion = true;
02982                     else
02983                         addPattern<TestSpec::NamePattern>();
02984                     startNewMode( Tag, ++m_pos );
02985                 }
02986             }
02987             else if( m_mode == QuotedName && c == '"' )
02988                 addPattern<TestSpec::NamePattern>();
02989             else if( m_mode == Tag && c == ']' )
02990                 addPattern<TestSpec::TagPattern>();
02991         }
02992         void startNewMode( Mode mode, std::size_t start ) {
02993             m_mode = mode;
02994             m_start = start;
02995         }
02996         std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
02997         template<typename T>
02998         void addPattern() {
02999             std::string token = subString();
03000             if( startsWith( token, "exclude:" ) ) {
03001                 m_exclusion = true;
03002                 token = token.substr( 8 );
03003             }
03004             if( !token.empty() ) {
03005                 Ptr<TestSpec::Pattern> pattern = new T( token );
03006                 if( m_exclusion )
03007                     pattern = new TestSpec::ExcludedPattern( pattern );
03008                 m_currentFilter.m_patterns.push_back( pattern );
03009             }
03010             m_exclusion = false;
03011             m_mode = None;
03012         }
03013         void addFilter() {
03014             if( !m_currentFilter.m_patterns.empty() ) {
03015                 m_testSpec.m_filters.push_back( m_currentFilter );
03016                 m_currentFilter = TestSpec::Filter();
03017             }
03018         }
03019     };
03020     inline TestSpec parseTestSpec( std::string const& arg ) {
03021         return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
03022     }
03023 
03024 } // namespace Catch
03025 
03026 #ifdef __clang__
03027 #pragma clang diagnostic pop
03028 #endif
03029 
03030 // #included from: catch_interfaces_config.h
03031 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
03032 
03033 #include <iostream>
03034 #include <string>
03035 #include <vector>
03036 
03037 namespace Catch {
03038 
03039     struct Verbosity { enum Level {
03040         NoOutput = 0,
03041         Quiet,
03042         Normal
03043     }; };
03044 
03045     struct WarnAbout { enum What {
03046         Nothing = 0x00,
03047         NoAssertions = 0x01
03048     }; };
03049 
03050     struct ShowDurations { enum OrNot {
03051         DefaultForReporter,
03052         Always,
03053         Never
03054     }; };
03055     struct RunTests { enum InWhatOrder {
03056         InDeclarationOrder,
03057         InLexicographicalOrder,
03058         InRandomOrder
03059     }; };
03060 
03061     class TestSpec;
03062 
03063     struct IConfig : IShared {
03064 
03065         virtual ~IConfig();
03066 
03067         virtual bool allowThrows() const = 0;
03068         virtual std::ostream& stream() const = 0;
03069         virtual std::string name() const = 0;
03070         virtual bool includeSuccessfulResults() const = 0;
03071         virtual bool shouldDebugBreak() const = 0;
03072         virtual bool warnAboutMissingAssertions() const = 0;
03073         virtual int abortAfter() const = 0;
03074         virtual bool showInvisibles() const = 0;
03075         virtual ShowDurations::OrNot showDurations() const = 0;
03076         virtual TestSpec const& testSpec() const = 0;
03077         virtual RunTests::InWhatOrder runOrder() const = 0;
03078         virtual unsigned int rngSeed() const = 0;
03079         virtual bool forceColour() const = 0;
03080     };
03081 }
03082 
03083 // #included from: catch_stream.h
03084 #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
03085 
03086 #include <streambuf>
03087 
03088 #ifdef __clang__
03089 #pragma clang diagnostic ignored "-Wpadded"
03090 #endif
03091 
03092 namespace Catch {
03093 
03094     class Stream {
03095     public:
03096         Stream();
03097         Stream( std::streambuf* _streamBuf, bool _isOwned );
03098         void release();
03099 
03100         std::streambuf* streamBuf;
03101 
03102     private:
03103         bool isOwned;
03104     };
03105 
03106     std::ostream& cout();
03107     std::ostream& cerr();
03108 }
03109 
03110 #include <memory>
03111 #include <vector>
03112 #include <string>
03113 #include <iostream>
03114 #include <ctime>
03115 
03116 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
03117 #define CATCH_CONFIG_CONSOLE_WIDTH 80
03118 #endif
03119 
03120 namespace Catch {
03121 
03122     struct ConfigData {
03123 
03124         ConfigData()
03125         :   listTests( false ),
03126             listTags( false ),
03127             listReporters( false ),
03128             listTestNamesOnly( false ),
03129             showSuccessfulTests( false ),
03130             shouldDebugBreak( false ),
03131             noThrow( false ),
03132             showHelp( false ),
03133             showInvisibles( false ),
03134             forceColour( false ),
03135             abortAfter( -1 ),
03136             rngSeed( 0 ),
03137             verbosity( Verbosity::Normal ),
03138             warnings( WarnAbout::Nothing ),
03139             showDurations( ShowDurations::DefaultForReporter ),
03140             runOrder( RunTests::InDeclarationOrder )
03141         {}
03142 
03143         bool listTests;
03144         bool listTags;
03145         bool listReporters;
03146         bool listTestNamesOnly;
03147 
03148         bool showSuccessfulTests;
03149         bool shouldDebugBreak;
03150         bool noThrow;
03151         bool showHelp;
03152         bool showInvisibles;
03153         bool forceColour;
03154 
03155         int abortAfter;
03156         unsigned int rngSeed;
03157 
03158         Verbosity::Level verbosity;
03159         WarnAbout::What warnings;
03160         ShowDurations::OrNot showDurations;
03161         RunTests::InWhatOrder runOrder;
03162 
03163         std::string reporterName;
03164         std::string outputFilename;
03165         std::string name;
03166         std::string processName;
03167 
03168         std::vector<std::string> testsOrTags;
03169     };
03170 
03171     class Config : public SharedImpl<IConfig> {
03172     private:
03173         Config( Config const& other );
03174         Config& operator = ( Config const& other );
03175         virtual void dummy();
03176     public:
03177 
03178         Config()
03179         :   m_os( Catch::cout().rdbuf() )
03180         {}
03181 
03182         Config( ConfigData const& data )
03183         :   m_data( data ),
03184             m_os( Catch::cout().rdbuf() )
03185         {
03186             if( !data.testsOrTags.empty() ) {
03187                 TestSpecParser parser( ITagAliasRegistry::get() );
03188                 for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
03189                     parser.parse( data.testsOrTags[i] );
03190                 m_testSpec = parser.testSpec();
03191             }
03192         }
03193 
03194         virtual ~Config() {
03195             m_os.rdbuf( Catch::cout().rdbuf() );
03196             m_stream.release();
03197         }
03198 
03199         void setFilename( std::string const& filename ) {
03200             m_data.outputFilename = filename;
03201         }
03202 
03203         std::string const& getFilename() const {
03204             return m_data.outputFilename ;
03205         }
03206 
03207         bool listTests() const { return m_data.listTests; }
03208         bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
03209         bool listTags() const { return m_data.listTags; }
03210         bool listReporters() const { return m_data.listReporters; }
03211 
03212         std::string getProcessName() const { return m_data.processName; }
03213 
03214         bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
03215 
03216         void setStreamBuf( std::streambuf* buf ) {
03217             m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() );
03218         }
03219 
03220         void useStream( std::string const& streamName ) {
03221             Stream stream = createStream( streamName );
03222             setStreamBuf( stream.streamBuf );
03223             m_stream.release();
03224             m_stream = stream;
03225         }
03226 
03227         std::string getReporterName() const { return m_data.reporterName; }
03228 
03229         int abortAfter() const { return m_data.abortAfter; }
03230 
03231         TestSpec const& testSpec() const { return m_testSpec; }
03232 
03233         bool showHelp() const { return m_data.showHelp; }
03234         bool showInvisibles() const { return m_data.showInvisibles; }
03235 
03236         // IConfig interface
03237         virtual bool allowThrows() const        { return !m_data.noThrow; }
03238         virtual std::ostream& stream() const    { return m_os; }
03239         virtual std::string name() const        { return m_data.name.empty() ? m_data.processName : m_data.name; }
03240         virtual bool includeSuccessfulResults() const   { return m_data.showSuccessfulTests; }
03241         virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
03242         virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
03243         virtual RunTests::InWhatOrder runOrder() const  { return m_data.runOrder; }
03244         virtual unsigned int rngSeed() const    { return m_data.rngSeed; }
03245         virtual bool forceColour() const { return m_data.forceColour; }
03246 
03247     private:
03248         ConfigData m_data;
03249 
03250         Stream m_stream;
03251         mutable std::ostream m_os;
03252         TestSpec m_testSpec;
03253     };
03254 
03255 } // end namespace Catch
03256 
03257 // #included from: catch_clara.h
03258 #define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
03259 
03260 // Use Catch's value for console width (store Clara's off to the side, if present)
03261 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
03262 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
03263 #undef CLARA_CONFIG_CONSOLE_WIDTH
03264 #endif
03265 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
03266 
03267 // Declare Clara inside the Catch namespace
03268 #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
03269 // #included from: ../external/clara.h
03270 
03271 // Only use header guard if we are not using an outer namespace
03272 #if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
03273 
03274 #ifndef STITCH_CLARA_OPEN_NAMESPACE
03275 #define TWOBLUECUBES_CLARA_H_INCLUDED
03276 #define STITCH_CLARA_OPEN_NAMESPACE
03277 #define STITCH_CLARA_CLOSE_NAMESPACE
03278 #else
03279 #define STITCH_CLARA_CLOSE_NAMESPACE }
03280 #endif
03281 
03282 #define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
03283 
03284 // ----------- #included from tbc_text_format.h -----------
03285 
03286 // Only use header guard if we are not using an outer namespace
03287 #if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
03288 #ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
03289 #define TBC_TEXT_FORMAT_H_INCLUDED
03290 #endif
03291 
03292 #include <string>
03293 #include <vector>
03294 #include <sstream>
03295 
03296 // Use optional outer namespace
03297 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
03298 namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
03299 #endif
03300 
03301 namespace Tbc {
03302 
03303 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
03304     const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
03305 #else
03306     const unsigned int consoleWidth = 80;
03307 #endif
03308 
03309     struct TextAttributes {
03310         TextAttributes()
03311         :   initialIndent( std::string::npos ),
03312             indent( 0 ),
03313             width( consoleWidth-1 ),
03314             tabChar( '\t' )
03315         {}
03316 
03317         TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
03318         TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
03319         TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
03320         TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }
03321 
03322         std::size_t initialIndent;  // indent of first line, or npos
03323         std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
03324         std::size_t width;          // maximum width of text, including indent. Longer text will wrap
03325         char tabChar;               // If this char is seen the indent is changed to current pos
03326     };
03327 
03328     class Text {
03329     public:
03330         Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
03331         : attr( _attr )
03332         {
03333             std::string wrappableChars = " [({.,/|\\-";
03334             std::size_t indent = _attr.initialIndent != std::string::npos
03335                 ? _attr.initialIndent
03336                 : _attr.indent;
03337             std::string remainder = _str;
03338 
03339             while( !remainder.empty() ) {
03340                 if( lines.size() >= 1000 ) {
03341                     lines.push_back( "... message truncated due to excessive size" );
03342                     return;
03343                 }
03344                 std::size_t tabPos = std::string::npos;
03345                 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
03346                 std::size_t pos = remainder.find_first_of( '\n' );
03347                 if( pos <= width ) {
03348                     width = pos;
03349                 }
03350                 pos = remainder.find_last_of( _attr.tabChar, width );
03351                 if( pos != std::string::npos ) {
03352                     tabPos = pos;
03353                     if( remainder[width] == '\n' )
03354                         width--;
03355                     remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
03356                 }
03357 
03358                 if( width == remainder.size() ) {
03359                     spliceLine( indent, remainder, width );
03360                 }
03361                 else if( remainder[width] == '\n' ) {
03362                     spliceLine( indent, remainder, width );
03363                     if( width <= 1 || remainder.size() != 1 )
03364                         remainder = remainder.substr( 1 );
03365                     indent = _attr.indent;
03366                 }
03367                 else {
03368                     pos = remainder.find_last_of( wrappableChars, width );
03369                     if( pos != std::string::npos && pos > 0 ) {
03370                         spliceLine( indent, remainder, pos );
03371                         if( remainder[0] == ' ' )
03372                             remainder = remainder.substr( 1 );
03373                     }
03374                     else {
03375                         spliceLine( indent, remainder, width-1 );
03376                         lines.back() += "-";
03377                     }
03378                     if( lines.size() == 1 )
03379                         indent = _attr.indent;
03380                     if( tabPos != std::string::npos )
03381                         indent += tabPos;
03382                 }
03383             }
03384         }
03385 
03386         void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
03387             lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
03388             _remainder = _remainder.substr( _pos );
03389         }
03390 
03391         typedef std::vector<std::string>::const_iterator const_iterator;
03392 
03393         const_iterator begin() const { return lines.begin(); }
03394         const_iterator end() const { return lines.end(); }
03395         std::string const& last() const { return lines.back(); }
03396         std::size_t size() const { return lines.size(); }
03397         std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
03398         std::string toString() const {
03399             std::ostringstream oss;
03400             oss << *this;
03401             return oss.str();
03402         }
03403 
03404         inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
03405             for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
03406                 it != itEnd; ++it ) {
03407                 if( it != _text.begin() )
03408                     _stream << "\n";
03409                 _stream << *it;
03410             }
03411             return _stream;
03412         }
03413 
03414     private:
03415         std::string str;
03416         TextAttributes attr;
03417         std::vector<std::string> lines;
03418     };
03419 
03420 } // end namespace Tbc
03421 
03422 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
03423 } // end outer namespace
03424 #endif
03425 
03426 #endif // TBC_TEXT_FORMAT_H_INCLUDED
03427 
03428 // ----------- end of #include from tbc_text_format.h -----------
03429 // ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h
03430 
03431 #undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
03432 
03433 #include <map>
03434 #include <algorithm>
03435 #include <stdexcept>
03436 #include <memory>
03437 
03438 // Use optional outer namespace
03439 #ifdef STITCH_CLARA_OPEN_NAMESPACE
03440 STITCH_CLARA_OPEN_NAMESPACE
03441 #endif
03442 
03443 namespace Clara {
03444 
03445     struct UnpositionalTag {};
03446 
03447     extern UnpositionalTag _;
03448 
03449 #ifdef CLARA_CONFIG_MAIN
03450     UnpositionalTag _;
03451 #endif
03452 
03453     namespace Detail {
03454 
03455 #ifdef CLARA_CONSOLE_WIDTH
03456     const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
03457 #else
03458     const unsigned int consoleWidth = 80;
03459 #endif
03460 
03461         using namespace Tbc;
03462 
03463         inline bool startsWith( std::string const& str, std::string const& prefix ) {
03464             return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
03465         }
03466 
03467         template<typename T> struct RemoveConstRef{ typedef T type; };
03468         template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
03469         template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
03470         template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
03471 
03472         template<typename T>    struct IsBool       { static const bool value = false; };
03473         template<>              struct IsBool<bool> { static const bool value = true; };
03474 
03475         template<typename T>
03476         void convertInto( std::string const& _source, T& _dest ) {
03477             std::stringstream ss;
03478             ss << _source;
03479             ss >> _dest;
03480             if( ss.fail() )
03481                 throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
03482         }
03483         inline void convertInto( std::string const& _source, std::string& _dest ) {
03484             _dest = _source;
03485         }
03486         inline void convertInto( std::string const& _source, bool& _dest ) {
03487             std::string sourceLC = _source;
03488             std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
03489             if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
03490                 _dest = true;
03491             else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
03492                 _dest = false;
03493             else
03494                 throw std::runtime_error( "Expected a boolean value but did not recognise:\n  '" + _source + "'" );
03495         }
03496         inline void convertInto( bool _source, bool& _dest ) {
03497             _dest = _source;
03498         }
03499         template<typename T>
03500         inline void convertInto( bool, T& ) {
03501             throw std::runtime_error( "Invalid conversion" );
03502         }
03503 
03504         template<typename ConfigT>
03505         struct IArgFunction {
03506             virtual ~IArgFunction() {}
03507 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
03508             IArgFunction()                      = default;
03509             IArgFunction( IArgFunction const& ) = default;
03510 #  endif
03511             virtual void set( ConfigT& config, std::string const& value ) const = 0;
03512             virtual void setFlag( ConfigT& config ) const = 0;
03513             virtual bool takesArg() const = 0;
03514             virtual IArgFunction* clone() const = 0;
03515         };
03516 
03517         template<typename ConfigT>
03518         class BoundArgFunction {
03519         public:
03520             BoundArgFunction() : functionObj( NULL ) {}
03521             BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
03522             BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : NULL ) {}
03523             BoundArgFunction& operator = ( BoundArgFunction const& other ) {
03524                 IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : NULL;
03525                 delete functionObj;
03526                 functionObj = newFunctionObj;
03527                 return *this;
03528             }
03529             ~BoundArgFunction() { delete functionObj; }
03530 
03531             void set( ConfigT& config, std::string const& value ) const {
03532                 functionObj->set( config, value );
03533             }
03534             void setFlag( ConfigT& config ) const {
03535                 functionObj->setFlag( config );
03536             }
03537             bool takesArg() const { return functionObj->takesArg(); }
03538 
03539             bool isSet() const {
03540                 return functionObj != NULL;
03541             }
03542         private:
03543             IArgFunction<ConfigT>* functionObj;
03544         };
03545 
03546         template<typename C>
03547         struct NullBinder : IArgFunction<C>{
03548             virtual void set( C&, std::string const& ) const {}
03549             virtual void setFlag( C& ) const {}
03550             virtual bool takesArg() const { return true; }
03551             virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
03552         };
03553 
03554         template<typename C, typename M>
03555         struct BoundDataMember : IArgFunction<C>{
03556             BoundDataMember( M C::* _member ) : member( _member ) {}
03557             virtual void set( C& p, std::string const& stringValue ) const {
03558                 convertInto( stringValue, p.*member );
03559             }
03560             virtual void setFlag( C& p ) const {
03561                 convertInto( true, p.*member );
03562             }
03563             virtual bool takesArg() const { return !IsBool<M>::value; }
03564             virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
03565             M C::* member;
03566         };
03567         template<typename C, typename M>
03568         struct BoundUnaryMethod : IArgFunction<C>{
03569             BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
03570             virtual void set( C& p, std::string const& stringValue ) const {
03571                 typename RemoveConstRef<M>::type value;
03572                 convertInto( stringValue, value );
03573                 (p.*member)( value );
03574             }
03575             virtual void setFlag( C& p ) const {
03576                 typename RemoveConstRef<M>::type value;
03577                 convertInto( true, value );
03578                 (p.*member)( value );
03579             }
03580             virtual bool takesArg() const { return !IsBool<M>::value; }
03581             virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
03582             void (C::*member)( M );
03583         };
03584         template<typename C>
03585         struct BoundNullaryMethod : IArgFunction<C>{
03586             BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
03587             virtual void set( C& p, std::string const& stringValue ) const {
03588                 bool value;
03589                 convertInto( stringValue, value );
03590                 if( value )
03591                     (p.*member)();
03592             }
03593             virtual void setFlag( C& p ) const {
03594                 (p.*member)();
03595             }
03596             virtual bool takesArg() const { return false; }
03597             virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
03598             void (C::*member)();
03599         };
03600 
03601         template<typename C>
03602         struct BoundUnaryFunction : IArgFunction<C>{
03603             BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
03604             virtual void set( C& obj, std::string const& stringValue ) const {
03605                 bool value;
03606                 convertInto( stringValue, value );
03607                 if( value )
03608                     function( obj );
03609             }
03610             virtual void setFlag( C& p ) const {
03611                 function( p );
03612             }
03613             virtual bool takesArg() const { return false; }
03614             virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
03615             void (*function)( C& );
03616         };
03617 
03618         template<typename C, typename T>
03619         struct BoundBinaryFunction : IArgFunction<C>{
03620             BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
03621             virtual void set( C& obj, std::string const& stringValue ) const {
03622                 typename RemoveConstRef<T>::type value;
03623                 convertInto( stringValue, value );
03624                 function( obj, value );
03625             }
03626             virtual void setFlag( C& obj ) const {
03627                 typename RemoveConstRef<T>::type value;
03628                 convertInto( true, value );
03629                 function( obj, value );
03630             }
03631             virtual bool takesArg() const { return !IsBool<T>::value; }
03632             virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
03633             void (*function)( C&, T );
03634         };
03635 
03636     } // namespace Detail
03637 
03638     struct Parser {
03639         Parser() : separators( " \t=:" ) {}
03640 
03641         struct Token {
03642             enum Type { Positional, ShortOpt, LongOpt };
03643             Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
03644             Type type;
03645             std::string data;
03646         };
03647 
03648         void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const {
03649             const std::string doubleDash = "--";
03650             for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
03651                 parseIntoTokens( argv[i] , tokens);
03652         }
03653         void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
03654             while( !arg.empty() ) {
03655                 Parser::Token token( Parser::Token::Positional, arg );
03656                 arg = "";
03657                 if( token.data[0] == '-' ) {
03658                     if( token.data.size() > 1 && token.data[1] == '-' ) {
03659                         token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
03660                     }
03661                     else {
03662                         token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
03663                         if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
03664                             arg = "-" + token.data.substr( 1 );
03665                             token.data = token.data.substr( 0, 1 );
03666                         }
03667                     }
03668                 }
03669                 if( token.type != Parser::Token::Positional ) {
03670                     std::size_t pos = token.data.find_first_of( separators );
03671                     if( pos != std::string::npos ) {
03672                         arg = token.data.substr( pos+1 );
03673                         token.data = token.data.substr( 0, pos );
03674                     }
03675                 }
03676                 tokens.push_back( token );
03677             }
03678         }
03679         std::string separators;
03680     };
03681 
03682     template<typename ConfigT>
03683     struct CommonArgProperties {
03684         CommonArgProperties() {}
03685         CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
03686 
03687         Detail::BoundArgFunction<ConfigT> boundField;
03688         std::string description;
03689         std::string detail;
03690         std::string placeholder; // Only value if boundField takes an arg
03691 
03692         bool takesArg() const {
03693             return !placeholder.empty();
03694         }
03695         void validate() const {
03696             if( !boundField.isSet() )
03697                 throw std::logic_error( "option not bound" );
03698         }
03699     };
03700     struct OptionArgProperties {
03701         std::vector<std::string> shortNames;
03702         std::string longName;
03703 
03704         bool hasShortName( std::string const& shortName ) const {
03705             return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
03706         }
03707         bool hasLongName( std::string const& _longName ) const {
03708             return _longName == longName;
03709         }
03710     };
03711     struct PositionalArgProperties {
03712         PositionalArgProperties() : position( -1 ) {}
03713         int position; // -1 means non-positional (floating)
03714 
03715         bool isFixedPositional() const {
03716             return position != -1;
03717         }
03718     };
03719 
03720     template<typename ConfigT>
03721     class CommandLine {
03722 
03723         struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
03724             Arg() {}
03725             Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
03726 
03727             using CommonArgProperties<ConfigT>::placeholder; // !TBD
03728 
03729             std::string dbgName() const {
03730                 if( !longName.empty() )
03731                     return "--" + longName;
03732                 if( !shortNames.empty() )
03733                     return "-" + shortNames[0];
03734                 return "positional args";
03735             }
03736             std::string commands() const {
03737                 std::ostringstream oss;
03738                 bool first = true;
03739                 std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
03740                 for(; it != itEnd; ++it ) {
03741                     if( first )
03742                         first = false;
03743                     else
03744                         oss << ", ";
03745                     oss << "-" << *it;
03746                 }
03747                 if( !longName.empty() ) {
03748                     if( !first )
03749                         oss << ", ";
03750                     oss << "--" << longName;
03751                 }
03752                 if( !placeholder.empty() )
03753                     oss << " <" << placeholder << ">";
03754                 return oss.str();
03755             }
03756         };
03757 
03758         // NOTE: std::auto_ptr is deprecated in c++11/c++0x
03759 #if defined(__cplusplus) && __cplusplus > 199711L
03760         typedef std::unique_ptr<Arg> ArgAutoPtr;
03761 #else
03762         typedef std::auto_ptr<Arg> ArgAutoPtr;
03763 #endif
03764 
03765         friend void addOptName( Arg& arg, std::string const& optName )
03766         {
03767             if( optName.empty() )
03768                 return;
03769             if( Detail::startsWith( optName, "--" ) ) {
03770                 if( !arg.longName.empty() )
03771                     throw std::logic_error( "Only one long opt may be specified. '"
03772                         + arg.longName
03773                         + "' already specified, now attempting to add '"
03774                         + optName + "'" );
03775                 arg.longName = optName.substr( 2 );
03776             }
03777             else if( Detail::startsWith( optName, "-" ) )
03778                 arg.shortNames.push_back( optName.substr( 1 ) );
03779             else
03780                 throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
03781         }
03782         friend void setPositionalArg( Arg& arg, int position )
03783         {
03784             arg.position = position;
03785         }
03786 
03787         class ArgBuilder {
03788         public:
03789             ArgBuilder( Arg* arg ) : m_arg( arg ) {}
03790 
03791             // Bind a non-boolean data member (requires placeholder string)
03792             template<typename C, typename M>
03793             void bind( M C::* field, std::string const& placeholder ) {
03794                 m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
03795                 m_arg->placeholder = placeholder;
03796             }
03797             // Bind a boolean data member (no placeholder required)
03798             template<typename C>
03799             void bind( bool C::* field ) {
03800                 m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
03801             }
03802 
03803             // Bind a method taking a single, non-boolean argument (requires a placeholder string)
03804             template<typename C, typename M>
03805             void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
03806                 m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
03807                 m_arg->placeholder = placeholder;
03808             }
03809 
03810             // Bind a method taking a single, boolean argument (no placeholder string required)
03811             template<typename C>
03812             void bind( void (C::* unaryMethod)( bool ) ) {
03813                 m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
03814             }
03815 
03816             // Bind a method that takes no arguments (will be called if opt is present)
03817             template<typename C>
03818             void bind( void (C::* nullaryMethod)() ) {
03819                 m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
03820             }
03821 
03822             // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
03823             template<typename C>
03824             void bind( void (* unaryFunction)( C& ) ) {
03825                 m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
03826             }
03827 
03828             // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
03829             template<typename C, typename T>
03830             void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
03831                 m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
03832                 m_arg->placeholder = placeholder;
03833             }
03834 
03835             ArgBuilder& describe( std::string const& description ) {
03836                 m_arg->description = description;
03837                 return *this;
03838             }
03839             ArgBuilder& detail( std::string const& detail ) {
03840                 m_arg->detail = detail;
03841                 return *this;
03842             }
03843 
03844         protected:
03845             Arg* m_arg;
03846         };
03847 
03848         class OptBuilder : public ArgBuilder {
03849         public:
03850             OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
03851             OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
03852 
03853             OptBuilder& operator[]( std::string const& optName ) {
03854                 addOptName( *ArgBuilder::m_arg, optName );
03855                 return *this;
03856             }
03857         };
03858 
03859     public:
03860 
03861         CommandLine()
03862         :   m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
03863             m_highestSpecifiedArgPosition( 0 ),
03864             m_throwOnUnrecognisedTokens( false )
03865         {}
03866         CommandLine( CommandLine const& other )
03867         :   m_boundProcessName( other.m_boundProcessName ),
03868             m_options ( other.m_options ),
03869             m_positionalArgs( other.m_positionalArgs ),
03870             m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
03871             m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
03872         {
03873             if( other.m_floatingArg.get() )
03874                 m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
03875         }
03876 
03877         CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
03878             m_throwOnUnrecognisedTokens = shouldThrow;
03879             return *this;
03880         }
03881 
03882         OptBuilder operator[]( std::string const& optName ) {
03883             m_options.push_back( Arg() );
03884             addOptName( m_options.back(), optName );
03885             OptBuilder builder( &m_options.back() );
03886             return builder;
03887         }
03888 
03889         ArgBuilder operator[]( int position ) {
03890             m_positionalArgs.insert( std::make_pair( position, Arg() ) );
03891             if( position > m_highestSpecifiedArgPosition )
03892                 m_highestSpecifiedArgPosition = position;
03893             setPositionalArg( m_positionalArgs[position], position );
03894             ArgBuilder builder( &m_positionalArgs[position] );
03895             return builder;
03896         }
03897 
03898         // Invoke this with the _ instance
03899         ArgBuilder operator[]( UnpositionalTag ) {
03900             if( m_floatingArg.get() )
03901                 throw std::logic_error( "Only one unpositional argument can be added" );
03902             m_floatingArg.reset( new Arg() );
03903             ArgBuilder builder( m_floatingArg.get() );
03904             return builder;
03905         }
03906 
03907         template<typename C, typename M>
03908         void bindProcessName( M C::* field ) {
03909             m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
03910         }
03911         template<typename C, typename M>
03912         void bindProcessName( void (C::*_unaryMethod)( M ) ) {
03913             m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
03914         }
03915 
03916         void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
03917             typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
03918             std::size_t maxWidth = 0;
03919             for( it = itBegin; it != itEnd; ++it )
03920                 maxWidth = (std::max)( maxWidth, it->commands().size() );
03921 
03922             for( it = itBegin; it != itEnd; ++it ) {
03923                 Detail::Text usage( it->commands(), Detail::TextAttributes()
03924                                                         .setWidth( maxWidth+indent )
03925                                                         .setIndent( indent ) );
03926                 Detail::Text desc( it->description, Detail::TextAttributes()
03927                                                         .setWidth( width - maxWidth - 3 ) );
03928 
03929                 for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
03930                     std::string usageCol = i < usage.size() ? usage[i] : "";
03931                     os << usageCol;
03932 
03933                     if( i < desc.size() && !desc[i].empty() )
03934                         os  << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
03935                             << desc[i];
03936                     os << "\n";
03937                 }
03938             }
03939         }
03940         std::string optUsage() const {
03941             std::ostringstream oss;
03942             optUsage( oss );
03943             return oss.str();
03944         }
03945 
03946         void argSynopsis( std::ostream& os ) const {
03947             for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
03948                 if( i > 1 )
03949                     os << " ";
03950                 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
03951                 if( it != m_positionalArgs.end() )
03952                     os << "<" << it->second.placeholder << ">";
03953                 else if( m_floatingArg.get() )
03954                     os << "<" << m_floatingArg->placeholder << ">";
03955                 else
03956                     throw std::logic_error( "non consecutive positional arguments with no floating args" );
03957             }
03958             // !TBD No indication of mandatory args
03959             if( m_floatingArg.get() ) {
03960                 if( m_highestSpecifiedArgPosition > 1 )
03961                     os << " ";
03962                 os << "[<" << m_floatingArg->placeholder << "> ...]";
03963             }
03964         }
03965         std::string argSynopsis() const {
03966             std::ostringstream oss;
03967             argSynopsis( oss );
03968             return oss.str();
03969         }
03970 
03971         void usage( std::ostream& os, std::string const& procName ) const {
03972             validate();
03973             os << "usage:\n  " << procName << " ";
03974             argSynopsis( os );
03975             if( !m_options.empty() ) {
03976                 os << " [options]\n\nwhere options are: \n";
03977                 optUsage( os, 2 );
03978             }
03979             os << "\n";
03980         }
03981         std::string usage( std::string const& procName ) const {
03982             std::ostringstream oss;
03983             usage( oss, procName );
03984             return oss.str();
03985         }
03986 
03987         ConfigT parse( int argc, char const * const * argv ) const {
03988             ConfigT config;
03989             parseInto( argc, argv, config );
03990             return config;
03991         }
03992 
03993         std::vector<Parser::Token> parseInto( int argc, char const * const * argv, ConfigT& config ) const {
03994             std::string processName = argv[0];
03995             std::size_t lastSlash = processName.find_last_of( "/\\" );
03996             if( lastSlash != std::string::npos )
03997                 processName = processName.substr( lastSlash+1 );
03998             m_boundProcessName.set( config, processName );
03999             std::vector<Parser::Token> tokens;
04000             Parser parser;
04001             parser.parseIntoTokens( argc, argv, tokens );
04002             return populate( tokens, config );
04003         }
04004 
04005         std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
04006             validate();
04007             std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
04008             unusedTokens = populateFixedArgs( unusedTokens, config );
04009             unusedTokens = populateFloatingArgs( unusedTokens, config );
04010             return unusedTokens;
04011         }
04012 
04013         std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
04014             std::vector<Parser::Token> unusedTokens;
04015             std::vector<std::string> errors;
04016             for( std::size_t i = 0; i < tokens.size(); ++i ) {
04017                 Parser::Token const& token = tokens[i];
04018                 typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
04019                 for(; it != itEnd; ++it ) {
04020                     Arg const& arg = *it;
04021 
04022                     try {
04023                         if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
04024                             ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
04025                             if( arg.takesArg() ) {
04026                                 if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
04027                                     errors.push_back( "Expected argument to option: " + token.data );
04028                                 else
04029                                     arg.boundField.set( config, tokens[++i].data );
04030                             }
04031                             else {
04032                                 arg.boundField.setFlag( config );
04033                             }
04034                             break;
04035                         }
04036                     }
04037                     catch( std::exception& ex ) {
04038                         errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
04039                     }
04040                 }
04041                 if( it == itEnd ) {
04042                     if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
04043                         unusedTokens.push_back( token );
04044                     else if( errors.empty() && m_throwOnUnrecognisedTokens )
04045                         errors.push_back( "unrecognised option: " + token.data );
04046                 }
04047             }
04048             if( !errors.empty() ) {
04049                 std::ostringstream oss;
04050                 for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
04051                         it != itEnd;
04052                         ++it ) {
04053                     if( it != errors.begin() )
04054                         oss << "\n";
04055                     oss << *it;
04056                 }
04057                 throw std::runtime_error( oss.str() );
04058             }
04059             return unusedTokens;
04060         }
04061         std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
04062             std::vector<Parser::Token> unusedTokens;
04063             int position = 1;
04064             for( std::size_t i = 0; i < tokens.size(); ++i ) {
04065                 Parser::Token const& token = tokens[i];
04066                 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
04067                 if( it != m_positionalArgs.end() )
04068                     it->second.boundField.set( config, token.data );
04069                 else
04070                     unusedTokens.push_back( token );
04071                 if( token.type == Parser::Token::Positional )
04072                     position++;
04073             }
04074             return unusedTokens;
04075         }
04076         std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
04077             if( !m_floatingArg.get() )
04078                 return tokens;
04079             std::vector<Parser::Token> unusedTokens;
04080             for( std::size_t i = 0; i < tokens.size(); ++i ) {
04081                 Parser::Token const& token = tokens[i];
04082                 if( token.type == Parser::Token::Positional )
04083                     m_floatingArg->boundField.set( config, token.data );
04084                 else
04085                     unusedTokens.push_back( token );
04086             }
04087             return unusedTokens;
04088         }
04089 
04090         void validate() const
04091         {
04092             if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
04093                 throw std::logic_error( "No options or arguments specified" );
04094 
04095             for( typename std::vector<Arg>::const_iterator  it = m_options.begin(),
04096                                                             itEnd = m_options.end();
04097                     it != itEnd; ++it )
04098                 it->validate();
04099         }
04100 
04101     private:
04102         Detail::BoundArgFunction<ConfigT> m_boundProcessName;
04103         std::vector<Arg> m_options;
04104         std::map<int, Arg> m_positionalArgs;
04105         ArgAutoPtr m_floatingArg;
04106         int m_highestSpecifiedArgPosition;
04107         bool m_throwOnUnrecognisedTokens;
04108     };
04109 
04110 } // end namespace Clara
04111 
04112 STITCH_CLARA_CLOSE_NAMESPACE
04113 #undef STITCH_CLARA_OPEN_NAMESPACE
04114 #undef STITCH_CLARA_CLOSE_NAMESPACE
04115 
04116 #endif // TWOBLUECUBES_CLARA_H_INCLUDED
04117 #undef STITCH_CLARA_OPEN_NAMESPACE
04118 
04119 // Restore Clara's value for console width, if present
04120 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
04121 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
04122 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
04123 #endif
04124 
04125 #include <fstream>
04126 
04127 namespace Catch {
04128 
04129     inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
04130     inline void abortAfterX( ConfigData& config, int x ) {
04131         if( x < 1 )
04132             throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
04133         config.abortAfter = x;
04134     }
04135     inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
04136 
04137     inline void addWarning( ConfigData& config, std::string const& _warning ) {
04138         if( _warning == "NoAssertions" )
04139             config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
04140         else
04141             throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
04142     }
04143     inline void setOrder( ConfigData& config, std::string const& order ) {
04144         if( startsWith( "declared", order ) )
04145             config.runOrder = RunTests::InDeclarationOrder;
04146         else if( startsWith( "lexical", order ) )
04147             config.runOrder = RunTests::InLexicographicalOrder;
04148         else if( startsWith( "random", order ) )
04149             config.runOrder = RunTests::InRandomOrder;
04150         else
04151             throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
04152     }
04153     inline void setRngSeed( ConfigData& config, std::string const& seed ) {
04154         if( seed == "time" ) {
04155             config.rngSeed = static_cast<unsigned int>( std::time(0) );
04156         }
04157         else {
04158             std::stringstream ss;
04159             ss << seed;
04160             ss >> config.rngSeed;
04161             if( ss.fail() )
04162                 throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
04163         }
04164     }
04165     inline void setVerbosity( ConfigData& config, int level ) {
04166         // !TBD: accept strings?
04167         config.verbosity = static_cast<Verbosity::Level>( level );
04168     }
04169     inline void setShowDurations( ConfigData& config, bool _showDurations ) {
04170         config.showDurations = _showDurations
04171             ? ShowDurations::Always
04172             : ShowDurations::Never;
04173     }
04174     inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
04175         std::ifstream f( _filename.c_str() );
04176         if( !f.is_open() )
04177             throw std::domain_error( "Unable to load input file: " + _filename );
04178 
04179         std::string line;
04180         while( std::getline( f, line ) ) {
04181             line = trim(line);
04182             if( !line.empty() && !startsWith( line, "#" ) )
04183                 addTestOrTags( config, "\"" + line + "\"," );
04184         }
04185     }
04186 
04187     inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
04188 
04189         using namespace Clara;
04190         CommandLine<ConfigData> cli;
04191 
04192         cli.bindProcessName( &ConfigData::processName );
04193 
04194         cli["-?"]["-h"]["--help"]
04195             .describe( "display usage information" )
04196             .bind( &ConfigData::showHelp );
04197 
04198         cli["-l"]["--list-tests"]
04199             .describe( "list all/matching test cases" )
04200             .bind( &ConfigData::listTests );
04201 
04202         cli["-t"]["--list-tags"]
04203             .describe( "list all/matching tags" )
04204             .bind( &ConfigData::listTags );
04205 
04206         cli["-s"]["--success"]
04207             .describe( "include successful tests in output" )
04208             .bind( &ConfigData::showSuccessfulTests );
04209 
04210         cli["-b"]["--break"]
04211             .describe( "break into debugger on failure" )
04212             .bind( &ConfigData::shouldDebugBreak );
04213 
04214         cli["-e"]["--nothrow"]
04215             .describe( "skip exception tests" )
04216             .bind( &ConfigData::noThrow );
04217 
04218         cli["-i"]["--invisibles"]
04219             .describe( "show invisibles (tabs, newlines)" )
04220             .bind( &ConfigData::showInvisibles );
04221 
04222         cli["-o"]["--out"]
04223             .describe( "output filename" )
04224             .bind( &ConfigData::outputFilename, "filename" );
04225 
04226         cli["-r"]["--reporter"]
04227 //            .placeholder( "name[:filename]" )
04228             .describe( "reporter to use (defaults to console)" )
04229             .bind( &ConfigData::reporterName, "name" );
04230 
04231         cli["-n"]["--name"]
04232             .describe( "suite name" )
04233             .bind( &ConfigData::name, "name" );
04234 
04235         cli["-a"]["--abort"]
04236             .describe( "abort at first failure" )
04237             .bind( &abortAfterFirst );
04238 
04239         cli["-x"]["--abortx"]
04240             .describe( "abort after x failures" )
04241             .bind( &abortAfterX, "no. failures" );
04242 
04243         cli["-w"]["--warn"]
04244             .describe( "enable warnings" )
04245             .bind( &addWarning, "warning name" );
04246 
04247 // - needs updating if reinstated
04248 //        cli.into( &setVerbosity )
04249 //            .describe( "level of verbosity (0=no output)" )
04250 //            .shortOpt( "v")
04251 //            .longOpt( "verbosity" )
04252 //            .placeholder( "level" );
04253 
04254         cli[_]
04255             .describe( "which test or tests to use" )
04256             .bind( &addTestOrTags, "test name, pattern or tags" );
04257 
04258         cli["-d"]["--durations"]
04259             .describe( "show test durations" )
04260             .bind( &setShowDurations, "yes/no" );
04261 
04262         cli["-f"]["--input-file"]
04263             .describe( "load test names to run from a file" )
04264             .bind( &loadTestNamesFromFile, "filename" );
04265 
04266         // Less common commands which don't have a short form
04267         cli["--list-test-names-only"]
04268             .describe( "list all/matching test cases names only" )
04269             .bind( &ConfigData::listTestNamesOnly );
04270 
04271         cli["--list-reporters"]
04272             .describe( "list all reporters" )
04273             .bind( &ConfigData::listReporters );
04274 
04275         cli["--order"]
04276             .describe( "test case order (defaults to decl)" )
04277             .bind( &setOrder, "decl|lex|rand" );
04278 
04279         cli["--rng-seed"]
04280             .describe( "set a specific seed for random numbers" )
04281             .bind( &setRngSeed, "'time'|number" );
04282 
04283         cli["--force-colour"]
04284             .describe( "force colourised output" )
04285             .bind( &ConfigData::forceColour );
04286 
04287         return cli;
04288     }
04289 
04290 } // end namespace Catch
04291 
04292 // #included from: internal/catch_list.hpp
04293 #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
04294 
04295 // #included from: catch_text.h
04296 #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
04297 
04298 #define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
04299 
04300 #define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
04301 // #included from: ../external/tbc_text_format.h
04302 // Only use header guard if we are not using an outer namespace
04303 #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
04304 # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
04305 #  ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
04306 #   define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
04307 #  endif
04308 # else
04309 #  define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
04310 # endif
04311 #endif
04312 #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
04313 #include <string>
04314 #include <vector>
04315 #include <sstream>
04316 
04317 // Use optional outer namespace
04318 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
04319 namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
04320 #endif
04321 
04322 namespace Tbc {
04323 
04324 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
04325     const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
04326 #else
04327     const unsigned int consoleWidth = 80;
04328 #endif
04329 
04330     struct TextAttributes {
04331         TextAttributes()
04332         :   initialIndent( std::string::npos ),
04333             indent( 0 ),
04334             width( consoleWidth-1 ),
04335             tabChar( '\t' )
04336         {}
04337 
04338         TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
04339         TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
04340         TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
04341         TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }
04342 
04343         std::size_t initialIndent;  // indent of first line, or npos
04344         std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
04345         std::size_t width;          // maximum width of text, including indent. Longer text will wrap
04346         char tabChar;               // If this char is seen the indent is changed to current pos
04347     };
04348 
04349     class Text {
04350     public:
04351         Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
04352         : attr( _attr )
04353         {
04354             std::string wrappableChars = " [({.,/|\\-";
04355             std::size_t indent = _attr.initialIndent != std::string::npos
04356                 ? _attr.initialIndent
04357                 : _attr.indent;
04358             std::string remainder = _str;
04359 
04360             while( !remainder.empty() ) {
04361                 if( lines.size() >= 1000 ) {
04362                     lines.push_back( "... message truncated due to excessive size" );
04363                     return;
04364                 }
04365                 std::size_t tabPos = std::string::npos;
04366                 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
04367                 std::size_t pos = remainder.find_first_of( '\n' );
04368                 if( pos <= width ) {
04369                     width = pos;
04370                 }
04371                 pos = remainder.find_last_of( _attr.tabChar, width );
04372                 if( pos != std::string::npos ) {
04373                     tabPos = pos;
04374                     if( remainder[width] == '\n' )
04375                         width--;
04376                     remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
04377                 }
04378 
04379                 if( width == remainder.size() ) {
04380                     spliceLine( indent, remainder, width );
04381                 }
04382                 else if( remainder[width] == '\n' ) {
04383                     spliceLine( indent, remainder, width );
04384                     if( width <= 1 || remainder.size() != 1 )
04385                         remainder = remainder.substr( 1 );
04386                     indent = _attr.indent;
04387                 }
04388                 else {
04389                     pos = remainder.find_last_of( wrappableChars, width );
04390                     if( pos != std::string::npos && pos > 0 ) {
04391                         spliceLine( indent, remainder, pos );
04392                         if( remainder[0] == ' ' )
04393                             remainder = remainder.substr( 1 );
04394                     }
04395                     else {
04396                         spliceLine( indent, remainder, width-1 );
04397                         lines.back() += "-";
04398                     }
04399                     if( lines.size() == 1 )
04400                         indent = _attr.indent;
04401                     if( tabPos != std::string::npos )
04402                         indent += tabPos;
04403                 }
04404             }
04405         }
04406 
04407         void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
04408             lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
04409             _remainder = _remainder.substr( _pos );
04410         }
04411 
04412         typedef std::vector<std::string>::const_iterator const_iterator;
04413 
04414         const_iterator begin() const { return lines.begin(); }
04415         const_iterator end() const { return lines.end(); }
04416         std::string const& last() const { return lines.back(); }
04417         std::size_t size() const { return lines.size(); }
04418         std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
04419         std::string toString() const {
04420             std::ostringstream oss;
04421             oss << *this;
04422             return oss.str();
04423         }
04424 
04425         inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
04426             for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
04427                 it != itEnd; ++it ) {
04428                 if( it != _text.begin() )
04429                     _stream << "\n";
04430                 _stream << *it;
04431             }
04432             return _stream;
04433         }
04434 
04435     private:
04436         std::string str;
04437         TextAttributes attr;
04438         std::vector<std::string> lines;
04439     };
04440 
04441 } // end namespace Tbc
04442 
04443 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
04444 } // end outer namespace
04445 #endif
04446 
04447 #endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
04448 #undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
04449 
04450 namespace Catch {
04451     using Tbc::Text;
04452     using Tbc::TextAttributes;
04453 }
04454 
04455 // #included from: catch_console_colour.hpp
04456 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
04457 
04458 namespace Catch {
04459 
04460     struct Colour {
04461         enum Code {
04462             None = 0,
04463 
04464             White,
04465             Red,
04466             Green,
04467             Blue,
04468             Cyan,
04469             Yellow,
04470             Grey,
04471 
04472             Bright = 0x10,
04473 
04474             BrightRed = Bright | Red,
04475             BrightGreen = Bright | Green,
04476             LightGrey = Bright | Grey,
04477             BrightWhite = Bright | White,
04478 
04479             // By intention
04480             FileName = LightGrey,
04481             Warning = Yellow,
04482             ResultError = BrightRed,
04483             ResultSuccess = BrightGreen,
04484             ResultExpectedFailure = Warning,
04485 
04486             Error = BrightRed,
04487             Success = Green,
04488 
04489             OriginalExpression = Cyan,
04490             ReconstructedExpression = Yellow,
04491 
04492             SecondaryText = LightGrey,
04493             Headers = White
04494         };
04495 
04496         // Use constructed object for RAII guard
04497         Colour( Code _colourCode );
04498         Colour( Colour const& other );
04499         ~Colour();
04500 
04501         // Use static method for one-shot changes
04502         static void use( Code _colourCode );
04503 
04504     private:
04505         bool m_moved;
04506     };
04507 
04508     inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
04509 
04510 } // end namespace Catch
04511 
04512 // #included from: catch_interfaces_reporter.h
04513 #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
04514 
04515 #include <string>
04516 #include <ostream>
04517 #include <map>
04518 #include <assert.h>
04519 
04520 namespace Catch
04521 {
04522     struct ReporterConfig {
04523         explicit ReporterConfig( Ptr<IConfig> const& _fullConfig )
04524         :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
04525 
04526         ReporterConfig( Ptr<IConfig> const& _fullConfig, std::ostream& _stream )
04527         :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
04528 
04529         std::ostream& stream() const    { return *m_stream; }
04530         Ptr<IConfig> fullConfig() const { return m_fullConfig; }
04531 
04532     private:
04533         std::ostream* m_stream;
04534         Ptr<IConfig> m_fullConfig;
04535     };
04536 
04537     struct ReporterPreferences {
04538         ReporterPreferences()
04539         : shouldRedirectStdOut( false )
04540         {}
04541 
04542         bool shouldRedirectStdOut;
04543     };
04544 
04545     template<typename T>
04546     struct LazyStat : Option<T> {
04547         LazyStat() : used( false ) {}
04548         LazyStat& operator=( T const& _value ) {
04549             Option<T>::operator=( _value );
04550             used = false;
04551             return *this;
04552         }
04553         void reset() {
04554             Option<T>::reset();
04555             used = false;
04556         }
04557         bool used;
04558     };
04559 
04560     struct TestRunInfo {
04561         TestRunInfo( std::string const& _name ) : name( _name ) {}
04562         std::string name;
04563     };
04564     struct GroupInfo {
04565         GroupInfo(  std::string const& _name,
04566                     std::size_t _groupIndex,
04567                     std::size_t _groupsCount )
04568         :   name( _name ),
04569             groupIndex( _groupIndex ),
04570             groupsCounts( _groupsCount )
04571         {}
04572 
04573         std::string name;
04574         std::size_t groupIndex;
04575         std::size_t groupsCounts;
04576     };
04577 
04578     struct AssertionStats {
04579         AssertionStats( AssertionResult const& _assertionResult,
04580                         std::vector<MessageInfo> const& _infoMessages,
04581                         Totals const& _totals )
04582         :   assertionResult( _assertionResult ),
04583             infoMessages( _infoMessages ),
04584             totals( _totals )
04585         {
04586             if( assertionResult.hasMessage() ) {
04587                 // Copy message into messages list.
04588                 // !TBD This should have been done earlier, somewhere
04589                 MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
04590                 builder << assertionResult.getMessage();
04591                 builder.m_info.message = builder.m_stream.str();
04592 
04593                 infoMessages.push_back( builder.m_info );
04594             }
04595         }
04596         virtual ~AssertionStats();
04597 
04598 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
04599         AssertionStats( AssertionStats const& )              = default;
04600         AssertionStats( AssertionStats && )                  = default;
04601         AssertionStats& operator = ( AssertionStats const& ) = default;
04602         AssertionStats& operator = ( AssertionStats && )     = default;
04603 #  endif
04604 
04605         AssertionResult assertionResult;
04606         std::vector<MessageInfo> infoMessages;
04607         Totals totals;
04608     };
04609 
04610     struct SectionStats {
04611         SectionStats(   SectionInfo const& _sectionInfo,
04612                         Counts const& _assertions,
04613                         double _durationInSeconds,
04614                         bool _missingAssertions )
04615         :   sectionInfo( _sectionInfo ),
04616             assertions( _assertions ),
04617             durationInSeconds( _durationInSeconds ),
04618             missingAssertions( _missingAssertions )
04619         {}
04620         virtual ~SectionStats();
04621 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
04622         SectionStats( SectionStats const& )              = default;
04623         SectionStats( SectionStats && )                  = default;
04624         SectionStats& operator = ( SectionStats const& ) = default;
04625         SectionStats& operator = ( SectionStats && )     = default;
04626 #  endif
04627 
04628         SectionInfo sectionInfo;
04629         Counts assertions;
04630         double durationInSeconds;
04631         bool missingAssertions;
04632     };
04633 
04634     struct TestCaseStats {
04635         TestCaseStats(  TestCaseInfo const& _testInfo,
04636                         Totals const& _totals,
04637                         std::string const& _stdOut,
04638                         std::string const& _stdErr,
04639                         bool _aborting )
04640         : testInfo( _testInfo ),
04641             totals( _totals ),
04642             stdOut( _stdOut ),
04643             stdErr( _stdErr ),
04644             aborting( _aborting )
04645         {}
04646         virtual ~TestCaseStats();
04647 
04648 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
04649         TestCaseStats( TestCaseStats const& )              = default;
04650         TestCaseStats( TestCaseStats && )                  = default;
04651         TestCaseStats& operator = ( TestCaseStats const& ) = default;
04652         TestCaseStats& operator = ( TestCaseStats && )     = default;
04653 #  endif
04654 
04655         TestCaseInfo testInfo;
04656         Totals totals;
04657         std::string stdOut;
04658         std::string stdErr;
04659         bool aborting;
04660     };
04661 
04662     struct TestGroupStats {
04663         TestGroupStats( GroupInfo const& _groupInfo,
04664                         Totals const& _totals,
04665                         bool _aborting )
04666         :   groupInfo( _groupInfo ),
04667             totals( _totals ),
04668             aborting( _aborting )
04669         {}
04670         TestGroupStats( GroupInfo const& _groupInfo )
04671         :   groupInfo( _groupInfo ),
04672             aborting( false )
04673         {}
04674         virtual ~TestGroupStats();
04675 
04676 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
04677         TestGroupStats( TestGroupStats const& )              = default;
04678         TestGroupStats( TestGroupStats && )                  = default;
04679         TestGroupStats& operator = ( TestGroupStats const& ) = default;
04680         TestGroupStats& operator = ( TestGroupStats && )     = default;
04681 #  endif
04682 
04683         GroupInfo groupInfo;
04684         Totals totals;
04685         bool aborting;
04686     };
04687 
04688     struct TestRunStats {
04689         TestRunStats(   TestRunInfo const& _runInfo,
04690                         Totals const& _totals,
04691                         bool _aborting )
04692         :   runInfo( _runInfo ),
04693             totals( _totals ),
04694             aborting( _aborting )
04695         {}
04696         virtual ~TestRunStats();
04697 
04698 #  ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
04699         TestRunStats( TestRunStats const& _other )
04700         :   runInfo( _other.runInfo ),
04701             totals( _other.totals ),
04702             aborting( _other.aborting )
04703         {}
04704 #  else
04705         TestRunStats( TestRunStats const& )              = default;
04706         TestRunStats( TestRunStats && )                  = default;
04707         TestRunStats& operator = ( TestRunStats const& ) = default;
04708         TestRunStats& operator = ( TestRunStats && )     = default;
04709 #  endif
04710 
04711         TestRunInfo runInfo;
04712         Totals totals;
04713         bool aborting;
04714     };
04715 
04716     struct IStreamingReporter : IShared {
04717         virtual ~IStreamingReporter();
04718 
04719         // Implementing class must also provide the following static method:
04720         // static std::string getDescription();
04721 
04722         virtual ReporterPreferences getPreferences() const = 0;
04723 
04724         virtual void noMatchingTestCases( std::string const& spec ) = 0;
04725 
04726         virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
04727         virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
04728 
04729         virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
04730         virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
04731 
04732         virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
04733 
04734         // The return value indicates if the messages buffer should be cleared:
04735         virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
04736         virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
04737         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
04738         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
04739         virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
04740 
04741         virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
04742     };
04743 
04744     struct IReporterFactory {
04745         virtual ~IReporterFactory();
04746         virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
04747         virtual std::string getDescription() const = 0;
04748     };
04749 
04750     struct IReporterRegistry {
04751         typedef std::map<std::string, IReporterFactory*> FactoryMap;
04752 
04753         virtual ~IReporterRegistry();
04754         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const = 0;
04755         virtual FactoryMap const& getFactories() const = 0;
04756     };
04757 
04758 }
04759 
04760 #include <limits>
04761 #include <algorithm>
04762 
04763 namespace Catch {
04764 
04765     inline std::size_t listTests( Config const& config ) {
04766 
04767         TestSpec testSpec = config.testSpec();
04768         if( config.testSpec().hasFilters() )
04769             Catch::cout() << "Matching test cases:\n";
04770         else {
04771             Catch::cout() << "All available test cases:\n";
04772             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
04773         }
04774 
04775         std::size_t matchedTests = 0;
04776         TextAttributes nameAttr, tagsAttr;
04777         nameAttr.setInitialIndent( 2 ).setIndent( 4 );
04778         tagsAttr.setIndent( 6 );
04779 
04780         std::vector<TestCase> matchedTestCases;
04781         getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
04782         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
04783                 it != itEnd;
04784                 ++it ) {
04785             matchedTests++;
04786             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
04787             Colour::Code colour = testCaseInfo.isHidden()
04788                 ? Colour::SecondaryText
04789                 : Colour::None;
04790             Colour colourGuard( colour );
04791 
04792             Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
04793             if( !testCaseInfo.tags.empty() )
04794                 Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
04795         }
04796 
04797         if( !config.testSpec().hasFilters() )
04798             Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
04799         else
04800             Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
04801         return matchedTests;
04802     }
04803 
04804     inline std::size_t listTestsNamesOnly( Config const& config ) {
04805         TestSpec testSpec = config.testSpec();
04806         if( !config.testSpec().hasFilters() )
04807             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
04808         std::size_t matchedTests = 0;
04809         std::vector<TestCase> matchedTestCases;
04810         getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
04811         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
04812                 it != itEnd;
04813                 ++it ) {
04814             matchedTests++;
04815             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
04816             Catch::cout() << testCaseInfo.name << std::endl;
04817         }
04818         return matchedTests;
04819     }
04820 
04821     struct TagInfo {
04822         TagInfo() : count ( 0 ) {}
04823         void add( std::string const& spelling ) {
04824             ++count;
04825             spellings.insert( spelling );
04826         }
04827         std::string all() const {
04828             std::string out;
04829             for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
04830                         it != itEnd;
04831                         ++it )
04832                 out += "[" + *it + "]";
04833             return out;
04834         }
04835         std::set<std::string> spellings;
04836         std::size_t count;
04837     };
04838 
04839     inline std::size_t listTags( Config const& config ) {
04840         TestSpec testSpec = config.testSpec();
04841         if( config.testSpec().hasFilters() )
04842             Catch::cout() << "Tags for matching test cases:\n";
04843         else {
04844             Catch::cout() << "All available tags:\n";
04845             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
04846         }
04847 
04848         std::map<std::string, TagInfo> tagCounts;
04849 
04850         std::vector<TestCase> matchedTestCases;
04851         getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
04852         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
04853                 it != itEnd;
04854                 ++it ) {
04855             for( std::set<std::string>::const_iterator  tagIt = it->getTestCaseInfo().tags.begin(),
04856                                                         tagItEnd = it->getTestCaseInfo().tags.end();
04857                     tagIt != tagItEnd;
04858                     ++tagIt ) {
04859                 std::string tagName = *tagIt;
04860                 std::string lcaseTagName = toLower( tagName );
04861                 std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
04862                 if( countIt == tagCounts.end() )
04863                     countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
04864                 countIt->second.add( tagName );
04865             }
04866         }
04867 
04868         for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
04869                                                             countItEnd = tagCounts.end();
04870                 countIt != countItEnd;
04871                 ++countIt ) {
04872             std::ostringstream oss;
04873             oss << "  " << std::setw(2) << countIt->second.count << "  ";
04874             Text wrapper( countIt->second.all(), TextAttributes()
04875                                                     .setInitialIndent( 0 )
04876                                                     .setIndent( oss.str().size() )
04877                                                     .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
04878             Catch::cout() << oss.str() << wrapper << "\n";
04879         }
04880         Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
04881         return tagCounts.size();
04882     }
04883 
04884     inline std::size_t listReporters( Config const& /*config*/ ) {
04885         Catch::cout() << "Available reporters:\n";
04886         IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
04887         IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
04888         std::size_t maxNameLen = 0;
04889         for(it = itBegin; it != itEnd; ++it )
04890             maxNameLen = (std::max)( maxNameLen, it->first.size() );
04891 
04892         for(it = itBegin; it != itEnd; ++it ) {
04893             Text wrapper( it->second->getDescription(), TextAttributes()
04894                                                         .setInitialIndent( 0 )
04895                                                         .setIndent( 7+maxNameLen )
04896                                                         .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
04897             Catch::cout() << "  "
04898                     << it->first
04899                     << ":"
04900                     << std::string( maxNameLen - it->first.size() + 2, ' ' )
04901                     << wrapper << "\n";
04902         }
04903         Catch::cout() << std::endl;
04904         return factories.size();
04905     }
04906 
04907     inline Option<std::size_t> list( Config const& config ) {
04908         Option<std::size_t> listedCount;
04909         if( config.listTests() )
04910             listedCount = listedCount.valueOr(0) + listTests( config );
04911         if( config.listTestNamesOnly() )
04912             listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
04913         if( config.listTags() )
04914             listedCount = listedCount.valueOr(0) + listTags( config );
04915         if( config.listReporters() )
04916             listedCount = listedCount.valueOr(0) + listReporters( config );
04917         return listedCount;
04918     }
04919 
04920 } // end namespace Catch
04921 
04922 // #included from: internal/catch_runner_impl.hpp
04923 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
04924 
04925 // #included from: catch_test_case_tracker.hpp
04926 #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
04927 
04928 #include <map>
04929 #include <string>
04930 #include <assert.h>
04931 
04932 namespace Catch {
04933 namespace SectionTracking {
04934 
04935     class TrackedSection {
04936 
04937         typedef std::map<std::string, TrackedSection> TrackedSections;
04938 
04939     public:
04940         enum RunState {
04941             NotStarted,
04942             Executing,
04943             ExecutingChildren,
04944             Completed
04945         };
04946 
04947         TrackedSection( std::string const& name, TrackedSection* parent )
04948         :   m_name( name ), m_runState( NotStarted ), m_parent( parent )
04949         {}
04950 
04951         RunState runState() const { return m_runState; }
04952 
04953         TrackedSection* findChild( std::string const& childName );
04954         TrackedSection* acquireChild( std::string const& childName );
04955 
04956         void enter() {
04957             if( m_runState == NotStarted )
04958                 m_runState = Executing;
04959         }
04960         void leave();
04961 
04962         TrackedSection* getParent() {
04963             return m_parent;
04964         }
04965         bool hasChildren() const {
04966             return !m_children.empty();
04967         }
04968 
04969     private:
04970         std::string m_name;
04971         RunState m_runState;
04972         TrackedSections m_children;
04973         TrackedSection* m_parent;
04974     };
04975 
04976     inline TrackedSection* TrackedSection::findChild( std::string const& childName ) {
04977         TrackedSections::iterator it = m_children.find( childName );
04978         return it != m_children.end()
04979             ? &it->second
04980             : NULL;
04981     }
04982     inline TrackedSection* TrackedSection::acquireChild( std::string const& childName ) {
04983         if( TrackedSection* child = findChild( childName ) )
04984             return child;
04985         m_children.insert( std::make_pair( childName, TrackedSection( childName, this ) ) );
04986         return findChild( childName );
04987     }
04988     inline void TrackedSection::leave() {
04989         for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end();
04990                 it != itEnd;
04991                 ++it )
04992             if( it->second.runState() != Completed ) {
04993                 m_runState = ExecutingChildren;
04994                 return;
04995             }
04996         m_runState = Completed;
04997     }
04998 
04999     class TestCaseTracker {
05000     public:
05001         TestCaseTracker( std::string const& testCaseName )
05002         :   m_testCase( testCaseName, NULL ),
05003             m_currentSection( &m_testCase ),
05004             m_completedASectionThisRun( false )
05005         {}
05006 
05007         bool enterSection( std::string const& name ) {
05008             TrackedSection* child = m_currentSection->acquireChild( name );
05009             if( m_completedASectionThisRun || child->runState() == TrackedSection::Completed )
05010                 return false;
05011 
05012             m_currentSection = child;
05013             m_currentSection->enter();
05014             return true;
05015         }
05016         void leaveSection() {
05017             m_currentSection->leave();
05018             m_currentSection = m_currentSection->getParent();
05019             assert( m_currentSection != NULL );
05020             m_completedASectionThisRun = true;
05021         }
05022 
05023         bool currentSectionHasChildren() const {
05024             return m_currentSection->hasChildren();
05025         }
05026         bool isCompleted() const {
05027             return m_testCase.runState() == TrackedSection::Completed;
05028         }
05029 
05030         class Guard {
05031         public:
05032             Guard( TestCaseTracker& tracker ) : m_tracker( tracker ) {
05033                 m_tracker.enterTestCase();
05034             }
05035             ~Guard() {
05036                 m_tracker.leaveTestCase();
05037             }
05038         private:
05039             Guard( Guard const& );
05040             void operator = ( Guard const& );
05041             TestCaseTracker& m_tracker;
05042         };
05043 
05044     private:
05045         void enterTestCase() {
05046             m_currentSection = &m_testCase;
05047             m_completedASectionThisRun = false;
05048             m_testCase.enter();
05049         }
05050         void leaveTestCase() {
05051             m_testCase.leave();
05052         }
05053 
05054         TrackedSection m_testCase;
05055         TrackedSection* m_currentSection;
05056         bool m_completedASectionThisRun;
05057     };
05058 
05059 } // namespace SectionTracking
05060 
05061 using SectionTracking::TestCaseTracker;
05062 
05063 } // namespace Catch
05064 
05065 // #included from: catch_fatal_condition.hpp
05066 #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
05067 
05068 namespace Catch {
05069 
05070     // Report the error condition then exit the process
05071     inline void fatal( std::string const& message, int exitCode ) {
05072         IContext& context = Catch::getCurrentContext();
05073         IResultCapture* resultCapture = context.getResultCapture();
05074         resultCapture->handleFatalErrorCondition( message );
05075 
05076                 if( Catch::alwaysTrue() ) // avoids "no return" warnings
05077             exit( exitCode );
05078     }
05079 
05080 } // namespace Catch
05081 
05082 #if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
05083 
05084 namespace Catch {
05085 
05086     struct FatalConditionHandler {
05087                 void reset() {}
05088         };
05089 
05090 } // namespace Catch
05091 
05092 #else // Not Windows - assumed to be POSIX compatible //////////////////////////
05093 
05094 #include <signal.h>
05095 
05096 namespace Catch {
05097 
05098     struct SignalDefs { int id; const char* name; };
05099     extern SignalDefs signalDefs[];
05100     SignalDefs signalDefs[] = {
05101             { SIGINT,  "SIGINT - Terminal interrupt signal" },
05102             { SIGILL,  "SIGILL - Illegal instruction signal" },
05103             { SIGFPE,  "SIGFPE - Floating point error signal" },
05104             { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
05105             { SIGTERM, "SIGTERM - Termination request signal" },
05106             { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
05107         };
05108 
05109     struct FatalConditionHandler {
05110 
05111         static void handleSignal( int sig ) {
05112             for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
05113                 if( sig == signalDefs[i].id )
05114                     fatal( signalDefs[i].name, -sig );
05115             fatal( "<unknown signal>", -sig );
05116         }
05117 
05118         FatalConditionHandler() : m_isSet( true ) {
05119             for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
05120                 signal( signalDefs[i].id, handleSignal );
05121         }
05122         ~FatalConditionHandler() {
05123             reset();
05124         }
05125         void reset() {
05126             if( m_isSet ) {
05127                 for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
05128                     signal( signalDefs[i].id, SIG_DFL );
05129                 m_isSet = false;
05130             }
05131         }
05132 
05133         bool m_isSet;
05134     };
05135 
05136 } // namespace Catch
05137 
05138 #endif // not Windows
05139 
05140 #include <set>
05141 #include <string>
05142 
05143 namespace Catch {
05144 
05145     class StreamRedirect {
05146 
05147     public:
05148         StreamRedirect( std::ostream& stream, std::string& targetString )
05149         :   m_stream( stream ),
05150             m_prevBuf( stream.rdbuf() ),
05151             m_targetString( targetString )
05152         {
05153             stream.rdbuf( m_oss.rdbuf() );
05154         }
05155 
05156         ~StreamRedirect() {
05157             m_targetString += m_oss.str();
05158             m_stream.rdbuf( m_prevBuf );
05159         }
05160 
05161     private:
05162         std::ostream& m_stream;
05163         std::streambuf* m_prevBuf;
05164         std::ostringstream m_oss;
05165         std::string& m_targetString;
05166     };
05167 
05169 
05170     class RunContext : public IResultCapture, public IRunner {
05171 
05172         RunContext( RunContext const& );
05173         void operator =( RunContext const& );
05174 
05175     public:
05176 
05177         explicit RunContext( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> const& reporter )
05178         :   m_runInfo( config->name() ),
05179             m_context( getCurrentMutableContext() ),
05180             m_activeTestCase( NULL ),
05181             m_config( config ),
05182             m_reporter( reporter ),
05183             m_prevRunner( m_context.getRunner() ),
05184             m_prevResultCapture( m_context.getResultCapture() ),
05185             m_prevConfig( m_context.getConfig() )
05186         {
05187             m_context.setRunner( this );
05188             m_context.setConfig( m_config );
05189             m_context.setResultCapture( this );
05190             m_reporter->testRunStarting( m_runInfo );
05191         }
05192 
05193         virtual ~RunContext() {
05194             m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
05195             m_context.setRunner( m_prevRunner );
05196             m_context.setConfig( NULL );
05197             m_context.setResultCapture( m_prevResultCapture );
05198             m_context.setConfig( m_prevConfig );
05199         }
05200 
05201         void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
05202             m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
05203         }
05204         void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
05205             m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
05206         }
05207 
05208         Totals runTest( TestCase const& testCase ) {
05209             Totals prevTotals = m_totals;
05210 
05211             std::string redirectedCout;
05212             std::string redirectedCerr;
05213 
05214             TestCaseInfo testInfo = testCase.getTestCaseInfo();
05215 
05216             m_reporter->testCaseStarting( testInfo );
05217 
05218             m_activeTestCase = &testCase;
05219             m_testCaseTracker = TestCaseTracker( testInfo.name );
05220 
05221             do {
05222                 do {
05223                     runCurrentTest( redirectedCout, redirectedCerr );
05224                 }
05225                 while( !m_testCaseTracker->isCompleted() && !aborting() );
05226             }
05227             while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
05228 
05229             Totals deltaTotals = m_totals.delta( prevTotals );
05230             m_totals.testCases += deltaTotals.testCases;
05231             m_reporter->testCaseEnded( TestCaseStats(   testInfo,
05232                                                         deltaTotals,
05233                                                         redirectedCout,
05234                                                         redirectedCerr,
05235                                                         aborting() ) );
05236 
05237             m_activeTestCase = NULL;
05238             m_testCaseTracker.reset();
05239 
05240             return deltaTotals;
05241         }
05242 
05243         Ptr<IConfig const> config() const {
05244             return m_config;
05245         }
05246 
05247     private: // IResultCapture
05248 
05249         virtual void assertionEnded( AssertionResult const& result ) {
05250             if( result.getResultType() == ResultWas::Ok ) {
05251                 m_totals.assertions.passed++;
05252             }
05253             else if( !result.isOk() ) {
05254                 m_totals.assertions.failed++;
05255             }
05256 
05257             if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
05258                 m_messages.clear();
05259 
05260             // Reset working state
05261             m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
05262             m_lastResult = result;
05263         }
05264 
05265         virtual bool sectionStarted (
05266             SectionInfo const& sectionInfo,
05267             Counts& assertions
05268         )
05269         {
05270             std::ostringstream oss;
05271             oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
05272 
05273             if( !m_testCaseTracker->enterSection( oss.str() ) )
05274                 return false;
05275 
05276             m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
05277 
05278             m_reporter->sectionStarting( sectionInfo );
05279 
05280             assertions = m_totals.assertions;
05281 
05282             return true;
05283         }
05284         bool testForMissingAssertions( Counts& assertions ) {
05285             if( assertions.total() != 0 ||
05286                     !m_config->warnAboutMissingAssertions() ||
05287                     m_testCaseTracker->currentSectionHasChildren() )
05288                 return false;
05289             m_totals.assertions.failed++;
05290             assertions.failed++;
05291             return true;
05292         }
05293 
05294         virtual void sectionEnded( SectionInfo const& info, Counts const& prevAssertions, double _durationInSeconds ) {
05295             if( std::uncaught_exception() ) {
05296                 m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) );
05297                 return;
05298             }
05299 
05300             Counts assertions = m_totals.assertions - prevAssertions;
05301             bool missingAssertions = testForMissingAssertions( assertions );
05302 
05303             m_testCaseTracker->leaveSection();
05304 
05305             m_reporter->sectionEnded( SectionStats( info, assertions, _durationInSeconds, missingAssertions ) );
05306             m_messages.clear();
05307         }
05308 
05309         virtual void pushScopedMessage( MessageInfo const& message ) {
05310             m_messages.push_back( message );
05311         }
05312 
05313         virtual void popScopedMessage( MessageInfo const& message ) {
05314             m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
05315         }
05316 
05317         virtual std::string getCurrentTestName() const {
05318             return m_activeTestCase
05319                 ? m_activeTestCase->getTestCaseInfo().name
05320                 : "";
05321         }
05322 
05323         virtual const AssertionResult* getLastResult() const {
05324             return &m_lastResult;
05325         }
05326 
05327         virtual void handleFatalErrorCondition( std::string const& message ) {
05328             ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
05329             resultBuilder.setResultType( ResultWas::FatalErrorCondition );
05330             resultBuilder << message;
05331             resultBuilder.captureExpression();
05332 
05333             handleUnfinishedSections();
05334 
05335             // Recreate section for test case (as we will lose the one that was in scope)
05336             TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
05337             SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
05338 
05339             Counts assertions;
05340             assertions.failed = 1;
05341             SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
05342             m_reporter->sectionEnded( testCaseSectionStats );
05343 
05344             TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
05345 
05346             Totals deltaTotals;
05347             deltaTotals.testCases.failed = 1;
05348             m_reporter->testCaseEnded( TestCaseStats(   testInfo,
05349                                                         deltaTotals,
05350                                                         "",
05351                                                         "",
05352                                                         false ) );
05353             m_totals.testCases.failed++;
05354             testGroupEnded( "", m_totals, 1, 1 );
05355             m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
05356         }
05357 
05358     public:
05359         // !TBD We need to do this another way!
05360         bool aborting() const {
05361             return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
05362         }
05363 
05364     private:
05365 
05366         void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
05367             TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
05368             SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
05369             m_reporter->sectionStarting( testCaseSection );
05370             Counts prevAssertions = m_totals.assertions;
05371             double duration = 0;
05372             try {
05373                 m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
05374                 TestCaseTracker::Guard guard( *m_testCaseTracker );
05375 
05376                 Timer timer;
05377                 timer.start();
05378                 if( m_reporter->getPreferences().shouldRedirectStdOut ) {
05379                     StreamRedirect coutRedir( Catch::cout(), redirectedCout );
05380                     StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
05381                     invokeActiveTestCase();
05382                 }
05383                 else {
05384                     invokeActiveTestCase();
05385                 }
05386                 duration = timer.getElapsedSeconds();
05387             }
05388             catch( TestFailureException& ) {
05389                 // This just means the test was aborted due to failure
05390             }
05391             catch(...) {
05392                 makeUnexpectedResultBuilder().useActiveException();
05393             }
05394             handleUnfinishedSections();
05395             m_messages.clear();
05396 
05397             Counts assertions = m_totals.assertions - prevAssertions;
05398             bool missingAssertions = testForMissingAssertions( assertions );
05399 
05400             if( testCaseInfo.okToFail() ) {
05401                 std::swap( assertions.failedButOk, assertions.failed );
05402                 m_totals.assertions.failed -= assertions.failedButOk;
05403                 m_totals.assertions.failedButOk += assertions.failedButOk;
05404             }
05405 
05406             SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
05407             m_reporter->sectionEnded( testCaseSectionStats );
05408         }
05409 
05410         void invokeActiveTestCase() {
05411             FatalConditionHandler fatalConditionHandler; // Handle signals
05412             m_activeTestCase->invoke();
05413             fatalConditionHandler.reset();
05414         }
05415 
05416     private:
05417 
05418         ResultBuilder makeUnexpectedResultBuilder() const {
05419             return ResultBuilder(   m_lastAssertionInfo.macroName.c_str(),
05420                                     m_lastAssertionInfo.lineInfo,
05421                                     m_lastAssertionInfo.capturedExpression.c_str(),
05422                                     m_lastAssertionInfo.resultDisposition );
05423         }
05424 
05425         void handleUnfinishedSections() {
05426             // If sections ended prematurely due to an exception we stored their
05427             // infos here so we can tear them down outside the unwind process.
05428             for( std::vector<UnfinishedSections>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
05429                         itEnd = m_unfinishedSections.rend();
05430                     it != itEnd;
05431                     ++it )
05432                 sectionEnded( it->info, it->prevAssertions, it->durationInSeconds );
05433             m_unfinishedSections.clear();
05434         }
05435 
05436         struct UnfinishedSections {
05437             UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds )
05438             : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
05439             {}
05440 
05441             SectionInfo info;
05442             Counts prevAssertions;
05443             double durationInSeconds;
05444         };
05445 
05446         TestRunInfo m_runInfo;
05447         IMutableContext& m_context;
05448         TestCase const* m_activeTestCase;
05449         Option<TestCaseTracker> m_testCaseTracker;
05450         AssertionResult m_lastResult;
05451 
05452         Ptr<IConfig const> m_config;
05453         Totals m_totals;
05454         Ptr<IStreamingReporter> m_reporter;
05455         std::vector<MessageInfo> m_messages;
05456         IRunner* m_prevRunner;
05457         IResultCapture* m_prevResultCapture;
05458         Ptr<IConfig const> m_prevConfig;
05459         AssertionInfo m_lastAssertionInfo;
05460         std::vector<UnfinishedSections> m_unfinishedSections;
05461     };
05462 
05463     IResultCapture& getResultCapture() {
05464         if( IResultCapture* capture = getCurrentContext().getResultCapture() )
05465             return *capture;
05466         else
05467             throw std::logic_error( "No result capture instance" );
05468     }
05469 
05470 } // end namespace Catch
05471 
05472 // #included from: internal/catch_version.h
05473 #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
05474 
05475 namespace Catch {
05476 
05477     // Versioning information
05478     struct Version {
05479         Version(    unsigned int _majorVersion,
05480                     unsigned int _minorVersion,
05481                     unsigned int _patchNumber,
05482                     std::string const& _branchName,
05483                     unsigned int _buildNumber );
05484 
05485         unsigned int const majorVersion;
05486         unsigned int const minorVersion;
05487         unsigned int const patchNumber;
05488 
05489         // buildNumber is only used if branchName is not null
05490         std::string const branchName;
05491         unsigned int const buildNumber;
05492 
05493         friend std::ostream& operator << ( std::ostream& os, Version const& version );
05494 
05495     private:
05496         void operator=( Version const& );
05497     };
05498 
05499     extern Version libraryVersion;
05500 }
05501 
05502 #include <fstream>
05503 #include <stdlib.h>
05504 #include <limits>
05505 
05506 namespace Catch {
05507 
05508     class Runner {
05509 
05510     public:
05511         Runner( Ptr<Config> const& config )
05512         :   m_config( config )
05513         {
05514             openStream();
05515             makeReporter();
05516         }
05517 
05518         Totals runTests() {
05519 
05520             RunContext context( m_config.get(), m_reporter );
05521 
05522             Totals totals;
05523 
05524             context.testGroupStarting( "all tests", 1, 1 ); // deprecated?
05525 
05526             TestSpec testSpec = m_config->testSpec();
05527             if( !testSpec.hasFilters() )
05528                 testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
05529 
05530             std::vector<TestCase> testCases;
05531             getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, testCases );
05532 
05533             int testsRunForGroup = 0;
05534             for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
05535                     it != itEnd;
05536                     ++it ) {
05537                 testsRunForGroup++;
05538                 if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
05539 
05540                     if( context.aborting() )
05541                         break;
05542 
05543                     totals += context.runTest( *it );
05544                     m_testsAlreadyRun.insert( *it );
05545                 }
05546             }
05547             std::vector<TestCase> skippedTestCases;
05548             getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, skippedTestCases, true );
05549 
05550             for( std::vector<TestCase>::const_iterator it = skippedTestCases.begin(), itEnd = skippedTestCases.end();
05551                     it != itEnd;
05552                     ++it )
05553                 m_reporter->skipTest( *it );
05554 
05555             context.testGroupEnded( "all tests", totals, 1, 1 );
05556             return totals;
05557         }
05558 
05559     private:
05560         void openStream() {
05561             // Open output file, if specified
05562             if( !m_config->getFilename().empty() ) {
05563                 m_ofs.open( m_config->getFilename().c_str() );
05564                 if( m_ofs.fail() ) {
05565                     std::ostringstream oss;
05566                     oss << "Unable to open file: '" << m_config->getFilename() << "'";
05567                     throw std::domain_error( oss.str() );
05568                 }
05569                 m_config->setStreamBuf( m_ofs.rdbuf() );
05570             }
05571         }
05572         void makeReporter() {
05573             std::string reporterName = m_config->getReporterName().empty()
05574                 ? "console"
05575                 : m_config->getReporterName();
05576 
05577             m_reporter = getRegistryHub().getReporterRegistry().create( reporterName, m_config.get() );
05578             if( !m_reporter ) {
05579                 std::ostringstream oss;
05580                 oss << "No reporter registered with name: '" << reporterName << "'";
05581                 throw std::domain_error( oss.str() );
05582             }
05583         }
05584 
05585     private:
05586         Ptr<Config> m_config;
05587         std::ofstream m_ofs;
05588         Ptr<IStreamingReporter> m_reporter;
05589         std::set<TestCase> m_testsAlreadyRun;
05590     };
05591 
05592     class Session : NonCopyable {
05593         static bool alreadyInstantiated;
05594 
05595     public:
05596 
05597         struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
05598 
05599         Session()
05600         : m_cli( makeCommandLineParser() ) {
05601             if( alreadyInstantiated ) {
05602                 std::string msg = "Only one instance of Catch::Session can ever be used";
05603                 Catch::cerr() << msg << std::endl;
05604                 throw std::logic_error( msg );
05605             }
05606             alreadyInstantiated = true;
05607         }
05608         ~Session() {
05609             Catch::cleanUp();
05610         }
05611 
05612         void showHelp( std::string const& processName ) {
05613             Catch::cout() << "\nCatch v" << libraryVersion << "\n";
05614 
05615             m_cli.usage( Catch::cout(), processName );
05616             Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
05617         }
05618 
05619         int applyCommandLine( int argc, char* const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
05620             try {
05621                 m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
05622                 m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
05623                 if( m_configData.showHelp )
05624                     showHelp( m_configData.processName );
05625                 m_config.reset();
05626             }
05627             catch( std::exception& ex ) {
05628                 {
05629                     Colour colourGuard( Colour::Red );
05630                     Catch::cerr()
05631                         << "\nError(s) in input:\n"
05632                         << Text( ex.what(), TextAttributes().setIndent(2) )
05633                         << "\n\n";
05634                 }
05635                 m_cli.usage( Catch::cout(), m_configData.processName );
05636                 return (std::numeric_limits<int>::max)();
05637             }
05638             return 0;
05639         }
05640 
05641         void useConfigData( ConfigData const& _configData ) {
05642             m_configData = _configData;
05643             m_config.reset();
05644         }
05645 
05646         int run( int argc, char* const argv[] ) {
05647 
05648             int returnCode = applyCommandLine( argc, argv );
05649             if( returnCode == 0 )
05650                 returnCode = run();
05651             return returnCode;
05652         }
05653 
05654         int run() {
05655             if( m_configData.showHelp )
05656                 return 0;
05657 
05658             try
05659             {
05660                 config(); // Force config to be constructed
05661 
05662                 std::srand( m_configData.rngSeed );
05663 
05664                 Runner runner( m_config );
05665 
05666                 // Handle list request
05667                 if( Option<std::size_t> listed = list( config() ) )
05668                     return static_cast<int>( *listed );
05669 
05670                 return static_cast<int>( runner.runTests().assertions.failed );
05671             }
05672             catch( std::exception& ex ) {
05673                 Catch::cerr() << ex.what() << std::endl;
05674                 return (std::numeric_limits<int>::max)();
05675             }
05676         }
05677 
05678         Clara::CommandLine<ConfigData> const& cli() const {
05679             return m_cli;
05680         }
05681         std::vector<Clara::Parser::Token> const& unusedTokens() const {
05682             return m_unusedTokens;
05683         }
05684         ConfigData& configData() {
05685             return m_configData;
05686         }
05687         Config& config() {
05688             if( !m_config )
05689                 m_config = new Config( m_configData );
05690             return *m_config;
05691         }
05692 
05693     private:
05694         Clara::CommandLine<ConfigData> m_cli;
05695         std::vector<Clara::Parser::Token> m_unusedTokens;
05696         ConfigData m_configData;
05697         Ptr<Config> m_config;
05698     };
05699 
05700     bool Session::alreadyInstantiated = false;
05701 
05702 } // end namespace Catch
05703 
05704 // #included from: catch_registry_hub.hpp
05705 #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
05706 
05707 // #included from: catch_test_case_registry_impl.hpp
05708 #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
05709 
05710 #include <vector>
05711 #include <set>
05712 #include <sstream>
05713 #include <iostream>
05714 #include <algorithm>
05715 
05716 namespace Catch {
05717 
05718     class TestRegistry : public ITestCaseRegistry {
05719         struct LexSort {
05720             bool operator() (TestCase i,TestCase j) const { return (i<j);}
05721         };
05722         struct RandomNumberGenerator {
05723             int operator()( int n ) const { return std::rand() % n; }
05724         };
05725 
05726     public:
05727         TestRegistry() : m_unnamedCount( 0 ) {}
05728         virtual ~TestRegistry();
05729 
05730         virtual void registerTest( TestCase const& testCase ) {
05731             std::string name = testCase.getTestCaseInfo().name;
05732             if( name == "" ) {
05733                 std::ostringstream oss;
05734                 oss << "Anonymous test case " << ++m_unnamedCount;
05735                 return registerTest( testCase.withName( oss.str() ) );
05736             }
05737 
05738             if( m_functions.find( testCase ) == m_functions.end() ) {
05739                 m_functions.insert( testCase );
05740                 m_functionsInOrder.push_back( testCase );
05741                 if( !testCase.isHidden() )
05742                     m_nonHiddenFunctions.push_back( testCase );
05743             }
05744             else {
05745                 TestCase const& prev = *m_functions.find( testCase );
05746                 {
05747                     Colour colourGuard( Colour::Red );
05748                     Catch::cerr()   << "error: TEST_CASE( \"" << name << "\" ) already defined.\n"
05749                                 << "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n"
05750                                 << "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl;
05751                 }
05752                 exit(1);
05753             }
05754         }
05755 
05756         virtual std::vector<TestCase> const& getAllTests() const {
05757             return m_functionsInOrder;
05758         }
05759 
05760         virtual std::vector<TestCase> const& getAllNonHiddenTests() const {
05761             return m_nonHiddenFunctions;
05762         }
05763 
05764         virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const {
05765 
05766             for( std::vector<TestCase>::const_iterator  it = m_functionsInOrder.begin(),
05767                                                         itEnd = m_functionsInOrder.end();
05768                     it != itEnd;
05769                     ++it ) {
05770                 bool includeTest = testSpec.matches( *it ) && ( config.allowThrows() || !it->throws() );
05771                 if( includeTest != negated )
05772                     matchingTestCases.push_back( *it );
05773             }
05774             sortTests( config, matchingTestCases );
05775         }
05776 
05777     private:
05778 
05779         static void sortTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) {
05780 
05781             switch( config.runOrder() ) {
05782                 case RunTests::InLexicographicalOrder:
05783                     std::sort( matchingTestCases.begin(), matchingTestCases.end(), LexSort() );
05784                     break;
05785                 case RunTests::InRandomOrder:
05786                 {
05787                     RandomNumberGenerator rng;
05788                     std::random_shuffle( matchingTestCases.begin(), matchingTestCases.end(), rng );
05789                 }
05790                     break;
05791                 case RunTests::InDeclarationOrder:
05792                     // already in declaration order
05793                     break;
05794             }
05795         }
05796         std::set<TestCase> m_functions;
05797         std::vector<TestCase> m_functionsInOrder;
05798         std::vector<TestCase> m_nonHiddenFunctions;
05799         size_t m_unnamedCount;
05800     };
05801 
05803 
05804     class FreeFunctionTestCase : public SharedImpl<ITestCase> {
05805     public:
05806 
05807         FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
05808 
05809         virtual void invoke() const {
05810             m_fun();
05811         }
05812 
05813     private:
05814         virtual ~FreeFunctionTestCase();
05815 
05816         TestFunction m_fun;
05817     };
05818 
05819     inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
05820         std::string className = classOrQualifiedMethodName;
05821         if( startsWith( className, "&" ) )
05822         {
05823             std::size_t lastColons = className.rfind( "::" );
05824             std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
05825             if( penultimateColons == std::string::npos )
05826                 penultimateColons = 1;
05827             className = className.substr( penultimateColons, lastColons-penultimateColons );
05828         }
05829         return className;
05830     }
05831 
05833 
05834     AutoReg::AutoReg(   TestFunction function,
05835                         SourceLineInfo const& lineInfo,
05836                         NameAndDesc const& nameAndDesc ) {
05837         registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
05838     }
05839 
05840     AutoReg::~AutoReg() {}
05841 
05842     void AutoReg::registerTestCase( ITestCase* testCase,
05843                                     char const* classOrQualifiedMethodName,
05844                                     NameAndDesc const& nameAndDesc,
05845                                     SourceLineInfo const& lineInfo ) {
05846 
05847         getMutableRegistryHub().registerTest
05848             ( makeTestCase( testCase,
05849                             extractClassName( classOrQualifiedMethodName ),
05850                             nameAndDesc.name,
05851                             nameAndDesc.description,
05852                             lineInfo ) );
05853     }
05854 
05855 } // end namespace Catch
05856 
05857 // #included from: catch_reporter_registry.hpp
05858 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
05859 
05860 #include <map>
05861 
05862 namespace Catch {
05863 
05864     class ReporterRegistry : public IReporterRegistry {
05865 
05866     public:
05867 
05868         virtual ~ReporterRegistry() {
05869             deleteAllValues( m_factories );
05870         }
05871 
05872         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const {
05873             FactoryMap::const_iterator it =  m_factories.find( name );
05874             if( it == m_factories.end() )
05875                 return NULL;
05876             return it->second->create( ReporterConfig( config ) );
05877         }
05878 
05879         void registerReporter( std::string const& name, IReporterFactory* factory ) {
05880             m_factories.insert( std::make_pair( name, factory ) );
05881         }
05882 
05883         FactoryMap const& getFactories() const {
05884             return m_factories;
05885         }
05886 
05887     private:
05888         FactoryMap m_factories;
05889     };
05890 }
05891 
05892 // #included from: catch_exception_translator_registry.hpp
05893 #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
05894 
05895 #ifdef __OBJC__
05896 #import "Foundation/Foundation.h"
05897 #endif
05898 
05899 namespace Catch {
05900 
05901     class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
05902     public:
05903         ~ExceptionTranslatorRegistry() {
05904             deleteAll( m_translators );
05905         }
05906 
05907         virtual void registerTranslator( const IExceptionTranslator* translator ) {
05908             m_translators.push_back( translator );
05909         }
05910 
05911         virtual std::string translateActiveException() const {
05912             try {
05913 #ifdef __OBJC__
05914                 // In Objective-C try objective-c exceptions first
05915                 @try {
05916                     throw;
05917                 }
05918                 @catch (NSException *exception) {
05919                     return Catch::toString( [exception description] );
05920                 }
05921 #else
05922                 throw;
05923 #endif
05924             }
05925             catch( TestFailureException& ) {
05926                 throw;
05927             }
05928             catch( std::exception& ex ) {
05929                 return ex.what();
05930             }
05931             catch( std::string& msg ) {
05932                 return msg;
05933             }
05934             catch( const char* msg ) {
05935                 return msg;
05936             }
05937             catch(...) {
05938                 return tryTranslators( m_translators.begin() );
05939             }
05940         }
05941 
05942         std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it ) const {
05943             if( it == m_translators.end() )
05944                 return "Unknown exception";
05945 
05946             try {
05947                 return (*it)->translate();
05948             }
05949             catch(...) {
05950                 return tryTranslators( it+1 );
05951             }
05952         }
05953 
05954     private:
05955         std::vector<const IExceptionTranslator*> m_translators;
05956     };
05957 }
05958 
05959 namespace Catch {
05960 
05961     namespace {
05962 
05963         class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
05964 
05965             RegistryHub( RegistryHub const& );
05966             void operator=( RegistryHub const& );
05967 
05968         public: // IRegistryHub
05969             RegistryHub() {
05970             }
05971             virtual IReporterRegistry const& getReporterRegistry() const {
05972                 return m_reporterRegistry;
05973             }
05974             virtual ITestCaseRegistry const& getTestCaseRegistry() const {
05975                 return m_testCaseRegistry;
05976             }
05977             virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() {
05978                 return m_exceptionTranslatorRegistry;
05979             }
05980 
05981         public: // IMutableRegistryHub
05982             virtual void registerReporter( std::string const& name, IReporterFactory* factory ) {
05983                 m_reporterRegistry.registerReporter( name, factory );
05984             }
05985             virtual void registerTest( TestCase const& testInfo ) {
05986                 m_testCaseRegistry.registerTest( testInfo );
05987             }
05988             virtual void registerTranslator( const IExceptionTranslator* translator ) {
05989                 m_exceptionTranslatorRegistry.registerTranslator( translator );
05990             }
05991 
05992         private:
05993             TestRegistry m_testCaseRegistry;
05994             ReporterRegistry m_reporterRegistry;
05995             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
05996         };
05997 
05998         // Single, global, instance
05999         inline RegistryHub*& getTheRegistryHub() {
06000             static RegistryHub* theRegistryHub = NULL;
06001             if( !theRegistryHub )
06002                 theRegistryHub = new RegistryHub();
06003             return theRegistryHub;
06004         }
06005     }
06006 
06007     IRegistryHub& getRegistryHub() {
06008         return *getTheRegistryHub();
06009     }
06010     IMutableRegistryHub& getMutableRegistryHub() {
06011         return *getTheRegistryHub();
06012     }
06013     void cleanUp() {
06014         delete getTheRegistryHub();
06015         getTheRegistryHub() = NULL;
06016         cleanUpContext();
06017     }
06018     std::string translateActiveException() {
06019         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
06020     }
06021 
06022 } // end namespace Catch
06023 
06024 // #included from: catch_notimplemented_exception.hpp
06025 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
06026 
06027 #include <ostream>
06028 
06029 namespace Catch {
06030 
06031     NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
06032     :   m_lineInfo( lineInfo ) {
06033         std::ostringstream oss;
06034         oss << lineInfo << ": function ";
06035         oss << "not implemented";
06036         m_what = oss.str();
06037     }
06038 
06039     const char* NotImplementedException::what() const CATCH_NOEXCEPT {
06040         return m_what.c_str();
06041     }
06042 
06043 } // end namespace Catch
06044 
06045 // #included from: catch_context_impl.hpp
06046 #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
06047 
06048 // #included from: catch_stream.hpp
06049 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
06050 
06051 // #included from: catch_streambuf.h
06052 #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
06053 
06054 #include <streambuf>
06055 
06056 namespace Catch {
06057 
06058     class StreamBufBase : public std::streambuf {
06059     public:
06060         virtual ~StreamBufBase() CATCH_NOEXCEPT;
06061     };
06062 }
06063 
06064 #include <stdexcept>
06065 #include <cstdio>
06066 #include <iostream>
06067 
06068 namespace Catch {
06069 
06070     template<typename WriterF, size_t bufferSize=256>
06071     class StreamBufImpl : public StreamBufBase {
06072         char data[bufferSize];
06073         WriterF m_writer;
06074 
06075     public:
06076         StreamBufImpl() {
06077             setp( data, data + sizeof(data) );
06078         }
06079 
06080         ~StreamBufImpl() CATCH_NOEXCEPT {
06081             sync();
06082         }
06083 
06084     private:
06085         int overflow( int c ) {
06086             sync();
06087 
06088             if( c != EOF ) {
06089                 if( pbase() == epptr() )
06090                     m_writer( std::string( 1, static_cast<char>( c ) ) );
06091                 else
06092                     sputc( static_cast<char>( c ) );
06093             }
06094             return 0;
06095         }
06096 
06097         int sync() {
06098             if( pbase() != pptr() ) {
06099                 m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
06100                 setp( pbase(), epptr() );
06101             }
06102             return 0;
06103         }
06104     };
06105 
06107 
06108     struct OutputDebugWriter {
06109 
06110         void operator()( std::string const&str ) {
06111             writeToDebugConsole( str );
06112         }
06113     };
06114 
06115     Stream::Stream()
06116     : streamBuf( NULL ), isOwned( false )
06117     {}
06118 
06119     Stream::Stream( std::streambuf* _streamBuf, bool _isOwned )
06120     : streamBuf( _streamBuf ), isOwned( _isOwned )
06121     {}
06122 
06123     void Stream::release() {
06124         if( isOwned ) {
06125             delete streamBuf;
06126             streamBuf = NULL;
06127             isOwned = false;
06128         }
06129     }
06130 
06131 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement this functions
06132     std::ostream& cout() {
06133         return std::cout;
06134     }
06135     std::ostream& cerr() {
06136         return std::cerr;
06137     }
06138 #endif
06139 }
06140 
06141 namespace Catch {
06142 
06143     class Context : public IMutableContext {
06144 
06145         Context() : m_config( NULL ), m_runner( NULL ), m_resultCapture( NULL ) {}
06146         Context( Context const& );
06147         void operator=( Context const& );
06148 
06149     public: // IContext
06150         virtual IResultCapture* getResultCapture() {
06151             return m_resultCapture;
06152         }
06153         virtual IRunner* getRunner() {
06154             return m_runner;
06155         }
06156         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
06157             return getGeneratorsForCurrentTest()
06158             .getGeneratorInfo( fileInfo, totalSize )
06159             .getCurrentIndex();
06160         }
06161         virtual bool advanceGeneratorsForCurrentTest() {
06162             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
06163             return generators && generators->moveNext();
06164         }
06165 
06166         virtual Ptr<IConfig const> getConfig() const {
06167             return m_config;
06168         }
06169 
06170     public: // IMutableContext
06171         virtual void setResultCapture( IResultCapture* resultCapture ) {
06172             m_resultCapture = resultCapture;
06173         }
06174         virtual void setRunner( IRunner* runner ) {
06175             m_runner = runner;
06176         }
06177         virtual void setConfig( Ptr<IConfig const> const& config ) {
06178             m_config = config;
06179         }
06180 
06181         friend IMutableContext& getCurrentMutableContext();
06182 
06183     private:
06184         IGeneratorsForTest* findGeneratorsForCurrentTest() {
06185             std::string testName = getResultCapture()->getCurrentTestName();
06186 
06187             std::map<std::string, IGeneratorsForTest*>::const_iterator it =
06188                 m_generatorsByTestName.find( testName );
06189             return it != m_generatorsByTestName.end()
06190                 ? it->second
06191                 : NULL;
06192         }
06193 
06194         IGeneratorsForTest& getGeneratorsForCurrentTest() {
06195             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
06196             if( !generators ) {
06197                 std::string testName = getResultCapture()->getCurrentTestName();
06198                 generators = createGeneratorsForTest();
06199                 m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
06200             }
06201             return *generators;
06202         }
06203 
06204     private:
06205         Ptr<IConfig const> m_config;
06206         IRunner* m_runner;
06207         IResultCapture* m_resultCapture;
06208         std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
06209     };
06210 
06211     namespace {
06212         Context* currentContext = NULL;
06213     }
06214     IMutableContext& getCurrentMutableContext() {
06215         if( !currentContext )
06216             currentContext = new Context();
06217         return *currentContext;
06218     }
06219     IContext& getCurrentContext() {
06220         return getCurrentMutableContext();
06221     }
06222 
06223     Stream createStream( std::string const& streamName ) {
06224         if( streamName == "stdout" ) return Stream( Catch::cout().rdbuf(), false );
06225         if( streamName == "stderr" ) return Stream( Catch::cerr().rdbuf(), false );
06226         if( streamName == "debug" ) return Stream( new StreamBufImpl<OutputDebugWriter>, true );
06227 
06228         throw std::domain_error( "Unknown stream: " + streamName );
06229     }
06230 
06231     void cleanUpContext() {
06232         delete currentContext;
06233         currentContext = NULL;
06234     }
06235 }
06236 
06237 // #included from: catch_console_colour_impl.hpp
06238 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
06239 
06240 namespace Catch {
06241     namespace {
06242 
06243         struct IColourImpl {
06244             virtual ~IColourImpl() {}
06245             virtual void use( Colour::Code _colourCode ) = 0;
06246         };
06247 
06248         struct NoColourImpl : IColourImpl {
06249             void use( Colour::Code ) {}
06250 
06251             static IColourImpl* instance() {
06252                 static NoColourImpl s_instance;
06253                 return &s_instance;
06254             }
06255         };
06256 
06257     } // anon namespace
06258 } // namespace Catch
06259 
06260 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
06261 #   ifdef CATCH_PLATFORM_WINDOWS
06262 #       define CATCH_CONFIG_COLOUR_WINDOWS
06263 #   else
06264 #       define CATCH_CONFIG_COLOUR_ANSI
06265 #   endif
06266 #endif
06267 
06268 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
06269 
06270 #ifndef NOMINMAX
06271 #define NOMINMAX
06272 #endif
06273 
06274 #ifdef __AFXDLL
06275 #include <AfxWin.h>
06276 #else
06277 #include <windows.h>
06278 #endif
06279 
06280 namespace Catch {
06281 namespace {
06282 
06283     class Win32ColourImpl : public IColourImpl {
06284     public:
06285         Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
06286         {
06287             CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
06288             GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
06289             originalAttributes = csbiInfo.wAttributes;
06290         }
06291 
06292         virtual void use( Colour::Code _colourCode ) {
06293             switch( _colourCode ) {
06294                 case Colour::None:      return setTextAttribute( originalAttributes );
06295                 case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
06296                 case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
06297                 case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
06298                 case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
06299                 case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
06300                 case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
06301                 case Colour::Grey:      return setTextAttribute( 0 );
06302 
06303                 case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
06304                 case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
06305                 case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
06306                 case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
06307 
06308                 case Colour::Bright: throw std::logic_error( "not a colour" );
06309             }
06310         }
06311 
06312     private:
06313         void setTextAttribute( WORD _textAttribute ) {
06314             SetConsoleTextAttribute( stdoutHandle, _textAttribute );
06315         }
06316         HANDLE stdoutHandle;
06317         WORD originalAttributes;
06318     };
06319 
06320     IColourImpl* platformColourInstance() {
06321         static Win32ColourImpl s_instance;
06322         return &s_instance;
06323     }
06324 
06325 } // end anon namespace
06326 } // end namespace Catch
06327 
06328 #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
06329 
06330 #include <unistd.h>
06331 
06332 namespace Catch {
06333 namespace {
06334 
06335     // use POSIX/ ANSI console terminal codes
06336     // Thanks to Adam Strzelecki for original contribution
06337     // (http://github.com/nanoant)
06338     // https://github.com/philsquared/Catch/pull/131
06339     class PosixColourImpl : public IColourImpl {
06340     public:
06341         virtual void use( Colour::Code _colourCode ) {
06342             switch( _colourCode ) {
06343                 case Colour::None:
06344                 case Colour::White:     return setColour( "[0m" );
06345                 case Colour::Red:       return setColour( "[0;31m" );
06346                 case Colour::Green:     return setColour( "[0;32m" );
06347                 case Colour::Blue:      return setColour( "[0:34m" );
06348                 case Colour::Cyan:      return setColour( "[0;36m" );
06349                 case Colour::Yellow:    return setColour( "[0;33m" );
06350                 case Colour::Grey:      return setColour( "[1;30m" );
06351 
06352                 case Colour::LightGrey:     return setColour( "[0;37m" );
06353                 case Colour::BrightRed:     return setColour( "[1;31m" );
06354                 case Colour::BrightGreen:   return setColour( "[1;32m" );
06355                 case Colour::BrightWhite:   return setColour( "[1;37m" );
06356 
06357                 case Colour::Bright: throw std::logic_error( "not a colour" );
06358             }
06359         }
06360         static IColourImpl* instance() {
06361             static PosixColourImpl s_instance;
06362             return &s_instance;
06363         }
06364 
06365     private:
06366         void setColour( const char* _escapeCode ) {
06367             Catch::cout() << '\033' << _escapeCode;
06368         }
06369     };
06370 
06371     IColourImpl* platformColourInstance() {
06372         Ptr<IConfig const> config = getCurrentContext().getConfig();
06373         return (config && config->forceColour()) || isatty(STDOUT_FILENO)
06374             ? PosixColourImpl::instance()
06375             : NoColourImpl::instance();
06376     }
06377 
06378 } // end anon namespace
06379 } // end namespace Catch
06380 
06381 #else  // not Windows or ANSI ///////////////////////////////////////////////
06382 
06383 namespace Catch {
06384 
06385     static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
06386 
06387 } // end namespace Catch
06388 
06389 #endif // Windows/ ANSI/ None
06390 
06391 namespace Catch {
06392 
06393     Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
06394     Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
06395     Colour::~Colour(){ if( !m_moved ) use( None ); }
06396 
06397     void Colour::use( Code _colourCode ) {
06398         static IColourImpl* impl = isDebuggerActive()
06399             ? NoColourImpl::instance()
06400             : platformColourInstance();
06401         impl->use( _colourCode );
06402     }
06403 
06404 } // end namespace Catch
06405 
06406 // #included from: catch_generators_impl.hpp
06407 #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
06408 
06409 #include <vector>
06410 #include <string>
06411 #include <map>
06412 
06413 namespace Catch {
06414 
06415     struct GeneratorInfo : IGeneratorInfo {
06416 
06417         GeneratorInfo( std::size_t size )
06418         :   m_size( size ),
06419             m_currentIndex( 0 )
06420         {}
06421 
06422         bool moveNext() {
06423             if( ++m_currentIndex == m_size ) {
06424                 m_currentIndex = 0;
06425                 return false;
06426             }
06427             return true;
06428         }
06429 
06430         std::size_t getCurrentIndex() const {
06431             return m_currentIndex;
06432         }
06433 
06434         std::size_t m_size;
06435         std::size_t m_currentIndex;
06436     };
06437 
06439 
06440     class GeneratorsForTest : public IGeneratorsForTest {
06441 
06442     public:
06443         ~GeneratorsForTest() {
06444             deleteAll( m_generatorsInOrder );
06445         }
06446 
06447         IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
06448             std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
06449             if( it == m_generatorsByName.end() ) {
06450                 IGeneratorInfo* info = new GeneratorInfo( size );
06451                 m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
06452                 m_generatorsInOrder.push_back( info );
06453                 return *info;
06454             }
06455             return *it->second;
06456         }
06457 
06458         bool moveNext() {
06459             std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
06460             std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
06461             for(; it != itEnd; ++it ) {
06462                 if( (*it)->moveNext() )
06463                     return true;
06464             }
06465             return false;
06466         }
06467 
06468     private:
06469         std::map<std::string, IGeneratorInfo*> m_generatorsByName;
06470         std::vector<IGeneratorInfo*> m_generatorsInOrder;
06471     };
06472 
06473     IGeneratorsForTest* createGeneratorsForTest()
06474     {
06475         return new GeneratorsForTest();
06476     }
06477 
06478 } // end namespace Catch
06479 
06480 // #included from: catch_assertionresult.hpp
06481 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
06482 
06483 namespace Catch {
06484 
06485     AssertionInfo::AssertionInfo(   std::string const& _macroName,
06486                                     SourceLineInfo const& _lineInfo,
06487                                     std::string const& _capturedExpression,
06488                                     ResultDisposition::Flags _resultDisposition )
06489     :   macroName( _macroName ),
06490         lineInfo( _lineInfo ),
06491         capturedExpression( _capturedExpression ),
06492         resultDisposition( _resultDisposition )
06493     {}
06494 
06495     AssertionResult::AssertionResult() {}
06496 
06497     AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
06498     :   m_info( info ),
06499         m_resultData( data )
06500     {}
06501 
06502     AssertionResult::~AssertionResult() {}
06503 
06504     // Result was a success
06505     bool AssertionResult::succeeded() const {
06506         return Catch::isOk( m_resultData.resultType );
06507     }
06508 
06509     // Result was a success, or failure is suppressed
06510     bool AssertionResult::isOk() const {
06511         return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
06512     }
06513 
06514     ResultWas::OfType AssertionResult::getResultType() const {
06515         return m_resultData.resultType;
06516     }
06517 
06518     bool AssertionResult::hasExpression() const {
06519         return !m_info.capturedExpression.empty();
06520     }
06521 
06522     bool AssertionResult::hasMessage() const {
06523         return !m_resultData.message.empty();
06524     }
06525 
06526     std::string AssertionResult::getExpression() const {
06527         if( isFalseTest( m_info.resultDisposition ) )
06528             return "!" + m_info.capturedExpression;
06529         else
06530             return m_info.capturedExpression;
06531     }
06532     std::string AssertionResult::getExpressionInMacro() const {
06533         if( m_info.macroName.empty() )
06534             return m_info.capturedExpression;
06535         else
06536             return m_info.macroName + "( " + m_info.capturedExpression + " )";
06537     }
06538 
06539     bool AssertionResult::hasExpandedExpression() const {
06540         return hasExpression() && getExpandedExpression() != getExpression();
06541     }
06542 
06543     std::string AssertionResult::getExpandedExpression() const {
06544         return m_resultData.reconstructedExpression;
06545     }
06546 
06547     std::string AssertionResult::getMessage() const {
06548         return m_resultData.message;
06549     }
06550     SourceLineInfo AssertionResult::getSourceInfo() const {
06551         return m_info.lineInfo;
06552     }
06553 
06554     std::string AssertionResult::getTestMacroName() const {
06555         return m_info.macroName;
06556     }
06557 
06558 } // end namespace Catch
06559 
06560 // #included from: catch_test_case_info.hpp
06561 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
06562 
06563 namespace Catch {
06564 
06565     inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
06566         if( startsWith( tag, "." ) ||
06567             tag == "hide" ||
06568             tag == "!hide" )
06569             return TestCaseInfo::IsHidden;
06570         else if( tag == "!throws" )
06571             return TestCaseInfo::Throws;
06572         else if( tag == "!shouldfail" )
06573             return TestCaseInfo::ShouldFail;
06574         else if( tag == "!mayfail" )
06575             return TestCaseInfo::MayFail;
06576         else
06577             return TestCaseInfo::None;
06578     }
06579     inline bool isReservedTag( std::string const& tag ) {
06580         return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
06581     }
06582     inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
06583         if( isReservedTag( tag ) ) {
06584             {
06585                 Colour colourGuard( Colour::Red );
06586                 Catch::cerr()
06587                     << "Tag name [" << tag << "] not allowed.\n"
06588                     << "Tag names starting with non alpha-numeric characters are reserved\n";
06589             }
06590             {
06591                 Colour colourGuard( Colour::FileName );
06592                 Catch::cerr() << _lineInfo << std::endl;
06593             }
06594             exit(1);
06595         }
06596     }
06597 
06598     TestCase makeTestCase(  ITestCase* _testCase,
06599                             std::string const& _className,
06600                             std::string const& _name,
06601                             std::string const& _descOrTags,
06602                             SourceLineInfo const& _lineInfo )
06603     {
06604         bool isHidden( startsWith( _name, "./" ) ); // Legacy support
06605 
06606         // Parse out tags
06607         std::set<std::string> tags;
06608         std::string desc, tag;
06609         bool inTag = false;
06610         for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
06611             char c = _descOrTags[i];
06612             if( !inTag ) {
06613                 if( c == '[' )
06614                     inTag = true;
06615                 else
06616                     desc += c;
06617             }
06618             else {
06619                 if( c == ']' ) {
06620                     TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
06621                     if( prop == TestCaseInfo::IsHidden )
06622                         isHidden = true;
06623                     else if( prop == TestCaseInfo::None )
06624                         enforceNotReservedTag( tag, _lineInfo );
06625 
06626                     tags.insert( tag );
06627                     tag.clear();
06628                     inTag = false;
06629                 }
06630                 else
06631                     tag += c;
06632             }
06633         }
06634         if( isHidden ) {
06635             tags.insert( "hide" );
06636             tags.insert( "." );
06637         }
06638 
06639         TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
06640         return TestCase( _testCase, info );
06641     }
06642 
06643     TestCaseInfo::TestCaseInfo( std::string const& _name,
06644                                 std::string const& _className,
06645                                 std::string const& _description,
06646                                 std::set<std::string> const& _tags,
06647                                 SourceLineInfo const& _lineInfo )
06648     :   name( _name ),
06649         className( _className ),
06650         description( _description ),
06651         tags( _tags ),
06652         lineInfo( _lineInfo ),
06653         properties( None )
06654     {
06655         std::ostringstream oss;
06656         for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) {
06657             oss << "[" << *it << "]";
06658             std::string lcaseTag = toLower( *it );
06659             properties = static_cast<SpecialProperties>( properties | parseSpecialTag( lcaseTag ) );
06660             lcaseTags.insert( lcaseTag );
06661         }
06662         tagsAsString = oss.str();
06663     }
06664 
06665     TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
06666     :   name( other.name ),
06667         className( other.className ),
06668         description( other.description ),
06669         tags( other.tags ),
06670         lcaseTags( other.lcaseTags ),
06671         tagsAsString( other.tagsAsString ),
06672         lineInfo( other.lineInfo ),
06673         properties( other.properties )
06674     {}
06675 
06676     bool TestCaseInfo::isHidden() const {
06677         return ( properties & IsHidden ) != 0;
06678     }
06679     bool TestCaseInfo::throws() const {
06680         return ( properties & Throws ) != 0;
06681     }
06682     bool TestCaseInfo::okToFail() const {
06683         return ( properties & (ShouldFail | MayFail ) ) != 0;
06684     }
06685     bool TestCaseInfo::expectedToFail() const {
06686         return ( properties & (ShouldFail ) ) != 0;
06687     }
06688 
06689     TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
06690 
06691     TestCase::TestCase( TestCase const& other )
06692     :   TestCaseInfo( other ),
06693         test( other.test )
06694     {}
06695 
06696     TestCase TestCase::withName( std::string const& _newName ) const {
06697         TestCase other( *this );
06698         other.name = _newName;
06699         return other;
06700     }
06701 
06702     void TestCase::swap( TestCase& other ) {
06703         test.swap( other.test );
06704         name.swap( other.name );
06705         className.swap( other.className );
06706         description.swap( other.description );
06707         tags.swap( other.tags );
06708         lcaseTags.swap( other.lcaseTags );
06709         tagsAsString.swap( other.tagsAsString );
06710         std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
06711         std::swap( lineInfo, other.lineInfo );
06712     }
06713 
06714     void TestCase::invoke() const {
06715         test->invoke();
06716     }
06717 
06718     bool TestCase::operator == ( TestCase const& other ) const {
06719         return  test.get() == other.test.get() &&
06720                 name == other.name &&
06721                 className == other.className;
06722     }
06723 
06724     bool TestCase::operator < ( TestCase const& other ) const {
06725         return name < other.name;
06726     }
06727     TestCase& TestCase::operator = ( TestCase const& other ) {
06728         TestCase temp( other );
06729         swap( temp );
06730         return *this;
06731     }
06732 
06733     TestCaseInfo const& TestCase::getTestCaseInfo() const
06734     {
06735         return *this;
06736     }
06737 
06738 } // end namespace Catch
06739 
06740 // #included from: catch_version.hpp
06741 #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
06742 
06743 namespace Catch {
06744 
06745     Version::Version
06746         (   unsigned int _majorVersion,
06747             unsigned int _minorVersion,
06748             unsigned int _patchNumber,
06749             std::string const& _branchName,
06750             unsigned int _buildNumber )
06751     :   majorVersion( _majorVersion ),
06752         minorVersion( _minorVersion ),
06753         patchNumber( _patchNumber ),
06754         branchName( _branchName ),
06755         buildNumber( _buildNumber )
06756     {}
06757 
06758     std::ostream& operator << ( std::ostream& os, Version const& version ) {
06759         os  << version.majorVersion << "."
06760             << version.minorVersion << "."
06761             << version.patchNumber;
06762 
06763         if( !version.branchName.empty() ) {
06764             os  << "-" << version.branchName
06765                 << "." << version.buildNumber;
06766         }
06767         return os;
06768     }
06769 
06770     Version libraryVersion( 1, 2, 1, "", 0 );
06771 
06772 }
06773 
06774 // #included from: catch_message.hpp
06775 #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
06776 
06777 namespace Catch {
06778 
06779     MessageInfo::MessageInfo(   std::string const& _macroName,
06780                                 SourceLineInfo const& _lineInfo,
06781                                 ResultWas::OfType _type )
06782     :   macroName( _macroName ),
06783         lineInfo( _lineInfo ),
06784         type( _type ),
06785         sequence( ++globalCount )
06786     {}
06787 
06788     // This may need protecting if threading support is added
06789     unsigned int MessageInfo::globalCount = 0;
06790 
06792 
06793     ScopedMessage::ScopedMessage( MessageBuilder const& builder )
06794     : m_info( builder.m_info )
06795     {
06796         m_info.message = builder.m_stream.str();
06797         getResultCapture().pushScopedMessage( m_info );
06798     }
06799     ScopedMessage::ScopedMessage( ScopedMessage const& other )
06800     : m_info( other.m_info )
06801     {}
06802 
06803     ScopedMessage::~ScopedMessage() {
06804         getResultCapture().popScopedMessage( m_info );
06805     }
06806 
06807 } // end namespace Catch
06808 
06809 // #included from: catch_legacy_reporter_adapter.hpp
06810 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
06811 
06812 // #included from: catch_legacy_reporter_adapter.h
06813 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
06814 
06815 namespace Catch
06816 {
06817     // Deprecated
06818     struct IReporter : IShared {
06819         virtual ~IReporter();
06820 
06821         virtual bool shouldRedirectStdout() const = 0;
06822 
06823         virtual void StartTesting() = 0;
06824         virtual void EndTesting( Totals const& totals ) = 0;
06825         virtual void StartGroup( std::string const& groupName ) = 0;
06826         virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
06827         virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
06828         virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
06829         virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
06830         virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
06831         virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
06832         virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
06833         virtual void Aborted() = 0;
06834         virtual void Result( AssertionResult const& result ) = 0;
06835     };
06836 
06837     class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
06838     {
06839     public:
06840         LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
06841         virtual ~LegacyReporterAdapter();
06842 
06843         virtual ReporterPreferences getPreferences() const;
06844         virtual void noMatchingTestCases( std::string const& );
06845         virtual void testRunStarting( TestRunInfo const& );
06846         virtual void testGroupStarting( GroupInfo const& groupInfo );
06847         virtual void testCaseStarting( TestCaseInfo const& testInfo );
06848         virtual void sectionStarting( SectionInfo const& sectionInfo );
06849         virtual void assertionStarting( AssertionInfo const& );
06850         virtual bool assertionEnded( AssertionStats const& assertionStats );
06851         virtual void sectionEnded( SectionStats const& sectionStats );
06852         virtual void testCaseEnded( TestCaseStats const& testCaseStats );
06853         virtual void testGroupEnded( TestGroupStats const& testGroupStats );
06854         virtual void testRunEnded( TestRunStats const& testRunStats );
06855         virtual void skipTest( TestCaseInfo const& );
06856 
06857     private:
06858         Ptr<IReporter> m_legacyReporter;
06859     };
06860 }
06861 
06862 namespace Catch
06863 {
06864     LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
06865     :   m_legacyReporter( legacyReporter )
06866     {}
06867     LegacyReporterAdapter::~LegacyReporterAdapter() {}
06868 
06869     ReporterPreferences LegacyReporterAdapter::getPreferences() const {
06870         ReporterPreferences prefs;
06871         prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
06872         return prefs;
06873     }
06874 
06875     void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
06876     void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
06877         m_legacyReporter->StartTesting();
06878     }
06879     void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
06880         m_legacyReporter->StartGroup( groupInfo.name );
06881     }
06882     void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
06883         m_legacyReporter->StartTestCase( testInfo );
06884     }
06885     void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
06886         m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
06887     }
06888     void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
06889         // Not on legacy interface
06890     }
06891 
06892     bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
06893         if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
06894             for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
06895                     it != itEnd;
06896                     ++it ) {
06897                 if( it->type == ResultWas::Info ) {
06898                     ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
06899                     rb << it->message;
06900                     rb.setResultType( ResultWas::Info );
06901                     AssertionResult result = rb.build();
06902                     m_legacyReporter->Result( result );
06903                 }
06904             }
06905         }
06906         m_legacyReporter->Result( assertionStats.assertionResult );
06907         return true;
06908     }
06909     void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
06910         if( sectionStats.missingAssertions )
06911             m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
06912         m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
06913     }
06914     void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
06915         m_legacyReporter->EndTestCase
06916             (   testCaseStats.testInfo,
06917                 testCaseStats.totals,
06918                 testCaseStats.stdOut,
06919                 testCaseStats.stdErr );
06920     }
06921     void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
06922         if( testGroupStats.aborting )
06923             m_legacyReporter->Aborted();
06924         m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
06925     }
06926     void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
06927         m_legacyReporter->EndTesting( testRunStats.totals );
06928     }
06929     void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
06930     }
06931 }
06932 
06933 // #included from: catch_timer.hpp
06934 
06935 #ifdef __clang__
06936 #pragma clang diagnostic push
06937 #pragma clang diagnostic ignored "-Wc++11-long-long"
06938 #endif
06939 
06940 #ifdef CATCH_PLATFORM_WINDOWS
06941 #include <windows.h>
06942 #else
06943 #include <sys/time.h>
06944 #endif
06945 
06946 namespace Catch {
06947 
06948     namespace {
06949 #ifdef CATCH_PLATFORM_WINDOWS
06950         uint64_t getCurrentTicks() {
06951             static uint64_t hz=0, hzo=0;
06952             if (!hz) {
06953                 QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
06954                 QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
06955             }
06956             uint64_t t;
06957             QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
06958             return ((t-hzo)*1000000)/hz;
06959         }
06960 #else
06961         uint64_t getCurrentTicks() {
06962             timeval t;
06963             gettimeofday(&t,NULL);
06964             return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
06965         }
06966 #endif
06967     }
06968 
06969     void Timer::start() {
06970         m_ticks = getCurrentTicks();
06971     }
06972     unsigned int Timer::getElapsedMicroseconds() const {
06973         return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
06974     }
06975     unsigned int Timer::getElapsedMilliseconds() const {
06976         return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
06977     }
06978     double Timer::getElapsedSeconds() const {
06979         return getElapsedMicroseconds()/1000000.0;
06980     }
06981 
06982 } // namespace Catch
06983 
06984 #ifdef __clang__
06985 #pragma clang diagnostic pop
06986 #endif
06987 // #included from: catch_common.hpp
06988 #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
06989 
06990 namespace Catch {
06991 
06992     bool startsWith( std::string const& s, std::string const& prefix ) {
06993         return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
06994     }
06995     bool endsWith( std::string const& s, std::string const& suffix ) {
06996         return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
06997     }
06998     bool contains( std::string const& s, std::string const& infix ) {
06999         return s.find( infix ) != std::string::npos;
07000     }
07001     void toLowerInPlace( std::string& s ) {
07002         std::transform( s.begin(), s.end(), s.begin(), ::tolower );
07003     }
07004     std::string toLower( std::string const& s ) {
07005         std::string lc = s;
07006         toLowerInPlace( lc );
07007         return lc;
07008     }
07009     std::string trim( std::string const& str ) {
07010         static char const* whitespaceChars = "\n\r\t ";
07011         std::string::size_type start = str.find_first_not_of( whitespaceChars );
07012         std::string::size_type end = str.find_last_not_of( whitespaceChars );
07013 
07014         return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
07015     }
07016 
07017     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
07018         bool replaced = false;
07019         std::size_t i = str.find( replaceThis );
07020         while( i != std::string::npos ) {
07021             replaced = true;
07022             str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
07023             if( i < str.size()-withThis.size() )
07024                 i = str.find( replaceThis, i+withThis.size() );
07025             else
07026                 i = std::string::npos;
07027         }
07028         return replaced;
07029     }
07030 
07031     pluralise::pluralise( std::size_t count, std::string const& label )
07032     :   m_count( count ),
07033         m_label( label )
07034     {}
07035 
07036     std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
07037         os << pluraliser.m_count << " " << pluraliser.m_label;
07038         if( pluraliser.m_count != 1 )
07039             os << "s";
07040         return os;
07041     }
07042 
07043     SourceLineInfo::SourceLineInfo() : line( 0 ){}
07044     SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
07045     :   file( _file ),
07046         line( _line )
07047     {}
07048     SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
07049     :   file( other.file ),
07050         line( other.line )
07051     {}
07052     bool SourceLineInfo::empty() const {
07053         return file.empty();
07054     }
07055     bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
07056         return line == other.line && file == other.file;
07057     }
07058     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
07059         return line < other.line || ( line == other.line  && file < other.file );
07060     }
07061 
07062     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
07063 #ifndef __GNUG__
07064         os << info.file << "(" << info.line << ")";
07065 #else
07066         os << info.file << ":" << info.line;
07067 #endif
07068         return os;
07069     }
07070 
07071     void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
07072         std::ostringstream oss;
07073         oss << locationInfo << ": Internal Catch error: '" << message << "'";
07074         if( alwaysTrue() )
07075             throw std::logic_error( oss.str() );
07076     }
07077 }
07078 
07079 // #included from: catch_section.hpp
07080 #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
07081 
07082 namespace Catch {
07083 
07084     SectionInfo::SectionInfo
07085         (   SourceLineInfo const& _lineInfo,
07086             std::string const& _name,
07087             std::string const& _description )
07088     :   name( _name ),
07089         description( _description ),
07090         lineInfo( _lineInfo )
07091     {}
07092 
07093     Section::Section( SectionInfo const& info )
07094     :   m_info( info ),
07095         m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
07096     {
07097         m_timer.start();
07098     }
07099 
07100     Section::~Section() {
07101         if( m_sectionIncluded )
07102             getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() );
07103     }
07104 
07105     // This indicates whether the section should be executed or not
07106     Section::operator bool() const {
07107         return m_sectionIncluded;
07108     }
07109 
07110 } // end namespace Catch
07111 
07112 // #included from: catch_debugger.hpp
07113 #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
07114 
07115 #include <iostream>
07116 
07117 #ifdef CATCH_PLATFORM_MAC
07118 
07119     #include <assert.h>
07120     #include <stdbool.h>
07121     #include <sys/types.h>
07122     #include <unistd.h>
07123     #include <sys/sysctl.h>
07124 
07125     namespace Catch{
07126 
07127         // The following function is taken directly from the following technical note:
07128         // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
07129 
07130         // Returns true if the current process is being debugged (either
07131         // running under the debugger or has a debugger attached post facto).
07132         bool isDebuggerActive(){
07133 
07134             int                 mib[4];
07135             struct kinfo_proc   info;
07136             size_t              size;
07137 
07138             // Initialize the flags so that, if sysctl fails for some bizarre
07139             // reason, we get a predictable result.
07140 
07141             info.kp_proc.p_flag = 0;
07142 
07143             // Initialize mib, which tells sysctl the info we want, in this case
07144             // we're looking for information about a specific process ID.
07145 
07146             mib[0] = CTL_KERN;
07147             mib[1] = KERN_PROC;
07148             mib[2] = KERN_PROC_PID;
07149             mib[3] = getpid();
07150 
07151             // Call sysctl.
07152 
07153             size = sizeof(info);
07154             if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0) != 0 ) {
07155                 Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
07156                 return false;
07157             }
07158 
07159             // We're being debugged if the P_TRACED flag is set.
07160 
07161             return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
07162         }
07163     } // namespace Catch
07164 
07165 #elif defined(_MSC_VER)
07166     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
07167     namespace Catch {
07168         bool isDebuggerActive() {
07169             return IsDebuggerPresent() != 0;
07170         }
07171     }
07172 #elif defined(__MINGW32__)
07173     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
07174     namespace Catch {
07175         bool isDebuggerActive() {
07176             return IsDebuggerPresent() != 0;
07177         }
07178     }
07179 #else
07180     namespace Catch {
07181        inline bool isDebuggerActive() { return false; }
07182     }
07183 #endif // Platform
07184 
07185 #ifdef CATCH_PLATFORM_WINDOWS
07186     extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
07187     namespace Catch {
07188         void writeToDebugConsole( std::string const& text ) {
07189             ::OutputDebugStringA( text.c_str() );
07190         }
07191     }
07192 #else
07193     namespace Catch {
07194         void writeToDebugConsole( std::string const& text ) {
07195             // !TBD: Need a version for Mac/ XCode and other IDEs
07196             Catch::cout() << text;
07197         }
07198     }
07199 #endif // Platform
07200 
07201 // #included from: catch_tostring.hpp
07202 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
07203 
07204 namespace Catch {
07205 
07206 namespace Detail {
07207 
07208     std::string unprintableString = "{?}";
07209 
07210     namespace {
07211         struct Endianness {
07212             enum Arch { Big, Little };
07213 
07214             static Arch which() {
07215                 union _{
07216                     int asInt;
07217                     char asChar[sizeof (int)];
07218                 } u;
07219 
07220                 u.asInt = 1;
07221                 return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
07222             }
07223         };
07224     }
07225 
07226     std::string rawMemoryToString( const void *object, std::size_t size )
07227     {
07228         // Reverse order for little endian architectures
07229         int i = 0, end = static_cast<int>( size ), inc = 1;
07230         if( Endianness::which() == Endianness::Little ) {
07231             i = end-1;
07232             end = inc = -1;
07233         }
07234 
07235         unsigned char const *bytes = static_cast<unsigned char const *>(object);
07236         std::ostringstream os;
07237         os << "0x" << std::setfill('0') << std::hex;
07238         for( ; i != end; i += inc )
07239              os << std::setw(2) << static_cast<unsigned>(bytes[i]);
07240        return os.str();
07241     }
07242 }
07243 
07244 std::string toString( std::string const& value ) {
07245     std::string s = value;
07246     if( getCurrentContext().getConfig()->showInvisibles() ) {
07247         for(size_t i = 0; i < s.size(); ++i ) {
07248             std::string subs;
07249             switch( s[i] ) {
07250             case '\n': subs = "\\n"; break;
07251             case '\t': subs = "\\t"; break;
07252             default: break;
07253             }
07254             if( !subs.empty() ) {
07255                 s = s.substr( 0, i ) + subs + s.substr( i+1 );
07256                 ++i;
07257             }
07258         }
07259     }
07260     return "\"" + s + "\"";
07261 }
07262 std::string toString( std::wstring const& value ) {
07263 
07264     std::string s;
07265     s.reserve( value.size() );
07266     for(size_t i = 0; i < value.size(); ++i )
07267         s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
07268     return Catch::toString( s );
07269 }
07270 
07271 std::string toString( const char* const value ) {
07272     return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
07273 }
07274 
07275 std::string toString( char* const value ) {
07276     return Catch::toString( static_cast<const char*>( value ) );
07277 }
07278 
07279 std::string toString( const wchar_t* const value )
07280 {
07281         return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
07282 }
07283 
07284 std::string toString( wchar_t* const value )
07285 {
07286         return Catch::toString( static_cast<const wchar_t*>( value ) );
07287 }
07288 
07289 std::string toString( int value ) {
07290     std::ostringstream oss;
07291     oss << value;
07292     if( value >= 255 )
07293         oss << " (0x" << std::hex << value << ")";
07294     return oss.str();
07295 }
07296 
07297 std::string toString( unsigned long value ) {
07298     std::ostringstream oss;
07299     oss << value;
07300     if( value >= 255 )
07301         oss << " (0x" << std::hex << value << ")";
07302     return oss.str();
07303 }
07304 
07305 std::string toString( unsigned int value ) {
07306     return Catch::toString( static_cast<unsigned long>( value ) );
07307 }
07308 
07309 template<typename T>
07310 std::string fpToString( T value, int precision ) {
07311     std::ostringstream oss;
07312     oss << std::setprecision( precision )
07313         << std::fixed
07314         << value;
07315     std::string d = oss.str();
07316     std::size_t i = d.find_last_not_of( '0' );
07317     if( i != std::string::npos && i != d.size()-1 ) {
07318         if( d[i] == '.' )
07319             i++;
07320         d = d.substr( 0, i+1 );
07321     }
07322     return d;
07323 }
07324 
07325 std::string toString( const double value ) {
07326     return fpToString( value, 10 );
07327 }
07328 std::string toString( const float value ) {
07329     return fpToString( value, 5 ) + "f";
07330 }
07331 
07332 std::string toString( bool value ) {
07333     return value ? "true" : "false";
07334 }
07335 
07336 std::string toString( char value ) {
07337     return value < ' '
07338         ? toString( static_cast<unsigned int>( value ) )
07339         : Detail::makeString( value );
07340 }
07341 
07342 std::string toString( signed char value ) {
07343     return toString( static_cast<char>( value ) );
07344 }
07345 
07346 std::string toString( unsigned char value ) {
07347     return toString( static_cast<char>( value ) );
07348 }
07349 
07350 #ifdef CATCH_CONFIG_CPP11_NULLPTR
07351 std::string toString( std::nullptr_t ) {
07352     return "nullptr";
07353 }
07354 #endif
07355 
07356 #ifdef __OBJC__
07357     std::string toString( NSString const * const& nsstring ) {
07358         if( !nsstring )
07359             return "nil";
07360         return "@" + toString([nsstring UTF8String]);
07361     }
07362     std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
07363         if( !nsstring )
07364             return "nil";
07365         return "@" + toString([nsstring UTF8String]);
07366     }
07367     std::string toString( NSObject* const& nsObject ) {
07368         return toString( [nsObject description] );
07369     }
07370 #endif
07371 
07372 } // end namespace Catch
07373 
07374 // #included from: catch_result_builder.hpp
07375 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
07376 
07377 namespace Catch {
07378 
07379     ResultBuilder::ResultBuilder(   char const* macroName,
07380                                     SourceLineInfo const& lineInfo,
07381                                     char const* capturedExpression,
07382                                     ResultDisposition::Flags resultDisposition )
07383     :   m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition ),
07384         m_shouldDebugBreak( false ),
07385         m_shouldThrow( false )
07386     {}
07387 
07388     ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
07389         m_data.resultType = result;
07390         return *this;
07391     }
07392     ResultBuilder& ResultBuilder::setResultType( bool result ) {
07393         m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
07394         return *this;
07395     }
07396     ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
07397         m_exprComponents.lhs = lhs;
07398         return *this;
07399     }
07400     ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
07401         m_exprComponents.rhs = rhs;
07402         return *this;
07403     }
07404     ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
07405         m_exprComponents.op = op;
07406         return *this;
07407     }
07408 
07409     void ResultBuilder::endExpression() {
07410         m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
07411         captureExpression();
07412     }
07413 
07414     void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
07415         m_assertionInfo.resultDisposition = resultDisposition;
07416         m_stream.oss << Catch::translateActiveException();
07417         captureResult( ResultWas::ThrewException );
07418     }
07419 
07420     void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
07421         setResultType( resultType );
07422         captureExpression();
07423     }
07424 
07425     void ResultBuilder::captureExpression() {
07426         AssertionResult result = build();
07427         getResultCapture().assertionEnded( result );
07428 
07429         if( !result.isOk() ) {
07430             if( getCurrentContext().getConfig()->shouldDebugBreak() )
07431                 m_shouldDebugBreak = true;
07432             if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
07433                 m_shouldThrow = true;
07434         }
07435     }
07436     void ResultBuilder::react() {
07437         if( m_shouldThrow )
07438             throw Catch::TestFailureException();
07439     }
07440 
07441     bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
07442     bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
07443 
07444     AssertionResult ResultBuilder::build() const
07445     {
07446         assert( m_data.resultType != ResultWas::Unknown );
07447 
07448         AssertionResultData data = m_data;
07449 
07450         // Flip bool results if testFalse is set
07451         if( m_exprComponents.testFalse ) {
07452             if( data.resultType == ResultWas::Ok )
07453                 data.resultType = ResultWas::ExpressionFailed;
07454             else if( data.resultType == ResultWas::ExpressionFailed )
07455                 data.resultType = ResultWas::Ok;
07456         }
07457 
07458         data.message = m_stream.oss.str();
07459         data.reconstructedExpression = reconstructExpression();
07460         if( m_exprComponents.testFalse ) {
07461             if( m_exprComponents.op == "" )
07462                 data.reconstructedExpression = "!" + data.reconstructedExpression;
07463             else
07464                 data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
07465         }
07466         return AssertionResult( m_assertionInfo, data );
07467     }
07468     std::string ResultBuilder::reconstructExpression() const {
07469         if( m_exprComponents.op == "" )
07470             return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
07471         else if( m_exprComponents.op == "matches" )
07472             return m_exprComponents.lhs + " " + m_exprComponents.rhs;
07473         else if( m_exprComponents.op != "!" ) {
07474             if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
07475                 m_exprComponents.lhs.find("\n") == std::string::npos &&
07476                 m_exprComponents.rhs.find("\n") == std::string::npos )
07477                 return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
07478             else
07479                 return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
07480         }
07481         else
07482             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}";
07483     }
07484 
07485 } // end namespace Catch
07486 
07487 // #included from: catch_tag_alias_registry.hpp
07488 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
07489 
07490 // #included from: catch_tag_alias_registry.h
07491 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
07492 
07493 #include <map>
07494 
07495 namespace Catch {
07496 
07497     class TagAliasRegistry : public ITagAliasRegistry {
07498     public:
07499         virtual ~TagAliasRegistry();
07500         virtual Option<TagAlias> find( std::string const& alias ) const;
07501         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
07502         void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
07503         static TagAliasRegistry& get();
07504 
07505     private:
07506         std::map<std::string, TagAlias> m_registry;
07507     };
07508 
07509 } // end namespace Catch
07510 
07511 #include <map>
07512 #include <iostream>
07513 
07514 namespace Catch {
07515 
07516     TagAliasRegistry::~TagAliasRegistry() {}
07517 
07518     Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
07519         std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
07520         if( it != m_registry.end() )
07521             return it->second;
07522         else
07523             return Option<TagAlias>();
07524     }
07525 
07526     std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
07527         std::string expandedTestSpec = unexpandedTestSpec;
07528         for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
07529                 it != itEnd;
07530                 ++it ) {
07531             std::size_t pos = expandedTestSpec.find( it->first );
07532             if( pos != std::string::npos ) {
07533                 expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
07534                                     it->second.tag +
07535                                     expandedTestSpec.substr( pos + it->first.size() );
07536             }
07537         }
07538         return expandedTestSpec;
07539     }
07540 
07541     void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
07542 
07543         if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
07544             std::ostringstream oss;
07545             oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
07546             throw std::domain_error( oss.str().c_str() );
07547         }
07548         if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
07549             std::ostringstream oss;
07550             oss << "error: tag alias, \"" << alias << "\" already registered.\n"
07551                 << "\tFirst seen at " << find(alias)->lineInfo << "\n"
07552                 << "\tRedefined at " << lineInfo;
07553             throw std::domain_error( oss.str().c_str() );
07554         }
07555     }
07556 
07557     TagAliasRegistry& TagAliasRegistry::get() {
07558         static TagAliasRegistry instance;
07559         return instance;
07560 
07561     }
07562 
07563     ITagAliasRegistry::~ITagAliasRegistry() {}
07564     ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
07565 
07566     RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
07567         try {
07568             TagAliasRegistry::get().add( alias, tag, lineInfo );
07569         }
07570         catch( std::exception& ex ) {
07571             Colour colourGuard( Colour::Red );
07572             Catch::cerr() << ex.what() << std::endl;
07573             exit(1);
07574         }
07575     }
07576 
07577 } // end namespace Catch
07578 
07579 // #included from: ../reporters/catch_reporter_xml.hpp
07580 #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
07581 
07582 // #included from: catch_reporter_bases.hpp
07583 #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
07584 
07585 #include <cstring>
07586 
07587 namespace Catch {
07588 
07589     struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
07590 
07591         StreamingReporterBase( ReporterConfig const& _config )
07592         :   m_config( _config.fullConfig() ),
07593             stream( _config.stream() )
07594         {}
07595 
07596         virtual ~StreamingReporterBase();
07597 
07598         virtual void noMatchingTestCases( std::string const& ) {}
07599 
07600         virtual void testRunStarting( TestRunInfo const& _testRunInfo ) {
07601             currentTestRunInfo = _testRunInfo;
07602         }
07603         virtual void testGroupStarting( GroupInfo const& _groupInfo ) {
07604             currentGroupInfo = _groupInfo;
07605         }
07606 
07607         virtual void testCaseStarting( TestCaseInfo const& _testInfo ) {
07608             currentTestCaseInfo = _testInfo;
07609         }
07610         virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
07611             m_sectionStack.push_back( _sectionInfo );
07612         }
07613 
07614         virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) {
07615             m_sectionStack.pop_back();
07616         }
07617         virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) {
07618             currentTestCaseInfo.reset();
07619         }
07620         virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) {
07621             currentGroupInfo.reset();
07622         }
07623         virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) {
07624             currentTestCaseInfo.reset();
07625             currentGroupInfo.reset();
07626             currentTestRunInfo.reset();
07627         }
07628 
07629         virtual void skipTest( TestCaseInfo const& ) {
07630             // Don't do anything with this by default.
07631             // It can optionally be overridden in the derived class.
07632         }
07633 
07634         Ptr<IConfig> m_config;
07635         std::ostream& stream;
07636 
07637         LazyStat<TestRunInfo> currentTestRunInfo;
07638         LazyStat<GroupInfo> currentGroupInfo;
07639         LazyStat<TestCaseInfo> currentTestCaseInfo;
07640 
07641         std::vector<SectionInfo> m_sectionStack;
07642     };
07643 
07644     struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
07645         template<typename T, typename ChildNodeT>
07646         struct Node : SharedImpl<> {
07647             explicit Node( T const& _value ) : value( _value ) {}
07648             virtual ~Node() {}
07649 
07650             typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
07651             T value;
07652             ChildNodes children;
07653         };
07654         struct SectionNode : SharedImpl<> {
07655             explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
07656             virtual ~SectionNode();
07657 
07658             bool operator == ( SectionNode const& other ) const {
07659                 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
07660             }
07661             bool operator == ( Ptr<SectionNode> const& other ) const {
07662                 return operator==( *other );
07663             }
07664 
07665             SectionStats stats;
07666             typedef std::vector<Ptr<SectionNode> > ChildSections;
07667             typedef std::vector<AssertionStats> Assertions;
07668             ChildSections childSections;
07669             Assertions assertions;
07670             std::string stdOut;
07671             std::string stdErr;
07672         };
07673 
07674         struct BySectionInfo {
07675             BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
07676                         BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
07677             bool operator() ( Ptr<SectionNode> const& node ) const {
07678                 return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
07679             }
07680         private:
07681                         void operator=( BySectionInfo const& );
07682             SectionInfo const& m_other;
07683         };
07684 
07685         typedef Node<TestCaseStats, SectionNode> TestCaseNode;
07686         typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
07687         typedef Node<TestRunStats, TestGroupNode> TestRunNode;
07688 
07689         CumulativeReporterBase( ReporterConfig const& _config )
07690         :   m_config( _config.fullConfig() ),
07691             stream( _config.stream() )
07692         {}
07693         ~CumulativeReporterBase();
07694 
07695         virtual void testRunStarting( TestRunInfo const& ) {}
07696         virtual void testGroupStarting( GroupInfo const& ) {}
07697 
07698         virtual void testCaseStarting( TestCaseInfo const& ) {}
07699 
07700         virtual void sectionStarting( SectionInfo const& sectionInfo ) {
07701             SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
07702             Ptr<SectionNode> node;
07703             if( m_sectionStack.empty() ) {
07704                 if( !m_rootSection )
07705                     m_rootSection = new SectionNode( incompleteStats );
07706                 node = m_rootSection;
07707             }
07708             else {
07709                 SectionNode& parentNode = *m_sectionStack.back();
07710                 SectionNode::ChildSections::const_iterator it =
07711                     std::find_if(   parentNode.childSections.begin(),
07712                                     parentNode.childSections.end(),
07713                                     BySectionInfo( sectionInfo ) );
07714                 if( it == parentNode.childSections.end() ) {
07715                     node = new SectionNode( incompleteStats );
07716                     parentNode.childSections.push_back( node );
07717                 }
07718                 else
07719                     node = *it;
07720             }
07721             m_sectionStack.push_back( node );
07722             m_deepestSection = node;
07723         }
07724 
07725         virtual void assertionStarting( AssertionInfo const& ) {}
07726 
07727         virtual bool assertionEnded( AssertionStats const& assertionStats ) {
07728             assert( !m_sectionStack.empty() );
07729             SectionNode& sectionNode = *m_sectionStack.back();
07730             sectionNode.assertions.push_back( assertionStats );
07731             return true;
07732         }
07733         virtual void sectionEnded( SectionStats const& sectionStats ) {
07734             assert( !m_sectionStack.empty() );
07735             SectionNode& node = *m_sectionStack.back();
07736             node.stats = sectionStats;
07737             m_sectionStack.pop_back();
07738         }
07739         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
07740             Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
07741             assert( m_sectionStack.size() == 0 );
07742             node->children.push_back( m_rootSection );
07743             m_testCases.push_back( node );
07744             m_rootSection.reset();
07745 
07746             assert( m_deepestSection );
07747             m_deepestSection->stdOut = testCaseStats.stdOut;
07748             m_deepestSection->stdErr = testCaseStats.stdErr;
07749         }
07750         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
07751             Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
07752             node->children.swap( m_testCases );
07753             m_testGroups.push_back( node );
07754         }
07755         virtual void testRunEnded( TestRunStats const& testRunStats ) {
07756             Ptr<TestRunNode> node = new TestRunNode( testRunStats );
07757             node->children.swap( m_testGroups );
07758             m_testRuns.push_back( node );
07759             testRunEndedCumulative();
07760         }
07761         virtual void testRunEndedCumulative() = 0;
07762 
07763         virtual void skipTest( TestCaseInfo const& ) {}
07764 
07765         Ptr<IConfig> m_config;
07766         std::ostream& stream;
07767         std::vector<AssertionStats> m_assertions;
07768         std::vector<std::vector<Ptr<SectionNode> > > m_sections;
07769         std::vector<Ptr<TestCaseNode> > m_testCases;
07770         std::vector<Ptr<TestGroupNode> > m_testGroups;
07771 
07772         std::vector<Ptr<TestRunNode> > m_testRuns;
07773 
07774         Ptr<SectionNode> m_rootSection;
07775         Ptr<SectionNode> m_deepestSection;
07776         std::vector<Ptr<SectionNode> > m_sectionStack;
07777 
07778     };
07779 
07780     template<char C>
07781     char const* getLineOfChars() {
07782         static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
07783         if( !*line ) {
07784             memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
07785             line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
07786         }
07787         return line;
07788     }
07789 
07790 } // end namespace Catch
07791 
07792 // #included from: ../internal/catch_reporter_registrars.hpp
07793 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
07794 
07795 namespace Catch {
07796 
07797     template<typename T>
07798     class LegacyReporterRegistrar {
07799 
07800         class ReporterFactory : public IReporterFactory {
07801             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
07802                 return new LegacyReporterAdapter( new T( config ) );
07803             }
07804 
07805             virtual std::string getDescription() const {
07806                 return T::getDescription();
07807             }
07808         };
07809 
07810     public:
07811 
07812         LegacyReporterRegistrar( std::string const& name ) {
07813             getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
07814         }
07815     };
07816 
07817     template<typename T>
07818     class ReporterRegistrar {
07819 
07820         class ReporterFactory : public IReporterFactory {
07821 
07822             // *** Please Note ***:
07823             // - If you end up here looking at a compiler error because it's trying to register
07824             // your custom reporter class be aware that the native reporter interface has changed
07825             // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
07826             // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
07827             // However please consider updating to the new interface as the old one is now
07828             // deprecated and will probably be removed quite soon!
07829             // Please contact me via github if you have any questions at all about this.
07830             // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
07831             // no idea who is actually using custom reporters at all (possibly no-one!).
07832             // The new interface is designed to minimise exposure to interface changes in the future.
07833             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
07834                 return new T( config );
07835             }
07836 
07837             virtual std::string getDescription() const {
07838                 return T::getDescription();
07839             }
07840         };
07841 
07842     public:
07843 
07844         ReporterRegistrar( std::string const& name ) {
07845             getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
07846         }
07847     };
07848 }
07849 
07850 #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
07851     namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
07852 #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
07853     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
07854 
07855 // #included from: ../internal/catch_xmlwriter.hpp
07856 #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
07857 
07858 #include <sstream>
07859 #include <string>
07860 #include <vector>
07861 
07862 namespace Catch {
07863 
07864     class XmlWriter {
07865     public:
07866 
07867         class ScopedElement {
07868         public:
07869             ScopedElement( XmlWriter* writer )
07870             :   m_writer( writer )
07871             {}
07872 
07873             ScopedElement( ScopedElement const& other )
07874             :   m_writer( other.m_writer ){
07875                 other.m_writer = NULL;
07876             }
07877 
07878             ~ScopedElement() {
07879                 if( m_writer )
07880                     m_writer->endElement();
07881             }
07882 
07883             ScopedElement& writeText( std::string const& text, bool indent = true ) {
07884                 m_writer->writeText( text, indent );
07885                 return *this;
07886             }
07887 
07888             template<typename T>
07889             ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
07890                 m_writer->writeAttribute( name, attribute );
07891                 return *this;
07892             }
07893 
07894         private:
07895             mutable XmlWriter* m_writer;
07896         };
07897 
07898         XmlWriter()
07899         :   m_tagIsOpen( false ),
07900             m_needsNewline( false ),
07901             m_os( &Catch::cout() )
07902         {}
07903 
07904         XmlWriter( std::ostream& os )
07905         :   m_tagIsOpen( false ),
07906             m_needsNewline( false ),
07907             m_os( &os )
07908         {}
07909 
07910         ~XmlWriter() {
07911             while( !m_tags.empty() )
07912                 endElement();
07913         }
07914 
07915         XmlWriter& startElement( std::string const& name ) {
07916             ensureTagClosed();
07917             newlineIfNecessary();
07918             stream() << m_indent << "<" << name;
07919             m_tags.push_back( name );
07920             m_indent += "  ";
07921             m_tagIsOpen = true;
07922             return *this;
07923         }
07924 
07925         ScopedElement scopedElement( std::string const& name ) {
07926             ScopedElement scoped( this );
07927             startElement( name );
07928             return scoped;
07929         }
07930 
07931         XmlWriter& endElement() {
07932             newlineIfNecessary();
07933             m_indent = m_indent.substr( 0, m_indent.size()-2 );
07934             if( m_tagIsOpen ) {
07935                 stream() << "/>\n";
07936                 m_tagIsOpen = false;
07937             }
07938             else {
07939                 stream() << m_indent << "</" << m_tags.back() << ">\n";
07940             }
07941             m_tags.pop_back();
07942             return *this;
07943         }
07944 
07945         XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
07946             if( !name.empty() && !attribute.empty() ) {
07947                 stream() << " " << name << "=\"";
07948                 writeEncodedText( attribute );
07949                 stream() << "\"";
07950             }
07951             return *this;
07952         }
07953 
07954         XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
07955             stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
07956             return *this;
07957         }
07958 
07959         template<typename T>
07960         XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
07961             if( !name.empty() )
07962                 stream() << " " << name << "=\"" << attribute << "\"";
07963             return *this;
07964         }
07965 
07966         XmlWriter& writeText( std::string const& text, bool indent = true ) {
07967             if( !text.empty() ){
07968                 bool tagWasOpen = m_tagIsOpen;
07969                 ensureTagClosed();
07970                 if( tagWasOpen && indent )
07971                     stream() << m_indent;
07972                 writeEncodedText( text );
07973                 m_needsNewline = true;
07974             }
07975             return *this;
07976         }
07977 
07978         XmlWriter& writeComment( std::string const& text ) {
07979             ensureTagClosed();
07980             stream() << m_indent << "<!--" << text << "-->";
07981             m_needsNewline = true;
07982             return *this;
07983         }
07984 
07985         XmlWriter& writeBlankLine() {
07986             ensureTagClosed();
07987             stream() << "\n";
07988             return *this;
07989         }
07990 
07991         void setStream( std::ostream& os ) {
07992             m_os = &os;
07993         }
07994 
07995     private:
07996         XmlWriter( XmlWriter const& );
07997         void operator=( XmlWriter const& );
07998 
07999         std::ostream& stream() {
08000             return *m_os;
08001         }
08002 
08003         void ensureTagClosed() {
08004             if( m_tagIsOpen ) {
08005                 stream() << ">\n";
08006                 m_tagIsOpen = false;
08007             }
08008         }
08009 
08010         void newlineIfNecessary() {
08011             if( m_needsNewline ) {
08012                 stream() << "\n";
08013                 m_needsNewline = false;
08014             }
08015         }
08016 
08017         void writeEncodedText( std::string const& text ) {
08018             static const char* charsToEncode = "<&\"";
08019             std::string mtext = text;
08020             std::string::size_type pos = mtext.find_first_of( charsToEncode );
08021             while( pos != std::string::npos ) {
08022                 stream() << mtext.substr( 0, pos );
08023 
08024                 switch( mtext[pos] ) {
08025                     case '<':
08026                         stream() << "&lt;";
08027                         break;
08028                     case '&':
08029                         stream() << "&amp;";
08030                         break;
08031                     case '\"':
08032                         stream() << "&quot;";
08033                         break;
08034                 }
08035                 mtext = mtext.substr( pos+1 );
08036                 pos = mtext.find_first_of( charsToEncode );
08037             }
08038             stream() << mtext;
08039         }
08040 
08041         bool m_tagIsOpen;
08042         bool m_needsNewline;
08043         std::vector<std::string> m_tags;
08044         std::string m_indent;
08045         std::ostream* m_os;
08046     };
08047 
08048 }
08049 namespace Catch {
08050     class XmlReporter : public StreamingReporterBase {
08051     public:
08052         XmlReporter( ReporterConfig const& _config )
08053         :   StreamingReporterBase( _config ),
08054             m_sectionDepth( 0 )
08055         {}
08056 
08057         virtual ~XmlReporter();
08058 
08059         static std::string getDescription() {
08060             return "Reports test results as an XML document";
08061         }
08062 
08063     public: // StreamingReporterBase
08064         virtual ReporterPreferences getPreferences() const {
08065             ReporterPreferences prefs;
08066             prefs.shouldRedirectStdOut = true;
08067             return prefs;
08068         }
08069 
08070         virtual void noMatchingTestCases( std::string const& s ) {
08071             StreamingReporterBase::noMatchingTestCases( s );
08072         }
08073 
08074         virtual void testRunStarting( TestRunInfo const& testInfo ) {
08075             StreamingReporterBase::testRunStarting( testInfo );
08076             m_xml.setStream( stream );
08077             m_xml.startElement( "Catch" );
08078             if( !m_config->name().empty() )
08079                 m_xml.writeAttribute( "name", m_config->name() );
08080         }
08081 
08082         virtual void testGroupStarting( GroupInfo const& groupInfo ) {
08083             StreamingReporterBase::testGroupStarting( groupInfo );
08084             m_xml.startElement( "Group" )
08085                 .writeAttribute( "name", groupInfo.name );
08086         }
08087 
08088         virtual void testCaseStarting( TestCaseInfo const& testInfo ) {
08089             StreamingReporterBase::testCaseStarting(testInfo);
08090             m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
08091 
08092             if ( m_config->showDurations() == ShowDurations::Always )
08093                 m_testCaseTimer.start();
08094         }
08095 
08096         virtual void sectionStarting( SectionInfo const& sectionInfo ) {
08097             StreamingReporterBase::sectionStarting( sectionInfo );
08098             if( m_sectionDepth++ > 0 ) {
08099                 m_xml.startElement( "Section" )
08100                     .writeAttribute( "name", trim( sectionInfo.name ) )
08101                     .writeAttribute( "description", sectionInfo.description );
08102             }
08103         }
08104 
08105         virtual void assertionStarting( AssertionInfo const& ) { }
08106 
08107         virtual bool assertionEnded( AssertionStats const& assertionStats ) {
08108             const AssertionResult& assertionResult = assertionStats.assertionResult;
08109 
08110             // Print any info messages in <Info> tags.
08111             if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
08112                 for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
08113                         it != itEnd;
08114                         ++it ) {
08115                     if( it->type == ResultWas::Info ) {
08116                         m_xml.scopedElement( "Info" )
08117                             .writeText( it->message );
08118                     } else if ( it->type == ResultWas::Warning ) {
08119                         m_xml.scopedElement( "Warning" )
08120                             .writeText( it->message );
08121                     }
08122                 }
08123             }
08124 
08125             // Drop out if result was successful but we're not printing them.
08126             if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
08127                 return true;
08128 
08129             // Print the expression if there is one.
08130             if( assertionResult.hasExpression() ) {
08131                 m_xml.startElement( "Expression" )
08132                     .writeAttribute( "success", assertionResult.succeeded() )
08133                                         .writeAttribute( "type", assertionResult.getTestMacroName() )
08134                     .writeAttribute( "filename", assertionResult.getSourceInfo().file )
08135                     .writeAttribute( "line", assertionResult.getSourceInfo().line );
08136 
08137                 m_xml.scopedElement( "Original" )
08138                     .writeText( assertionResult.getExpression() );
08139                 m_xml.scopedElement( "Expanded" )
08140                     .writeText( assertionResult.getExpandedExpression() );
08141             }
08142 
08143             // And... Print a result applicable to each result type.
08144             switch( assertionResult.getResultType() ) {
08145                 case ResultWas::ThrewException:
08146                     m_xml.scopedElement( "Exception" )
08147                         .writeAttribute( "filename", assertionResult.getSourceInfo().file )
08148                         .writeAttribute( "line", assertionResult.getSourceInfo().line )
08149                         .writeText( assertionResult.getMessage() );
08150                     break;
08151                 case ResultWas::FatalErrorCondition:
08152                     m_xml.scopedElement( "Fatal Error Condition" )
08153                         .writeAttribute( "filename", assertionResult.getSourceInfo().file )
08154                         .writeAttribute( "line", assertionResult.getSourceInfo().line )
08155                         .writeText( assertionResult.getMessage() );
08156                     break;
08157                 case ResultWas::Info:
08158                     m_xml.scopedElement( "Info" )
08159                         .writeText( assertionResult.getMessage() );
08160                     break;
08161                 case ResultWas::Warning:
08162                     // Warning will already have been written
08163                     break;
08164                 case ResultWas::ExplicitFailure:
08165                     m_xml.scopedElement( "Failure" )
08166                         .writeText( assertionResult.getMessage() );
08167                     break;
08168                 default:
08169                     break;
08170             }
08171 
08172             if( assertionResult.hasExpression() )
08173                 m_xml.endElement();
08174 
08175             return true;
08176         }
08177 
08178         virtual void sectionEnded( SectionStats const& sectionStats ) {
08179             StreamingReporterBase::sectionEnded( sectionStats );
08180             if( --m_sectionDepth > 0 ) {
08181                 XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
08182                 e.writeAttribute( "successes", sectionStats.assertions.passed );
08183                 e.writeAttribute( "failures", sectionStats.assertions.failed );
08184                 e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
08185 
08186                 if ( m_config->showDurations() == ShowDurations::Always )
08187                     e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
08188 
08189                 m_xml.endElement();
08190             }
08191         }
08192 
08193         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
08194             StreamingReporterBase::testCaseEnded( testCaseStats );
08195             XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
08196             e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
08197 
08198             if ( m_config->showDurations() == ShowDurations::Always )
08199                 e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
08200 
08201             m_xml.endElement();
08202         }
08203 
08204         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
08205             StreamingReporterBase::testGroupEnded( testGroupStats );
08206             // TODO: Check testGroupStats.aborting and act accordingly.
08207             m_xml.scopedElement( "OverallResults" )
08208                 .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
08209                 .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
08210                 .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
08211             m_xml.endElement();
08212         }
08213 
08214         virtual void testRunEnded( TestRunStats const& testRunStats ) {
08215             StreamingReporterBase::testRunEnded( testRunStats );
08216             m_xml.scopedElement( "OverallResults" )
08217                 .writeAttribute( "successes", testRunStats.totals.assertions.passed )
08218                 .writeAttribute( "failures", testRunStats.totals.assertions.failed )
08219                 .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
08220             m_xml.endElement();
08221         }
08222 
08223     private:
08224         Timer m_testCaseTimer;
08225         XmlWriter m_xml;
08226         int m_sectionDepth;
08227     };
08228 
08229      INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
08230 
08231 } // end namespace Catch
08232 
08233 // #included from: ../reporters/catch_reporter_junit.hpp
08234 #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
08235 
08236 #include <assert.h>
08237 
08238 namespace Catch {
08239 
08240     class JunitReporter : public CumulativeReporterBase {
08241     public:
08242         JunitReporter( ReporterConfig const& _config )
08243         :   CumulativeReporterBase( _config ),
08244             xml( _config.stream() )
08245         {}
08246 
08247         ~JunitReporter();
08248 
08249         static std::string getDescription() {
08250             return "Reports test results in an XML format that looks like Ant's junitreport target";
08251         }
08252 
08253         virtual void noMatchingTestCases( std::string const& /*spec*/ ) {}
08254 
08255         virtual ReporterPreferences getPreferences() const {
08256             ReporterPreferences prefs;
08257             prefs.shouldRedirectStdOut = true;
08258             return prefs;
08259         }
08260 
08261         virtual void testRunStarting( TestRunInfo const& runInfo ) {
08262             CumulativeReporterBase::testRunStarting( runInfo );
08263             xml.startElement( "testsuites" );
08264         }
08265 
08266         virtual void testGroupStarting( GroupInfo const& groupInfo ) {
08267             suiteTimer.start();
08268             stdOutForSuite.str("");
08269             stdErrForSuite.str("");
08270             unexpectedExceptions = 0;
08271             CumulativeReporterBase::testGroupStarting( groupInfo );
08272         }
08273 
08274         virtual bool assertionEnded( AssertionStats const& assertionStats ) {
08275             if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
08276                 unexpectedExceptions++;
08277             return CumulativeReporterBase::assertionEnded( assertionStats );
08278         }
08279 
08280         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
08281             stdOutForSuite << testCaseStats.stdOut;
08282             stdErrForSuite << testCaseStats.stdErr;
08283             CumulativeReporterBase::testCaseEnded( testCaseStats );
08284         }
08285 
08286         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
08287             double suiteTime = suiteTimer.getElapsedSeconds();
08288             CumulativeReporterBase::testGroupEnded( testGroupStats );
08289             writeGroup( *m_testGroups.back(), suiteTime );
08290         }
08291 
08292         virtual void testRunEndedCumulative() {
08293             xml.endElement();
08294         }
08295 
08296         void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
08297             XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
08298             TestGroupStats const& stats = groupNode.value;
08299             xml.writeAttribute( "name", stats.groupInfo.name );
08300             xml.writeAttribute( "errors", unexpectedExceptions );
08301             xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
08302             xml.writeAttribute( "tests", stats.totals.assertions.total() );
08303             xml.writeAttribute( "hostname", "tbd" ); // !TBD
08304             if( m_config->showDurations() == ShowDurations::Never )
08305                 xml.writeAttribute( "time", "" );
08306             else
08307                 xml.writeAttribute( "time", suiteTime );
08308             xml.writeAttribute( "timestamp", "tbd" ); // !TBD
08309 
08310             // Write test cases
08311             for( TestGroupNode::ChildNodes::const_iterator
08312                     it = groupNode.children.begin(), itEnd = groupNode.children.end();
08313                     it != itEnd;
08314                     ++it )
08315                 writeTestCase( **it );
08316 
08317             xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
08318             xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
08319         }
08320 
08321         void writeTestCase( TestCaseNode const& testCaseNode ) {
08322             TestCaseStats const& stats = testCaseNode.value;
08323 
08324             // All test cases have exactly one section - which represents the
08325             // test case itself. That section may have 0-n nested sections
08326             assert( testCaseNode.children.size() == 1 );
08327             SectionNode const& rootSection = *testCaseNode.children.front();
08328 
08329             std::string className = stats.testInfo.className;
08330 
08331             if( className.empty() ) {
08332                 if( rootSection.childSections.empty() )
08333                     className = "global";
08334             }
08335             writeSection( className, "", rootSection );
08336         }
08337 
08338         void writeSection(  std::string const& className,
08339                             std::string const& rootName,
08340                             SectionNode const& sectionNode ) {
08341             std::string name = trim( sectionNode.stats.sectionInfo.name );
08342             if( !rootName.empty() )
08343                 name = rootName + "/" + name;
08344 
08345             if( !sectionNode.assertions.empty() ||
08346                 !sectionNode.stdOut.empty() ||
08347                 !sectionNode.stdErr.empty() ) {
08348                 XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
08349                 if( className.empty() ) {
08350                     xml.writeAttribute( "classname", name );
08351                     xml.writeAttribute( "name", "root" );
08352                 }
08353                 else {
08354                     xml.writeAttribute( "classname", className );
08355                     xml.writeAttribute( "name", name );
08356                 }
08357                 xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
08358 
08359                 writeAssertions( sectionNode );
08360 
08361                 if( !sectionNode.stdOut.empty() )
08362                     xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
08363                 if( !sectionNode.stdErr.empty() )
08364                     xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
08365             }
08366             for( SectionNode::ChildSections::const_iterator
08367                     it = sectionNode.childSections.begin(),
08368                     itEnd = sectionNode.childSections.end();
08369                     it != itEnd;
08370                     ++it )
08371                 if( className.empty() )
08372                     writeSection( name, "", **it );
08373                 else
08374                     writeSection( className, name, **it );
08375         }
08376 
08377         void writeAssertions( SectionNode const& sectionNode ) {
08378             for( SectionNode::Assertions::const_iterator
08379                     it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
08380                     it != itEnd;
08381                     ++it )
08382                 writeAssertion( *it );
08383         }
08384         void writeAssertion( AssertionStats const& stats ) {
08385             AssertionResult const& result = stats.assertionResult;
08386             if( !result.isOk() ) {
08387                 std::string elementName;
08388                 switch( result.getResultType() ) {
08389                     case ResultWas::ThrewException:
08390                     case ResultWas::FatalErrorCondition:
08391                         elementName = "error";
08392                         break;
08393                     case ResultWas::ExplicitFailure:
08394                         elementName = "failure";
08395                         break;
08396                     case ResultWas::ExpressionFailed:
08397                         elementName = "failure";
08398                         break;
08399                     case ResultWas::DidntThrowException:
08400                         elementName = "failure";
08401                         break;
08402 
08403                     // We should never see these here:
08404                     case ResultWas::Info:
08405                     case ResultWas::Warning:
08406                     case ResultWas::Ok:
08407                     case ResultWas::Unknown:
08408                     case ResultWas::FailureBit:
08409                     case ResultWas::Exception:
08410                         elementName = "internalError";
08411                         break;
08412                 }
08413 
08414                 XmlWriter::ScopedElement e = xml.scopedElement( elementName );
08415 
08416                 xml.writeAttribute( "message", result.getExpandedExpression() );
08417                 xml.writeAttribute( "type", result.getTestMacroName() );
08418 
08419                 std::ostringstream oss;
08420                 if( !result.getMessage().empty() )
08421                     oss << result.getMessage() << "\n";
08422                 for( std::vector<MessageInfo>::const_iterator
08423                         it = stats.infoMessages.begin(),
08424                         itEnd = stats.infoMessages.end();
08425                             it != itEnd;
08426                             ++it )
08427                     if( it->type == ResultWas::Info )
08428                         oss << it->message << "\n";
08429 
08430                 oss << "at " << result.getSourceInfo();
08431                 xml.writeText( oss.str(), false );
08432             }
08433         }
08434 
08435         XmlWriter xml;
08436         Timer suiteTimer;
08437         std::ostringstream stdOutForSuite;
08438         std::ostringstream stdErrForSuite;
08439         unsigned int unexpectedExceptions;
08440     };
08441 
08442     INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
08443 
08444 } // end namespace Catch
08445 
08446 // #included from: ../reporters/catch_reporter_console.hpp
08447 #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
08448 
08449 namespace Catch {
08450 
08451     struct ConsoleReporter : StreamingReporterBase {
08452         ConsoleReporter( ReporterConfig const& _config )
08453         :   StreamingReporterBase( _config ),
08454             m_headerPrinted( false )
08455         {}
08456 
08457         virtual ~ConsoleReporter();
08458         static std::string getDescription() {
08459             return "Reports test results as plain lines of text";
08460         }
08461         virtual ReporterPreferences getPreferences() const {
08462             ReporterPreferences prefs;
08463             prefs.shouldRedirectStdOut = false;
08464             return prefs;
08465         }
08466 
08467         virtual void noMatchingTestCases( std::string const& spec ) {
08468             stream << "No test cases matched '" << spec << "'" << std::endl;
08469         }
08470 
08471         virtual void assertionStarting( AssertionInfo const& ) {
08472         }
08473 
08474         virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
08475             AssertionResult const& result = _assertionStats.assertionResult;
08476 
08477             bool printInfoMessages = true;
08478 
08479             // Drop out if result was successful and we're not printing those
08480             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
08481                 if( result.getResultType() != ResultWas::Warning )
08482                     return false;
08483                 printInfoMessages = false;
08484             }
08485 
08486             lazyPrint();
08487 
08488             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
08489             printer.print();
08490             stream << std::endl;
08491             return true;
08492         }
08493 
08494         virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
08495             m_headerPrinted = false;
08496             StreamingReporterBase::sectionStarting( _sectionInfo );
08497         }
08498         virtual void sectionEnded( SectionStats const& _sectionStats ) {
08499             if( _sectionStats.missingAssertions ) {
08500                 lazyPrint();
08501                 Colour colour( Colour::ResultError );
08502                 if( m_sectionStack.size() > 1 )
08503                     stream << "\nNo assertions in section";
08504                 else
08505                     stream << "\nNo assertions in test case";
08506                 stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
08507             }
08508             if( m_headerPrinted ) {
08509                 if( m_config->showDurations() == ShowDurations::Always )
08510                     stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
08511                 m_headerPrinted = false;
08512             }
08513             else {
08514                 if( m_config->showDurations() == ShowDurations::Always )
08515                     stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
08516             }
08517             StreamingReporterBase::sectionEnded( _sectionStats );
08518         }
08519 
08520         virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) {
08521             StreamingReporterBase::testCaseEnded( _testCaseStats );
08522             m_headerPrinted = false;
08523         }
08524         virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) {
08525             if( currentGroupInfo.used ) {
08526                 printSummaryDivider();
08527                 stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
08528                 printTotals( _testGroupStats.totals );
08529                 stream << "\n" << std::endl;
08530             }
08531             StreamingReporterBase::testGroupEnded( _testGroupStats );
08532         }
08533         virtual void testRunEnded( TestRunStats const& _testRunStats ) {
08534             printTotalsDivider( _testRunStats.totals );
08535             printTotals( _testRunStats.totals );
08536             stream << std::endl;
08537             StreamingReporterBase::testRunEnded( _testRunStats );
08538         }
08539 
08540     private:
08541 
08542         class AssertionPrinter {
08543             void operator= ( AssertionPrinter const& );
08544         public:
08545             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
08546             :   stream( _stream ),
08547                 stats( _stats ),
08548                 result( _stats.assertionResult ),
08549                 colour( Colour::None ),
08550                 message( result.getMessage() ),
08551                 messages( _stats.infoMessages ),
08552                 printInfoMessages( _printInfoMessages )
08553             {
08554                 switch( result.getResultType() ) {
08555                     case ResultWas::Ok:
08556                         colour = Colour::Success;
08557                         passOrFail = "PASSED";
08558                         //if( result.hasMessage() )
08559                         if( _stats.infoMessages.size() == 1 )
08560                             messageLabel = "with message";
08561                         if( _stats.infoMessages.size() > 1 )
08562                             messageLabel = "with messages";
08563                         break;
08564                     case ResultWas::ExpressionFailed:
08565                         if( result.isOk() ) {
08566                             colour = Colour::Success;
08567                             passOrFail = "FAILED - but was ok";
08568                         }
08569                         else {
08570                             colour = Colour::Error;
08571                             passOrFail = "FAILED";
08572                         }
08573                         if( _stats.infoMessages.size() == 1 )
08574                             messageLabel = "with message";
08575                         if( _stats.infoMessages.size() > 1 )
08576                             messageLabel = "with messages";
08577                         break;
08578                     case ResultWas::ThrewException:
08579                         colour = Colour::Error;
08580                         passOrFail = "FAILED";
08581                         messageLabel = "due to unexpected exception with message";
08582                         break;
08583                     case ResultWas::FatalErrorCondition:
08584                         colour = Colour::Error;
08585                         passOrFail = "FAILED";
08586                         messageLabel = "due to a fatal error condition";
08587                         break;
08588                     case ResultWas::DidntThrowException:
08589                         colour = Colour::Error;
08590                         passOrFail = "FAILED";
08591                         messageLabel = "because no exception was thrown where one was expected";
08592                         break;
08593                     case ResultWas::Info:
08594                         messageLabel = "info";
08595                         break;
08596                     case ResultWas::Warning:
08597                         messageLabel = "warning";
08598                         break;
08599                     case ResultWas::ExplicitFailure:
08600                         passOrFail = "FAILED";
08601                         colour = Colour::Error;
08602                         if( _stats.infoMessages.size() == 1 )
08603                             messageLabel = "explicitly with message";
08604                         if( _stats.infoMessages.size() > 1 )
08605                             messageLabel = "explicitly with messages";
08606                         break;
08607                     // These cases are here to prevent compiler warnings
08608                     case ResultWas::Unknown:
08609                     case ResultWas::FailureBit:
08610                     case ResultWas::Exception:
08611                         passOrFail = "** internal error **";
08612                         colour = Colour::Error;
08613                         break;
08614                 }
08615             }
08616 
08617             void print() const {
08618                 printSourceInfo();
08619                 if( stats.totals.assertions.total() > 0 ) {
08620                     if( result.isOk() )
08621                         stream << "\n";
08622                     printResultType();
08623                     printOriginalExpression();
08624                     printReconstructedExpression();
08625                 }
08626                 else {
08627                     stream << "\n";
08628                 }
08629                 printMessage();
08630             }
08631 
08632         private:
08633             void printResultType() const {
08634                 if( !passOrFail.empty() ) {
08635                     Colour colourGuard( colour );
08636                     stream << passOrFail << ":\n";
08637                 }
08638             }
08639             void printOriginalExpression() const {
08640                 if( result.hasExpression() ) {
08641                     Colour colourGuard( Colour::OriginalExpression );
08642                     stream  << "  ";
08643                     stream << result.getExpressionInMacro();
08644                     stream << "\n";
08645                 }
08646             }
08647             void printReconstructedExpression() const {
08648                 if( result.hasExpandedExpression() ) {
08649                     stream << "with expansion:\n";
08650                     Colour colourGuard( Colour::ReconstructedExpression );
08651                     stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
08652                 }
08653             }
08654             void printMessage() const {
08655                 if( !messageLabel.empty() )
08656                     stream << messageLabel << ":" << "\n";
08657                 for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
08658                         it != itEnd;
08659                         ++it ) {
08660                     // If this assertion is a warning ignore any INFO messages
08661                     if( printInfoMessages || it->type != ResultWas::Info )
08662                         stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
08663                 }
08664             }
08665             void printSourceInfo() const {
08666                 Colour colourGuard( Colour::FileName );
08667                 stream << result.getSourceInfo() << ": ";
08668             }
08669 
08670             std::ostream& stream;
08671             AssertionStats const& stats;
08672             AssertionResult const& result;
08673             Colour::Code colour;
08674             std::string passOrFail;
08675             std::string messageLabel;
08676             std::string message;
08677             std::vector<MessageInfo> messages;
08678             bool printInfoMessages;
08679         };
08680 
08681         void lazyPrint() {
08682 
08683             if( !currentTestRunInfo.used )
08684                 lazyPrintRunInfo();
08685             if( !currentGroupInfo.used )
08686                 lazyPrintGroupInfo();
08687 
08688             if( !m_headerPrinted ) {
08689                 printTestCaseAndSectionHeader();
08690                 m_headerPrinted = true;
08691             }
08692         }
08693         void lazyPrintRunInfo() {
08694             stream  << "\n" << getLineOfChars<'~'>() << "\n";
08695             Colour colour( Colour::SecondaryText );
08696             stream  << currentTestRunInfo->name
08697                     << " is a Catch v"  << libraryVersion << " host application.\n"
08698                     << "Run with -? for options\n\n";
08699 
08700             if( m_config->rngSeed() != 0 )
08701                 stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
08702 
08703             currentTestRunInfo.used = true;
08704         }
08705         void lazyPrintGroupInfo() {
08706             if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
08707                 printClosedHeader( "Group: " + currentGroupInfo->name );
08708                 currentGroupInfo.used = true;
08709             }
08710         }
08711         void printTestCaseAndSectionHeader() {
08712             assert( !m_sectionStack.empty() );
08713             printOpenHeader( currentTestCaseInfo->name );
08714 
08715             if( m_sectionStack.size() > 1 ) {
08716                 Colour colourGuard( Colour::Headers );
08717 
08718                 std::vector<SectionInfo>::const_iterator
08719                     it = m_sectionStack.begin()+1, // Skip first section (test case)
08720                     itEnd = m_sectionStack.end();
08721                 for( ; it != itEnd; ++it )
08722                     printHeaderString( it->name, 2 );
08723             }
08724 
08725             SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
08726 
08727             if( !lineInfo.empty() ){
08728                 stream << getLineOfChars<'-'>() << "\n";
08729                 Colour colourGuard( Colour::FileName );
08730                 stream << lineInfo << "\n";
08731             }
08732             stream << getLineOfChars<'.'>() << "\n" << std::endl;
08733         }
08734 
08735         void printClosedHeader( std::string const& _name ) {
08736             printOpenHeader( _name );
08737             stream << getLineOfChars<'.'>() << "\n";
08738         }
08739         void printOpenHeader( std::string const& _name ) {
08740             stream  << getLineOfChars<'-'>() << "\n";
08741             {
08742                 Colour colourGuard( Colour::Headers );
08743                 printHeaderString( _name );
08744             }
08745         }
08746 
08747         // if string has a : in first line will set indent to follow it on
08748         // subsequent lines
08749         void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
08750             std::size_t i = _string.find( ": " );
08751             if( i != std::string::npos )
08752                 i+=2;
08753             else
08754                 i = 0;
08755             stream << Text( _string, TextAttributes()
08756                                         .setIndent( indent+i)
08757                                         .setInitialIndent( indent ) ) << "\n";
08758         }
08759 
08760         struct SummaryColumn {
08761 
08762             SummaryColumn( std::string const& _label, Colour::Code _colour )
08763             :   label( _label ),
08764                 colour( _colour )
08765             {}
08766             SummaryColumn addRow( std::size_t count ) {
08767                 std::ostringstream oss;
08768                 oss << count;
08769                 std::string row = oss.str();
08770                 for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
08771                     while( it->size() < row.size() )
08772                         *it = " " + *it;
08773                     while( it->size() > row.size() )
08774                         row = " " + row;
08775                 }
08776                 rows.push_back( row );
08777                 return *this;
08778             }
08779 
08780             std::string label;
08781             Colour::Code colour;
08782             std::vector<std::string> rows;
08783 
08784         };
08785 
08786         void printTotals( Totals const& totals ) {
08787             if( totals.testCases.total() == 0 ) {
08788                 stream << Colour( Colour::Warning ) << "No tests ran\n";
08789             }
08790             else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
08791                 stream << Colour( Colour::ResultSuccess ) << "All tests passed";
08792                 stream << " ("
08793                         << pluralise( totals.assertions.passed, "assertion" ) << " in "
08794                         << pluralise( totals.testCases.passed, "test case" ) << ")"
08795                         << "\n";
08796             }
08797             else {
08798 
08799                 std::vector<SummaryColumn> columns;
08800                 columns.push_back( SummaryColumn( "", Colour::None )
08801                                         .addRow( totals.testCases.total() )
08802                                         .addRow( totals.assertions.total() ) );
08803                 columns.push_back( SummaryColumn( "passed", Colour::Success )
08804                                         .addRow( totals.testCases.passed )
08805                                         .addRow( totals.assertions.passed ) );
08806                 columns.push_back( SummaryColumn( "failed", Colour::ResultError )
08807                                         .addRow( totals.testCases.failed )
08808                                         .addRow( totals.assertions.failed ) );
08809                 columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
08810                                         .addRow( totals.testCases.failedButOk )
08811                                         .addRow( totals.assertions.failedButOk ) );
08812 
08813                 printSummaryRow( "test cases", columns, 0 );
08814                 printSummaryRow( "assertions", columns, 1 );
08815             }
08816         }
08817         void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
08818             for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
08819                 std::string value = it->rows[row];
08820                 if( it->label.empty() ) {
08821                     stream << label << ": ";
08822                     if( value != "0" )
08823                         stream << value;
08824                     else
08825                         stream << Colour( Colour::Warning ) << "- none -";
08826                 }
08827                 else if( value != "0" ) {
08828                     stream  << Colour( Colour::LightGrey ) << " | ";
08829                     stream  << Colour( it->colour )
08830                             << value << " " << it->label;
08831                 }
08832             }
08833             stream << "\n";
08834         }
08835 
08836         static std::size_t makeRatio( std::size_t number, std::size_t total ) {
08837             std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
08838             return ( ratio == 0 && number > 0 ) ? 1 : ratio;
08839         }
08840         static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
08841             if( i > j && i > k )
08842                 return i;
08843             else if( j > k )
08844                 return j;
08845             else
08846                 return k;
08847         }
08848 
08849         void printTotalsDivider( Totals const& totals ) {
08850             if( totals.testCases.total() > 0 ) {
08851                 std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
08852                 std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
08853                 std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
08854                 while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
08855                     findMax( failedRatio, failedButOkRatio, passedRatio )++;
08856                 while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
08857                     findMax( failedRatio, failedButOkRatio, passedRatio )--;
08858 
08859                 stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
08860                 stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
08861                 if( totals.testCases.allPassed() )
08862                     stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
08863                 else
08864                     stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
08865             }
08866             else {
08867                 stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
08868             }
08869             stream << "\n";
08870         }
08871         void printSummaryDivider() {
08872             stream << getLineOfChars<'-'>() << "\n";
08873         }
08874 
08875     private:
08876         bool m_headerPrinted;
08877     };
08878 
08879     INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
08880 
08881 } // end namespace Catch
08882 
08883 // #included from: ../reporters/catch_reporter_compact.hpp
08884 #define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
08885 
08886 namespace Catch {
08887 
08888     struct CompactReporter : StreamingReporterBase {
08889 
08890         CompactReporter( ReporterConfig const& _config )
08891         : StreamingReporterBase( _config )
08892         {}
08893 
08894         virtual ~CompactReporter();
08895 
08896         static std::string getDescription() {
08897             return "Reports test results on a single line, suitable for IDEs";
08898         }
08899 
08900         virtual ReporterPreferences getPreferences() const {
08901             ReporterPreferences prefs;
08902             prefs.shouldRedirectStdOut = false;
08903             return prefs;
08904         }
08905 
08906         virtual void noMatchingTestCases( std::string const& spec ) {
08907             stream << "No test cases matched '" << spec << "'" << std::endl;
08908         }
08909 
08910         virtual void assertionStarting( AssertionInfo const& ) {
08911         }
08912 
08913         virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
08914             AssertionResult const& result = _assertionStats.assertionResult;
08915 
08916             bool printInfoMessages = true;
08917 
08918             // Drop out if result was successful and we're not printing those
08919             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
08920                 if( result.getResultType() != ResultWas::Warning )
08921                     return false;
08922                 printInfoMessages = false;
08923             }
08924 
08925             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
08926             printer.print();
08927 
08928             stream << std::endl;
08929             return true;
08930         }
08931 
08932         virtual void testRunEnded( TestRunStats const& _testRunStats ) {
08933             printTotals( _testRunStats.totals );
08934             stream << "\n" << std::endl;
08935             StreamingReporterBase::testRunEnded( _testRunStats );
08936         }
08937 
08938     private:
08939         class AssertionPrinter {
08940             void operator= ( AssertionPrinter const& );
08941         public:
08942             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
08943             : stream( _stream )
08944             , stats( _stats )
08945             , result( _stats.assertionResult )
08946             , messages( _stats.infoMessages )
08947             , itMessage( _stats.infoMessages.begin() )
08948             , printInfoMessages( _printInfoMessages )
08949             {}
08950 
08951             void print() {
08952                 printSourceInfo();
08953 
08954                 itMessage = messages.begin();
08955 
08956                 switch( result.getResultType() ) {
08957                     case ResultWas::Ok:
08958                         printResultType( Colour::ResultSuccess, passedString() );
08959                         printOriginalExpression();
08960                         printReconstructedExpression();
08961                         if ( ! result.hasExpression() )
08962                             printRemainingMessages( Colour::None );
08963                         else
08964                             printRemainingMessages();
08965                         break;
08966                     case ResultWas::ExpressionFailed:
08967                         if( result.isOk() )
08968                             printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
08969                         else
08970                             printResultType( Colour::Error, failedString() );
08971                         printOriginalExpression();
08972                         printReconstructedExpression();
08973                         printRemainingMessages();
08974                         break;
08975                     case ResultWas::ThrewException:
08976                         printResultType( Colour::Error, failedString() );
08977                         printIssue( "unexpected exception with message:" );
08978                         printMessage();
08979                         printExpressionWas();
08980                         printRemainingMessages();
08981                         break;
08982                     case ResultWas::FatalErrorCondition:
08983                         printResultType( Colour::Error, failedString() );
08984                         printIssue( "fatal error condition with message:" );
08985                         printMessage();
08986                         printExpressionWas();
08987                         printRemainingMessages();
08988                         break;
08989                     case ResultWas::DidntThrowException:
08990                         printResultType( Colour::Error, failedString() );
08991                         printIssue( "expected exception, got none" );
08992                         printExpressionWas();
08993                         printRemainingMessages();
08994                         break;
08995                     case ResultWas::Info:
08996                         printResultType( Colour::None, "info" );
08997                         printMessage();
08998                         printRemainingMessages();
08999                         break;
09000                     case ResultWas::Warning:
09001                         printResultType( Colour::None, "warning" );
09002                         printMessage();
09003                         printRemainingMessages();
09004                         break;
09005                     case ResultWas::ExplicitFailure:
09006                         printResultType( Colour::Error, failedString() );
09007                         printIssue( "explicitly" );
09008                         printRemainingMessages( Colour::None );
09009                         break;
09010                     // These cases are here to prevent compiler warnings
09011                     case ResultWas::Unknown:
09012                     case ResultWas::FailureBit:
09013                     case ResultWas::Exception:
09014                         printResultType( Colour::Error, "** internal error **" );
09015                         break;
09016                 }
09017             }
09018 
09019         private:
09020             // Colour::LightGrey
09021 
09022             static Colour::Code dimColour() { return Colour::FileName; }
09023 
09024 #ifdef CATCH_PLATFORM_MAC
09025             static const char* failedString() { return "FAILED"; }
09026             static const char* passedString() { return "PASSED"; }
09027 #else
09028             static const char* failedString() { return "failed"; }
09029             static const char* passedString() { return "passed"; }
09030 #endif
09031 
09032             void printSourceInfo() const {
09033                 Colour colourGuard( Colour::FileName );
09034                 stream << result.getSourceInfo() << ":";
09035             }
09036 
09037             void printResultType( Colour::Code colour, std::string passOrFail ) const {
09038                 if( !passOrFail.empty() ) {
09039                     {
09040                         Colour colourGuard( colour );
09041                         stream << " " << passOrFail;
09042                     }
09043                     stream << ":";
09044                 }
09045             }
09046 
09047             void printIssue( std::string issue ) const {
09048                 stream << " " << issue;
09049             }
09050 
09051             void printExpressionWas() {
09052                 if( result.hasExpression() ) {
09053                     stream << ";";
09054                     {
09055                         Colour colour( dimColour() );
09056                         stream << " expression was:";
09057                     }
09058                     printOriginalExpression();
09059                 }
09060             }
09061 
09062             void printOriginalExpression() const {
09063                 if( result.hasExpression() ) {
09064                     stream << " " << result.getExpression();
09065                 }
09066             }
09067 
09068             void printReconstructedExpression() const {
09069                 if( result.hasExpandedExpression() ) {
09070                     {
09071                         Colour colour( dimColour() );
09072                         stream << " for: ";
09073                     }
09074                     stream << result.getExpandedExpression();
09075                 }
09076             }
09077 
09078             void printMessage() {
09079                 if ( itMessage != messages.end() ) {
09080                     stream << " '" << itMessage->message << "'";
09081                     ++itMessage;
09082                 }
09083             }
09084 
09085             void printRemainingMessages( Colour::Code colour = dimColour() ) {
09086                 if ( itMessage == messages.end() )
09087                     return;
09088 
09089                 // using messages.end() directly yields compilation error:
09090                 std::vector<MessageInfo>::const_iterator itEnd = messages.end();
09091                 const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
09092 
09093                 {
09094                     Colour colourGuard( colour );
09095                     stream << " with " << pluralise( N, "message" ) << ":";
09096                 }
09097 
09098                 for(; itMessage != itEnd; ) {
09099                     // If this assertion is a warning ignore any INFO messages
09100                     if( printInfoMessages || itMessage->type != ResultWas::Info ) {
09101                         stream << " '" << itMessage->message << "'";
09102                         if ( ++itMessage != itEnd ) {
09103                             Colour colourGuard( dimColour() );
09104                             stream << " and";
09105                         }
09106                     }
09107                 }
09108             }
09109 
09110         private:
09111             std::ostream& stream;
09112             AssertionStats const& stats;
09113             AssertionResult const& result;
09114             std::vector<MessageInfo> messages;
09115             std::vector<MessageInfo>::const_iterator itMessage;
09116             bool printInfoMessages;
09117         };
09118 
09119         // Colour, message variants:
09120         // - white: No tests ran.
09121         // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
09122         // - white: Passed [both/all] N test cases (no assertions).
09123         // -   red: Failed N tests cases, failed M assertions.
09124         // - green: Passed [both/all] N tests cases with M assertions.
09125 
09126         std::string bothOrAll( std::size_t count ) const {
09127             return count == 1 ? "" : count == 2 ? "both " : "all " ;
09128         }
09129 
09130         void printTotals( const Totals& totals ) const {
09131             if( totals.testCases.total() == 0 ) {
09132                 stream << "No tests ran.";
09133             }
09134             else if( totals.testCases.failed == totals.testCases.total() ) {
09135                 Colour colour( Colour::ResultError );
09136                 const std::string qualify_assertions_failed =
09137                     totals.assertions.failed == totals.assertions.total() ?
09138                         bothOrAll( totals.assertions.failed ) : "";
09139                 stream <<
09140                     "Failed " << bothOrAll( totals.testCases.failed )
09141                               << pluralise( totals.testCases.failed, "test case"  ) << ", "
09142                     "failed " << qualify_assertions_failed <<
09143                                  pluralise( totals.assertions.failed, "assertion" ) << ".";
09144             }
09145             else if( totals.assertions.total() == 0 ) {
09146                 stream <<
09147                     "Passed " << bothOrAll( totals.testCases.total() )
09148                               << pluralise( totals.testCases.total(), "test case" )
09149                               << " (no assertions).";
09150             }
09151             else if( totals.assertions.failed ) {
09152                 Colour colour( Colour::ResultError );
09153                 stream <<
09154                     "Failed " << pluralise( totals.testCases.failed, "test case"  ) << ", "
09155                     "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
09156             }
09157             else {
09158                 Colour colour( Colour::ResultSuccess );
09159                 stream <<
09160                     "Passed " << bothOrAll( totals.testCases.passed )
09161                               << pluralise( totals.testCases.passed, "test case"  ) <<
09162                     " with "  << pluralise( totals.assertions.passed, "assertion" ) << ".";
09163             }
09164         }
09165     };
09166 
09167     INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
09168 
09169 } // end namespace Catch
09170 
09171 namespace Catch {
09172     NonCopyable::~NonCopyable() {}
09173     IShared::~IShared() {}
09174     StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
09175     IContext::~IContext() {}
09176     IResultCapture::~IResultCapture() {}
09177     ITestCase::~ITestCase() {}
09178     ITestCaseRegistry::~ITestCaseRegistry() {}
09179     IRegistryHub::~IRegistryHub() {}
09180     IMutableRegistryHub::~IMutableRegistryHub() {}
09181     IExceptionTranslator::~IExceptionTranslator() {}
09182     IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
09183     IReporter::~IReporter() {}
09184     IReporterFactory::~IReporterFactory() {}
09185     IReporterRegistry::~IReporterRegistry() {}
09186     IStreamingReporter::~IStreamingReporter() {}
09187     AssertionStats::~AssertionStats() {}
09188     SectionStats::~SectionStats() {}
09189     TestCaseStats::~TestCaseStats() {}
09190     TestGroupStats::~TestGroupStats() {}
09191     TestRunStats::~TestRunStats() {}
09192     CumulativeReporterBase::SectionNode::~SectionNode() {}
09193     CumulativeReporterBase::~CumulativeReporterBase() {}
09194 
09195     StreamingReporterBase::~StreamingReporterBase() {}
09196     ConsoleReporter::~ConsoleReporter() {}
09197     CompactReporter::~CompactReporter() {}
09198     IRunner::~IRunner() {}
09199     IMutableContext::~IMutableContext() {}
09200     IConfig::~IConfig() {}
09201     XmlReporter::~XmlReporter() {}
09202     JunitReporter::~JunitReporter() {}
09203     TestRegistry::~TestRegistry() {}
09204     FreeFunctionTestCase::~FreeFunctionTestCase() {}
09205     IGeneratorInfo::~IGeneratorInfo() {}
09206     IGeneratorsForTest::~IGeneratorsForTest() {}
09207     TestSpec::Pattern::~Pattern() {}
09208     TestSpec::NamePattern::~NamePattern() {}
09209     TestSpec::TagPattern::~TagPattern() {}
09210     TestSpec::ExcludedPattern::~ExcludedPattern() {}
09211 
09212     Matchers::Impl::StdString::Equals::~Equals() {}
09213     Matchers::Impl::StdString::Contains::~Contains() {}
09214     Matchers::Impl::StdString::StartsWith::~StartsWith() {}
09215     Matchers::Impl::StdString::EndsWith::~EndsWith() {}
09216 
09217     void Config::dummy() {}
09218 }
09219 
09220 #ifdef __clang__
09221 #pragma clang diagnostic pop
09222 #endif
09223 
09224 #endif
09225 
09226 #ifdef CATCH_CONFIG_MAIN
09227 // #included from: internal/catch_default_main.hpp
09228 #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
09229 
09230 #ifndef __OBJC__
09231 
09232 // Standard C/C++ main entry point
09233 int main (int argc, char * const argv[]) {
09234     return Catch::Session().run( argc, argv );
09235 }
09236 
09237 #else // __OBJC__
09238 
09239 // Objective-C entry point
09240 int main (int argc, char * const argv[]) {
09241 #if !CATCH_ARC_ENABLED
09242     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
09243 #endif
09244 
09245     Catch::registerTestMethods();
09246     int result = Catch::Session().run( argc, (char* const*)argv );
09247 
09248 #if !CATCH_ARC_ENABLED
09249     [pool drain];
09250 #endif
09251 
09252     return result;
09253 }
09254 
09255 #endif // __OBJC__
09256 
09257 #endif
09258 
09259 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
09260 #  undef CLARA_CONFIG_MAIN
09261 #endif
09262 
09264 
09265 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
09266 #ifdef CATCH_CONFIG_PREFIX_ALL
09267 
09268 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
09269 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
09270 
09271 #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS" )
09272 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
09273 #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
09274 
09275 #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
09276 #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
09277 #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
09278 #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
09279 #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
09280 
09281 #define CATCH_CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
09282 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
09283 #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
09284 
09285 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
09286 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
09287 
09288 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
09289 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
09290 #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
09291 #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
09292 #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
09293 
09294 #ifdef CATCH_CONFIG_VARIADIC_MACROS
09295     #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
09296     #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
09297     #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
09298     #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
09299     #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
09300     #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
09301 #else
09302     #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
09303     #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
09304     #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
09305     #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
09306     #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
09307     #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
09308 #endif
09309 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
09310 
09311 #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
09312 #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
09313 
09314 #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
09315 
09316 // "BDD-style" convenience wrappers
09317 #ifdef CATCH_CONFIG_VARIADIC_MACROS
09318 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
09319 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
09320 #else
09321 #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
09322 #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
09323 #endif
09324 #define CATCH_GIVEN( desc )    CATCH_SECTION( "Given: " desc, "" )
09325 #define CATCH_WHEN( desc )     CATCH_SECTION( " When: " desc, "" )
09326 #define CATCH_AND_WHEN( desc ) CATCH_SECTION( "  And: " desc, "" )
09327 #define CATCH_THEN( desc )     CATCH_SECTION( " Then: " desc, "" )
09328 #define CATCH_AND_THEN( desc ) CATCH_SECTION( "  And: " desc, "" )
09329 
09330 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
09331 #else
09332 
09333 #define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
09334 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
09335 
09336 #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "REQUIRE_THROWS" )
09337 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
09338 #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
09339 
09340 #define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
09341 #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
09342 #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
09343 #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
09344 #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
09345 
09346 #define CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS" )
09347 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
09348 #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
09349 
09350 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
09351 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
09352 
09353 #define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
09354 #define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
09355 #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
09356 #define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
09357 #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
09358 
09359 #ifdef CATCH_CONFIG_VARIADIC_MACROS
09360     #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
09361     #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
09362     #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
09363     #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
09364     #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
09365     #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
09366 #else
09367     #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
09368     #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
09369     #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
09370     #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
09371     #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
09372     #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
09373 #endif
09374 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
09375 
09376 #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
09377 #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
09378 
09379 #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
09380 
09381 #endif
09382 
09383 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
09384 
09385 // "BDD-style" convenience wrappers
09386 #ifdef CATCH_CONFIG_VARIADIC_MACROS
09387 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
09388 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
09389 #else
09390 #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
09391 #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
09392 #endif
09393 #define GIVEN( desc )    SECTION( "   Given: " desc, "" )
09394 #define WHEN( desc )     SECTION( "    When: " desc, "" )
09395 #define AND_WHEN( desc ) SECTION( "And when: " desc, "" )
09396 #define THEN( desc )     SECTION( "    Then: " desc, "" )
09397 #define AND_THEN( desc ) SECTION( "     And: " desc, "" )
09398 
09399 using Catch::Detail::Approx;
09400 
09401 // #included from: internal/catch_reenable_warnings.h
09402 
09403 #define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
09404 
09405 #ifdef __clang__
09406 #    ifdef __ICC // icpc defines the __clang__ macro
09407 #        pragma warning(pop)
09408 #    else
09409 #        pragma clang diagnostic pop
09410 #    endif
09411 #elif defined __GNUC__
09412 #    pragma GCC diagnostic pop
09413 #endif
09414 
09415 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
09416 


librealsense
Author(s): Sergey Dorodnicov , Mark Horn , Reagan Lopez
autogenerated on Tue Jun 25 2019 19:54:38