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