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