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