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