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