1/*
2 *  CATCH v1.1 build 1 (master branch)
3 *  Generated: 2015-03-27 18:00:16.346230
4 *  ----------------------------------------------------------
5 *  This file has been merged from multiple headers. Please don't edit it directly
6 *  Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
7 *
8 *  Distributed under the Boost Software License, Version 1.0. (See accompanying
9 *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10 */
11#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
12#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
13
14#define TWOBLUECUBES_CATCH_HPP_INCLUDED
15
16// #included from: internal/catch_suppress_warnings.h
17
18#define TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED
19
20#ifdef __clang__
21#   ifdef __ICC // icpc defines the __clang__ macro
22#       pragma warning(push)
23#       pragma warning(disable: 161 1682)
24#   else // __ICC
25#       pragma clang diagnostic ignored "-Wglobal-constructors"
26#       pragma clang diagnostic ignored "-Wvariadic-macros"
27#       pragma clang diagnostic ignored "-Wc99-extensions"
28#       pragma clang diagnostic ignored "-Wunused-variable"
29#       pragma clang diagnostic push
30#       pragma clang diagnostic ignored "-Wpadded"
31#       pragma clang diagnostic ignored "-Wc++98-compat"
32#       pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
33#    endif
34#elif defined __GNUC__
35#    pragma GCC diagnostic ignored "-Wvariadic-macros"
36#    pragma GCC diagnostic ignored "-Wunused-variable"
37#    pragma GCC diagnostic push
38#    pragma GCC diagnostic ignored "-Wpadded"
39#endif
40
41#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
42#  define CATCH_IMPL
43#endif
44
45#ifdef CATCH_IMPL
46#  ifndef CLARA_CONFIG_MAIN
47#    define CLARA_CONFIG_MAIN_NOT_DEFINED
48#    define CLARA_CONFIG_MAIN
49#  endif
50#endif
51
52// #included from: internal/catch_notimplemented_exception.h
53#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
54
55// #included from: catch_common.h
56#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
57
58#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
59#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
60#define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
61
62#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
63#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
64
65#include <sstream>
66#include <stdexcept>
67#include <algorithm>
68
69// #included from: catch_compiler_capabilities.h
70#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
71
72// Much of the following code is based on Boost (1.53)
73
74#ifdef __clang__
75
76#  if __has_feature(cxx_nullptr)
77#    define CATCH_CONFIG_CPP11_NULLPTR
78#  endif
79
80#  if __has_feature(cxx_noexcept)
81#    define CATCH_CONFIG_CPP11_NOEXCEPT
82#  endif
83
84#endif // __clang__
85
86////////////////////////////////////////////////////////////////////////////////
87// Borland
88#ifdef __BORLANDC__
89
90#if (__BORLANDC__ > 0x582 )
91//#define CATCH_CONFIG_SFINAE // Not confirmed
92#endif
93
94#endif // __BORLANDC__
95
96////////////////////////////////////////////////////////////////////////////////
97// EDG
98#ifdef __EDG_VERSION__
99
100#if (__EDG_VERSION__ > 238 )
101//#define CATCH_CONFIG_SFINAE // Not confirmed
102#endif
103
104#endif // __EDG_VERSION__
105
106////////////////////////////////////////////////////////////////////////////////
107// Digital Mars
108#ifdef __DMC__
109
110#if (__DMC__ > 0x840 )
111//#define CATCH_CONFIG_SFINAE // Not confirmed
112#endif
113
114#endif // __DMC__
115
116////////////////////////////////////////////////////////////////////////////////
117// GCC
118#ifdef __GNUC__
119
120#if __GNUC__ < 3
121
122#if (__GNUC_MINOR__ >= 96 )
123//#define CATCH_CONFIG_SFINAE
124#endif
125
126#elif __GNUC__ >= 3
127
128// #define CATCH_CONFIG_SFINAE // Taking this out completely for now
129
130#endif // __GNUC__ < 3
131
132#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) )
133
134#define CATCH_CONFIG_CPP11_NULLPTR
135#endif
136
137#endif // __GNUC__
138
139////////////////////////////////////////////////////////////////////////////////
140// Visual C++
141#ifdef _MSC_VER
142
143#if (_MSC_VER >= 1600)
144#define CATCH_CONFIG_CPP11_NULLPTR
145#endif
146
147#if (_MSC_VER >= 1310 ) // (VC++ 7.0+)
148//#define CATCH_CONFIG_SFINAE // Not confirmed
149#endif
150
151#endif // _MSC_VER
152
153// Use variadic macros if the compiler supports them
154#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
155    ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
156    ( defined __GNUC__ && __GNUC__ >= 3 ) || \
157    ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
158
159#ifndef CATCH_CONFIG_NO_VARIADIC_MACROS
160#define CATCH_CONFIG_VARIADIC_MACROS
161#endif
162
163#endif
164
165////////////////////////////////////////////////////////////////////////////////
166// C++ language feature support
167
168// detect language version:
169#if (__cplusplus == 201103L)
170#  define CATCH_CPP11
171#  define CATCH_CPP11_OR_GREATER
172#elif (__cplusplus >= 201103L)
173#  define CATCH_CPP11_OR_GREATER
174#endif
175
176// noexcept support:
177#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
178#  define CATCH_NOEXCEPT noexcept
179#  define CATCH_NOEXCEPT_IS(x) noexcept(x)
180#else
181#  define CATCH_NOEXCEPT throw()
182#  define CATCH_NOEXCEPT_IS(x)
183#endif
184
185namespace Catch {
186
187    class NonCopyable {
188#ifdef CATCH_CPP11_OR_GREATER
189        NonCopyable( NonCopyable const& )              = delete;
190        NonCopyable( NonCopyable && )                  = delete;
191        NonCopyable& operator = ( NonCopyable const& ) = delete;
192        NonCopyable& operator = ( NonCopyable && )     = delete;
193#else
194        NonCopyable( NonCopyable const& info );
195        NonCopyable& operator = ( NonCopyable const& );
196#endif
197
198    protected:
199        NonCopyable() {}
200        virtual ~NonCopyable();
201    };
202
203    class SafeBool {
204    public:
205        typedef void (SafeBool::*type)() const;
206
207        static type makeSafe( bool value ) {
208            return value ? &SafeBool::trueValue : 0;
209        }
210    private:
211        void trueValue() const {}
212    };
213
214    template<typename ContainerT>
215    inline void deleteAll( ContainerT& container ) {
216        typename ContainerT::const_iterator it = container.begin();
217        typename ContainerT::const_iterator itEnd = container.end();
218        for(; it != itEnd; ++it )
219            delete *it;
220    }
221    template<typename AssociativeContainerT>
222    inline void deleteAllValues( AssociativeContainerT& container ) {
223        typename AssociativeContainerT::const_iterator it = container.begin();
224        typename AssociativeContainerT::const_iterator itEnd = container.end();
225        for(; it != itEnd; ++it )
226            delete it->second;
227    }
228
229    bool startsWith( std::string const& s, std::string const& prefix );
230    bool endsWith( std::string const& s, std::string const& suffix );
231    bool contains( std::string const& s, std::string const& infix );
232    void toLowerInPlace( std::string& s );
233    std::string toLower( std::string const& s );
234    std::string trim( std::string const& str );
235    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
236
237    struct pluralise {
238        pluralise( std::size_t count, std::string const& label );
239
240        friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
241
242        std::size_t m_count;
243        std::string m_label;
244    };
245
246    struct SourceLineInfo {
247
248        SourceLineInfo();
249        SourceLineInfo( char const* _file, std::size_t _line );
250        SourceLineInfo( SourceLineInfo const& other );
251#  ifdef CATCH_CPP11_OR_GREATER
252        SourceLineInfo( SourceLineInfo && )                  = default;
253        SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
254        SourceLineInfo& operator = ( SourceLineInfo && )     = default;
255#  endif
256        bool empty() const;
257        bool operator == ( SourceLineInfo const& other ) const;
258        bool operator < ( SourceLineInfo const& other ) const;
259
260        std::string file;
261        std::size_t line;
262    };
263
264    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
265
266    // This is just here to avoid compiler warnings with macro constants and boolean literals
267    inline bool isTrue( bool value ){ return value; }
268    inline bool alwaysTrue() { return true; }
269    inline bool alwaysFalse() { return false; }
270
271    void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
272
273    // Use this in variadic streaming macros to allow
274    //    >> +StreamEndStop
275    // as well as
276    //    >> stuff +StreamEndStop
277    struct StreamEndStop {
278        std::string operator+() {
279            return std::string();
280        }
281    };
282    template<typename T>
283    T const& operator + ( T const& value, StreamEndStop ) {
284        return value;
285    }
286}
287
288#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
289#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
290
291#include <ostream>
292
293namespace Catch {
294
295    class NotImplementedException : public std::exception
296    {
297    public:
298        NotImplementedException( SourceLineInfo const& lineInfo );
299        NotImplementedException( NotImplementedException const& ) {}
300
301        virtual ~NotImplementedException() CATCH_NOEXCEPT {}
302
303        virtual const char* what() const CATCH_NOEXCEPT;
304
305    private:
306        std::string m_what;
307        SourceLineInfo m_lineInfo;
308    };
309
310} // end namespace Catch
311
312///////////////////////////////////////////////////////////////////////////////
313#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
314
315// #included from: internal/catch_context.h
316#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
317
318// #included from: catch_interfaces_generators.h
319#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
320
321#include <string>
322
323namespace Catch {
324
325    struct IGeneratorInfo {
326        virtual ~IGeneratorInfo();
327        virtual bool moveNext() = 0;
328        virtual std::size_t getCurrentIndex() const = 0;
329    };
330
331    struct IGeneratorsForTest {
332        virtual ~IGeneratorsForTest();
333
334        virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
335        virtual bool moveNext() = 0;
336    };
337
338    IGeneratorsForTest* createGeneratorsForTest();
339
340} // end namespace Catch
341
342// #included from: catch_ptr.hpp
343#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
344
345#ifdef __clang__
346#pragma clang diagnostic push
347#pragma clang diagnostic ignored "-Wpadded"
348#endif
349
350namespace Catch {
351
352    // An intrusive reference counting smart pointer.
353    // T must implement addRef() and release() methods
354    // typically implementing the IShared interface
355    template<typename T>
356    class Ptr {
357    public:
358        Ptr() : m_p( NULL ){}
359        Ptr( T* p ) : m_p( p ){
360            if( m_p )
361                m_p->addRef();
362        }
363        Ptr( Ptr const& other ) : m_p( other.m_p ){
364            if( m_p )
365                m_p->addRef();
366        }
367        ~Ptr(){
368            if( m_p )
369                m_p->release();
370        }
371        void reset() {
372            if( m_p )
373                m_p->release();
374            m_p = NULL;
375        }
376        Ptr& operator = ( T* p ){
377            Ptr temp( p );
378            swap( temp );
379            return *this;
380        }
381        Ptr& operator = ( Ptr const& other ){
382            Ptr temp( other );
383            swap( temp );
384            return *this;
385        }
386        void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
387        T* get() { return m_p; }
388        const T* get() const{ return m_p; }
389        T& operator*() const { return *m_p; }
390        T* operator->() const { return m_p; }
391        bool operator !() const { return m_p == NULL; }
392        operator SafeBool::type() const { return SafeBool::makeSafe( m_p != NULL ); }
393
394    private:
395        T* m_p;
396    };
397
398    struct IShared : NonCopyable {
399        virtual ~IShared();
400        virtual void addRef() const = 0;
401        virtual void release() const = 0;
402    };
403
404    template<typename T = IShared>
405    struct SharedImpl : T {
406
407        SharedImpl() : m_rc( 0 ){}
408
409        virtual void addRef() const {
410            ++m_rc;
411        }
412        virtual void release() const {
413            if( --m_rc == 0 )
414                delete this;
415        }
416
417        mutable unsigned int m_rc;
418    };
419
420} // end namespace Catch
421
422#ifdef __clang__
423#pragma clang diagnostic pop
424#endif
425
426#include <memory>
427#include <vector>
428#include <stdlib.h>
429
430namespace Catch {
431
432    class TestCase;
433    class Stream;
434    struct IResultCapture;
435    struct IRunner;
436    struct IGeneratorsForTest;
437    struct IConfig;
438
439    struct IContext
440    {
441        virtual ~IContext();
442
443        virtual IResultCapture* getResultCapture() = 0;
444        virtual IRunner* getRunner() = 0;
445        virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
446        virtual bool advanceGeneratorsForCurrentTest() = 0;
447        virtual Ptr<IConfig const> getConfig() const = 0;
448    };
449
450    struct IMutableContext : IContext
451    {
452        virtual ~IMutableContext();
453        virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
454        virtual void setRunner( IRunner* runner ) = 0;
455        virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
456    };
457
458    IContext& getCurrentContext();
459    IMutableContext& getCurrentMutableContext();
460    void cleanUpContext();
461    Stream createStream( std::string const& streamName );
462
463}
464
465// #included from: internal/catch_test_registry.hpp
466#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
467
468// #included from: catch_interfaces_testcase.h
469#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
470
471#include <vector>
472
473namespace Catch {
474
475    class TestSpec;
476
477    struct ITestCase : IShared {
478        virtual void invoke () const = 0;
479    protected:
480        virtual ~ITestCase();
481    };
482
483    class TestCase;
484    struct IConfig;
485
486    struct ITestCaseRegistry {
487        virtual ~ITestCaseRegistry();
488        virtual std::vector<TestCase> const& getAllTests() const = 0;
489        virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const = 0;
490
491    };
492}
493
494namespace Catch {
495
496template<typename C>
497class MethodTestCase : public SharedImpl<ITestCase> {
498
499public:
500    MethodTestCase( void (C::*method)() ) : m_method( method ) {}
501
502    virtual void invoke() const {
503        C obj;
504        (obj.*m_method)();
505    }
506
507private:
508    virtual ~MethodTestCase() {}
509
510    void (C::*m_method)();
511};
512
513typedef void(*TestFunction)();
514
515struct NameAndDesc {
516    NameAndDesc( const char* _name = "", const char* _description= "" )
517    : name( _name ), description( _description )
518    {}
519
520    const char* name;
521    const char* description;
522};
523
524struct AutoReg {
525
526    AutoReg(    TestFunction function,
527                SourceLineInfo const& lineInfo,
528                NameAndDesc const& nameAndDesc );
529
530    template<typename C>
531    AutoReg(    void (C::*method)(),
532                char const* className,
533                NameAndDesc const& nameAndDesc,
534                SourceLineInfo const& lineInfo ) {
535        registerTestCase(   new MethodTestCase<C>( method ),
536                            className,
537                            nameAndDesc,
538                            lineInfo );
539    }
540
541    void registerTestCase(  ITestCase* testCase,
542                            char const* className,
543                            NameAndDesc const& nameAndDesc,
544                            SourceLineInfo const& lineInfo );
545
546    ~AutoReg();
547
548private:
549    AutoReg( AutoReg const& );
550    void operator= ( AutoReg const& );
551};
552
553} // end namespace Catch
554
555#ifdef CATCH_CONFIG_VARIADIC_MACROS
556    ///////////////////////////////////////////////////////////////////////////////
557    #define INTERNAL_CATCH_TESTCASE( ... ) \
558        static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
559        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__ ) ); }\
560        static void INTERNAL_CATCH_UNIQUE_NAME(  ____C_A_T_C_H____T_E_S_T____ )()
561
562    ///////////////////////////////////////////////////////////////////////////////
563    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
564        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
565
566    ///////////////////////////////////////////////////////////////////////////////
567    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
568        namespace{ \
569            struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
570                void test(); \
571            }; \
572            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 ); \
573        } \
574        void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
575
576#else
577    ///////////////////////////////////////////////////////////////////////////////
578    #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
579        static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
580        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 ) ); }\
581        static void INTERNAL_CATCH_UNIQUE_NAME(  ____C_A_T_C_H____T_E_S_T____ )()
582
583    ///////////////////////////////////////////////////////////////////////////////
584    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
585        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
586
587    ///////////////////////////////////////////////////////////////////////////////
588    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
589        namespace{ \
590            struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
591                void test(); \
592            }; \
593            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 ); \
594        } \
595        void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
596
597#endif
598
599// #included from: internal/catch_capture.hpp
600#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
601
602// #included from: catch_result_builder.h
603#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
604
605// #included from: catch_result_type.h
606#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
607
608namespace Catch {
609
610    // ResultWas::OfType enum
611    struct ResultWas { enum OfType {
612        Unknown = -1,
613        Ok = 0,
614        Info = 1,
615        Warning = 2,
616
617        FailureBit = 0x10,
618
619        ExpressionFailed = FailureBit | 1,
620        ExplicitFailure = FailureBit | 2,
621
622        Exception = 0x100 | FailureBit,
623
624        ThrewException = Exception | 1,
625        DidntThrowException = Exception | 2,
626
627        FatalErrorCondition = 0x200 | FailureBit
628
629    }; };
630
631    inline bool isOk( ResultWas::OfType resultType ) {
632        return ( resultType & ResultWas::FailureBit ) == 0;
633    }
634    inline bool isJustInfo( int flags ) {
635        return flags == ResultWas::Info;
636    }
637
638    // ResultDisposition::Flags enum
639    struct ResultDisposition { enum Flags {
640        Normal = 0x00,
641
642        ContinueOnFailure = 0x01,   // Failures fail test, but execution continues
643        FalseTest = 0x02,           // Prefix expression with !
644        SuppressFail = 0x04         // Failures are reported but do not fail the test
645    }; };
646
647    inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
648        return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
649    }
650
651    inline bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
652    inline bool isFalseTest( int flags )                { return ( flags & ResultDisposition::FalseTest ) != 0; }
653    inline bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
654
655} // end namespace Catch
656
657// #included from: catch_assertionresult.h
658#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
659
660#include <string>
661
662namespace Catch {
663
664    struct AssertionInfo
665    {
666        AssertionInfo() {}
667        AssertionInfo(  std::string const& _macroName,
668                        SourceLineInfo const& _lineInfo,
669                        std::string const& _capturedExpression,
670                        ResultDisposition::Flags _resultDisposition );
671
672        std::string macroName;
673        SourceLineInfo lineInfo;
674        std::string capturedExpression;
675        ResultDisposition::Flags resultDisposition;
676    };
677
678    struct AssertionResultData
679    {
680        AssertionResultData() : resultType( ResultWas::Unknown ) {}
681
682        std::string reconstructedExpression;
683        std::string message;
684        ResultWas::OfType resultType;
685    };
686
687    class AssertionResult {
688    public:
689        AssertionResult();
690        AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
691        ~AssertionResult();
692#  ifdef CATCH_CPP11_OR_GREATER
693         AssertionResult( AssertionResult const& )              = default;
694         AssertionResult( AssertionResult && )                  = default;
695         AssertionResult& operator = ( AssertionResult const& ) = default;
696         AssertionResult& operator = ( AssertionResult && )     = default;
697#  endif
698
699        bool isOk() const;
700        bool succeeded() const;
701        ResultWas::OfType getResultType() const;
702        bool hasExpression() const;
703        bool hasMessage() const;
704        std::string getExpression() const;
705        std::string getExpressionInMacro() const;
706        bool hasExpandedExpression() const;
707        std::string getExpandedExpression() const;
708        std::string getMessage() const;
709        SourceLineInfo getSourceInfo() const;
710        std::string getTestMacroName() const;
711
712    protected:
713        AssertionInfo m_info;
714        AssertionResultData m_resultData;
715    };
716
717} // end namespace Catch
718
719namespace Catch {
720
721    struct TestFailureException{};
722
723    template<typename T> class ExpressionLhs;
724
725    struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
726
727    struct CopyableStream {
728        CopyableStream() {}
729        CopyableStream( CopyableStream const& other ) {
730            oss << other.oss.str();
731        }
732        CopyableStream& operator=( CopyableStream const& other ) {
733            oss.str("");
734            oss << other.oss.str();
735            return *this;
736        }
737        std::ostringstream oss;
738    };
739
740    class ResultBuilder {
741    public:
742        ResultBuilder(  char const* macroName,
743                        SourceLineInfo const& lineInfo,
744                        char const* capturedExpression,
745                        ResultDisposition::Flags resultDisposition );
746
747        template<typename T>
748        ExpressionLhs<T const&> operator->* ( T const& operand );
749        ExpressionLhs<bool> operator->* ( bool value );
750
751        template<typename T>
752        ResultBuilder& operator << ( T const& value ) {
753            m_stream.oss << value;
754            return *this;
755        }
756
757        template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
758        template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
759
760        ResultBuilder& setResultType( ResultWas::OfType result );
761        ResultBuilder& setResultType( bool result );
762        ResultBuilder& setLhs( std::string const& lhs );
763        ResultBuilder& setRhs( std::string const& rhs );
764        ResultBuilder& setOp( std::string const& op );
765
766        void endExpression();
767
768        std::string reconstructExpression() const;
769        AssertionResult build() const;
770
771        void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
772        void captureResult( ResultWas::OfType resultType );
773        void captureExpression();
774        void react();
775        bool shouldDebugBreak() const;
776        bool allowThrows() const;
777
778    private:
779        AssertionInfo m_assertionInfo;
780        AssertionResultData m_data;
781        struct ExprComponents {
782            ExprComponents() : testFalse( false ) {}
783            bool testFalse;
784            std::string lhs, rhs, op;
785        } m_exprComponents;
786        CopyableStream m_stream;
787
788        bool m_shouldDebugBreak;
789        bool m_shouldThrow;
790    };
791
792} // namespace Catch
793
794// Include after due to circular dependency:
795// #included from: catch_expression_lhs.hpp
796#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
797
798// #included from: catch_evaluate.hpp
799#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
800
801#ifdef _MSC_VER
802#pragma warning(push)
803#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
804#endif
805
806#include <cstddef>
807
808namespace Catch {
809namespace Internal {
810
811    enum Operator {
812        IsEqualTo,
813        IsNotEqualTo,
814        IsLessThan,
815        IsGreaterThan,
816        IsLessThanOrEqualTo,
817        IsGreaterThanOrEqualTo
818    };
819
820    template<Operator Op> struct OperatorTraits             { static const char* getName(){ return "*error*"; } };
821    template<> struct OperatorTraits<IsEqualTo>             { static const char* getName(){ return "=="; } };
822    template<> struct OperatorTraits<IsNotEqualTo>          { static const char* getName(){ return "!="; } };
823    template<> struct OperatorTraits<IsLessThan>            { static const char* getName(){ return "<"; } };
824    template<> struct OperatorTraits<IsGreaterThan>         { static const char* getName(){ return ">"; } };
825    template<> struct OperatorTraits<IsLessThanOrEqualTo>   { static const char* getName(){ return "<="; } };
826    template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
827
828    template<typename T>
829    inline T& opCast(T const& t) { return const_cast<T&>(t); }
830
831// nullptr_t support based on pull request #154 from Konstantin Baumann
832#ifdef CATCH_CONFIG_CPP11_NULLPTR
833    inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
834#endif // CATCH_CONFIG_CPP11_NULLPTR
835
836    // So the compare overloads can be operator agnostic we convey the operator as a template
837    // enum, which is used to specialise an Evaluator for doing the comparison.
838    template<typename T1, typename T2, Operator Op>
839    class Evaluator{};
840
841    template<typename T1, typename T2>
842    struct Evaluator<T1, T2, IsEqualTo> {
843        static bool evaluate( T1 const& lhs, T2 const& rhs) {
844            return opCast( lhs ) ==  opCast( rhs );
845        }
846    };
847    template<typename T1, typename T2>
848    struct Evaluator<T1, T2, IsNotEqualTo> {
849        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
850            return opCast( lhs ) != opCast( rhs );
851        }
852    };
853    template<typename T1, typename T2>
854    struct Evaluator<T1, T2, IsLessThan> {
855        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
856            return opCast( lhs ) < opCast( rhs );
857        }
858    };
859    template<typename T1, typename T2>
860    struct Evaluator<T1, T2, IsGreaterThan> {
861        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
862            return opCast( lhs ) > opCast( rhs );
863        }
864    };
865    template<typename T1, typename T2>
866    struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
867        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
868            return opCast( lhs ) >= opCast( rhs );
869        }
870    };
871    template<typename T1, typename T2>
872    struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
873        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
874            return opCast( lhs ) <= opCast( rhs );
875        }
876    };
877
878    template<Operator Op, typename T1, typename T2>
879    bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
880        return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
881    }
882
883    // This level of indirection allows us to specialise for integer types
884    // to avoid signed/ unsigned warnings
885
886    // "base" overload
887    template<Operator Op, typename T1, typename T2>
888    bool compare( T1 const& lhs, T2 const& rhs ) {
889        return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
890    }
891
892    // unsigned X to int
893    template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
894        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
895    }
896    template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
897        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
898    }
899    template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
900        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
901    }
902
903    // unsigned X to long
904    template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
905        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
906    }
907    template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
908        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
909    }
910    template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
911        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
912    }
913
914    // int to unsigned X
915    template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
916        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
917    }
918    template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
919        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
920    }
921    template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
922        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
923    }
924
925    // long to unsigned X
926    template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
927        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
928    }
929    template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
930        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
931    }
932    template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
933        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
934    }
935
936    // pointer to long (when comparing against NULL)
937    template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
938        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
939    }
940    template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
941        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
942    }
943
944    // pointer to int (when comparing against NULL)
945    template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
946        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
947    }
948    template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
949        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
950    }
951
952#ifdef CATCH_CONFIG_CPP11_NULLPTR
953    // pointer to nullptr_t (when comparing against nullptr)
954    template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
955        return Evaluator<T*, T*, Op>::evaluate( NULL, rhs );
956    }
957    template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
958        return Evaluator<T*, T*, Op>::evaluate( lhs, NULL );
959    }
960#endif // CATCH_CONFIG_CPP11_NULLPTR
961
962} // end of namespace Internal
963} // end of namespace Catch
964
965#ifdef _MSC_VER
966#pragma warning(pop)
967#endif
968
969// #included from: catch_tostring.h
970#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
971
972// #included from: catch_sfinae.hpp
973#define TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED
974
975// Try to detect if the current compiler supports SFINAE
976
977namespace Catch {
978
979    struct TrueType {
980        static const bool value = true;
981        typedef void Enable;
982        char sizer[1];
983    };
984    struct FalseType {
985        static const bool value = false;
986        typedef void Disable;
987        char sizer[2];
988    };
989
990#ifdef CATCH_CONFIG_SFINAE
991
992    template<bool> struct NotABooleanExpression;
993
994    template<bool c> struct If : NotABooleanExpression<c> {};
995    template<> struct If<true> : TrueType {};
996    template<> struct If<false> : FalseType {};
997
998    template<int size> struct SizedIf;
999    template<> struct SizedIf<sizeof(TrueType)> : TrueType {};
1000    template<> struct SizedIf<sizeof(FalseType)> : FalseType {};
1001
1002#endif // CATCH_CONFIG_SFINAE
1003
1004} // end namespace Catch
1005
1006#include <sstream>
1007#include <iomanip>
1008#include <limits>
1009#include <vector>
1010#include <cstddef>
1011
1012#ifdef __OBJC__
1013// #included from: catch_objc_arc.hpp
1014#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
1015
1016#import <Foundation/Foundation.h>
1017
1018#ifdef __has_feature
1019#define CATCH_ARC_ENABLED __has_feature(objc_arc)
1020#else
1021#define CATCH_ARC_ENABLED 0
1022#endif
1023
1024void arcSafeRelease( NSObject* obj );
1025id performOptionalSelector( id obj, SEL sel );
1026
1027#if !CATCH_ARC_ENABLED
1028inline void arcSafeRelease( NSObject* obj ) {
1029    [obj release];
1030}
1031inline id performOptionalSelector( id obj, SEL sel ) {
1032    if( [obj respondsToSelector: sel] )
1033        return [obj performSelector: sel];
1034    return nil;
1035}
1036#define CATCH_UNSAFE_UNRETAINED
1037#define CATCH_ARC_STRONG
1038#else
1039inline void arcSafeRelease( NSObject* ){}
1040inline id performOptionalSelector( id obj, SEL sel ) {
1041#ifdef __clang__
1042#pragma clang diagnostic push
1043#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1044#endif
1045    if( [obj respondsToSelector: sel] )
1046        return [obj performSelector: sel];
1047#ifdef __clang__
1048#pragma clang diagnostic pop
1049#endif
1050    return nil;
1051}
1052#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1053#define CATCH_ARC_STRONG __strong
1054#endif
1055
1056#endif
1057
1058#ifdef CATCH_CPP11_OR_GREATER
1059#include <tuple>
1060#include <type_traits>
1061#endif
1062
1063namespace Catch {
1064
1065// Why we're here.
1066template<typename T>
1067std::string toString( T const& value );
1068
1069// Built in overloads
1070
1071std::string toString( std::string const& value );
1072std::string toString( std::wstring const& value );
1073std::string toString( const char* const value );
1074std::string toString( char* const value );
1075std::string toString( const wchar_t* const value );
1076std::string toString( wchar_t* const value );
1077std::string toString( int value );
1078std::string toString( unsigned long value );
1079std::string toString( unsigned int value );
1080std::string toString( const double value );
1081std::string toString( const float value );
1082std::string toString( bool value );
1083std::string toString( char value );
1084std::string toString( signed char value );
1085std::string toString( unsigned char value );
1086
1087#ifdef CATCH_CONFIG_CPP11_NULLPTR
1088std::string toString( std::nullptr_t );
1089#endif
1090
1091#ifdef __OBJC__
1092    std::string toString( NSString const * const& nsstring );
1093    std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
1094    std::string toString( NSObject* const& nsObject );
1095#endif
1096
1097namespace Detail {
1098
1099    extern std::string unprintableString;
1100
1101// SFINAE is currently disabled by default for all compilers.
1102// If the non SFINAE version of IsStreamInsertable is ambiguous for you
1103// and your compiler supports SFINAE, try #defining CATCH_CONFIG_SFINAE
1104#ifdef CATCH_CONFIG_SFINAE
1105
1106    template<typename T>
1107    class IsStreamInsertableHelper {
1108        template<int N> struct TrueIfSizeable : TrueType {};
1109
1110        template<typename T2>
1111        static TrueIfSizeable<sizeof((*(std::ostream*)0) << *((T2 const*)0))> dummy(T2*);
1112        static FalseType dummy(...);
1113
1114    public:
1115        typedef SizedIf<sizeof(dummy((T*)0))> type;
1116    };
1117
1118    template<typename T>
1119    struct IsStreamInsertable : IsStreamInsertableHelper<T>::type {};
1120
1121#else
1122
1123    struct BorgType {
1124        template<typename T> BorgType( T const& );
1125    };
1126
1127    TrueType& testStreamable( std::ostream& );
1128    FalseType testStreamable( FalseType );
1129
1130    FalseType operator<<( std::ostream const&, BorgType const& );
1131
1132    template<typename T>
1133    struct IsStreamInsertable {
1134        static std::ostream &s;
1135        static T  const&t;
1136        enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
1137    };
1138
1139#endif
1140
1141#if defined(CATCH_CPP11_OR_GREATER)
1142    template<typename T,
1143             bool IsEnum = std::is_enum<T>::value
1144             >
1145    struct EnumStringMaker
1146    {
1147        static std::string convert( T const& ) { return unprintableString; }
1148    };
1149
1150    template<typename T>
1151    struct EnumStringMaker<T,true>
1152    {
1153        static std::string convert( T const& v )
1154        {
1155            return ::Catch::toString(
1156                static_cast<typename std::underlying_type<T>::type>(v)
1157                );
1158        }
1159    };
1160#endif
1161    template<bool C>
1162    struct StringMakerBase {
1163#if defined(CATCH_CPP11_OR_GREATER)
1164        template<typename T>
1165        static std::string convert( T const& v )
1166        {
1167            return EnumStringMaker<T>::convert( v );
1168        }
1169#else
1170        template<typename T>
1171        static std::string convert( T const& ) { return unprintableString; }
1172#endif
1173    };
1174
1175    template<>
1176    struct StringMakerBase<true> {
1177        template<typename T>
1178        static std::string convert( T const& _value ) {
1179            std::ostringstream oss;
1180            oss << _value;
1181            return oss.str();
1182        }
1183    };
1184
1185    std::string rawMemoryToString( const void *object, std::size_t size );
1186
1187    template<typename T>
1188    inline std::string rawMemoryToString( const T& object ) {
1189      return rawMemoryToString( &object, sizeof(object) );
1190    }
1191
1192} // end namespace Detail
1193
1194template<typename T>
1195struct StringMaker :
1196    Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
1197
1198template<typename T>
1199struct StringMaker<T*> {
1200    template<typename U>
1201    static std::string convert( U* p ) {
1202        if( !p )
1203            return INTERNAL_CATCH_STRINGIFY( NULL );
1204        else
1205            return Detail::rawMemoryToString( p );
1206    }
1207};
1208
1209template<typename R, typename C>
1210struct StringMaker<R C::*> {
1211    static std::string convert( R C::* p ) {
1212        if( !p )
1213            return INTERNAL_CATCH_STRINGIFY( NULL );
1214        else
1215            return Detail::rawMemoryToString( p );
1216    }
1217};
1218
1219namespace Detail {
1220    template<typename InputIterator>
1221    std::string rangeToString( InputIterator first, InputIterator last );
1222}
1223
1224//template<typename T, typename Allocator>
1225//struct StringMaker<std::vector<T, Allocator> > {
1226//    static std::string convert( std::vector<T,Allocator> const& v ) {
1227//        return Detail::rangeToString( v.begin(), v.end() );
1228//    }
1229//};
1230
1231template<typename T, typename Allocator>
1232std::string toString( std::vector<T,Allocator> const& v ) {
1233    return Detail::rangeToString( v.begin(), v.end() );
1234}
1235
1236#ifdef CATCH_CPP11_OR_GREATER
1237
1238// toString for tuples
1239namespace TupleDetail {
1240  template<
1241      typename Tuple,
1242      std::size_t N = 0,
1243      bool = (N < std::tuple_size<Tuple>::value)
1244      >
1245  struct ElementPrinter {
1246      static void print( const Tuple& tuple, std::ostream& os )
1247      {
1248          os << ( N ? ", " : " " )
1249             << Catch::toString(std::get<N>(tuple));
1250          ElementPrinter<Tuple,N+1>::print(tuple,os);
1251      }
1252  };
1253
1254  template<
1255      typename Tuple,
1256      std::size_t N
1257      >
1258  struct ElementPrinter<Tuple,N,false> {
1259      static void print( const Tuple&, std::ostream& ) {}
1260  };
1261
1262}
1263
1264template<typename ...Types>
1265struct StringMaker<std::tuple<Types...>> {
1266
1267    static std::string convert( const std::tuple<Types...>& tuple )
1268    {
1269        std::ostringstream os;
1270        os << '{';
1271        TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
1272        os << " }";
1273        return os.str();
1274    }
1275};
1276#endif
1277
1278namespace Detail {
1279    template<typename T>
1280    std::string makeString( T const& value ) {
1281        return StringMaker<T>::convert( value );
1282    }
1283} // end namespace Detail
1284
1285/// \brief converts any type to a string
1286///
1287/// The default template forwards on to ostringstream - except when an
1288/// ostringstream overload does not exist - in which case it attempts to detect
1289/// that and writes {?}.
1290/// Overload (not specialise) this template for custom typs that you don't want
1291/// to provide an ostream overload for.
1292template<typename T>
1293std::string toString( T const& value ) {
1294    return StringMaker<T>::convert( value );
1295}
1296
1297    namespace Detail {
1298    template<typename InputIterator>
1299    std::string rangeToString( InputIterator first, InputIterator last ) {
1300        std::ostringstream oss;
1301        oss << "{ ";
1302        if( first != last ) {
1303            oss << Catch::toString( *first );
1304            for( ++first ; first != last ; ++first )
1305                oss << ", " << Catch::toString( *first );
1306        }
1307        oss << " }";
1308        return oss.str();
1309    }
1310}
1311
1312} // end namespace Catch
1313
1314namespace Catch {
1315
1316// Wraps the LHS of an expression and captures the operator and RHS (if any) -
1317// wrapping them all in a ResultBuilder object
1318template<typename T>
1319class ExpressionLhs {
1320    ExpressionLhs& operator = ( ExpressionLhs const& );
1321#  ifdef CATCH_CPP11_OR_GREATER
1322    ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
1323#  endif
1324
1325public:
1326    ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
1327#  ifdef CATCH_CPP11_OR_GREATER
1328    ExpressionLhs( ExpressionLhs const& ) = default;
1329    ExpressionLhs( ExpressionLhs && )     = default;
1330#  endif
1331
1332    template<typename RhsT>
1333    ResultBuilder& operator == ( RhsT const& rhs ) {
1334        return captureExpression<Internal::IsEqualTo>( rhs );
1335    }
1336
1337    template<typename RhsT>
1338    ResultBuilder& operator != ( RhsT const& rhs ) {
1339        return captureExpression<Internal::IsNotEqualTo>( rhs );
1340    }
1341
1342    template<typename RhsT>
1343    ResultBuilder& operator < ( RhsT const& rhs ) {
1344        return captureExpression<Internal::IsLessThan>( rhs );
1345    }
1346
1347    template<typename RhsT>
1348    ResultBuilder& operator > ( RhsT const& rhs ) {
1349        return captureExpression<Internal::IsGreaterThan>( rhs );
1350    }
1351
1352    template<typename RhsT>
1353    ResultBuilder& operator <= ( RhsT const& rhs ) {
1354        return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
1355    }
1356
1357    template<typename RhsT>
1358    ResultBuilder& operator >= ( RhsT const& rhs ) {
1359        return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
1360    }
1361
1362    ResultBuilder& operator == ( bool rhs ) {
1363        return captureExpression<Internal::IsEqualTo>( rhs );
1364    }
1365
1366    ResultBuilder& operator != ( bool rhs ) {
1367        return captureExpression<Internal::IsNotEqualTo>( rhs );
1368    }
1369
1370    void endExpression() {
1371        bool value = m_lhs ? true : false;
1372        m_rb
1373            .setLhs( Catch::toString( value ) )
1374            .setResultType( value )
1375            .endExpression();
1376    }
1377
1378    // Only simple binary expressions are allowed on the LHS.
1379    // If more complex compositions are required then place the sub expression in parentheses
1380    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
1381    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
1382    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
1383    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
1384    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
1385    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
1386
1387private:
1388    template<Internal::Operator Op, typename RhsT>
1389    ResultBuilder& captureExpression( RhsT const& rhs ) {
1390        return m_rb
1391            .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
1392            .setLhs( Catch::toString( m_lhs ) )
1393            .setRhs( Catch::toString( rhs ) )
1394            .setOp( Internal::OperatorTraits<Op>::getName() );
1395    }
1396
1397private:
1398    ResultBuilder& m_rb;
1399    T m_lhs;
1400};
1401
1402} // end namespace Catch
1403
1404
1405namespace Catch {
1406
1407    template<typename T>
1408    inline ExpressionLhs<T const&> ResultBuilder::operator->* ( T const& operand ) {
1409        return ExpressionLhs<T const&>( *this, operand );
1410    }
1411
1412    inline ExpressionLhs<bool> ResultBuilder::operator->* ( bool value ) {
1413        return ExpressionLhs<bool>( *this, value );
1414    }
1415
1416} // namespace Catch
1417
1418// #included from: catch_message.h
1419#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
1420
1421#include <string>
1422
1423namespace Catch {
1424
1425    struct MessageInfo {
1426        MessageInfo(    std::string const& _macroName,
1427                        SourceLineInfo const& _lineInfo,
1428                        ResultWas::OfType _type );
1429
1430        std::string macroName;
1431        SourceLineInfo lineInfo;
1432        ResultWas::OfType type;
1433        std::string message;
1434        unsigned int sequence;
1435
1436        bool operator == ( MessageInfo const& other ) const {
1437            return sequence == other.sequence;
1438        }
1439        bool operator < ( MessageInfo const& other ) const {
1440            return sequence < other.sequence;
1441        }
1442    private:
1443        static unsigned int globalCount;
1444    };
1445
1446    struct MessageBuilder {
1447        MessageBuilder( std::string const& macroName,
1448                        SourceLineInfo const& lineInfo,
1449                        ResultWas::OfType type )
1450        : m_info( macroName, lineInfo, type )
1451        {}
1452
1453        template<typename T>
1454        MessageBuilder& operator << ( T const& value ) {
1455            m_stream << value;
1456            return *this;
1457        }
1458
1459        MessageInfo m_info;
1460        std::ostringstream m_stream;
1461    };
1462
1463    class ScopedMessage {
1464    public:
1465        ScopedMessage( MessageBuilder const& builder );
1466        ScopedMessage( ScopedMessage const& other );
1467        ~ScopedMessage();
1468
1469        MessageInfo m_info;
1470    };
1471
1472} // end namespace Catch
1473
1474// #included from: catch_interfaces_capture.h
1475#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
1476
1477#include <string>
1478
1479namespace Catch {
1480
1481    class TestCase;
1482    class AssertionResult;
1483    struct AssertionInfo;
1484    struct SectionInfo;
1485    struct MessageInfo;
1486    class ScopedMessageBuilder;
1487    struct Counts;
1488
1489    struct IResultCapture {
1490
1491        virtual ~IResultCapture();
1492
1493        virtual void assertionEnded( AssertionResult const& result ) = 0;
1494        virtual bool sectionStarted(    SectionInfo const& sectionInfo,
1495                                        Counts& assertions ) = 0;
1496        virtual void sectionEnded( SectionInfo const& name, Counts const& assertions, double _durationInSeconds ) = 0;
1497        virtual void pushScopedMessage( MessageInfo const& message ) = 0;
1498        virtual void popScopedMessage( MessageInfo const& message ) = 0;
1499
1500        virtual std::string getCurrentTestName() const = 0;
1501        virtual const AssertionResult* getLastResult() const = 0;
1502
1503        virtual void handleFatalErrorCondition( std::string const& message ) = 0;
1504    };
1505
1506    IResultCapture& getResultCapture();
1507}
1508
1509// #included from: catch_debugger.h
1510#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
1511
1512// #included from: catch_platform.h
1513#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
1514
1515#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
1516#define CATCH_PLATFORM_MAC
1517#elif  defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
1518#define CATCH_PLATFORM_IPHONE
1519#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
1520#define CATCH_PLATFORM_WINDOWS
1521#endif
1522
1523#include <string>
1524
1525namespace Catch{
1526
1527    bool isDebuggerActive();
1528    void writeToDebugConsole( std::string const& text );
1529}
1530
1531#ifdef CATCH_PLATFORM_MAC
1532
1533    // The following code snippet based on:
1534    // http://cocoawithlove.com/2008/03/break-into-debugger.html
1535    #ifdef DEBUG
1536        #if defined(__ppc64__) || defined(__ppc__)
1537            #define CATCH_BREAK_INTO_DEBUGGER() \
1538                if( Catch::isDebuggerActive() ) { \
1539                    __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
1540                    : : : "memory","r0","r3","r4" ); \
1541                }
1542        #else
1543            #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
1544        #endif
1545    #endif
1546
1547#elif defined(_MSC_VER)
1548    #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
1549#elif defined(__MINGW32__)
1550    extern "C" __declspec(dllimport) void __stdcall DebugBreak();
1551    #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
1552#endif
1553
1554#ifndef CATCH_BREAK_INTO_DEBUGGER
1555#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
1556#endif
1557
1558// #included from: catch_interfaces_runner.h
1559#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
1560
1561namespace Catch {
1562    class TestCase;
1563
1564    struct IRunner {
1565        virtual ~IRunner();
1566        virtual bool aborting() const = 0;
1567    };
1568}
1569
1570///////////////////////////////////////////////////////////////////////////////
1571// In the event of a failure works out if the debugger needs to be invoked
1572// and/or an exception thrown and takes appropriate action.
1573// This needs to be done as a macro so the debugger will stop in the user
1574// source code rather than in Catch library code
1575#define INTERNAL_CATCH_REACT( resultBuilder ) \
1576    if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
1577    resultBuilder.react();
1578
1579///////////////////////////////////////////////////////////////////////////////
1580#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
1581    do { \
1582        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
1583        try { \
1584            ( __catchResult->*expr ).endExpression(); \
1585        } \
1586        catch( ... ) { \
1587            __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
1588        } \
1589        INTERNAL_CATCH_REACT( __catchResult ) \
1590    } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
1591
1592///////////////////////////////////////////////////////////////////////////////
1593#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
1594    INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
1595    if( Catch::getResultCapture().getLastResult()->succeeded() )
1596
1597///////////////////////////////////////////////////////////////////////////////
1598#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
1599    INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
1600    if( !Catch::getResultCapture().getLastResult()->succeeded() )
1601
1602///////////////////////////////////////////////////////////////////////////////
1603#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
1604    do { \
1605        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
1606        try { \
1607            expr; \
1608            __catchResult.captureResult( Catch::ResultWas::Ok ); \
1609        } \
1610        catch( ... ) { \
1611            __catchResult.useActiveException( resultDisposition ); \
1612        } \
1613        INTERNAL_CATCH_REACT( __catchResult ) \
1614    } while( Catch::alwaysFalse() )
1615
1616///////////////////////////////////////////////////////////////////////////////
1617#define INTERNAL_CATCH_THROWS( expr, resultDisposition, macroName ) \
1618    do { \
1619        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
1620        if( __catchResult.allowThrows() ) \
1621            try { \
1622                expr; \
1623                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
1624            } \
1625            catch( ... ) { \
1626                __catchResult.captureResult( Catch::ResultWas::Ok ); \
1627            } \
1628        else \
1629            __catchResult.captureResult( Catch::ResultWas::Ok ); \
1630        INTERNAL_CATCH_REACT( __catchResult ) \
1631    } while( Catch::alwaysFalse() )
1632
1633///////////////////////////////////////////////////////////////////////////////
1634#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
1635    do { \
1636        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
1637        if( __catchResult.allowThrows() ) \
1638            try { \
1639                expr; \
1640                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
1641            } \
1642            catch( exceptionType ) { \
1643                __catchResult.captureResult( Catch::ResultWas::Ok ); \
1644            } \
1645            catch( ... ) { \
1646                __catchResult.useActiveException( resultDisposition ); \
1647            } \
1648        else \
1649            __catchResult.captureResult( Catch::ResultWas::Ok ); \
1650        INTERNAL_CATCH_REACT( __catchResult ) \
1651    } while( Catch::alwaysFalse() )
1652
1653///////////////////////////////////////////////////////////////////////////////
1654#ifdef CATCH_CONFIG_VARIADIC_MACROS
1655    #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
1656        do { \
1657            Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
1658            __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
1659            __catchResult.captureResult( messageType ); \
1660            INTERNAL_CATCH_REACT( __catchResult ) \
1661        } while( Catch::alwaysFalse() )
1662#else
1663    #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
1664        do { \
1665            Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
1666            __catchResult << log + ::Catch::StreamEndStop(); \
1667            __catchResult.captureResult( messageType ); \
1668            INTERNAL_CATCH_REACT( __catchResult ) \
1669        } while( Catch::alwaysFalse() )
1670#endif
1671
1672///////////////////////////////////////////////////////////////////////////////
1673#define INTERNAL_CATCH_INFO( log, macroName ) \
1674    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
1675
1676///////////////////////////////////////////////////////////////////////////////
1677#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
1678    do { \
1679        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \
1680        try { \
1681            std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \
1682            __catchResult \
1683                .setLhs( Catch::toString( arg ) ) \
1684                .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
1685                .setOp( "matches" ) \
1686                .setResultType( ::Catch::Matchers::matcher.match( arg ) ); \
1687            __catchResult.captureExpression(); \
1688        } catch( ... ) { \
1689            __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
1690        } \
1691        INTERNAL_CATCH_REACT( __catchResult ) \
1692    } while( Catch::alwaysFalse() )
1693
1694// #included from: internal/catch_section.h
1695#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
1696
1697// #included from: catch_section_info.h
1698#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
1699
1700namespace Catch {
1701
1702    struct SectionInfo {
1703        SectionInfo
1704            (   SourceLineInfo const& _lineInfo,
1705                std::string const& _name,
1706                std::string const& _description = std::string() );
1707
1708        std::string name;
1709        std::string description;
1710        SourceLineInfo lineInfo;
1711    };
1712
1713} // end namespace Catch
1714
1715// #included from: catch_totals.hpp
1716#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
1717
1718#include <cstddef>
1719
1720namespace Catch {
1721
1722    struct Counts {
1723        Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
1724
1725        Counts operator - ( Counts const& other ) const {
1726            Counts diff;
1727            diff.passed = passed - other.passed;
1728            diff.failed = failed - other.failed;
1729            diff.failedButOk = failedButOk - other.failedButOk;
1730            return diff;
1731        }
1732        Counts& operator += ( Counts const& other ) {
1733            passed += other.passed;
1734            failed += other.failed;
1735            failedButOk += other.failedButOk;
1736            return *this;
1737        }
1738
1739        std::size_t total() const {
1740            return passed + failed + failedButOk;
1741        }
1742        bool allPassed() const {
1743            return failed == 0 && failedButOk == 0;
1744        }
1745        bool allOk() const {
1746            return failed == 0;
1747        }
1748
1749        std::size_t passed;
1750        std::size_t failed;
1751        std::size_t failedButOk;
1752    };
1753
1754    struct Totals {
1755
1756        Totals operator - ( Totals const& other ) const {
1757            Totals diff;
1758            diff.assertions = assertions - other.assertions;
1759            diff.testCases = testCases - other.testCases;
1760            return diff;
1761        }
1762
1763        Totals delta( Totals const& prevTotals ) const {
1764            Totals diff = *this - prevTotals;
1765            if( diff.assertions.failed > 0 )
1766                ++diff.testCases.failed;
1767            else if( diff.assertions.failedButOk > 0 )
1768                ++diff.testCases.failedButOk;
1769            else
1770                ++diff.testCases.passed;
1771            return diff;
1772        }
1773
1774        Totals& operator += ( Totals const& other ) {
1775            assertions += other.assertions;
1776            testCases += other.testCases;
1777            return *this;
1778        }
1779
1780        Counts assertions;
1781        Counts testCases;
1782    };
1783}
1784
1785// #included from: catch_timer.h
1786#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
1787
1788#ifdef CATCH_PLATFORM_WINDOWS
1789typedef unsigned long long uint64_t;
1790#else
1791#include <stdint.h>
1792#endif
1793
1794namespace Catch {
1795
1796    class Timer {
1797    public:
1798        Timer() : m_ticks( 0 ) {}
1799        void start();
1800        unsigned int getElapsedMicroseconds() const;
1801        unsigned int getElapsedMilliseconds() const;
1802        double getElapsedSeconds() const;
1803
1804    private:
1805        uint64_t m_ticks;
1806    };
1807
1808} // namespace Catch
1809
1810#include <string>
1811
1812namespace Catch {
1813
1814    class Section : NonCopyable {
1815    public:
1816        Section( SectionInfo const& info );
1817        ~Section();
1818
1819        // This indicates whether the section should be executed or not
1820        operator bool() const;
1821
1822    private:
1823        SectionInfo m_info;
1824
1825        std::string m_name;
1826        Counts m_assertions;
1827        bool m_sectionIncluded;
1828        Timer m_timer;
1829    };
1830
1831} // end namespace Catch
1832
1833#ifdef CATCH_CONFIG_VARIADIC_MACROS
1834    #define INTERNAL_CATCH_SECTION( ... ) \
1835        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
1836#else
1837    #define INTERNAL_CATCH_SECTION( name, desc ) \
1838        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
1839#endif
1840
1841// #included from: internal/catch_generators.hpp
1842#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
1843
1844#include <iterator>
1845#include <vector>
1846#include <string>
1847#include <stdlib.h>
1848
1849namespace Catch {
1850
1851template<typename T>
1852struct IGenerator {
1853    virtual ~IGenerator() {}
1854    virtual T getValue( std::size_t index ) const = 0;
1855    virtual std::size_t size () const = 0;
1856};
1857
1858template<typename T>
1859class BetweenGenerator : public IGenerator<T> {
1860public:
1861    BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
1862
1863    virtual T getValue( std::size_t index ) const {
1864        return m_from+static_cast<int>( index );
1865    }
1866
1867    virtual std::size_t size() const {
1868        return static_cast<std::size_t>( 1+m_to-m_from );
1869    }
1870
1871private:
1872
1873    T m_from;
1874    T m_to;
1875};
1876
1877template<typename T>
1878class ValuesGenerator : public IGenerator<T> {
1879public:
1880    ValuesGenerator(){}
1881
1882    void add( T value ) {
1883        m_values.push_back( value );
1884    }
1885
1886    virtual T getValue( std::size_t index ) const {
1887        return m_values[index];
1888    }
1889
1890    virtual std::size_t size() const {
1891        return m_values.size();
1892    }
1893
1894private:
1895    std::vector<T> m_values;
1896};
1897
1898template<typename T>
1899class CompositeGenerator {
1900public:
1901    CompositeGenerator() : m_totalSize( 0 ) {}
1902
1903    // *** Move semantics, similar to auto_ptr ***
1904    CompositeGenerator( CompositeGenerator& other )
1905    :   m_fileInfo( other.m_fileInfo ),
1906        m_totalSize( 0 )
1907    {
1908        move( other );
1909    }
1910
1911    CompositeGenerator& setFileInfo( const char* fileInfo ) {
1912        m_fileInfo = fileInfo;
1913        return *this;
1914    }
1915
1916    ~CompositeGenerator() {
1917        deleteAll( m_composed );
1918    }
1919
1920    operator T () const {
1921        size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
1922
1923        typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
1924        typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
1925        for( size_t index = 0; it != itEnd; ++it )
1926        {
1927            const IGenerator<T>* generator = *it;
1928            if( overallIndex >= index && overallIndex < index + generator->size() )
1929            {
1930                return generator->getValue( overallIndex-index );
1931            }
1932            index += generator->size();
1933        }
1934        CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
1935        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
1936    }
1937
1938    void add( const IGenerator<T>* generator ) {
1939        m_totalSize += generator->size();
1940        m_composed.push_back( generator );
1941    }
1942
1943    CompositeGenerator& then( CompositeGenerator& other ) {
1944        move( other );
1945        return *this;
1946    }
1947
1948    CompositeGenerator& then( T value ) {
1949        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1950        valuesGen->add( value );
1951        add( valuesGen );
1952        return *this;
1953    }
1954
1955private:
1956
1957    void move( CompositeGenerator& other ) {
1958        std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
1959        m_totalSize += other.m_totalSize;
1960        other.m_composed.clear();
1961    }
1962
1963    std::vector<const IGenerator<T>*> m_composed;
1964    std::string m_fileInfo;
1965    size_t m_totalSize;
1966};
1967
1968namespace Generators
1969{
1970    template<typename T>
1971    CompositeGenerator<T> between( T from, T to ) {
1972        CompositeGenerator<T> generators;
1973        generators.add( new BetweenGenerator<T>( from, to ) );
1974        return generators;
1975    }
1976
1977    template<typename T>
1978    CompositeGenerator<T> values( T val1, T val2 ) {
1979        CompositeGenerator<T> generators;
1980        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1981        valuesGen->add( val1 );
1982        valuesGen->add( val2 );
1983        generators.add( valuesGen );
1984        return generators;
1985    }
1986
1987    template<typename T>
1988    CompositeGenerator<T> values( T val1, T val2, T val3 ){
1989        CompositeGenerator<T> generators;
1990        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1991        valuesGen->add( val1 );
1992        valuesGen->add( val2 );
1993        valuesGen->add( val3 );
1994        generators.add( valuesGen );
1995        return generators;
1996    }
1997
1998    template<typename T>
1999    CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
2000        CompositeGenerator<T> generators;
2001        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2002        valuesGen->add( val1 );
2003        valuesGen->add( val2 );
2004        valuesGen->add( val3 );
2005        valuesGen->add( val4 );
2006        generators.add( valuesGen );
2007        return generators;
2008    }
2009
2010} // end namespace Generators
2011
2012using namespace Generators;
2013
2014} // end namespace Catch
2015
2016#define INTERNAL_CATCH_LINESTR2( line ) #line
2017#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
2018
2019#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
2020
2021// #included from: internal/catch_interfaces_exception.h
2022#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
2023
2024#include <string>
2025// #included from: catch_interfaces_registry_hub.h
2026#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
2027
2028#include <string>
2029
2030namespace Catch {
2031
2032    class TestCase;
2033    struct ITestCaseRegistry;
2034    struct IExceptionTranslatorRegistry;
2035    struct IExceptionTranslator;
2036    struct IReporterRegistry;
2037    struct IReporterFactory;
2038
2039    struct IRegistryHub {
2040        virtual ~IRegistryHub();
2041
2042        virtual IReporterRegistry const& getReporterRegistry() const = 0;
2043        virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2044        virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
2045    };
2046
2047    struct IMutableRegistryHub {
2048        virtual ~IMutableRegistryHub();
2049        virtual void registerReporter( std::string const& name, IReporterFactory* factory ) = 0;
2050        virtual void registerTest( TestCase const& testInfo ) = 0;
2051        virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2052    };
2053
2054    IRegistryHub& getRegistryHub();
2055    IMutableRegistryHub& getMutableRegistryHub();
2056    void cleanUp();
2057    std::string translateActiveException();
2058
2059}
2060
2061
2062namespace Catch {
2063
2064    typedef std::string(*exceptionTranslateFunction)();
2065
2066    struct IExceptionTranslator {
2067        virtual ~IExceptionTranslator();
2068        virtual std::string translate() const = 0;
2069    };
2070
2071    struct IExceptionTranslatorRegistry {
2072        virtual ~IExceptionTranslatorRegistry();
2073
2074        virtual std::string translateActiveException() const = 0;
2075    };
2076
2077    class ExceptionTranslatorRegistrar {
2078        template<typename T>
2079        class ExceptionTranslator : public IExceptionTranslator {
2080        public:
2081
2082            ExceptionTranslator( std::string(*translateFunction)( T& ) )
2083            : m_translateFunction( translateFunction )
2084            {}
2085
2086            virtual std::string translate() const {
2087                try {
2088                    throw;
2089                }
2090                catch( T& ex ) {
2091                    return m_translateFunction( ex );
2092                }
2093            }
2094
2095        protected:
2096            std::string(*m_translateFunction)( T& );
2097        };
2098
2099    public:
2100        template<typename T>
2101        ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
2102            getMutableRegistryHub().registerTranslator
2103                ( new ExceptionTranslator<T>( translateFunction ) );
2104        }
2105    };
2106}
2107
2108///////////////////////////////////////////////////////////////////////////////
2109#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
2110    static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
2111    namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
2112    static std::string INTERNAL_CATCH_UNIQUE_NAME(  catch_internal_ExceptionTranslator )( signature )
2113
2114// #included from: internal/catch_approx.hpp
2115#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
2116
2117#include <cmath>
2118#include <limits>
2119
2120namespace Catch {
2121namespace Detail {
2122
2123    class Approx {
2124    public:
2125        explicit Approx ( double value )
2126        :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
2127            m_scale( 1.0 ),
2128            m_value( value )
2129        {}
2130
2131        Approx( Approx const& other )
2132        :   m_epsilon( other.m_epsilon ),
2133            m_scale( other.m_scale ),
2134            m_value( other.m_value )
2135        {}
2136
2137        static Approx custom() {
2138            return Approx( 0 );
2139        }
2140
2141        Approx operator()( double value ) {
2142            Approx approx( value );
2143            approx.epsilon( m_epsilon );
2144            approx.scale( m_scale );
2145            return approx;
2146        }
2147
2148        friend bool operator == ( double lhs, Approx const& rhs ) {
2149            // Thanks to Richard Harris for his help refining this formula
2150            return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
2151        }
2152
2153        friend bool operator == ( Approx const& lhs, double rhs ) {
2154            return operator==( rhs, lhs );
2155        }
2156
2157        friend bool operator != ( double lhs, Approx const& rhs ) {
2158            return !operator==( lhs, rhs );
2159        }
2160
2161        friend bool operator != ( Approx const& lhs, double rhs ) {
2162            return !operator==( rhs, lhs );
2163        }
2164
2165        Approx& epsilon( double newEpsilon ) {
2166            m_epsilon = newEpsilon;
2167            return *this;
2168        }
2169
2170        Approx& scale( double newScale ) {
2171            m_scale = newScale;
2172            return *this;
2173        }
2174
2175        std::string toString() const {
2176            std::ostringstream oss;
2177            oss << "Approx( " << Catch::toString( m_value ) << " )";
2178            return oss.str();
2179        }
2180
2181    private:
2182        double m_epsilon;
2183        double m_scale;
2184        double m_value;
2185    };
2186}
2187
2188template<>
2189inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
2190    return value.toString();
2191}
2192
2193} // end namespace Catch
2194
2195// #included from: internal/catch_matchers.hpp
2196#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
2197
2198namespace Catch {
2199namespace Matchers {
2200    namespace Impl {
2201
2202    template<typename ExpressionT>
2203    struct Matcher : SharedImpl<IShared>
2204    {
2205        typedef ExpressionT ExpressionType;
2206
2207        virtual ~Matcher() {}
2208        virtual Ptr<Matcher> clone() const = 0;
2209        virtual bool match( ExpressionT const& expr ) const = 0;
2210        virtual std::string toString() const = 0;
2211    };
2212
2213    template<typename DerivedT, typename ExpressionT>
2214    struct MatcherImpl : Matcher<ExpressionT> {
2215
2216        virtual Ptr<Matcher<ExpressionT> > clone() const {
2217            return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
2218        }
2219    };
2220
2221    namespace Generic {
2222
2223        template<typename ExpressionT>
2224        class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
2225        public:
2226
2227            AllOf() {}
2228            AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
2229
2230            AllOf& add( Matcher<ExpressionT> const& matcher ) {
2231                m_matchers.push_back( matcher.clone() );
2232                return *this;
2233            }
2234            virtual bool match( ExpressionT const& expr ) const
2235            {
2236                for( std::size_t i = 0; i < m_matchers.size(); ++i )
2237                    if( !m_matchers[i]->match( expr ) )
2238                        return false;
2239                return true;
2240            }
2241            virtual std::string toString() const {
2242                std::ostringstream oss;
2243                oss << "( ";
2244                for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
2245                    if( i != 0 )
2246                        oss << " and ";
2247                    oss << m_matchers[i]->toString();
2248                }
2249                oss << " )";
2250                return oss.str();
2251            }
2252
2253        private:
2254            std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
2255        };
2256
2257        template<typename ExpressionT>
2258        class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
2259        public:
2260
2261            AnyOf() {}
2262            AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
2263
2264            AnyOf& add( Matcher<ExpressionT> const& matcher ) {
2265                m_matchers.push_back( matcher.clone() );
2266                return *this;
2267            }
2268            virtual bool match( ExpressionT const& expr ) const
2269            {
2270                for( std::size_t i = 0; i < m_matchers.size(); ++i )
2271                    if( m_matchers[i]->match( expr ) )
2272                        return true;
2273                return false;
2274            }
2275            virtual std::string toString() const {
2276                std::ostringstream oss;
2277                oss << "( ";
2278                for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
2279                    if( i != 0 )
2280                        oss << " or ";
2281                    oss << m_matchers[i]->toString();
2282                }
2283                oss << " )";
2284                return oss.str();
2285            }
2286
2287        private:
2288            std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
2289        };
2290
2291    }
2292
2293    namespace StdString {
2294
2295        inline std::string makeString( std::string const& str ) { return str; }
2296        inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
2297
2298        struct Equals : MatcherImpl<Equals, std::string> {
2299            Equals( std::string const& str ) : m_str( str ){}
2300            Equals( Equals const& other ) : m_str( other.m_str ){}
2301
2302            virtual ~Equals();
2303
2304            virtual bool match( std::string const& expr ) const {
2305                return m_str == expr;
2306            }
2307            virtual std::string toString() const {
2308                return "equals: \"" + m_str + "\"";
2309            }
2310
2311            std::string m_str;
2312        };
2313
2314        struct Contains : MatcherImpl<Contains, std::string> {
2315            Contains( std::string const& substr ) : m_substr( substr ){}
2316            Contains( Contains const& other ) : m_substr( other.m_substr ){}
2317
2318            virtual ~Contains();
2319
2320            virtual bool match( std::string const& expr ) const {
2321                return expr.find( m_substr ) != std::string::npos;
2322            }
2323            virtual std::string toString() const {
2324                return "contains: \"" + m_substr + "\"";
2325            }
2326
2327            std::string m_substr;
2328        };
2329
2330        struct StartsWith : MatcherImpl<StartsWith, std::string> {
2331            StartsWith( std::string const& substr ) : m_substr( substr ){}
2332            StartsWith( StartsWith const& other ) : m_substr( other.m_substr ){}
2333
2334            virtual ~StartsWith();
2335
2336            virtual bool match( std::string const& expr ) const {
2337                return expr.find( m_substr ) == 0;
2338            }
2339            virtual std::string toString() const {
2340                return "starts with: \"" + m_substr + "\"";
2341            }
2342
2343            std::string m_substr;
2344        };
2345
2346        struct EndsWith : MatcherImpl<EndsWith, std::string> {
2347            EndsWith( std::string const& substr ) : m_substr( substr ){}
2348            EndsWith( EndsWith const& other ) : m_substr( other.m_substr ){}
2349
2350            virtual ~EndsWith();
2351
2352            virtual bool match( std::string const& expr ) const {
2353                return expr.find( m_substr ) == expr.size() - m_substr.size();
2354            }
2355            virtual std::string toString() const {
2356                return "ends with: \"" + m_substr + "\"";
2357            }
2358
2359            std::string m_substr;
2360        };
2361    } // namespace StdString
2362    } // namespace Impl
2363
2364    // The following functions create the actual matcher objects.
2365    // This allows the types to be inferred
2366    template<typename ExpressionT>
2367    inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
2368                                                    Impl::Matcher<ExpressionT> const& m2 ) {
2369        return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
2370    }
2371    template<typename ExpressionT>
2372    inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
2373                                                    Impl::Matcher<ExpressionT> const& m2,
2374                                                    Impl::Matcher<ExpressionT> const& m3 ) {
2375        return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
2376    }
2377    template<typename ExpressionT>
2378    inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
2379                                                    Impl::Matcher<ExpressionT> const& m2 ) {
2380        return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
2381    }
2382    template<typename ExpressionT>
2383    inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
2384                                                    Impl::Matcher<ExpressionT> const& m2,
2385                                                    Impl::Matcher<ExpressionT> const& m3 ) {
2386        return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
2387    }
2388
2389    inline Impl::StdString::Equals      Equals( std::string const& str ) {
2390        return Impl::StdString::Equals( str );
2391    }
2392    inline Impl::StdString::Equals      Equals( const char* str ) {
2393        return Impl::StdString::Equals( Impl::StdString::makeString( str ) );
2394    }
2395    inline Impl::StdString::Contains    Contains( std::string const& substr ) {
2396        return Impl::StdString::Contains( substr );
2397    }
2398    inline Impl::StdString::Contains    Contains( const char* substr ) {
2399        return Impl::StdString::Contains( Impl::StdString::makeString( substr ) );
2400    }
2401    inline Impl::StdString::StartsWith  StartsWith( std::string const& substr ) {
2402        return Impl::StdString::StartsWith( substr );
2403    }
2404    inline Impl::StdString::StartsWith  StartsWith( const char* substr ) {
2405        return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
2406    }
2407    inline Impl::StdString::EndsWith    EndsWith( std::string const& substr ) {
2408        return Impl::StdString::EndsWith( substr );
2409    }
2410    inline Impl::StdString::EndsWith    EndsWith( const char* substr ) {
2411        return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
2412    }
2413
2414} // namespace Matchers
2415
2416using namespace Matchers;
2417
2418} // namespace Catch
2419
2420// #included from: internal/catch_interfaces_tag_alias_registry.h
2421#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
2422
2423// #included from: catch_tag_alias.h
2424#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
2425
2426#include <string>
2427
2428namespace Catch {
2429
2430    struct TagAlias {
2431        TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
2432
2433        std::string tag;
2434        SourceLineInfo lineInfo;
2435    };
2436
2437    struct RegistrarForTagAliases {
2438        RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
2439    };
2440
2441} // end namespace Catch
2442
2443#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
2444// #included from: catch_option.hpp
2445#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
2446
2447namespace Catch {
2448
2449    // An optional type
2450    template<typename T>
2451    class Option {
2452    public:
2453        Option() : nullableValue( NULL ) {}
2454        Option( T const& _value )
2455        : nullableValue( new( storage ) T( _value ) )
2456        {}
2457        Option( Option const& _other )
2458        : nullableValue( _other ? new( storage ) T( *_other ) : NULL )
2459        {}
2460
2461        ~Option() {
2462            reset();
2463        }
2464
2465        Option& operator= ( Option const& _other ) {
2466            if( &_other != this ) {
2467                reset();
2468                if( _other )
2469                    nullableValue = new( storage ) T( *_other );
2470            }
2471            return *this;
2472        }
2473        Option& operator = ( T const& _value ) {
2474            reset();
2475            nullableValue = new( storage ) T( _value );
2476            return *this;
2477        }
2478
2479        void reset() {
2480            if( nullableValue )
2481                nullableValue->~T();
2482            nullableValue = NULL;
2483        }
2484
2485        T& operator*() { return *nullableValue; }
2486        T const& operator*() const { return *nullableValue; }
2487        T* operator->() { return nullableValue; }
2488        const T* operator->() const { return nullableValue; }
2489
2490        T valueOr( T const& defaultValue ) const {
2491            return nullableValue ? *nullableValue : defaultValue;
2492        }
2493
2494        bool some() const { return nullableValue != NULL; }
2495        bool none() const { return nullableValue == NULL; }
2496
2497        bool operator !() const { return nullableValue == NULL; }
2498        operator SafeBool::type() const {
2499            return SafeBool::makeSafe( some() );
2500        }
2501
2502    private:
2503        T* nullableValue;
2504        char storage[sizeof(T)];
2505    };
2506
2507} // end namespace Catch
2508
2509namespace Catch {
2510
2511    struct ITagAliasRegistry {
2512        virtual ~ITagAliasRegistry();
2513        virtual Option<TagAlias> find( std::string const& alias ) const = 0;
2514        virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
2515
2516        static ITagAliasRegistry const& get();
2517    };
2518
2519} // end namespace Catch
2520
2521// These files are included here so the single_include script doesn't put them
2522// in the conditionally compiled sections
2523// #included from: internal/catch_test_case_info.h
2524#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
2525
2526#include <string>
2527#include <set>
2528
2529#ifdef __clang__
2530#pragma clang diagnostic push
2531#pragma clang diagnostic ignored "-Wpadded"
2532#endif
2533
2534namespace Catch {
2535
2536    struct ITestCase;
2537
2538    struct TestCaseInfo {
2539        enum SpecialProperties{
2540            None = 0,
2541            IsHidden = 1 << 1,
2542            ShouldFail = 1 << 2,
2543            MayFail = 1 << 3,
2544            Throws = 1 << 4
2545        };
2546
2547        TestCaseInfo(   std::string const& _name,
2548                        std::string const& _className,
2549                        std::string const& _description,
2550                        std::set<std::string> const& _tags,
2551                        SourceLineInfo const& _lineInfo );
2552
2553        TestCaseInfo( TestCaseInfo const& other );
2554
2555        bool isHidden() const;
2556        bool throws() const;
2557        bool okToFail() const;
2558        bool expectedToFail() const;
2559
2560        std::string name;
2561        std::string className;
2562        std::string description;
2563        std::set<std::string> tags;
2564        std::set<std::string> lcaseTags;
2565        std::string tagsAsString;
2566        SourceLineInfo lineInfo;
2567        SpecialProperties properties;
2568    };
2569
2570    class TestCase : public TestCaseInfo {
2571    public:
2572
2573        TestCase( ITestCase* testCase, TestCaseInfo const& info );
2574        TestCase( TestCase const& other );
2575
2576        TestCase withName( std::string const& _newName ) const;
2577
2578        void invoke() const;
2579
2580        TestCaseInfo const& getTestCaseInfo() const;
2581
2582        void swap( TestCase& other );
2583        bool operator == ( TestCase const& other ) const;
2584        bool operator < ( TestCase const& other ) const;
2585        TestCase& operator = ( TestCase const& other );
2586
2587    private:
2588        Ptr<ITestCase> test;
2589    };
2590
2591    TestCase makeTestCase(  ITestCase* testCase,
2592                            std::string const& className,
2593                            std::string const& name,
2594                            std::string const& description,
2595                            SourceLineInfo const& lineInfo );
2596}
2597
2598#ifdef __clang__
2599#pragma clang diagnostic pop
2600#endif
2601
2602
2603#ifdef __OBJC__
2604// #included from: internal/catch_objc.hpp
2605#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
2606
2607#import <objc/runtime.h>
2608
2609#include <string>
2610
2611// NB. Any general catch headers included here must be included
2612// in catch.hpp first to make sure they are included by the single
2613// header for non obj-usage
2614
2615///////////////////////////////////////////////////////////////////////////////
2616// This protocol is really only here for (self) documenting purposes, since
2617// all its methods are optional.
2618@protocol OcFixture
2619
2620@optional
2621
2622-(void) setUp;
2623-(void) tearDown;
2624
2625@end
2626
2627namespace Catch {
2628
2629    class OcMethod : public SharedImpl<ITestCase> {
2630
2631    public:
2632        OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
2633
2634        virtual void invoke() const {
2635            id obj = [[m_cls alloc] init];
2636
2637            performOptionalSelector( obj, @selector(setUp)  );
2638            performOptionalSelector( obj, m_sel );
2639            performOptionalSelector( obj, @selector(tearDown)  );
2640
2641            arcSafeRelease( obj );
2642        }
2643    private:
2644        virtual ~OcMethod() {}
2645
2646        Class m_cls;
2647        SEL m_sel;
2648    };
2649
2650    namespace Detail{
2651
2652        inline std::string getAnnotation(   Class cls,
2653                                            std::string const& annotationName,
2654                                            std::string const& testCaseName ) {
2655            NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
2656            SEL sel = NSSelectorFromString( selStr );
2657            arcSafeRelease( selStr );
2658            id value = performOptionalSelector( cls, sel );
2659            if( value )
2660                return [(NSString*)value UTF8String];
2661            return "";
2662        }
2663    }
2664
2665    inline size_t registerTestMethods() {
2666        size_t noTestMethods = 0;
2667        int noClasses = objc_getClassList( NULL, 0 );
2668
2669        Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
2670        objc_getClassList( classes, noClasses );
2671
2672        for( int c = 0; c < noClasses; c++ ) {
2673            Class cls = classes[c];
2674            {
2675                u_int count;
2676                Method* methods = class_copyMethodList( cls, &count );
2677                for( u_int m = 0; m < count ; m++ ) {
2678                    SEL selector = method_getName(methods[m]);
2679                    std::string methodName = sel_getName(selector);
2680                    if( startsWith( methodName, "Catch_TestCase_" ) ) {
2681                        std::string testCaseName = methodName.substr( 15 );
2682                        std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
2683                        std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
2684                        const char* className = class_getName( cls );
2685
2686                        getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
2687                        noTestMethods++;
2688                    }
2689                }
2690                free(methods);
2691            }
2692        }
2693        return noTestMethods;
2694    }
2695
2696    namespace Matchers {
2697        namespace Impl {
2698        namespace NSStringMatchers {
2699
2700            template<typename MatcherT>
2701            struct StringHolder : MatcherImpl<MatcherT, NSString*>{
2702                StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
2703                StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
2704                StringHolder() {
2705                    arcSafeRelease( m_substr );
2706                }
2707
2708                NSString* m_substr;
2709            };
2710
2711            struct Equals : StringHolder<Equals> {
2712                Equals( NSString* substr ) : StringHolder( substr ){}
2713
2714                virtual bool match( ExpressionType const& str ) const {
2715                    return  (str != nil || m_substr == nil ) &&
2716                            [str isEqualToString:m_substr];
2717                }
2718
2719                virtual std::string toString() const {
2720                    return "equals string: " + Catch::toString( m_substr );
2721                }
2722            };
2723
2724            struct Contains : StringHolder<Contains> {
2725                Contains( NSString* substr ) : StringHolder( substr ){}
2726
2727                virtual bool match( ExpressionType const& str ) const {
2728                    return  (str != nil || m_substr == nil ) &&
2729                            [str rangeOfString:m_substr].location != NSNotFound;
2730                }
2731
2732                virtual std::string toString() const {
2733                    return "contains string: " + Catch::toString( m_substr );
2734                }
2735            };
2736
2737            struct StartsWith : StringHolder<StartsWith> {
2738                StartsWith( NSString* substr ) : StringHolder( substr ){}
2739
2740                virtual bool match( ExpressionType const& str ) const {
2741                    return  (str != nil || m_substr == nil ) &&
2742                            [str rangeOfString:m_substr].location == 0;
2743                }
2744
2745                virtual std::string toString() const {
2746                    return "starts with: " + Catch::toString( m_substr );
2747                }
2748            };
2749            struct EndsWith : StringHolder<EndsWith> {
2750                EndsWith( NSString* substr ) : StringHolder( substr ){}
2751
2752                virtual bool match( ExpressionType const& str ) const {
2753                    return  (str != nil || m_substr == nil ) &&
2754                            [str rangeOfString:m_substr].location == [str length] - [m_substr length];
2755                }
2756
2757                virtual std::string toString() const {
2758                    return "ends with: " + Catch::toString( m_substr );
2759                }
2760            };
2761
2762        } // namespace NSStringMatchers
2763        } // namespace Impl
2764
2765        inline Impl::NSStringMatchers::Equals
2766            Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
2767
2768        inline Impl::NSStringMatchers::Contains
2769            Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
2770
2771        inline Impl::NSStringMatchers::StartsWith
2772            StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
2773
2774        inline Impl::NSStringMatchers::EndsWith
2775            EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
2776
2777    } // namespace Matchers
2778
2779    using namespace Matchers;
2780
2781} // namespace Catch
2782
2783///////////////////////////////////////////////////////////////////////////////
2784#define OC_TEST_CASE( name, desc )\
2785+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
2786{\
2787return @ name; \
2788}\
2789+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
2790{ \
2791return @ desc; \
2792} \
2793-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
2794
2795#endif
2796
2797#ifdef CATCH_IMPL
2798// #included from: internal/catch_impl.hpp
2799#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
2800
2801// Collect all the implementation files together here
2802// These are the equivalent of what would usually be cpp files
2803
2804#ifdef __clang__
2805#pragma clang diagnostic push
2806#pragma clang diagnostic ignored "-Wweak-vtables"
2807#endif
2808
2809// #included from: ../catch_runner.hpp
2810#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
2811
2812// #included from: internal/catch_commandline.hpp
2813#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
2814
2815// #included from: catch_config.hpp
2816#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
2817
2818// #included from: catch_test_spec_parser.hpp
2819#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
2820
2821#ifdef __clang__
2822#pragma clang diagnostic push
2823#pragma clang diagnostic ignored "-Wpadded"
2824#endif
2825
2826// #included from: catch_test_spec.hpp
2827#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
2828
2829#ifdef __clang__
2830#pragma clang diagnostic push
2831#pragma clang diagnostic ignored "-Wpadded"
2832#endif
2833
2834#include <string>
2835#include <vector>
2836
2837namespace Catch {
2838
2839    class TestSpec {
2840        struct Pattern : SharedImpl<> {
2841            virtual ~Pattern();
2842            virtual bool matches( TestCaseInfo const& testCase ) const = 0;
2843        };
2844        class NamePattern : public Pattern {
2845            enum WildcardPosition {
2846                NoWildcard = 0,
2847                WildcardAtStart = 1,
2848                WildcardAtEnd = 2,
2849                WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
2850            };
2851
2852        public:
2853            NamePattern( std::string const& name ) : m_name( toLower( name ) ), m_wildcard( NoWildcard ) {
2854                if( startsWith( m_name, "*" ) ) {
2855                    m_name = m_name.substr( 1 );
2856                    m_wildcard = WildcardAtStart;
2857                }
2858                if( endsWith( m_name, "*" ) ) {
2859                    m_name = m_name.substr( 0, m_name.size()-1 );
2860                    m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
2861                }
2862            }
2863            virtual ~NamePattern();
2864            virtual bool matches( TestCaseInfo const& testCase ) const {
2865                switch( m_wildcard ) {
2866                    case NoWildcard:
2867                        return m_name == toLower( testCase.name );
2868                    case WildcardAtStart:
2869                        return endsWith( toLower( testCase.name ), m_name );
2870                    case WildcardAtEnd:
2871                        return startsWith( toLower( testCase.name ), m_name );
2872                    case WildcardAtBothEnds:
2873                        return contains( toLower( testCase.name ), m_name );
2874                }
2875
2876#ifdef __clang__
2877#pragma clang diagnostic push
2878#pragma clang diagnostic ignored "-Wunreachable-code"
2879#endif
2880                throw std::logic_error( "Unknown enum" );
2881#ifdef __clang__
2882#pragma clang diagnostic pop
2883#endif
2884            }
2885        private:
2886            std::string m_name;
2887            WildcardPosition m_wildcard;
2888        };
2889        class TagPattern : public Pattern {
2890        public:
2891            TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
2892            virtual ~TagPattern();
2893            virtual bool matches( TestCaseInfo const& testCase ) const {
2894                return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
2895            }
2896        private:
2897            std::string m_tag;
2898        };
2899        class ExcludedPattern : public Pattern {
2900        public:
2901            ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
2902            virtual ~ExcludedPattern();
2903            virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
2904        private:
2905            Ptr<Pattern> m_underlyingPattern;
2906        };
2907
2908        struct Filter {
2909            std::vector<Ptr<Pattern> > m_patterns;
2910
2911            bool matches( TestCaseInfo const& testCase ) const {
2912                // All patterns in a filter must match for the filter to be a match
2913                for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
2914                    if( !(*it)->matches( testCase ) )
2915                        return false;
2916                    return true;
2917            }
2918        };
2919
2920    public:
2921        bool hasFilters() const {
2922            return !m_filters.empty();
2923        }
2924        bool matches( TestCaseInfo const& testCase ) const {
2925            // A TestSpec matches if any filter matches
2926            for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
2927                if( it->matches( testCase ) )
2928                    return true;
2929            return false;
2930        }
2931
2932    private:
2933        std::vector<Filter> m_filters;
2934
2935        friend class TestSpecParser;
2936    };
2937}
2938
2939#ifdef __clang__
2940#pragma clang diagnostic pop
2941#endif
2942
2943namespace Catch {
2944
2945    class TestSpecParser {
2946        enum Mode{ None, Name, QuotedName, Tag };
2947        Mode m_mode;
2948        bool m_exclusion;
2949        std::size_t m_start, m_pos;
2950        std::string m_arg;
2951        TestSpec::Filter m_currentFilter;
2952        TestSpec m_testSpec;
2953        ITagAliasRegistry const* m_tagAliases;
2954
2955    public:
2956        TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
2957
2958        TestSpecParser& parse( std::string const& arg ) {
2959            m_mode = None;
2960            m_exclusion = false;
2961            m_start = std::string::npos;
2962            m_arg = m_tagAliases->expandAliases( arg );
2963            for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
2964                visitChar( m_arg[m_pos] );
2965            if( m_mode == Name )
2966                addPattern<TestSpec::NamePattern>();
2967            return *this;
2968        }
2969        TestSpec testSpec() {
2970            addFilter();
2971            return m_testSpec;
2972        }
2973    private:
2974        void visitChar( char c ) {
2975            if( m_mode == None ) {
2976                switch( c ) {
2977                case ' ': return;
2978                case '~': m_exclusion = true; return;
2979                case '[': return startNewMode( Tag, ++m_pos );
2980                case '"': return startNewMode( QuotedName, ++m_pos );
2981                default: startNewMode( Name, m_pos ); break;
2982                }
2983            }
2984            if( m_mode == Name ) {
2985                if( c == ',' ) {
2986                    addPattern<TestSpec::NamePattern>();
2987                    addFilter();
2988                }
2989                else if( c == '[' ) {
2990                    if( subString() == "exclude:" )
2991                        m_exclusion = true;
2992                    else
2993                        addPattern<TestSpec::NamePattern>();
2994                    startNewMode( Tag, ++m_pos );
2995                }
2996            }
2997            else if( m_mode == QuotedName && c == '"' )
2998                addPattern<TestSpec::NamePattern>();
2999            else if( m_mode == Tag && c == ']' )
3000                addPattern<TestSpec::TagPattern>();
3001        }
3002        void startNewMode( Mode mode, std::size_t start ) {
3003            m_mode = mode;
3004            m_start = start;
3005        }
3006        std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
3007        template<typename T>
3008        void addPattern() {
3009            std::string token = subString();
3010            if( startsWith( token, "exclude:" ) ) {
3011                m_exclusion = true;
3012                token = token.substr( 8 );
3013            }
3014            if( !token.empty() ) {
3015                Ptr<TestSpec::Pattern> pattern = new T( token );
3016                if( m_exclusion )
3017                    pattern = new TestSpec::ExcludedPattern( pattern );
3018                m_currentFilter.m_patterns.push_back( pattern );
3019            }
3020            m_exclusion = false;
3021            m_mode = None;
3022        }
3023        void addFilter() {
3024            if( !m_currentFilter.m_patterns.empty() ) {
3025                m_testSpec.m_filters.push_back( m_currentFilter );
3026                m_currentFilter = TestSpec::Filter();
3027            }
3028        }
3029    };
3030    inline TestSpec parseTestSpec( std::string const& arg ) {
3031        return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
3032    }
3033
3034} // namespace Catch
3035
3036#ifdef __clang__
3037#pragma clang diagnostic pop
3038#endif
3039
3040// #included from: catch_interfaces_config.h
3041#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
3042
3043#include <iostream>
3044#include <string>
3045#include <vector>
3046
3047namespace Catch {
3048
3049    struct Verbosity { enum Level {
3050        NoOutput = 0,
3051        Quiet,
3052        Normal
3053    }; };
3054
3055    struct WarnAbout { enum What {
3056        Nothing = 0x00,
3057        NoAssertions = 0x01
3058    }; };
3059
3060    struct ShowDurations { enum OrNot {
3061        DefaultForReporter,
3062        Always,
3063        Never
3064    }; };
3065    struct RunTests { enum InWhatOrder {
3066        InDeclarationOrder,
3067        InLexicographicalOrder,
3068        InRandomOrder
3069    }; };
3070
3071    class TestSpec;
3072
3073    struct IConfig : IShared {
3074
3075        virtual ~IConfig();
3076
3077        virtual bool allowThrows() const = 0;
3078        virtual std::ostream& stream() const = 0;
3079        virtual std::string name() const = 0;
3080        virtual bool includeSuccessfulResults() const = 0;
3081        virtual bool shouldDebugBreak() const = 0;
3082        virtual bool warnAboutMissingAssertions() const = 0;
3083        virtual int abortAfter() const = 0;
3084        virtual bool showInvisibles() const = 0;
3085        virtual ShowDurations::OrNot showDurations() const = 0;
3086        virtual TestSpec const& testSpec() const = 0;
3087        virtual RunTests::InWhatOrder runOrder() const = 0;
3088        virtual unsigned int rngSeed() const = 0;
3089        virtual bool forceColour() const = 0;
3090    };
3091}
3092
3093// #included from: catch_stream.h
3094#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
3095
3096#include <streambuf>
3097
3098#ifdef __clang__
3099#pragma clang diagnostic ignored "-Wpadded"
3100#endif
3101
3102namespace Catch {
3103
3104    class Stream {
3105    public:
3106        Stream();
3107        Stream( std::streambuf* _streamBuf, bool _isOwned );
3108        void release();
3109
3110        std::streambuf* streamBuf;
3111
3112    private:
3113        bool isOwned;
3114    };
3115
3116    std::ostream& cout();
3117    std::ostream& cerr();
3118}
3119
3120#include <memory>
3121#include <vector>
3122#include <string>
3123#include <iostream>
3124#include <ctime>
3125
3126#ifndef CATCH_CONFIG_CONSOLE_WIDTH
3127#define CATCH_CONFIG_CONSOLE_WIDTH 80
3128#endif
3129
3130namespace Catch {
3131
3132    struct ConfigData {
3133
3134        ConfigData()
3135        :   listTests( false ),
3136            listTags( false ),
3137            listReporters( false ),
3138            listTestNamesOnly( false ),
3139            showSuccessfulTests( false ),
3140            shouldDebugBreak( false ),
3141            noThrow( false ),
3142            showHelp( false ),
3143            showInvisibles( false ),
3144            forceColour( false ),
3145            abortAfter( -1 ),
3146            rngSeed( 0 ),
3147            verbosity( Verbosity::Normal ),
3148            warnings( WarnAbout::Nothing ),
3149            showDurations( ShowDurations::DefaultForReporter ),
3150            runOrder( RunTests::InDeclarationOrder )
3151        {}
3152
3153        bool listTests;
3154        bool listTags;
3155        bool listReporters;
3156        bool listTestNamesOnly;
3157
3158        bool showSuccessfulTests;
3159        bool shouldDebugBreak;
3160        bool noThrow;
3161        bool showHelp;
3162        bool showInvisibles;
3163        bool forceColour;
3164
3165        int abortAfter;
3166        unsigned int rngSeed;
3167
3168        Verbosity::Level verbosity;
3169        WarnAbout::What warnings;
3170        ShowDurations::OrNot showDurations;
3171        RunTests::InWhatOrder runOrder;
3172
3173        std::string reporterName;
3174        std::string outputFilename;
3175        std::string name;
3176        std::string processName;
3177
3178        std::vector<std::string> testsOrTags;
3179    };
3180
3181    class Config : public SharedImpl<IConfig> {
3182    private:
3183        Config( Config const& other );
3184        Config& operator = ( Config const& other );
3185        virtual void dummy();
3186    public:
3187
3188        Config()
3189        :   m_os( Catch::cout().rdbuf() )
3190        {}
3191
3192        Config( ConfigData const& data )
3193        :   m_data( data ),
3194            m_os( Catch::cout().rdbuf() )
3195        {
3196            if( !data.testsOrTags.empty() ) {
3197                TestSpecParser parser( ITagAliasRegistry::get() );
3198                for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
3199                    parser.parse( data.testsOrTags[i] );
3200                m_testSpec = parser.testSpec();
3201            }
3202        }
3203
3204        virtual ~Config() {
3205            m_os.rdbuf( Catch::cout().rdbuf() );
3206            m_stream.release();
3207        }
3208
3209        void setFilename( std::string const& filename ) {
3210            m_data.outputFilename = filename;
3211        }
3212
3213        std::string const& getFilename() const {
3214            return m_data.outputFilename ;
3215        }
3216
3217        bool listTests() const { return m_data.listTests; }
3218        bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
3219        bool listTags() const { return m_data.listTags; }
3220        bool listReporters() const { return m_data.listReporters; }
3221
3222        std::string getProcessName() const { return m_data.processName; }
3223
3224        bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
3225
3226        void setStreamBuf( std::streambuf* buf ) {
3227            m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() );
3228        }
3229
3230        void useStream( std::string const& streamName ) {
3231            Stream stream = createStream( streamName );
3232            setStreamBuf( stream.streamBuf );
3233            m_stream.release();
3234            m_stream = stream;
3235        }
3236
3237        std::string getReporterName() const { return m_data.reporterName; }
3238
3239        int abortAfter() const { return m_data.abortAfter; }
3240
3241        TestSpec const& testSpec() const { return m_testSpec; }
3242
3243        bool showHelp() const { return m_data.showHelp; }
3244        bool showInvisibles() const { return m_data.showInvisibles; }
3245
3246        // IConfig interface
3247        virtual bool allowThrows() const        { return !m_data.noThrow; }
3248        virtual std::ostream& stream() const    { return m_os; }
3249        virtual std::string name() const        { return m_data.name.empty() ? m_data.processName : m_data.name; }
3250        virtual bool includeSuccessfulResults() const   { return m_data.showSuccessfulTests; }
3251        virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
3252        virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
3253        virtual RunTests::InWhatOrder runOrder() const  { return m_data.runOrder; }
3254        virtual unsigned int rngSeed() const    { return m_data.rngSeed; }
3255        virtual bool forceColour() const { return m_data.forceColour; }
3256
3257    private:
3258        ConfigData m_data;
3259
3260        Stream m_stream;
3261        mutable std::ostream m_os;
3262        TestSpec m_testSpec;
3263    };
3264
3265} // end namespace Catch
3266
3267// #included from: catch_clara.h
3268#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
3269
3270// Use Catch's value for console width (store Clara's off to the side, if present)
3271#ifdef CLARA_CONFIG_CONSOLE_WIDTH
3272#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
3273#undef CLARA_CONFIG_CONSOLE_WIDTH
3274#endif
3275#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
3276
3277// Declare Clara inside the Catch namespace
3278#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
3279// #included from: ../external/clara.h
3280
3281// Only use header guard if we are not using an outer namespace
3282#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
3283
3284#ifndef STITCH_CLARA_OPEN_NAMESPACE
3285#define TWOBLUECUBES_CLARA_H_INCLUDED
3286#define STITCH_CLARA_OPEN_NAMESPACE
3287#define STITCH_CLARA_CLOSE_NAMESPACE
3288#else
3289#define STITCH_CLARA_CLOSE_NAMESPACE }
3290#endif
3291
3292#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
3293
3294// ----------- #included from tbc_text_format.h -----------
3295
3296// Only use header guard if we are not using an outer namespace
3297#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
3298#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3299#define TBC_TEXT_FORMAT_H_INCLUDED
3300#endif
3301
3302#include <string>
3303#include <vector>
3304#include <sstream>
3305
3306// Use optional outer namespace
3307#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3308namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
3309#endif
3310
3311namespace Tbc {
3312
3313#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
3314    const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
3315#else
3316    const unsigned int consoleWidth = 80;
3317#endif
3318
3319    struct TextAttributes {
3320        TextAttributes()
3321        :   initialIndent( std::string::npos ),
3322            indent( 0 ),
3323            width( consoleWidth-1 ),
3324            tabChar( '\t' )
3325        {}
3326
3327        TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
3328        TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
3329        TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
3330        TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }
3331
3332        std::size_t initialIndent;  // indent of first line, or npos
3333        std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
3334        std::size_t width;          // maximum width of text, including indent. Longer text will wrap
3335        char tabChar;               // If this char is seen the indent is changed to current pos
3336    };
3337
3338    class Text {
3339    public:
3340        Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
3341        : attr( _attr )
3342        {
3343            std::string wrappableChars = " [({.,/|\\-";
3344            std::size_t indent = _attr.initialIndent != std::string::npos
3345                ? _attr.initialIndent
3346                : _attr.indent;
3347            std::string remainder = _str;
3348
3349            while( !remainder.empty() ) {
3350                if( lines.size() >= 1000 ) {
3351                    lines.push_back( "... message truncated due to excessive size" );
3352                    return;
3353                }
3354                std::size_t tabPos = std::string::npos;
3355                std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
3356                std::size_t pos = remainder.find_first_of( '\n' );
3357                if( pos <= width ) {
3358                    width = pos;
3359                }
3360                pos = remainder.find_last_of( _attr.tabChar, width );
3361                if( pos != std::string::npos ) {
3362                    tabPos = pos;
3363                    if( remainder[width] == '\n' )
3364                        width--;
3365                    remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
3366                }
3367
3368                if( width == remainder.size() ) {
3369                    spliceLine( indent, remainder, width );
3370                }
3371                else if( remainder[width] == '\n' ) {
3372                    spliceLine( indent, remainder, width );
3373                    if( width <= 1 || remainder.size() != 1 )
3374                        remainder = remainder.substr( 1 );
3375                    indent = _attr.indent;
3376                }
3377                else {
3378                    pos = remainder.find_last_of( wrappableChars, width );
3379                    if( pos != std::string::npos && pos > 0 ) {
3380                        spliceLine( indent, remainder, pos );
3381                        if( remainder[0] == ' ' )
3382                            remainder = remainder.substr( 1 );
3383                    }
3384                    else {
3385                        spliceLine( indent, remainder, width-1 );
3386                        lines.back() += "-";
3387                    }
3388                    if( lines.size() == 1 )
3389                        indent = _attr.indent;
3390                    if( tabPos != std::string::npos )
3391                        indent += tabPos;
3392                }
3393            }
3394        }
3395
3396        void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
3397            lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
3398            _remainder = _remainder.substr( _pos );
3399        }
3400
3401        typedef std::vector<std::string>::const_iterator const_iterator;
3402
3403        const_iterator begin() const { return lines.begin(); }
3404        const_iterator end() const { return lines.end(); }
3405        std::string const& last() const { return lines.back(); }
3406        std::size_t size() const { return lines.size(); }
3407        std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
3408        std::string toString() const {
3409            std::ostringstream oss;
3410            oss << *this;
3411            return oss.str();
3412        }
3413
3414        inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
3415            for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
3416                it != itEnd; ++it ) {
3417                if( it != _text.begin() )
3418                    _stream << "\n";
3419                _stream << *it;
3420            }
3421            return _stream;
3422        }
3423
3424    private:
3425        std::string str;
3426        TextAttributes attr;
3427        std::vector<std::string> lines;
3428    };
3429
3430} // end namespace Tbc
3431
3432#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3433} // end outer namespace
3434#endif
3435
3436#endif // TBC_TEXT_FORMAT_H_INCLUDED
3437
3438// ----------- end of #include from tbc_text_format.h -----------
3439// ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h
3440
3441#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
3442
3443#include <map>
3444#include <algorithm>
3445#include <stdexcept>
3446#include <memory>
3447
3448// Use optional outer namespace
3449#ifdef STITCH_CLARA_OPEN_NAMESPACE
3450STITCH_CLARA_OPEN_NAMESPACE
3451#endif
3452
3453namespace Clara {
3454
3455    struct UnpositionalTag {};
3456
3457    extern UnpositionalTag _;
3458
3459#ifdef CLARA_CONFIG_MAIN
3460    UnpositionalTag _;
3461#endif
3462
3463    namespace Detail {
3464
3465#ifdef CLARA_CONSOLE_WIDTH
3466    const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
3467#else
3468    const unsigned int consoleWidth = 80;
3469#endif
3470
3471        using namespace Tbc;
3472
3473        inline bool startsWith( std::string const& str, std::string const& prefix ) {
3474            return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
3475        }
3476
3477        template<typename T> struct RemoveConstRef{ typedef T type; };
3478        template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
3479        template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
3480        template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
3481
3482        template<typename T>    struct IsBool       { static const bool value = false; };
3483        template<>              struct IsBool<bool> { static const bool value = true; };
3484
3485        template<typename T>
3486        void convertInto( std::string const& _source, T& _dest ) {
3487            std::stringstream ss;
3488            ss << _source;
3489            ss >> _dest;
3490            if( ss.fail() )
3491                throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
3492        }
3493        inline void convertInto( std::string const& _source, std::string& _dest ) {
3494            _dest = _source;
3495        }
3496        inline void convertInto( std::string const& _source, bool& _dest ) {
3497            std::string sourceLC = _source;
3498            std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
3499            if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
3500                _dest = true;
3501            else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
3502                _dest = false;
3503            else
3504                throw std::runtime_error( "Expected a boolean value but did not recognise:\n  '" + _source + "'" );
3505        }
3506        inline void convertInto( bool _source, bool& _dest ) {
3507            _dest = _source;
3508        }
3509        template<typename T>
3510        inline void convertInto( bool, T& ) {
3511            throw std::runtime_error( "Invalid conversion" );
3512        }
3513
3514        template<typename ConfigT>
3515        struct IArgFunction {
3516            virtual ~IArgFunction() {}
3517#  ifdef CATCH_CPP11_OR_GREATER
3518            IArgFunction()                      = default;
3519            IArgFunction( IArgFunction const& ) = default;
3520#  endif
3521            virtual void set( ConfigT& config, std::string const& value ) const = 0;
3522            virtual void setFlag( ConfigT& config ) const = 0;
3523            virtual bool takesArg() const = 0;
3524            virtual IArgFunction* clone() const = 0;
3525        };
3526
3527        template<typename ConfigT>
3528        class BoundArgFunction {
3529        public:
3530            BoundArgFunction() : functionObj( NULL ) {}
3531            BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
3532            BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : NULL ) {}
3533            BoundArgFunction& operator = ( BoundArgFunction const& other ) {
3534                IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : NULL;
3535                delete functionObj;
3536                functionObj = newFunctionObj;
3537                return *this;
3538            }
3539            ~BoundArgFunction() { delete functionObj; }
3540
3541            void set( ConfigT& config, std::string const& value ) const {
3542                functionObj->set( config, value );
3543            }
3544            void setFlag( ConfigT& config ) const {
3545                functionObj->setFlag( config );
3546            }
3547            bool takesArg() const { return functionObj->takesArg(); }
3548
3549            bool isSet() const {
3550                return functionObj != NULL;
3551            }
3552        private:
3553            IArgFunction<ConfigT>* functionObj;
3554        };
3555
3556        template<typename C>
3557        struct NullBinder : IArgFunction<C>{
3558            virtual void set( C&, std::string const& ) const {}
3559            virtual void setFlag( C& ) const {}
3560            virtual bool takesArg() const { return true; }
3561            virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
3562        };
3563
3564        template<typename C, typename M>
3565        struct BoundDataMember : IArgFunction<C>{
3566            BoundDataMember( M C::* _member ) : member( _member ) {}
3567            virtual void set( C& p, std::string const& stringValue ) const {
3568                convertInto( stringValue, p.*member );
3569            }
3570            virtual void setFlag( C& p ) const {
3571                convertInto( true, p.*member );
3572            }
3573            virtual bool takesArg() const { return !IsBool<M>::value; }
3574            virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
3575            M C::* member;
3576        };
3577        template<typename C, typename M>
3578        struct BoundUnaryMethod : IArgFunction<C>{
3579            BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
3580            virtual void set( C& p, std::string const& stringValue ) const {
3581                typename RemoveConstRef<M>::type value;
3582                convertInto( stringValue, value );
3583                (p.*member)( value );
3584            }
3585            virtual void setFlag( C& p ) const {
3586                typename RemoveConstRef<M>::type value;
3587                convertInto( true, value );
3588                (p.*member)( value );
3589            }
3590            virtual bool takesArg() const { return !IsBool<M>::value; }
3591            virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
3592            void (C::*member)( M );
3593        };
3594        template<typename C>
3595        struct BoundNullaryMethod : IArgFunction<C>{
3596            BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
3597            virtual void set( C& p, std::string const& stringValue ) const {
3598                bool value;
3599                convertInto( stringValue, value );
3600                if( value )
3601                    (p.*member)();
3602            }
3603            virtual void setFlag( C& p ) const {
3604                (p.*member)();
3605            }
3606            virtual bool takesArg() const { return false; }
3607            virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
3608            void (C::*member)();
3609        };
3610
3611        template<typename C>
3612        struct BoundUnaryFunction : IArgFunction<C>{
3613            BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
3614            virtual void set( C& obj, std::string const& stringValue ) const {
3615                bool value;
3616                convertInto( stringValue, value );
3617                if( value )
3618                    function( obj );
3619            }
3620            virtual void setFlag( C& p ) const {
3621                function( p );
3622            }
3623            virtual bool takesArg() const { return false; }
3624            virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
3625            void (*function)( C& );
3626        };
3627
3628        template<typename C, typename T>
3629        struct BoundBinaryFunction : IArgFunction<C>{
3630            BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
3631            virtual void set( C& obj, std::string const& stringValue ) const {
3632                typename RemoveConstRef<T>::type value;
3633                convertInto( stringValue, value );
3634                function( obj, value );
3635            }
3636            virtual void setFlag( C& obj ) const {
3637                typename RemoveConstRef<T>::type value;
3638                convertInto( true, value );
3639                function( obj, value );
3640            }
3641            virtual bool takesArg() const { return !IsBool<T>::value; }
3642            virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
3643            void (*function)( C&, T );
3644        };
3645
3646    } // namespace Detail
3647
3648    struct Parser {
3649        Parser() : separators( " \t=:" ) {}
3650
3651        struct Token {
3652            enum Type { Positional, ShortOpt, LongOpt };
3653            Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
3654            Type type;
3655            std::string data;
3656        };
3657
3658        void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const {
3659            const std::string doubleDash = "--";
3660            for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
3661                parseIntoTokens( argv[i] , tokens);
3662        }
3663        void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
3664            while( !arg.empty() ) {
3665                Parser::Token token( Parser::Token::Positional, arg );
3666                arg = "";
3667                if( token.data[0] == '-' ) {
3668                    if( token.data.size() > 1 && token.data[1] == '-' ) {
3669                        token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
3670                    }
3671                    else {
3672                        token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
3673                        if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
3674                            arg = "-" + token.data.substr( 1 );
3675                            token.data = token.data.substr( 0, 1 );
3676                        }
3677                    }
3678                }
3679                if( token.type != Parser::Token::Positional ) {
3680                    std::size_t pos = token.data.find_first_of( separators );
3681                    if( pos != std::string::npos ) {
3682                        arg = token.data.substr( pos+1 );
3683                        token.data = token.data.substr( 0, pos );
3684                    }
3685                }
3686                tokens.push_back( token );
3687            }
3688        }
3689        std::string separators;
3690    };
3691
3692    template<typename ConfigT>
3693    struct CommonArgProperties {
3694        CommonArgProperties() {}
3695        CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
3696
3697        Detail::BoundArgFunction<ConfigT> boundField;
3698        std::string description;
3699        std::string detail;
3700        std::string placeholder; // Only value if boundField takes an arg
3701
3702        bool takesArg() const {
3703            return !placeholder.empty();
3704        }
3705        void validate() const {
3706            if( !boundField.isSet() )
3707                throw