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