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