1 /*
2  *  Catch v1.12.0
3  *  Generated: 2018-01-11 21:56:34.893972
4  *  ----------------------------------------------------------
5  *  This file has been merged from multiple headers. Please don't edit it directly
6  *  Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
7  *
8  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
9  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10  */
11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
13 
14 #define TWOBLUECUBES_CATCH_HPP_INCLUDED
15 
16 #ifdef __clang__
17 #    pragma clang system_header
18 #elif defined __GNUC__
19 #    pragma GCC system_header
20 #endif
21 
22 // #included from: internal/catch_suppress_warnings.h
23 
24 #ifdef __clang__
25 #   ifdef __ICC // icpc defines the __clang__ macro
26 #       pragma warning(push)
27 #       pragma warning(disable: 161 1682)
28 #   else // __ICC
29 #       pragma clang diagnostic ignored "-Wglobal-constructors"
30 #       pragma clang diagnostic ignored "-Wvariadic-macros"
31 #       pragma clang diagnostic ignored "-Wc99-extensions"
32 #       pragma clang diagnostic ignored "-Wunused-variable"
33 #       pragma clang diagnostic push
34 #       pragma clang diagnostic ignored "-Wpadded"
35 #       pragma clang diagnostic ignored "-Wc++98-compat"
36 #       pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
37 #       pragma clang diagnostic ignored "-Wswitch-enum"
38 #       pragma clang diagnostic ignored "-Wcovered-switch-default"
39 #    endif
40 #elif defined __GNUC__
41 #    pragma GCC diagnostic ignored "-Wvariadic-macros"
42 #    pragma GCC diagnostic ignored "-Wunused-variable"
43 #    pragma GCC diagnostic ignored "-Wparentheses"
44 
45 #    pragma GCC diagnostic push
46 #    pragma GCC diagnostic ignored "-Wpadded"
47 #endif
48 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
49 #  define CATCH_IMPL
50 #endif
51 
52 #ifdef CATCH_IMPL
53 #  ifndef CLARA_CONFIG_MAIN
54 #    define CLARA_CONFIG_MAIN_NOT_DEFINED
55 #    define CLARA_CONFIG_MAIN
56 #  endif
57 #endif
58 
59 // #included from: internal/catch_notimplemented_exception.h
60 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
61 
62 // #included from: catch_common.h
63 #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
64 
65 // #included from: catch_compiler_capabilities.h
66 #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
67 
68 // Detect a number of compiler features - mostly C++11/14 conformance - by compiler
69 // The following features are defined:
70 //
71 // CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
72 // CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
73 // CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
74 // CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
75 // CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
76 // CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
77 // CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
78 // CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
79 // CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported?
80 // CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported?
81 
82 // CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
83 
84 // CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
85 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
86 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
87 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
88 // ****************
89 // Note to maintainers: if new toggles are added please document them
90 // in configuration.md, too
91 // ****************
92 
93 // In general each macro has a _NO_<feature name> form
94 // (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
95 // Many features, at point of detection, define an _INTERNAL_ macro, so they
96 // can be combined, en-mass, with the _NO_ forms later.
97 
98 // All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
99 
100 #ifdef __cplusplus
101 
102 #  if __cplusplus >= 201103L
103 #    define CATCH_CPP11_OR_GREATER
104 #  endif
105 
106 #  if __cplusplus >= 201402L
107 #    define CATCH_CPP14_OR_GREATER
108 #  endif
109 
110 #endif
111 
112 #ifdef __clang__
113 
114 #  if __has_feature(cxx_nullptr)
115 #    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
116 #  endif
117 
118 #  if __has_feature(cxx_noexcept)
119 #    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
120 #  endif
121 
122 #   if defined(CATCH_CPP11_OR_GREATER)
123 #       define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
124             _Pragma( "clang diagnostic push" ) \
125             _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" )
126 #       define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
127             _Pragma( "clang diagnostic pop" )
128 
129 #       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
130             _Pragma( "clang diagnostic push" ) \
131             _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
132 #       define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
133             _Pragma( "clang diagnostic pop" )
134 #   endif
135 
136 #endif // __clang__
137 
138 ////////////////////////////////////////////////////////////////////////////////
139 // We know some environments not to support full POSIX signals
140 #if defined(__CYGWIN__) || defined(__QNX__)
141 
142 #   if !defined(CATCH_CONFIG_POSIX_SIGNALS)
143 #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
144 #   endif
145 
146 #endif
147 
148 #ifdef __OS400__
149 #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
150 #       define CATCH_CONFIG_COLOUR_NONE
151 #endif
152 
153 ////////////////////////////////////////////////////////////////////////////////
154 // Cygwin
155 #ifdef __CYGWIN__
156 
157 // Required for some versions of Cygwin to declare gettimeofday
158 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
159 #   define _BSD_SOURCE
160 
161 #endif // __CYGWIN__
162 
163 ////////////////////////////////////////////////////////////////////////////////
164 // Borland
165 #ifdef __BORLANDC__
166 
167 #endif // __BORLANDC__
168 
169 ////////////////////////////////////////////////////////////////////////////////
170 // EDG
171 #ifdef __EDG_VERSION__
172 
173 #endif // __EDG_VERSION__
174 
175 ////////////////////////////////////////////////////////////////////////////////
176 // Digital Mars
177 #ifdef __DMC__
178 
179 #endif // __DMC__
180 
181 ////////////////////////////////////////////////////////////////////////////////
182 // GCC
183 #ifdef __GNUC__
184 
185 #   if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
186 #       define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
187 #   endif
188 
189 // - otherwise more recent versions define __cplusplus >= 201103L
190 // and will get picked up below
191 
192 #endif // __GNUC__
193 
194 ////////////////////////////////////////////////////////////////////////////////
195 // Visual C++
196 #ifdef _MSC_VER
197 
198 #define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
199 
200 #if (_MSC_VER >= 1600)
201 #   define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
202 #   define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
203 #endif
204 
205 #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
206 #define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
207 #define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
208 #define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
209 #define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
210 #endif
211 
212 #endif // _MSC_VER
213 
214 ////////////////////////////////////////////////////////////////////////////////
215 
216 // Use variadic macros if the compiler supports them
217 #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
218     ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
219     ( defined __GNUC__ && __GNUC__ >= 3 ) || \
220     ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
221 
222 #define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
223 
224 #endif
225 
226 // Use __COUNTER__ if the compiler supports it
227 #if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
228     ( defined __GNUC__  && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \
229     ( defined __clang__ && __clang_major__ >= 3 )
230 
231 // Use of __COUNTER__ is suppressed during code analysis in CLion/AppCode 2017.2.x and former,
232 // because __COUNTER__ is not properly handled by it.
233 // This does not affect compilation
234 #if ( !defined __JETBRAINS_IDE__ || __JETBRAINS_IDE__ >= 20170300L )
235     #define CATCH_INTERNAL_CONFIG_COUNTER
236 #endif
237 
238 #endif
239 
240 ////////////////////////////////////////////////////////////////////////////////
241 // C++ language feature support
242 
243 // catch all support for C++11
244 #if defined(CATCH_CPP11_OR_GREATER)
245 
246 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
247 #    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
248 #  endif
249 
250 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
251 #    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
252 #  endif
253 
254 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
255 #    define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
256 #  endif
257 
258 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
259 #    define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
260 #  endif
261 
262 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
263 #    define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
264 #  endif
265 
266 #  ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
267 #    define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
268 #  endif
269 
270 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
271 #    define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
272 #  endif
273 
274 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
275 #    define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
276 #  endif
277 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
278 #    define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
279 #  endif
280 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE)
281 #   define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
282 #  endif
283 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS)
284 #  define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
285 # endif
286 
287 #endif // __cplusplus >= 201103L
288 
289 // Now set the actual defines based on the above + anything the user has configured
290 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
291 #   define CATCH_CONFIG_CPP11_NULLPTR
292 #endif
293 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
294 #   define CATCH_CONFIG_CPP11_NOEXCEPT
295 #endif
296 #if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
297 #   define CATCH_CONFIG_CPP11_GENERATED_METHODS
298 #endif
299 #if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
300 #   define CATCH_CONFIG_CPP11_IS_ENUM
301 #endif
302 #if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
303 #   define CATCH_CONFIG_CPP11_TUPLE
304 #endif
305 #if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
306 #   define CATCH_CONFIG_VARIADIC_MACROS
307 #endif
308 #if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
309 #   define CATCH_CONFIG_CPP11_LONG_LONG
310 #endif
311 #if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
312 #   define CATCH_CONFIG_CPP11_OVERRIDE
313 #endif
314 #if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
315 #   define CATCH_CONFIG_CPP11_UNIQUE_PTR
316 #endif
317 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
318 #   define CATCH_CONFIG_COUNTER
319 #endif
320 #if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)
321 #   define CATCH_CONFIG_CPP11_SHUFFLE
322 #endif
323 # if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11)
324 #  define CATCH_CONFIG_CPP11_TYPE_TRAITS
325 # endif
326 #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
327 #   define CATCH_CONFIG_WINDOWS_SEH
328 #endif
329 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
330 #if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
331 #   define CATCH_CONFIG_POSIX_SIGNALS
332 #endif
333 
334 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
335 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
336 #   define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
337 #endif
338 #if !defined(CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS)
339 #   define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS
340 #   define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
341 #endif
342 
343 // noexcept support:
344 #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
345 #  define CATCH_NOEXCEPT noexcept
346 #  define CATCH_NOEXCEPT_IS(x) noexcept(x)
347 #else
348 #  define CATCH_NOEXCEPT throw()
349 #  define CATCH_NOEXCEPT_IS(x)
350 #endif
351 
352 // nullptr support
353 #ifdef CATCH_CONFIG_CPP11_NULLPTR
354 #   define CATCH_NULL nullptr
355 #else
356 #   define CATCH_NULL NULL
357 #endif
358 
359 // override support
360 #ifdef CATCH_CONFIG_CPP11_OVERRIDE
361 #   define CATCH_OVERRIDE override
362 #else
363 #   define CATCH_OVERRIDE
364 #endif
365 
366 // unique_ptr support
367 #ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
368 #   define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
369 #else
370 #   define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
371 #endif
372 
373 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
374 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
375 #ifdef CATCH_CONFIG_COUNTER
376 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
377 #else
378 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
379 #endif
380 
381 #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
382 #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
383 
384 #include <sstream>
385 #include <algorithm>
386 
387 namespace Catch {
388 
389     struct IConfig;
390 
391     struct CaseSensitive { enum Choice {
392         Yes,
393         No
394     }; };
395 
396     class NonCopyable {
397 #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
398         NonCopyable( NonCopyable const& )              = delete;
399         NonCopyable( NonCopyable && )                  = delete;
400         NonCopyable& operator = ( NonCopyable const& ) = delete;
401         NonCopyable& operator = ( NonCopyable && )     = delete;
402 #else
403         NonCopyable( NonCopyable const& info );
404         NonCopyable& operator = ( NonCopyable const& );
405 #endif
406 
407     protected:
NonCopyable()408         NonCopyable() {}
409         virtual ~NonCopyable();
410     };
411 
412     class SafeBool {
413     public:
414         typedef void (SafeBool::*type)() const;
415 
makeSafe(bool value)416         static type makeSafe( bool value ) {
417             return value ? &SafeBool::trueValue : 0;
418         }
419     private:
trueValue() const420         void trueValue() const {}
421     };
422 
423     template<typename ContainerT>
deleteAll(ContainerT & container)424     void deleteAll( ContainerT& container ) {
425         typename ContainerT::const_iterator it = container.begin();
426         typename ContainerT::const_iterator itEnd = container.end();
427         for(; it != itEnd; ++it )
428             delete *it;
429     }
430     template<typename AssociativeContainerT>
deleteAllValues(AssociativeContainerT & container)431     void deleteAllValues( AssociativeContainerT& container ) {
432         typename AssociativeContainerT::const_iterator it = container.begin();
433         typename AssociativeContainerT::const_iterator itEnd = container.end();
434         for(; it != itEnd; ++it )
435             delete it->second;
436     }
437 
438     bool startsWith( std::string const& s, std::string const& prefix );
439     bool startsWith( std::string const& s, char prefix );
440     bool endsWith( std::string const& s, std::string const& suffix );
441     bool endsWith( std::string const& s, char suffix );
442     bool contains( std::string const& s, std::string const& infix );
443     void toLowerInPlace( std::string& s );
444     std::string toLower( std::string const& s );
445     std::string trim( std::string const& str );
446     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
447 
448     struct pluralise {
449         pluralise( std::size_t count, std::string const& label );
450 
451         friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
452 
453         std::size_t m_count;
454         std::string m_label;
455     };
456 
457     struct SourceLineInfo {
458 
459         SourceLineInfo();
460         SourceLineInfo( char const* _file, std::size_t _line );
461 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
462         SourceLineInfo(SourceLineInfo const& other)          = default;
463         SourceLineInfo( SourceLineInfo && )                  = default;
464         SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
465         SourceLineInfo& operator = ( SourceLineInfo && )     = default;
466 #  endif
467         bool empty() const;
468         bool operator == ( SourceLineInfo const& other ) const;
469         bool operator < ( SourceLineInfo const& other ) const;
470 
471         char const* file;
472         std::size_t line;
473     };
474 
475     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
476 
477     // This is just here to avoid compiler warnings with macro constants and boolean literals
isTrue(bool value)478     inline bool isTrue( bool value ){ return value; }
alwaysTrue()479     inline bool alwaysTrue() { return true; }
alwaysFalse()480     inline bool alwaysFalse() { return false; }
481 
482     void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
483 
484     void seedRng( IConfig const& config );
485     unsigned int rngSeed();
486 
487     // Use this in variadic streaming macros to allow
488     //    >> +StreamEndStop
489     // as well as
490     //    >> stuff +StreamEndStop
491     struct StreamEndStop {
operator +Catch::StreamEndStop492         std::string operator+() {
493             return std::string();
494         }
495     };
496     template<typename T>
operator +(T const & value,StreamEndStop)497     T const& operator + ( T const& value, StreamEndStop ) {
498         return value;
499     }
500 }
501 
502 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
503 #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
504 
505 namespace Catch {
506 
507     class NotImplementedException : public std::exception
508     {
509     public:
510         NotImplementedException( SourceLineInfo const& lineInfo );
511 
~NotImplementedException()512         virtual ~NotImplementedException() CATCH_NOEXCEPT {}
513 
514         virtual const char* what() const CATCH_NOEXCEPT;
515 
516     private:
517         std::string m_what;
518         SourceLineInfo m_lineInfo;
519     };
520 
521 } // end namespace Catch
522 
523 ///////////////////////////////////////////////////////////////////////////////
524 #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
525 
526 // #included from: internal/catch_context.h
527 #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
528 
529 // #included from: catch_interfaces_generators.h
530 #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
531 
532 #include <string>
533 
534 namespace Catch {
535 
536     struct IGeneratorInfo {
537         virtual ~IGeneratorInfo();
538         virtual bool moveNext() = 0;
539         virtual std::size_t getCurrentIndex() const = 0;
540     };
541 
542     struct IGeneratorsForTest {
543         virtual ~IGeneratorsForTest();
544 
545         virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
546         virtual bool moveNext() = 0;
547     };
548 
549     IGeneratorsForTest* createGeneratorsForTest();
550 
551 } // end namespace Catch
552 
553 // #included from: catch_ptr.hpp
554 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
555 
556 #ifdef __clang__
557 #pragma clang diagnostic push
558 #pragma clang diagnostic ignored "-Wpadded"
559 #endif
560 
561 namespace Catch {
562 
563     // An intrusive reference counting smart pointer.
564     // T must implement addRef() and release() methods
565     // typically implementing the IShared interface
566     template<typename T>
567     class Ptr {
568     public:
Ptr()569         Ptr() : m_p( CATCH_NULL ){}
Ptr(T * p)570         Ptr( T* p ) : m_p( p ){
571             if( m_p )
572                 m_p->addRef();
573         }
Ptr(Ptr const & other)574         Ptr( Ptr const& other ) : m_p( other.m_p ){
575             if( m_p )
576                 m_p->addRef();
577         }
~Ptr()578         ~Ptr(){
579             if( m_p )
580                 m_p->release();
581         }
reset()582         void reset() {
583             if( m_p )
584                 m_p->release();
585             m_p = CATCH_NULL;
586         }
operator =(T * p)587         Ptr& operator = ( T* p ){
588             Ptr temp( p );
589             swap( temp );
590             return *this;
591         }
operator =(Ptr const & other)592         Ptr& operator = ( Ptr const& other ){
593             Ptr temp( other );
594             swap( temp );
595             return *this;
596         }
swap(Ptr & other)597         void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
get() const598         T* get() const{ return m_p; }
operator *() const599         T& operator*() const { return *m_p; }
operator ->() const600         T* operator->() const { return m_p; }
operator !() const601         bool operator !() const { return m_p == CATCH_NULL; }
operator SafeBool::type() const602         operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
603 
604     private:
605         T* m_p;
606     };
607 
608     struct IShared : NonCopyable {
609         virtual ~IShared();
610         virtual void addRef() const = 0;
611         virtual void release() const = 0;
612     };
613 
614     template<typename T = IShared>
615     struct SharedImpl : T {
616 
SharedImplCatch::SharedImpl617         SharedImpl() : m_rc( 0 ){}
618 
addRefCatch::SharedImpl619         virtual void addRef() const {
620             ++m_rc;
621         }
releaseCatch::SharedImpl622         virtual void release() const {
623             if( --m_rc == 0 )
624                 delete this;
625         }
626 
627         mutable unsigned int m_rc;
628     };
629 
630 } // end namespace Catch
631 
632 #ifdef __clang__
633 #pragma clang diagnostic pop
634 #endif
635 
636 namespace Catch {
637 
638     class TestCase;
639     class Stream;
640     struct IResultCapture;
641     struct IRunner;
642     struct IGeneratorsForTest;
643     struct IConfig;
644 
645     struct IContext
646     {
647         virtual ~IContext();
648 
649         virtual IResultCapture* getResultCapture() = 0;
650         virtual IRunner* getRunner() = 0;
651         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
652         virtual bool advanceGeneratorsForCurrentTest() = 0;
653         virtual Ptr<IConfig const> getConfig() const = 0;
654     };
655 
656     struct IMutableContext : IContext
657     {
658         virtual ~IMutableContext();
659         virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
660         virtual void setRunner( IRunner* runner ) = 0;
661         virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
662     };
663 
664     IContext& getCurrentContext();
665     IMutableContext& getCurrentMutableContext();
666     void cleanUpContext();
667     Stream createStream( std::string const& streamName );
668 
669 }
670 
671 // #included from: internal/catch_test_registry.hpp
672 #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
673 
674 // #included from: catch_interfaces_testcase.h
675 #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
676 
677 #include <vector>
678 
679 namespace Catch {
680 
681     class TestSpec;
682 
683     struct ITestCase : IShared {
684         virtual void invoke () const = 0;
685     protected:
686         virtual ~ITestCase();
687     };
688 
689     class TestCase;
690     struct IConfig;
691 
692     struct ITestCaseRegistry {
693         virtual ~ITestCaseRegistry();
694         virtual std::vector<TestCase> const& getAllTests() const = 0;
695         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
696     };
697 
698     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
699     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
700     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
701 
702 }
703 
704 namespace Catch {
705 
706 template<typename C>
707 class MethodTestCase : public SharedImpl<ITestCase> {
708 
709 public:
MethodTestCase(void (C::* method)())710     MethodTestCase( void (C::*method)() ) : m_method( method ) {}
711 
invoke() const712     virtual void invoke() const {
713         C obj;
714         (obj.*m_method)();
715     }
716 
717 private:
~MethodTestCase()718     virtual ~MethodTestCase() {}
719 
720     void (C::*m_method)();
721 };
722 
723 typedef void(*TestFunction)();
724 
725 struct NameAndDesc {
NameAndDescCatch::NameAndDesc726     NameAndDesc( const char* _name = "", const char* _description= "" )
727     : name( _name ), description( _description )
728     {}
729 
730     const char* name;
731     const char* description;
732 };
733 
734 void registerTestCase
735     (   ITestCase* testCase,
736         char const* className,
737         NameAndDesc const& nameAndDesc,
738         SourceLineInfo const& lineInfo );
739 
740 struct AutoReg {
741 
742     AutoReg
743         (   TestFunction function,
744             SourceLineInfo const& lineInfo,
745             NameAndDesc const& nameAndDesc );
746 
747     template<typename C>
AutoRegCatch::AutoReg748     AutoReg
749         (   void (C::*method)(),
750             char const* className,
751             NameAndDesc const& nameAndDesc,
752             SourceLineInfo const& lineInfo ) {
753 
754         registerTestCase
755             (   new MethodTestCase<C>( method ),
756                 className,
757                 nameAndDesc,
758                 lineInfo );
759     }
760 
761     ~AutoReg();
762 
763 private:
764     AutoReg( AutoReg const& );
765     void operator= ( AutoReg const& );
766 };
767 
768 void registerTestCaseFunction
769     (   TestFunction function,
770         SourceLineInfo const& lineInfo,
771         NameAndDesc const& nameAndDesc );
772 
773 } // end namespace Catch
774 
775 #ifdef CATCH_CONFIG_VARIADIC_MACROS
776     ///////////////////////////////////////////////////////////////////////////////
777     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
778         static void TestName(); \
779         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
780         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); } /* NOLINT */ \
781         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
782         static void TestName()
783     #define INTERNAL_CATCH_TESTCASE( ... ) \
784         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
785 
786     ///////////////////////////////////////////////////////////////////////////////
787     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
788         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
789         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \
790         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
791 
792     ///////////////////////////////////////////////////////////////////////////////
793     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
794         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
795         namespace{ \
796             struct TestName : ClassName{ \
797                 void test(); \
798             }; \
799             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \
800         } \
801         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
802         void TestName::test()
803     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
804         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
805 
806     ///////////////////////////////////////////////////////////////////////////////
807     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
808         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
809         Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); /* NOLINT */ \
810         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
811 
812 #else
813     ///////////////////////////////////////////////////////////////////////////////
814     #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
815         static void TestName(); \
816         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
817         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); } /* NOLINT */ \
818         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
819         static void TestName()
820     #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
821         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
822 
823     ///////////////////////////////////////////////////////////////////////////////
824     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
825         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
826         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \
827         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
828 
829     ///////////////////////////////////////////////////////////////////////////////
830     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
831         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
832         namespace{ \
833             struct TestCaseName : ClassName{ \
834                 void test(); \
835             }; \
836             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \
837         } \
838         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
839         void TestCaseName::test()
840     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
841         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
842 
843     ///////////////////////////////////////////////////////////////////////////////
844     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
845         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
846         Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); /* NOLINT */ \
847         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
848 
849 #endif
850 
851 // #included from: internal/catch_capture.hpp
852 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
853 
854 // #included from: catch_result_builder.h
855 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
856 
857 // #included from: catch_result_type.h
858 #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
859 
860 namespace Catch {
861 
862     // ResultWas::OfType enum
863     struct ResultWas { enum OfType {
864         Unknown = -1,
865         Ok = 0,
866         Info = 1,
867         Warning = 2,
868 
869         FailureBit = 0x10,
870 
871         ExpressionFailed = FailureBit | 1,
872         ExplicitFailure = FailureBit | 2,
873 
874         Exception = 0x100 | FailureBit,
875 
876         ThrewException = Exception | 1,
877         DidntThrowException = Exception | 2,
878 
879         FatalErrorCondition = 0x200 | FailureBit
880 
881     }; };
882 
isOk(ResultWas::OfType resultType)883     inline bool isOk( ResultWas::OfType resultType ) {
884         return ( resultType & ResultWas::FailureBit ) == 0;
885     }
isJustInfo(int flags)886     inline bool isJustInfo( int flags ) {
887         return flags == ResultWas::Info;
888     }
889 
890     // ResultDisposition::Flags enum
891     struct ResultDisposition { enum Flags {
892         Normal = 0x01,
893 
894         ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
895         FalseTest = 0x04,           // Prefix expression with !
896         SuppressFail = 0x08         // Failures are reported but do not fail the test
897     }; };
898 
operator |(ResultDisposition::Flags lhs,ResultDisposition::Flags rhs)899     inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
900         return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
901     }
902 
shouldContinueOnFailure(int flags)903     inline bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
isFalseTest(int flags)904     inline bool isFalseTest( int flags )                { return ( flags & ResultDisposition::FalseTest ) != 0; }
shouldSuppressFailure(int flags)905     inline bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
906 
907 } // end namespace Catch
908 
909 // #included from: catch_assertionresult.h
910 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
911 
912 #include <string>
913 
914 namespace Catch {
915 
916     struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
917 
918     struct DecomposedExpression
919     {
~DecomposedExpressionCatch::DecomposedExpression920         virtual ~DecomposedExpression() {}
isBinaryExpressionCatch::DecomposedExpression921         virtual bool isBinaryExpression() const {
922             return false;
923         }
924         virtual void reconstructExpression( std::string& dest ) const = 0;
925 
926         // Only simple binary comparisons can be decomposed.
927         // If more complex check is required then wrap sub-expressions in parentheses.
928         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& );
929         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& );
930         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& );
931         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& );
932         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& );
933         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& );
934         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& );
935 
936     private:
937         DecomposedExpression& operator = (DecomposedExpression const&);
938     };
939 
940     struct AssertionInfo
941     {
942         AssertionInfo();
943         AssertionInfo(  char const * _macroName,
944                         SourceLineInfo const& _lineInfo,
945                         char const * _capturedExpression,
946                         ResultDisposition::Flags _resultDisposition,
947                         char const * _secondArg = "");
948 
949         char const * macroName;
950         SourceLineInfo lineInfo;
951         char const * capturedExpression;
952         ResultDisposition::Flags resultDisposition;
953         char const * secondArg;
954     };
955 
956     struct AssertionResultData
957     {
AssertionResultDataCatch::AssertionResultData958         AssertionResultData() : decomposedExpression( CATCH_NULL )
959                               , resultType( ResultWas::Unknown )
960                               , negated( false )
961                               , parenthesized( false ) {}
962 
negateCatch::AssertionResultData963         void negate( bool parenthesize ) {
964             negated = !negated;
965             parenthesized = parenthesize;
966             if( resultType == ResultWas::Ok )
967                 resultType = ResultWas::ExpressionFailed;
968             else if( resultType == ResultWas::ExpressionFailed )
969                 resultType = ResultWas::Ok;
970         }
971 
reconstructExpressionCatch::AssertionResultData972         std::string const& reconstructExpression() const {
973             if( decomposedExpression != CATCH_NULL ) {
974                 decomposedExpression->reconstructExpression( reconstructedExpression );
975                 if( parenthesized ) {
976                     reconstructedExpression.insert( 0, 1, '(' );
977                     reconstructedExpression.append( 1, ')' );
978                 }
979                 if( negated ) {
980                     reconstructedExpression.insert( 0, 1, '!' );
981                 }
982                 decomposedExpression = CATCH_NULL;
983             }
984             return reconstructedExpression;
985         }
986 
987         mutable DecomposedExpression const* decomposedExpression;
988         mutable std::string reconstructedExpression;
989         std::string message;
990         ResultWas::OfType resultType;
991         bool negated;
992         bool parenthesized;
993     };
994 
995     class AssertionResult {
996     public:
997         AssertionResult();
998         AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
999         ~AssertionResult();
1000 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
1001          AssertionResult( AssertionResult const& )              = default;
1002          AssertionResult( AssertionResult && )                  = default;
1003          AssertionResult& operator = ( AssertionResult const& ) = default;
1004          AssertionResult& operator = ( AssertionResult && )     = default;
1005 #  endif
1006 
1007         bool isOk() const;
1008         bool succeeded() const;
1009         ResultWas::OfType getResultType() const;
1010         bool hasExpression() const;
1011         bool hasMessage() const;
1012         std::string getExpression() const;
1013         std::string getExpressionInMacro() const;
1014         bool hasExpandedExpression() const;
1015         std::string getExpandedExpression() const;
1016         std::string getMessage() const;
1017         SourceLineInfo getSourceInfo() const;
1018         std::string getTestMacroName() const;
1019         void discardDecomposedExpression() const;
1020         void expandDecomposedExpression() const;
1021 
1022     protected:
1023         AssertionInfo m_info;
1024         AssertionResultData m_resultData;
1025     };
1026 
1027 } // end namespace Catch
1028 
1029 // #included from: catch_matchers.hpp
1030 #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
1031 
1032 namespace Catch {
1033 namespace Matchers {
1034     namespace Impl {
1035 
1036         template<typename ArgT> struct MatchAllOf;
1037         template<typename ArgT> struct MatchAnyOf;
1038         template<typename ArgT> struct MatchNotOf;
1039 
1040         class MatcherUntypedBase {
1041         public:
toString() const1042             std::string toString() const {
1043                 if( m_cachedToString.empty() )
1044                     m_cachedToString = describe();
1045                 return m_cachedToString;
1046             }
1047 
1048         protected:
1049             virtual ~MatcherUntypedBase();
1050             virtual std::string describe() const = 0;
1051             mutable std::string m_cachedToString;
1052         private:
1053             MatcherUntypedBase& operator = ( MatcherUntypedBase const& );
1054         };
1055 
1056         template<typename ObjectT>
1057         struct MatcherMethod {
1058             virtual bool match( ObjectT const& arg ) const = 0;
1059         };
1060         template<typename PtrT>
1061         struct MatcherMethod<PtrT*> {
1062             virtual bool match( PtrT* arg ) const = 0;
1063         };
1064 
1065         template<typename ObjectT, typename ComparatorT = ObjectT>
1066         struct MatcherBase : MatcherUntypedBase, MatcherMethod<ObjectT> {
1067 
1068             MatchAllOf<ComparatorT> operator && ( MatcherBase const& other ) const;
1069             MatchAnyOf<ComparatorT> operator || ( MatcherBase const& other ) const;
1070             MatchNotOf<ComparatorT> operator ! () const;
1071         };
1072 
1073         template<typename ArgT>
1074         struct MatchAllOf : MatcherBase<ArgT> {
matchCatch::Matchers::Impl::MatchAllOf1075             virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
1076                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
1077                     if (!m_matchers[i]->match(arg))
1078                         return false;
1079                 }
1080                 return true;
1081             }
describeCatch::Matchers::Impl::MatchAllOf1082             virtual std::string describe() const CATCH_OVERRIDE {
1083                 std::string description;
1084                 description.reserve( 4 + m_matchers.size()*32 );
1085                 description += "( ";
1086                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
1087                     if( i != 0 )
1088                         description += " and ";
1089                     description += m_matchers[i]->toString();
1090                 }
1091                 description += " )";
1092                 return description;
1093             }
1094 
operator &&Catch::Matchers::Impl::MatchAllOf1095             MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
1096                 m_matchers.push_back( &other );
1097                 return *this;
1098             }
1099 
1100             std::vector<MatcherBase<ArgT> const*> m_matchers;
1101         };
1102         template<typename ArgT>
1103         struct MatchAnyOf : MatcherBase<ArgT> {
1104 
matchCatch::Matchers::Impl::MatchAnyOf1105             virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
1106                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
1107                     if (m_matchers[i]->match(arg))
1108                         return true;
1109                 }
1110                 return false;
1111             }
describeCatch::Matchers::Impl::MatchAnyOf1112             virtual std::string describe() const CATCH_OVERRIDE {
1113                 std::string description;
1114                 description.reserve( 4 + m_matchers.size()*32 );
1115                 description += "( ";
1116                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
1117                     if( i != 0 )
1118                         description += " or ";
1119                     description += m_matchers[i]->toString();
1120                 }
1121                 description += " )";
1122                 return description;
1123             }
1124 
operator ||Catch::Matchers::Impl::MatchAnyOf1125             MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
1126                 m_matchers.push_back( &other );
1127                 return *this;
1128             }
1129 
1130             std::vector<MatcherBase<ArgT> const*> m_matchers;
1131         };
1132 
1133         template<typename ArgT>
1134         struct MatchNotOf : MatcherBase<ArgT> {
1135 
MatchNotOfCatch::Matchers::Impl::MatchNotOf1136             MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
1137 
matchCatch::Matchers::Impl::MatchNotOf1138             virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
1139                 return !m_underlyingMatcher.match( arg );
1140             }
1141 
describeCatch::Matchers::Impl::MatchNotOf1142             virtual std::string describe() const CATCH_OVERRIDE {
1143                 return "not " + m_underlyingMatcher.toString();
1144             }
1145             MatcherBase<ArgT> const& m_underlyingMatcher;
1146         };
1147 
1148         template<typename ObjectT, typename ComparatorT>
operator &&(MatcherBase const & other) const1149         MatchAllOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator && ( MatcherBase const& other ) const {
1150             return MatchAllOf<ComparatorT>() && *this && other;
1151         }
1152         template<typename ObjectT, typename ComparatorT>
operator ||(MatcherBase const & other) const1153         MatchAnyOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator || ( MatcherBase const& other ) const {
1154             return MatchAnyOf<ComparatorT>() || *this || other;
1155         }
1156         template<typename ObjectT, typename ComparatorT>
operator !() const1157         MatchNotOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator ! () const {
1158             return MatchNotOf<ComparatorT>( *this );
1159         }
1160 
1161     } // namespace Impl
1162 
1163     // The following functions create the actual matcher objects.
1164     // This allows the types to be inferred
1165     // - deprecated: prefer ||, && and !
1166     template<typename T>
Not(Impl::MatcherBase<T> const & underlyingMatcher)1167     Impl::MatchNotOf<T> Not( Impl::MatcherBase<T> const& underlyingMatcher ) {
1168         return Impl::MatchNotOf<T>( underlyingMatcher );
1169     }
1170     template<typename T>
AllOf(Impl::MatcherBase<T> const & m1,Impl::MatcherBase<T> const & m2)1171     Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
1172         return Impl::MatchAllOf<T>() && m1 && m2;
1173     }
1174     template<typename T>
AllOf(Impl::MatcherBase<T> const & m1,Impl::MatcherBase<T> const & m2,Impl::MatcherBase<T> const & m3)1175     Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
1176         return Impl::MatchAllOf<T>() && m1 && m2 && m3;
1177     }
1178     template<typename T>
AnyOf(Impl::MatcherBase<T> const & m1,Impl::MatcherBase<T> const & m2)1179     Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
1180         return Impl::MatchAnyOf<T>() || m1 || m2;
1181     }
1182     template<typename T>
AnyOf(Impl::MatcherBase<T> const & m1,Impl::MatcherBase<T> const & m2,Impl::MatcherBase<T> const & m3)1183     Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
1184         return Impl::MatchAnyOf<T>() || m1 || m2 || m3;
1185     }
1186 
1187 } // namespace Matchers
1188 
1189 using namespace Matchers;
1190 using Matchers::Impl::MatcherBase;
1191 
1192 } // namespace Catch
1193 
1194 namespace Catch {
1195 
1196     struct TestFailureException{};
1197 
1198     template<typename T> class ExpressionLhs;
1199 
1200     struct CopyableStream {
CopyableStreamCatch::CopyableStream1201         CopyableStream() {}
CopyableStreamCatch::CopyableStream1202         CopyableStream( CopyableStream const& other ) {
1203             oss << other.oss.str();
1204         }
operator =Catch::CopyableStream1205         CopyableStream& operator=( CopyableStream const& other ) {
1206             oss.str(std::string());
1207             oss << other.oss.str();
1208             return *this;
1209         }
1210         std::ostringstream oss;
1211     };
1212 
1213     class ResultBuilder : public DecomposedExpression {
1214     public:
1215         ResultBuilder(  char const* macroName,
1216                         SourceLineInfo const& lineInfo,
1217                         char const* capturedExpression,
1218                         ResultDisposition::Flags resultDisposition,
1219                         char const* secondArg = "" );
1220         ~ResultBuilder();
1221 
1222         template<typename T>
1223         ExpressionLhs<T const&> operator <= ( T const& operand );
1224         ExpressionLhs<bool> operator <= ( bool value );
1225 
1226         template<typename T>
operator <<(T const & value)1227         ResultBuilder& operator << ( T const& value ) {
1228             stream().oss << value;
1229             return *this;
1230         }
1231 
1232         ResultBuilder& setResultType( ResultWas::OfType result );
1233         ResultBuilder& setResultType( bool result );
1234 
1235         void endExpression( DecomposedExpression const& expr );
1236 
1237         virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE;
1238 
1239         AssertionResult build() const;
1240         AssertionResult build( DecomposedExpression const& expr ) const;
1241 
1242         void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
1243         void captureResult( ResultWas::OfType resultType );
1244         void captureExpression();
1245         void captureExpectedException( std::string const& expectedMessage );
1246         void captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher );
1247         void handleResult( AssertionResult const& result );
1248         void react();
1249         bool shouldDebugBreak() const;
1250         bool allowThrows() const;
1251 
1252         template<typename ArgT, typename MatcherT>
1253         void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString );
1254 
1255         void setExceptionGuard();
1256         void unsetExceptionGuard();
1257 
1258     private:
1259         AssertionInfo m_assertionInfo;
1260         AssertionResultData m_data;
1261 
stream()1262         CopyableStream &stream()
1263         {
1264             if(!m_usedStream)
1265             {
1266                 m_usedStream = true;
1267                 m_stream().oss.str("");
1268             }
1269             return m_stream();
1270         }
1271 
m_stream()1272         static CopyableStream &m_stream()
1273         {
1274             static CopyableStream s;
1275             return s;
1276         }
1277 
1278         bool m_shouldDebugBreak;
1279         bool m_shouldThrow;
1280         bool m_guardException;
1281         bool m_usedStream;
1282     };
1283 
1284 } // namespace Catch
1285 
1286 // Include after due to circular dependency:
1287 // #included from: catch_expression_lhs.hpp
1288 #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
1289 
1290 // #included from: catch_evaluate.hpp
1291 #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
1292 
1293 #ifdef _MSC_VER
1294 #pragma warning(push)
1295 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
1296 #pragma warning(disable:4018) // more "signed/unsigned mismatch"
1297 #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
1298 #endif
1299 
1300 #include <cstddef>
1301 
1302 namespace Catch {
1303 namespace Internal {
1304 
1305     enum Operator {
1306         IsEqualTo,
1307         IsNotEqualTo,
1308         IsLessThan,
1309         IsGreaterThan,
1310         IsLessThanOrEqualTo,
1311         IsGreaterThanOrEqualTo
1312     };
1313 
getNameCatch::Internal::OperatorTraits1314     template<Operator Op> struct OperatorTraits             { static const char* getName(){ return "*error*"; } };
getNameCatch::Internal::OperatorTraits1315     template<> struct OperatorTraits<IsEqualTo>             { static const char* getName(){ return "=="; } };
getNameCatch::Internal::OperatorTraits1316     template<> struct OperatorTraits<IsNotEqualTo>          { static const char* getName(){ return "!="; } };
getNameCatch::Internal::OperatorTraits1317     template<> struct OperatorTraits<IsLessThan>            { static const char* getName(){ return "<"; } };
getNameCatch::Internal::OperatorTraits1318     template<> struct OperatorTraits<IsGreaterThan>         { static const char* getName(){ return ">"; } };
getNameCatch::Internal::OperatorTraits1319     template<> struct OperatorTraits<IsLessThanOrEqualTo>   { static const char* getName(){ return "<="; } };
getNameCatch::Internal::OperatorTraits1320     template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
1321 
1322     template<typename T>
opCast(T const & t)1323     T& opCast(T const& t) { return const_cast<T&>(t); }
1324 
1325 // nullptr_t support based on pull request #154 from Konstantin Baumann
1326 #ifdef CATCH_CONFIG_CPP11_NULLPTR
opCast(std::nullptr_t)1327     inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
1328 #endif // CATCH_CONFIG_CPP11_NULLPTR
1329 
1330     // So the compare overloads can be operator agnostic we convey the operator as a template
1331     // enum, which is used to specialise an Evaluator for doing the comparison.
1332     template<typename T1, typename T2, Operator Op>
1333     struct Evaluator{};
1334 
1335     template<typename T1, typename T2>
1336     struct Evaluator<T1, T2, IsEqualTo> {
evaluateCatch::Internal::Evaluator1337         static bool evaluate( T1 const& lhs, T2 const& rhs) {
1338             return bool( opCast( lhs ) ==  opCast( rhs ) );
1339         }
1340     };
1341     template<typename T1, typename T2>
1342     struct Evaluator<T1, T2, IsNotEqualTo> {
evaluateCatch::Internal::Evaluator1343         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1344             return bool( opCast( lhs ) != opCast( rhs ) );
1345         }
1346     };
1347     template<typename T1, typename T2>
1348     struct Evaluator<T1, T2, IsLessThan> {
evaluateCatch::Internal::Evaluator1349         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1350             return bool( opCast( lhs ) < opCast( rhs ) );
1351         }
1352     };
1353     template<typename T1, typename T2>
1354     struct Evaluator<T1, T2, IsGreaterThan> {
evaluateCatch::Internal::Evaluator1355         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1356             return bool( opCast( lhs ) > opCast( rhs ) );
1357         }
1358     };
1359     template<typename T1, typename T2>
1360     struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
evaluateCatch::Internal::Evaluator1361         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1362             return bool( opCast( lhs ) >= opCast( rhs ) );
1363         }
1364     };
1365     template<typename T1, typename T2>
1366     struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
evaluateCatch::Internal::Evaluator1367         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1368             return bool( opCast( lhs ) <= opCast( rhs ) );
1369         }
1370     };
1371 
1372     template<Operator Op, typename T1, typename T2>
applyEvaluator(T1 const & lhs,T2 const & rhs)1373     bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
1374         return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1375     }
1376 
1377     // This level of indirection allows us to specialise for integer types
1378     // to avoid signed/ unsigned warnings
1379 
1380     // "base" overload
1381     template<Operator Op, typename T1, typename T2>
compare(T1 const & lhs,T2 const & rhs)1382     bool compare( T1 const& lhs, T2 const& rhs ) {
1383         return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1384     }
1385 
1386     // unsigned X to int
compare(unsigned int lhs,int rhs)1387     template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
1388         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1389     }
compare(unsigned long lhs,int rhs)1390     template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
1391         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1392     }
compare(unsigned char lhs,int rhs)1393     template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
1394         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1395     }
1396 
1397     // unsigned X to long
compare(unsigned int lhs,long rhs)1398     template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
1399         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1400     }
compare(unsigned long lhs,long rhs)1401     template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
1402         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1403     }
compare(unsigned char lhs,long rhs)1404     template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
1405         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1406     }
1407 
1408     // int to unsigned X
compare(int lhs,unsigned int rhs)1409     template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
1410         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1411     }
compare(int lhs,unsigned long rhs)1412     template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
1413         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1414     }
compare(int lhs,unsigned char rhs)1415     template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
1416         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1417     }
1418 
1419     // long to unsigned X
compare(long lhs,unsigned int rhs)1420     template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
1421         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1422     }
compare(long lhs,unsigned long rhs)1423     template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
1424         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1425     }
compare(long lhs,unsigned char rhs)1426     template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
1427         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1428     }
1429 
1430     // pointer to long (when comparing against NULL)
compare(long lhs,T * rhs)1431     template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
1432         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1433     }
compare(T * lhs,long rhs)1434     template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
1435         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1436     }
1437 
1438     // pointer to int (when comparing against NULL)
compare(int lhs,T * rhs)1439     template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
1440         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1441     }
compare(T * lhs,int rhs)1442     template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
1443         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1444     }
1445 
1446 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
1447     // long long to unsigned X
compare(long long lhs,unsigned int rhs)1448     template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
1449         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1450     }
compare(long long lhs,unsigned long rhs)1451     template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
1452         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1453     }
compare(long long lhs,unsigned long long rhs)1454     template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
1455         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1456     }
compare(long long lhs,unsigned char rhs)1457     template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
1458         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1459     }
1460 
1461     // unsigned long long to X
compare(unsigned long long lhs,int rhs)1462     template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
1463         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1464     }
compare(unsigned long long lhs,long rhs)1465     template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
1466         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1467     }
compare(unsigned long long lhs,long long rhs)1468     template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
1469         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1470     }
compare(unsigned long long lhs,char rhs)1471     template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
1472         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1473     }
1474 
1475     // pointer to long long (when comparing against NULL)
compare(long long lhs,T * rhs)1476     template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
1477         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1478     }
compare(T * lhs,long long rhs)1479     template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
1480         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1481     }
1482 #endif // CATCH_CONFIG_CPP11_LONG_LONG
1483 
1484 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1485     // pointer to nullptr_t (when comparing against nullptr)
compare(std::nullptr_t,T * rhs)1486     template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
1487         return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
1488     }
compare(T * lhs,std::nullptr_t)1489     template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
1490         return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
1491     }
1492 #endif // CATCH_CONFIG_CPP11_NULLPTR
1493 
1494 } // end of namespace Internal
1495 } // end of namespace Catch
1496 
1497 #ifdef _MSC_VER
1498 #pragma warning(pop)
1499 #endif
1500 
1501 // #included from: catch_tostring.h
1502 #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
1503 
1504 #include <sstream>
1505 #include <iomanip>
1506 #include <limits>
1507 #include <vector>
1508 #include <cstddef>
1509 
1510 #ifdef __OBJC__
1511 // #included from: catch_objc_arc.hpp
1512 #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
1513 
1514 #import <Foundation/Foundation.h>
1515 
1516 #ifdef __has_feature
1517 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1518 #else
1519 #define CATCH_ARC_ENABLED 0
1520 #endif
1521 
1522 void arcSafeRelease( NSObject* obj );
1523 id performOptionalSelector( id obj, SEL sel );
1524 
1525 #if !CATCH_ARC_ENABLED
arcSafeRelease(NSObject * obj)1526 inline void arcSafeRelease( NSObject* obj ) {
1527     [obj release];
1528 }
performOptionalSelector(id obj,SEL sel)1529 inline id performOptionalSelector( id obj, SEL sel ) {
1530     if( [obj respondsToSelector: sel] )
1531         return [obj performSelector: sel];
1532     return nil;
1533 }
1534 #define CATCH_UNSAFE_UNRETAINED
1535 #define CATCH_ARC_STRONG
1536 #else
arcSafeRelease(NSObject *)1537 inline void arcSafeRelease( NSObject* ){}
performOptionalSelector(id obj,SEL sel)1538 inline id performOptionalSelector( id obj, SEL sel ) {
1539 #ifdef __clang__
1540 #pragma clang diagnostic push
1541 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1542 #endif
1543     if( [obj respondsToSelector: sel] )
1544         return [obj performSelector: sel];
1545 #ifdef __clang__
1546 #pragma clang diagnostic pop
1547 #endif
1548     return nil;
1549 }
1550 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1551 #define CATCH_ARC_STRONG __strong
1552 #endif
1553 
1554 #endif
1555 
1556 #ifdef CATCH_CONFIG_CPP11_TUPLE
1557 #include <tuple>
1558 #endif
1559 
1560 #ifdef CATCH_CONFIG_CPP11_IS_ENUM
1561 #include <type_traits>
1562 #endif
1563 
1564 namespace Catch {
1565 
1566 // Why we're here.
1567 template<typename T>
1568 std::string toString( T const& value );
1569 
1570 // Built in overloads
1571 
1572 std::string toString( std::string const& value );
1573 std::string toString( std::wstring const& value );
1574 std::string toString( const char* const value );
1575 std::string toString( char* const value );
1576 std::string toString( const wchar_t* const value );
1577 std::string toString( wchar_t* const value );
1578 std::string toString( int value );
1579 std::string toString( unsigned long value );
1580 std::string toString( unsigned int value );
1581 std::string toString( const double value );
1582 std::string toString( const float value );
1583 std::string toString( bool value );
1584 std::string toString( char value );
1585 std::string toString( signed char value );
1586 std::string toString( unsigned char value );
1587 
1588 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
1589 std::string toString( long long value );
1590 std::string toString( unsigned long long value );
1591 #endif
1592 
1593 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1594 std::string toString( std::nullptr_t );
1595 #endif
1596 
1597 #ifdef __OBJC__
1598     std::string toString( NSString const * const& nsstring );
1599     std::string toString( NSString * CATCH_ARC_STRONG & nsstring );
1600     std::string toString( NSObject* const& nsObject );
1601 #endif
1602 
1603 namespace Detail {
1604 
1605     extern const std::string unprintableString;
1606 
1607  #if !defined(CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK)
1608     struct BorgType {
1609         template<typename T> BorgType( T const& );
1610     };
1611 
1612     struct TrueType { char sizer[1]; };
1613     struct FalseType { char sizer[2]; };
1614 
1615     TrueType& testStreamable( std::ostream& );
1616     FalseType testStreamable( FalseType );
1617 
1618     FalseType operator<<( std::ostream const&, BorgType const& );
1619 
1620     template<typename T>
1621     struct IsStreamInsertable {
1622         static std::ostream &s;
1623         static T  const&t;
1624         enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
1625     };
1626 #else
1627     template<typename T>
1628     class IsStreamInsertable {
1629         template<typename SS, typename TT>
1630         static auto test(int)
1631         -> decltype( std::declval<SS&>() << std::declval<TT>(), std::true_type() );
1632 
1633         template<typename, typename>
1634         static auto test(...) -> std::false_type;
1635 
1636     public:
1637         static const bool value = decltype(test<std::ostream,const T&>(0))::value;
1638     };
1639 #endif
1640 
1641 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1642     template<typename T,
1643              bool IsEnum = std::is_enum<T>::value
1644              >
1645     struct EnumStringMaker
1646     {
convertCatch::Detail::EnumStringMaker1647         static std::string convert( T const& ) { return unprintableString; }
1648     };
1649 
1650     template<typename T>
1651     struct EnumStringMaker<T,true>
1652     {
convertCatch::Detail::EnumStringMaker1653         static std::string convert( T const& v )
1654         {
1655             return ::Catch::toString(
1656                 static_cast<typename std::underlying_type<T>::type>(v)
1657                 );
1658         }
1659     };
1660 #endif
1661     template<bool C>
1662     struct StringMakerBase {
1663 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1664         template<typename T>
convertCatch::Detail::StringMakerBase1665         static std::string convert( T const& v )
1666         {
1667             return EnumStringMaker<T>::convert( v );
1668         }
1669 #else
1670         template<typename T>
1671         static std::string convert( T const& ) { return unprintableString; }
1672 #endif
1673     };
1674 
1675     template<>
1676     struct StringMakerBase<true> {
1677         template<typename T>
convertCatch::Detail::StringMakerBase1678         static std::string convert( T const& _value ) {
1679             std::ostringstream oss;
1680             oss << _value;
1681             return oss.str();
1682         }
1683     };
1684 
1685     std::string rawMemoryToString( const void *object, std::size_t size );
1686 
1687     template<typename T>
rawMemoryToString(const T & object)1688     std::string rawMemoryToString( const T& object ) {
1689       return rawMemoryToString( &object, sizeof(object) );
1690     }
1691 
1692 } // end namespace Detail
1693 
1694 template<typename T>
1695 struct StringMaker :
1696     Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
1697 
1698 template<typename T>
1699 struct StringMaker<T*> {
1700     template<typename U>
convertCatch::StringMaker1701     static std::string convert( U* p ) {
1702         if( !p )
1703             return "NULL";
1704         else
1705             return Detail::rawMemoryToString( p );
1706     }
1707 };
1708 
1709 template<typename R, typename C>
1710 struct StringMaker<R C::*> {
convertCatch::StringMaker1711     static std::string convert( R C::* p ) {
1712         if( !p )
1713             return "NULL";
1714         else
1715             return Detail::rawMemoryToString( p );
1716     }
1717 };
1718 
1719 namespace Detail {
1720     template<typename InputIterator>
1721     std::string rangeToString( InputIterator first, InputIterator last );
1722 }
1723 
1724 //template<typename T, typename Allocator>
1725 //struct StringMaker<std::vector<T, Allocator> > {
1726 //    static std::string convert( std::vector<T,Allocator> const& v ) {
1727 //        return Detail::rangeToString( v.begin(), v.end() );
1728 //    }
1729 //};
1730 
1731 template<typename T, typename Allocator>
toString(std::vector<T,Allocator> const & v)1732 std::string toString( std::vector<T,Allocator> const& v ) {
1733     return Detail::rangeToString( v.begin(), v.end() );
1734 }
1735 
1736 #ifdef CATCH_CONFIG_CPP11_TUPLE
1737 
1738 // toString for tuples
1739 namespace TupleDetail {
1740   template<
1741       typename Tuple,
1742       std::size_t N = 0,
1743       bool = (N < std::tuple_size<Tuple>::value)
1744       >
1745   struct ElementPrinter {
printCatch::TupleDetail::ElementPrinter1746       static void print( const Tuple& tuple, std::ostream& os )
1747       {
1748           os << ( N ? ", " : " " )
1749              << Catch::toString(std::get<N>(tuple));
1750           ElementPrinter<Tuple,N+1>::print(tuple,os);
1751       }
1752   };
1753 
1754   template<
1755       typename Tuple,
1756       std::size_t N
1757       >
1758   struct ElementPrinter<Tuple,N,false> {
printCatch::TupleDetail::ElementPrinter1759       static void print( const Tuple&, std::ostream& ) {}
1760   };
1761 
1762 }
1763 
1764 template<typename ...Types>
1765 struct StringMaker<std::tuple<Types...>> {
1766 
convertCatch::StringMaker1767     static std::string convert( const std::tuple<Types...>& tuple )
1768     {
1769         std::ostringstream os;
1770         os << '{';
1771         TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
1772         os << " }";
1773         return os.str();
1774     }
1775 };
1776 #endif // CATCH_CONFIG_CPP11_TUPLE
1777 
1778 namespace Detail {
1779     template<typename T>
makeString(T const & value)1780     std::string makeString( T const& value ) {
1781         return StringMaker<T>::convert( value );
1782     }
1783 } // end namespace Detail
1784 
1785 /// \brief converts any type to a string
1786 ///
1787 /// The default template forwards on to ostringstream - except when an
1788 /// ostringstream overload does not exist - in which case it attempts to detect
1789 /// that and writes {?}.
1790 /// Overload (not specialise) this template for custom typs that you don't want
1791 /// to provide an ostream overload for.
1792 template<typename T>
toString(T const & value)1793 std::string toString( T const& value ) {
1794     return StringMaker<T>::convert( value );
1795 }
1796 
1797     namespace Detail {
1798     template<typename InputIterator>
rangeToString(InputIterator first,InputIterator last)1799     std::string rangeToString( InputIterator first, InputIterator last ) {
1800         std::ostringstream oss;
1801         oss << "{ ";
1802         if( first != last ) {
1803             oss << Catch::toString( *first );
1804             for( ++first ; first != last ; ++first )
1805                 oss << ", " << Catch::toString( *first );
1806         }
1807         oss << " }";
1808         return oss.str();
1809     }
1810 }
1811 
1812 } // end namespace Catch
1813 
1814 namespace Catch {
1815 
1816 template<typename LhsT, Internal::Operator Op, typename RhsT>
1817 class BinaryExpression;
1818 
1819 template<typename ArgT, typename MatcherT>
1820 class MatchExpression;
1821 
1822 // Wraps the LHS of an expression and overloads comparison operators
1823 // for also capturing those and RHS (if any)
1824 template<typename T>
1825 class ExpressionLhs : public DecomposedExpression {
1826 public:
ExpressionLhs(ResultBuilder & rb,T lhs)1827     ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {}
1828 
1829     ExpressionLhs& operator = ( const ExpressionLhs& );
1830 
1831     template<typename RhsT>
1832     BinaryExpression<T, Internal::IsEqualTo, RhsT const&>
operator ==(RhsT const & rhs)1833     operator == ( RhsT const& rhs ) {
1834         return captureExpression<Internal::IsEqualTo>( rhs );
1835     }
1836 
1837     template<typename RhsT>
1838     BinaryExpression<T, Internal::IsNotEqualTo, RhsT const&>
operator !=(RhsT const & rhs)1839     operator != ( RhsT const& rhs ) {
1840         return captureExpression<Internal::IsNotEqualTo>( rhs );
1841     }
1842 
1843     template<typename RhsT>
1844     BinaryExpression<T, Internal::IsLessThan, RhsT const&>
operator <(RhsT const & rhs)1845     operator < ( RhsT const& rhs ) {
1846         return captureExpression<Internal::IsLessThan>( rhs );
1847     }
1848 
1849     template<typename RhsT>
1850     BinaryExpression<T, Internal::IsGreaterThan, RhsT const&>
operator >(RhsT const & rhs)1851     operator > ( RhsT const& rhs ) {
1852         return captureExpression<Internal::IsGreaterThan>( rhs );
1853     }
1854 
1855     template<typename RhsT>
1856     BinaryExpression<T, Internal::IsLessThanOrEqualTo, RhsT const&>
operator <=(RhsT const & rhs)1857     operator <= ( RhsT const& rhs ) {
1858         return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
1859     }
1860 
1861     template<typename RhsT>
1862     BinaryExpression<T, Internal::IsGreaterThanOrEqualTo, RhsT const&>
operator >=(RhsT const & rhs)1863     operator >= ( RhsT const& rhs ) {
1864         return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
1865     }
1866 
operator ==(bool rhs)1867     BinaryExpression<T, Internal::IsEqualTo, bool> operator == ( bool rhs ) {
1868         return captureExpression<Internal::IsEqualTo>( rhs );
1869     }
1870 
operator !=(bool rhs)1871     BinaryExpression<T, Internal::IsNotEqualTo, bool> operator != ( bool rhs ) {
1872         return captureExpression<Internal::IsNotEqualTo>( rhs );
1873     }
1874 
endExpression()1875     void endExpression() {
1876         m_truthy = m_lhs ? true : false;
1877         m_rb
1878             .setResultType( m_truthy )
1879             .endExpression( *this );
1880     }
1881 
reconstructExpression(std::string & dest) const1882     virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
1883         dest = Catch::toString( m_lhs );
1884     }
1885 
1886 private:
1887     template<Internal::Operator Op, typename RhsT>
captureExpression(RhsT & rhs) const1888     BinaryExpression<T, Op, RhsT&> captureExpression( RhsT& rhs ) const {
1889         return BinaryExpression<T, Op, RhsT&>( m_rb, m_lhs, rhs );
1890     }
1891 
1892     template<Internal::Operator Op>
captureExpression(bool rhs) const1893     BinaryExpression<T, Op, bool> captureExpression( bool rhs ) const {
1894         return BinaryExpression<T, Op, bool>( m_rb, m_lhs, rhs );
1895     }
1896 
1897 private:
1898     ResultBuilder& m_rb;
1899     T m_lhs;
1900     bool m_truthy;
1901 };
1902 
1903 template<typename LhsT, Internal::Operator Op, typename RhsT>
1904 class BinaryExpression : public DecomposedExpression {
1905 public:
BinaryExpression(ResultBuilder & rb,LhsT lhs,RhsT rhs)1906     BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs )
1907         : m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {}
1908 
1909     BinaryExpression& operator = ( BinaryExpression& );
1910 
endExpression() const1911     void endExpression() const {
1912         m_rb
1913             .setResultType( Internal::compare<Op>( m_lhs, m_rhs ) )
1914             .endExpression( *this );
1915     }
1916 
isBinaryExpression() const1917     virtual bool isBinaryExpression() const CATCH_OVERRIDE {
1918         return true;
1919     }
1920 
reconstructExpression(std::string & dest) const1921     virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
1922         std::string lhs = Catch::toString( m_lhs );
1923         std::string rhs = Catch::toString( m_rhs );
1924         char delim = lhs.size() + rhs.size() < 40 &&
1925                      lhs.find('\n') == std::string::npos &&
1926                      rhs.find('\n') == std::string::npos ? ' ' : '\n';
1927         dest.reserve( 7 + lhs.size() + rhs.size() );
1928                    // 2 for spaces around operator
1929                    // 2 for operator
1930                    // 2 for parentheses (conditionally added later)
1931                    // 1 for negation (conditionally added later)
1932         dest = lhs;
1933         dest += delim;
1934         dest += Internal::OperatorTraits<Op>::getName();
1935         dest += delim;
1936         dest += rhs;
1937     }
1938 
1939 private:
1940     ResultBuilder& m_rb;
1941     LhsT m_lhs;
1942     RhsT m_rhs;
1943 };
1944 
1945 template<typename ArgT, typename MatcherT>
1946 class MatchExpression : public DecomposedExpression {
1947 public:
MatchExpression(ArgT arg,MatcherT matcher,char const * matcherString)1948     MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString )
1949         : m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {}
1950 
isBinaryExpression() const1951     virtual bool isBinaryExpression() const CATCH_OVERRIDE {
1952         return true;
1953     }
1954 
reconstructExpression(std::string & dest) const1955     virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
1956         std::string matcherAsString = m_matcher.toString();
1957         dest = Catch::toString( m_arg );
1958         dest += ' ';
1959         if( matcherAsString == Detail::unprintableString )
1960             dest += m_matcherString;
1961         else
1962             dest += matcherAsString;
1963     }
1964 
1965 private:
1966     ArgT m_arg;
1967     MatcherT m_matcher;
1968     char const* m_matcherString;
1969 };
1970 
1971 } // end namespace Catch
1972 
1973 
1974 namespace Catch {
1975 
1976     template<typename T>
operator <=(T const & operand)1977     ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
1978         return ExpressionLhs<T const&>( *this, operand );
1979     }
1980 
operator <=(bool value)1981     inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
1982         return ExpressionLhs<bool>( *this, value );
1983     }
1984 
1985     template<typename ArgT, typename MatcherT>
captureMatch(ArgT const & arg,MatcherT const & matcher,char const * matcherString)1986     void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher,
1987                                              char const* matcherString ) {
1988         MatchExpression<ArgT const&, MatcherT const&> expr( arg, matcher, matcherString );
1989         setResultType( matcher.match( arg ) );
1990         endExpression( expr );
1991     }
1992 
1993 } // namespace Catch
1994 
1995 // #included from: catch_message.h
1996 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
1997 
1998 #include <string>
1999 
2000 namespace Catch {
2001 
2002     struct MessageInfo {
2003         MessageInfo(    std::string const& _macroName,
2004                         SourceLineInfo const& _lineInfo,
2005                         ResultWas::OfType _type );
2006 
2007         std::string macroName;
2008         SourceLineInfo lineInfo;
2009         ResultWas::OfType type;
2010         std::string message;
2011         unsigned int sequence;
2012 
operator ==Catch::MessageInfo2013         bool operator == ( MessageInfo const& other ) const {
2014             return sequence == other.sequence;
2015         }
operator <Catch::MessageInfo2016         bool operator < ( MessageInfo const& other ) const {
2017             return sequence < other.sequence;
2018         }
2019     private:
2020         static unsigned int globalCount;
2021     };
2022 
2023     struct MessageBuilder {
MessageBuilderCatch::MessageBuilder2024         MessageBuilder( std::string const& macroName,
2025                         SourceLineInfo const& lineInfo,
2026                         ResultWas::OfType type )
2027         : m_info( macroName, lineInfo, type )
2028         {}
2029 
2030         template<typename T>
operator <<Catch::MessageBuilder2031         MessageBuilder& operator << ( T const& value ) {
2032             m_stream << value;
2033             return *this;
2034         }
2035 
2036         MessageInfo m_info;
2037         std::ostringstream m_stream;
2038     };
2039 
2040     class ScopedMessage {
2041     public:
2042         ScopedMessage( MessageBuilder const& builder );
2043         ScopedMessage( ScopedMessage const& other );
2044         ~ScopedMessage();
2045 
2046         MessageInfo m_info;
2047     };
2048 
2049 } // end namespace Catch
2050 
2051 // #included from: catch_interfaces_capture.h
2052 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
2053 
2054 #include <string>
2055 
2056 namespace Catch {
2057 
2058     class TestCase;
2059     class AssertionResult;
2060     struct AssertionInfo;
2061     struct SectionInfo;
2062     struct SectionEndInfo;
2063     struct MessageInfo;
2064     class ScopedMessageBuilder;
2065     struct Counts;
2066 
2067     struct IResultCapture {
2068 
2069         virtual ~IResultCapture();
2070 
2071         virtual void assertionEnded( AssertionResult const& result ) = 0;
2072         virtual bool sectionStarted(    SectionInfo const& sectionInfo,
2073                                         Counts& assertions ) = 0;
2074         virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
2075         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
2076         virtual void pushScopedMessage( MessageInfo const& message ) = 0;
2077         virtual void popScopedMessage( MessageInfo const& message ) = 0;
2078 
2079         virtual std::string getCurrentTestName() const = 0;
2080         virtual const AssertionResult* getLastResult() const = 0;
2081 
2082         virtual void exceptionEarlyReported() = 0;
2083 
2084         virtual void handleFatalErrorCondition( std::string const& message ) = 0;
2085 
2086         virtual bool lastAssertionPassed() = 0;
2087         virtual void assertionPassed() = 0;
2088         virtual void assertionRun() = 0;
2089     };
2090 
2091     IResultCapture& getResultCapture();
2092 }
2093 
2094 // #included from: catch_debugger.h
2095 #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
2096 
2097 // #included from: catch_platform.h
2098 #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
2099 
2100 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
2101 #  define CATCH_PLATFORM_MAC
2102 #elif  defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
2103 #  define CATCH_PLATFORM_IPHONE
2104 #elif defined(linux) || defined(__linux) || defined(__linux__)
2105 #  define CATCH_PLATFORM_LINUX
2106 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
2107 #  define CATCH_PLATFORM_WINDOWS
2108 #  if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
2109 #    define CATCH_DEFINES_NOMINMAX
2110 #  endif
2111 #  if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
2112 #    define CATCH_DEFINES_WIN32_LEAN_AND_MEAN
2113 #  endif
2114 #endif
2115 
2116 #include <string>
2117 
2118 namespace Catch{
2119 
2120     bool isDebuggerActive();
2121     void writeToDebugConsole( std::string const& text );
2122 }
2123 
2124 #ifdef CATCH_PLATFORM_MAC
2125 
2126     // The following code snippet based on:
2127     // http://cocoawithlove.com/2008/03/break-into-debugger.html
2128     #if defined(__ppc64__) || defined(__ppc__)
2129         #define CATCH_TRAP() \
2130                 __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
2131                 : : : "memory","r0","r3","r4" ) /* NOLINT */
2132     #else
2133         #define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ )
2134     #endif
2135 
2136 #elif defined(CATCH_PLATFORM_LINUX)
2137     // If we can use inline assembler, do it because this allows us to break
2138     // directly at the location of the failing check instead of breaking inside
2139     // raise() called from it, i.e. one stack frame below.
2140     #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
2141         #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
2142     #else // Fall back to the generic way.
2143         #include <signal.h>
2144 
2145         #define CATCH_TRAP() raise(SIGTRAP)
2146     #endif
2147 #elif defined(_MSC_VER)
2148     #define CATCH_TRAP() __debugbreak()
2149 #elif defined(__MINGW32__)
2150     extern "C" __declspec(dllimport) void __stdcall DebugBreak();
2151     #define CATCH_TRAP() DebugBreak()
2152 #endif
2153 
2154 #ifdef CATCH_TRAP
2155     #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
2156 #else
2157     #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
2158 #endif
2159 
2160 // #included from: catch_interfaces_runner.h
2161 #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
2162 
2163 namespace Catch {
2164     class TestCase;
2165 
2166     struct IRunner {
2167         virtual ~IRunner();
2168         virtual bool aborting() const = 0;
2169     };
2170 }
2171 
2172 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
2173 # define CATCH_INTERNAL_STRINGIFY(expr) #expr
2174 #else
2175 # define CATCH_INTERNAL_STRINGIFY(expr) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
2176 #endif
2177 
2178 #if defined(CATCH_CONFIG_FAST_COMPILE)
2179 ///////////////////////////////////////////////////////////////////////////////
2180 // We can speedup compilation significantly by breaking into debugger lower in
2181 // the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER
2182 // macro in each assertion
2183 #define INTERNAL_CATCH_REACT( resultBuilder ) \
2184     resultBuilder.react();
2185 
2186 ///////////////////////////////////////////////////////////////////////////////
2187 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
2188 // macros.
2189 // This can potentially cause false negative, if the test code catches
2190 // the exception before it propagates back up to the runner.
2191 #define INTERNAL_CATCH_TEST_NO_TRY( macroName, resultDisposition, expr ) \
2192     do { \
2193         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
2194         __catchResult.setExceptionGuard(); \
2195         CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2196         ( __catchResult <= expr ).endExpression(); \
2197         CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
2198         __catchResult.unsetExceptionGuard(); \
2199         INTERNAL_CATCH_REACT( __catchResult ) \
2200     } 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
2201 // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
2202 
2203 #define INTERNAL_CHECK_THAT_NO_TRY( macroName, matcher, resultDisposition, arg ) \
2204     do { \
2205         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2206         __catchResult.setExceptionGuard(); \
2207         __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \
2208         __catchResult.unsetExceptionGuard(); \
2209         INTERNAL_CATCH_REACT( __catchResult ) \
2210     } while( Catch::alwaysFalse() )
2211 
2212 #else
2213 ///////////////////////////////////////////////////////////////////////////////
2214 // In the event of a failure works out if the debugger needs to be invoked
2215 // and/or an exception thrown and takes appropriate action.
2216 // This needs to be done as a macro so the debugger will stop in the user
2217 // source code rather than in Catch library code
2218 #define INTERNAL_CATCH_REACT( resultBuilder ) \
2219     if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
2220     resultBuilder.react();
2221 #endif
2222 
2223 ///////////////////////////////////////////////////////////////////////////////
2224 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ) \
2225     do { \
2226         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
2227         try { \
2228             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2229             ( __catchResult <= expr ).endExpression(); \
2230             CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
2231         } \
2232         catch( ... ) { \
2233             __catchResult.useActiveException( resultDisposition ); \
2234         } \
2235         INTERNAL_CATCH_REACT( __catchResult ) \
2236     } 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
2237     // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
2238 
2239 ///////////////////////////////////////////////////////////////////////////////
2240 #define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \
2241     INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
2242     if( Catch::getResultCapture().lastAssertionPassed() )
2243 
2244 ///////////////////////////////////////////////////////////////////////////////
2245 #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \
2246     INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
2247     if( !Catch::getResultCapture().lastAssertionPassed() )
2248 
2249 ///////////////////////////////////////////////////////////////////////////////
2250 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \
2251     do { \
2252         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
2253         try { \
2254             static_cast<void>(expr); \
2255             __catchResult.captureResult( Catch::ResultWas::Ok ); \
2256         } \
2257         catch( ... ) { \
2258             __catchResult.useActiveException( resultDisposition ); \
2259         } \
2260         INTERNAL_CATCH_REACT( __catchResult ) \
2261     } while( Catch::alwaysFalse() )
2262 
2263 ///////////////////////////////////////////////////////////////////////////////
2264 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, matcher, expr ) \
2265     do { \
2266         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition, CATCH_INTERNAL_STRINGIFY(matcher) ); \
2267         if( __catchResult.allowThrows() ) \
2268             try { \
2269                 static_cast<void>(expr); \
2270                 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
2271             } \
2272             catch( ... ) { \
2273                 __catchResult.captureExpectedException( matcher ); \
2274             } \
2275         else \
2276             __catchResult.captureResult( Catch::ResultWas::Ok ); \
2277         INTERNAL_CATCH_REACT( __catchResult ) \
2278     } while( Catch::alwaysFalse() )
2279 
2280 ///////////////////////////////////////////////////////////////////////////////
2281 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
2282     do { \
2283         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
2284         if( __catchResult.allowThrows() ) \
2285             try { \
2286                 static_cast<void>(expr); \
2287                 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
2288             } \
2289             catch( exceptionType ) { \
2290                 __catchResult.captureResult( Catch::ResultWas::Ok ); \
2291             } \
2292             catch( ... ) { \
2293                 __catchResult.useActiveException( resultDisposition ); \
2294             } \
2295         else \
2296             __catchResult.captureResult( Catch::ResultWas::Ok ); \
2297         INTERNAL_CATCH_REACT( __catchResult ) \
2298     } while( Catch::alwaysFalse() )
2299 
2300 ///////////////////////////////////////////////////////////////////////////////
2301 #ifdef CATCH_CONFIG_VARIADIC_MACROS
2302     #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
2303         do { \
2304             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
2305             __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
2306             __catchResult.captureResult( messageType ); \
2307             INTERNAL_CATCH_REACT( __catchResult ) \
2308         } while( Catch::alwaysFalse() )
2309 #else
2310     #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \
2311         do { \
2312             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
2313             __catchResult << log + ::Catch::StreamEndStop(); \
2314             __catchResult.captureResult( messageType ); \
2315             INTERNAL_CATCH_REACT( __catchResult ) \
2316         } while( Catch::alwaysFalse() )
2317 #endif
2318 
2319 ///////////////////////////////////////////////////////////////////////////////
2320 #define INTERNAL_CATCH_INFO( macroName, log ) \
2321     Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
2322 
2323 ///////////////////////////////////////////////////////////////////////////////
2324 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
2325     do { \
2326         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2327         try { \
2328             __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \
2329         } catch( ... ) { \
2330             __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
2331         } \
2332         INTERNAL_CATCH_REACT( __catchResult ) \
2333     } while( Catch::alwaysFalse() )
2334 
2335 // #included from: internal/catch_section.h
2336 #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
2337 
2338 // #included from: catch_section_info.h
2339 #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
2340 
2341 // #included from: catch_totals.hpp
2342 #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
2343 
2344 #include <cstddef>
2345 
2346 namespace Catch {
2347 
2348     struct Counts {
CountsCatch::Counts2349         Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
2350 
operator -Catch::Counts2351         Counts operator - ( Counts const& other ) const {
2352             Counts diff;
2353             diff.passed = passed - other.passed;
2354             diff.failed = failed - other.failed;
2355             diff.failedButOk = failedButOk - other.failedButOk;
2356             return diff;
2357         }
operator +=Catch::Counts2358         Counts& operator += ( Counts const& other ) {
2359             passed += other.passed;
2360             failed += other.failed;
2361             failedButOk += other.failedButOk;
2362             return *this;
2363         }
2364 
totalCatch::Counts2365         std::size_t total() const {
2366             return passed + failed + failedButOk;
2367         }
allPassedCatch::Counts2368         bool allPassed() const {
2369             return failed == 0 && failedButOk == 0;
2370         }
allOkCatch::Counts2371         bool allOk() const {
2372             return failed == 0;
2373         }
2374 
2375         std::size_t passed;
2376         std::size_t failed;
2377         std::size_t failedButOk;
2378     };
2379 
2380     struct Totals {
2381 
operator -Catch::Totals2382         Totals operator - ( Totals const& other ) const {
2383             Totals diff;
2384             diff.assertions = assertions - other.assertions;
2385             diff.testCases = testCases - other.testCases;
2386             return diff;
2387         }
2388 
deltaCatch::Totals2389         Totals delta( Totals const& prevTotals ) const {
2390             Totals diff = *this - prevTotals;
2391             if( diff.assertions.failed > 0 )
2392                 ++diff.testCases.failed;
2393             else if( diff.assertions.failedButOk > 0 )
2394                 ++diff.testCases.failedButOk;
2395             else
2396                 ++diff.testCases.passed;
2397             return diff;
2398         }
2399 
operator +=Catch::Totals2400         Totals& operator += ( Totals const& other ) {
2401             assertions += other.assertions;
2402             testCases += other.testCases;
2403             return *this;
2404         }
2405 
2406         Counts assertions;
2407         Counts testCases;
2408     };
2409 }
2410 
2411 #include <string>
2412 
2413 namespace Catch {
2414 
2415     struct SectionInfo {
2416         SectionInfo
2417             (   SourceLineInfo const& _lineInfo,
2418                 std::string const& _name,
2419                 std::string const& _description = std::string() );
2420 
2421         std::string name;
2422         std::string description;
2423         SourceLineInfo lineInfo;
2424     };
2425 
2426     struct SectionEndInfo {
SectionEndInfoCatch::SectionEndInfo2427         SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
2428         : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
2429         {}
2430 
2431         SectionInfo sectionInfo;
2432         Counts prevAssertions;
2433         double durationInSeconds;
2434     };
2435 
2436 } // end namespace Catch
2437 
2438 // #included from: catch_timer.h
2439 #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
2440 
2441 #ifdef _MSC_VER
2442 
2443 namespace Catch {
2444     typedef unsigned long long UInt64;
2445 }
2446 #else
2447 #include <stdint.h>
2448 namespace Catch {
2449     typedef uint64_t UInt64;
2450 }
2451 #endif
2452 
2453 namespace Catch {
2454     class Timer {
2455     public:
Timer()2456         Timer() : m_ticks( 0 ) {}
2457         void start();
2458         unsigned int getElapsedMicroseconds() const;
2459         unsigned int getElapsedMilliseconds() const;
2460         double getElapsedSeconds() const;
2461 
2462     private:
2463         UInt64 m_ticks;
2464     };
2465 
2466 } // namespace Catch
2467 
2468 #include <string>
2469 
2470 namespace Catch {
2471 
2472     class Section : NonCopyable {
2473     public:
2474         Section( SectionInfo const& info );
2475         ~Section();
2476 
2477         // This indicates whether the section should be executed or not
2478         operator bool() const;
2479 
2480     private:
2481         SectionInfo m_info;
2482 
2483         std::string m_name;
2484         Counts m_assertions;
2485         bool m_sectionIncluded;
2486         Timer m_timer;
2487     };
2488 
2489 } // end namespace Catch
2490 
2491 #ifdef CATCH_CONFIG_VARIADIC_MACROS
2492     #define INTERNAL_CATCH_SECTION( ... ) \
2493         if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
2494 #else
2495     #define INTERNAL_CATCH_SECTION( name, desc ) \
2496         if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
2497 #endif
2498 
2499 // #included from: internal/catch_generators.hpp
2500 #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
2501 
2502 #include <vector>
2503 #include <string>
2504 #include <stdlib.h>
2505 
2506 namespace Catch {
2507 
2508 template<typename T>
2509 struct IGenerator {
~IGeneratorCatch::IGenerator2510     virtual ~IGenerator() {}
2511     virtual T getValue( std::size_t index ) const = 0;
2512     virtual std::size_t size () const = 0;
2513 };
2514 
2515 template<typename T>
2516 class BetweenGenerator : public IGenerator<T> {
2517 public:
BetweenGenerator(T from,T to)2518     BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
2519 
getValue(std::size_t index) const2520     virtual T getValue( std::size_t index ) const {
2521         return m_from+static_cast<int>( index );
2522     }
2523 
size() const2524     virtual std::size_t size() const {
2525         return static_cast<std::size_t>( 1+m_to-m_from );
2526     }
2527 
2528 private:
2529 
2530     T m_from;
2531     T m_to;
2532 };
2533 
2534 template<typename T>
2535 class ValuesGenerator : public IGenerator<T> {
2536 public:
ValuesGenerator()2537     ValuesGenerator(){}
2538 
add(T value)2539     void add( T value ) {
2540         m_values.push_back( value );
2541     }
2542 
getValue(std::size_t index) const2543     virtual T getValue( std::size_t index ) const {
2544         return m_values[index];
2545     }
2546 
size() const2547     virtual std::size_t size() const {
2548         return m_values.size();
2549     }
2550 
2551 private:
2552     std::vector<T> m_values;
2553 };
2554 
2555 template<typename T>
2556 class CompositeGenerator {
2557 public:
CompositeGenerator()2558     CompositeGenerator() : m_totalSize( 0 ) {}
2559 
2560     // *** Move semantics, similar to auto_ptr ***
CompositeGenerator(CompositeGenerator & other)2561     CompositeGenerator( CompositeGenerator& other )
2562     :   m_fileInfo( other.m_fileInfo ),
2563         m_totalSize( 0 )
2564     {
2565         move( other );
2566     }
2567 
setFileInfo(const char * fileInfo)2568     CompositeGenerator& setFileInfo( const char* fileInfo ) {
2569         m_fileInfo = fileInfo;
2570         return *this;
2571     }
2572 
~CompositeGenerator()2573     ~CompositeGenerator() {
2574         deleteAll( m_composed );
2575     }
2576 
operator T() const2577     operator T () const {
2578         size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
2579 
2580         typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
2581         typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
2582         for( size_t index = 0; it != itEnd; ++it )
2583         {
2584             const IGenerator<T>* generator = *it;
2585             if( overallIndex >= index && overallIndex < index + generator->size() )
2586             {
2587                 return generator->getValue( overallIndex-index );
2588             }
2589             index += generator->size();
2590         }
2591         CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
2592         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
2593     }
2594 
add(const IGenerator<T> * generator)2595     void add( const IGenerator<T>* generator ) {
2596         m_totalSize += generator->size();
2597         m_composed.push_back( generator );
2598     }
2599 
then(CompositeGenerator & other)2600     CompositeGenerator& then( CompositeGenerator& other ) {
2601         move( other );
2602         return *this;
2603     }
2604 
then(T value)2605     CompositeGenerator& then( T value ) {
2606         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2607         valuesGen->add( value );
2608         add( valuesGen );
2609         return *this;
2610     }
2611 
2612 private:
2613 
move(CompositeGenerator & other)2614     void move( CompositeGenerator& other ) {
2615         m_composed.insert( m_composed.end(), other.m_composed.begin(), other.m_composed.end() );
2616         m_totalSize += other.m_totalSize;
2617         other.m_composed.clear();
2618     }
2619 
2620     std::vector<const IGenerator<T>*> m_composed;
2621     std::string m_fileInfo;
2622     size_t m_totalSize;
2623 };
2624 
2625 namespace Generators
2626 {
2627     template<typename T>
between(T from,T to)2628     CompositeGenerator<T> between( T from, T to ) {
2629         CompositeGenerator<T> generators;
2630         generators.add( new BetweenGenerator<T>( from, to ) );
2631         return generators;
2632     }
2633 
2634     template<typename T>
values(T val1,T val2)2635     CompositeGenerator<T> values( T val1, T val2 ) {
2636         CompositeGenerator<T> generators;
2637         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2638         valuesGen->add( val1 );
2639         valuesGen->add( val2 );
2640         generators.add( valuesGen );
2641         return generators;
2642     }
2643 
2644     template<typename T>
values(T val1,T val2,T val3)2645     CompositeGenerator<T> values( T val1, T val2, T val3 ){
2646         CompositeGenerator<T> generators;
2647         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2648         valuesGen->add( val1 );
2649         valuesGen->add( val2 );
2650         valuesGen->add( val3 );
2651         generators.add( valuesGen );
2652         return generators;
2653     }
2654 
2655     template<typename T>
values(T val1,T val2,T val3,T val4)2656     CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
2657         CompositeGenerator<T> generators;
2658         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2659         valuesGen->add( val1 );
2660         valuesGen->add( val2 );
2661         valuesGen->add( val3 );
2662         valuesGen->add( val4 );
2663         generators.add( valuesGen );
2664         return generators;
2665     }
2666 
2667 } // end namespace Generators
2668 
2669 using namespace Generators;
2670 
2671 } // end namespace Catch
2672 
2673 #define INTERNAL_CATCH_LINESTR2( line ) #line
2674 #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
2675 
2676 #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
2677 
2678 // #included from: internal/catch_interfaces_exception.h
2679 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
2680 
2681 #include <string>
2682 #include <vector>
2683 
2684 // #included from: catch_interfaces_registry_hub.h
2685 #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
2686 
2687 #include <string>
2688 
2689 namespace Catch {
2690 
2691     class TestCase;
2692     struct ITestCaseRegistry;
2693     struct IExceptionTranslatorRegistry;
2694     struct IExceptionTranslator;
2695     struct IReporterRegistry;
2696     struct IReporterFactory;
2697     struct ITagAliasRegistry;
2698 
2699     struct IRegistryHub {
2700         virtual ~IRegistryHub();
2701 
2702         virtual IReporterRegistry const& getReporterRegistry() const = 0;
2703         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2704         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
2705 
2706         virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
2707     };
2708 
2709     struct IMutableRegistryHub {
2710         virtual ~IMutableRegistryHub();
2711         virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
2712         virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
2713         virtual void registerTest( TestCase const& testInfo ) = 0;
2714         virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2715         virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
2716     };
2717 
2718     IRegistryHub& getRegistryHub();
2719     IMutableRegistryHub& getMutableRegistryHub();
2720     void cleanUp();
2721     std::string translateActiveException();
2722 
2723 }
2724 
2725 namespace Catch {
2726 
2727     typedef std::string(*exceptionTranslateFunction)();
2728 
2729     struct IExceptionTranslator;
2730     typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
2731 
2732     struct IExceptionTranslator {
2733         virtual ~IExceptionTranslator();
2734         virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
2735     };
2736 
2737     struct IExceptionTranslatorRegistry {
2738         virtual ~IExceptionTranslatorRegistry();
2739 
2740         virtual std::string translateActiveException() const = 0;
2741     };
2742 
2743     class ExceptionTranslatorRegistrar {
2744         template<typename T>
2745         class ExceptionTranslator : public IExceptionTranslator {
2746         public:
2747 
ExceptionTranslator(std::string (* translateFunction)(T &))2748             ExceptionTranslator( std::string(*translateFunction)( T& ) )
2749             : m_translateFunction( translateFunction )
2750             {}
2751 
translate(ExceptionTranslators::const_iterator it,ExceptionTranslators::const_iterator itEnd) const2752             virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
2753                 try {
2754                     if( it == itEnd )
2755                         throw;
2756                     else
2757                         return (*it)->translate( it+1, itEnd );
2758                 }
2759                 catch( T& ex ) {
2760                     return m_translateFunction( ex );
2761                 }
2762             }
2763 
2764         protected:
2765             std::string(*m_translateFunction)( T& );
2766         };
2767 
2768     public:
2769         template<typename T>
ExceptionTranslatorRegistrar(std::string (* translateFunction)(T &))2770         ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
2771             getMutableRegistryHub().registerTranslator
2772                 ( new ExceptionTranslator<T>( translateFunction ) );
2773         }
2774     };
2775 }
2776 
2777 ///////////////////////////////////////////////////////////////////////////////
2778 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
2779     static std::string translatorName( signature ); \
2780     namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
2781     static std::string translatorName( signature )
2782 
2783 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
2784 
2785 // #included from: internal/catch_approx.hpp
2786 #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
2787 
2788 #include <cmath>
2789 #include <limits>
2790 
2791 #if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
2792 #include <type_traits>
2793 #endif
2794 
2795 namespace Catch {
2796 namespace Detail {
2797 
2798     class Approx {
2799     public:
Approx(double value)2800         explicit Approx ( double value )
2801         :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
2802             m_margin( 0.0 ),
2803             m_scale( 1.0 ),
2804             m_value( value )
2805         {}
2806 
custom()2807         static Approx custom() {
2808             return Approx( 0 );
2809         }
2810 
2811 #if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
2812 
2813         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator ()(T value)2814         Approx operator()( T value ) {
2815             Approx approx( static_cast<double>(value) );
2816             approx.epsilon( m_epsilon );
2817             approx.margin( m_margin );
2818             approx.scale( m_scale );
2819             return approx;
2820         }
2821 
2822         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
Approx(T value)2823         explicit Approx( T value ): Approx(static_cast<double>(value))
2824         {}
2825 
2826         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator ==(const T & lhs,Approx const & rhs)2827         friend bool operator == ( const T& lhs, Approx const& rhs ) {
2828             // Thanks to Richard Harris for his help refining this formula
2829             auto lhs_v = double(lhs);
2830             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)));
2831             if (relativeOK) {
2832                 return true;
2833             }
2834 
2835             return std::fabs(lhs_v - rhs.m_value) <= rhs.m_margin;
2836         }
2837 
2838         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator ==(Approx const & lhs,const T & rhs)2839         friend bool operator == ( Approx const& lhs, const T& rhs ) {
2840             return operator==( rhs, lhs );
2841         }
2842 
2843         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator !=(T lhs,Approx const & rhs)2844         friend bool operator != ( T lhs, Approx const& rhs ) {
2845             return !operator==( lhs, rhs );
2846         }
2847 
2848         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator !=(Approx const & lhs,T rhs)2849         friend bool operator != ( Approx const& lhs, T rhs ) {
2850             return !operator==( rhs, lhs );
2851         }
2852 
2853         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator <=(T lhs,Approx const & rhs)2854         friend bool operator <= ( T lhs, Approx const& rhs ) {
2855             return double(lhs) < rhs.m_value || lhs == rhs;
2856         }
2857 
2858         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator <=(Approx const & lhs,T rhs)2859         friend bool operator <= ( Approx const& lhs, T rhs ) {
2860             return lhs.m_value < double(rhs) || lhs == rhs;
2861         }
2862 
2863         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator >=(T lhs,Approx const & rhs)2864         friend bool operator >= ( T lhs, Approx const& rhs ) {
2865             return double(lhs) > rhs.m_value || lhs == rhs;
2866         }
2867 
2868         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator >=(Approx const & lhs,T rhs)2869         friend bool operator >= ( Approx const& lhs, T rhs ) {
2870             return lhs.m_value > double(rhs) || lhs == rhs;
2871         }
2872 
2873         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
epsilon(T newEpsilon)2874         Approx& epsilon( T newEpsilon ) {
2875             m_epsilon = double(newEpsilon);
2876             return *this;
2877         }
2878 
2879         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
margin(T newMargin)2880         Approx& margin( T newMargin ) {
2881             m_margin = double(newMargin);
2882             return *this;
2883         }
2884 
2885         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
scale(T newScale)2886         Approx& scale( T newScale ) {
2887             m_scale = double(newScale);
2888             return *this;
2889         }
2890 
2891 #else
2892 
operator ()(double value)2893         Approx operator()( double value ) {
2894             Approx approx( value );
2895             approx.epsilon( m_epsilon );
2896             approx.margin( m_margin );
2897             approx.scale( m_scale );
2898             return approx;
2899         }
2900 
operator ==(double lhs,Approx const & rhs)2901         friend bool operator == ( double lhs, Approx const& rhs ) {
2902             // Thanks to Richard Harris for his help refining this formula
2903             bool relativeOK = std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) );
2904             if (relativeOK) {
2905                 return true;
2906             }
2907             return std::fabs(lhs - rhs.m_value) <= rhs.m_margin;
2908         }
2909 
operator ==(Approx const & lhs,double rhs)2910         friend bool operator == ( Approx const& lhs, double rhs ) {
2911             return operator==( rhs, lhs );
2912         }
2913 
operator !=(double lhs,Approx const & rhs)2914         friend bool operator != ( double lhs, Approx const& rhs ) {
2915             return !operator==( lhs, rhs );
2916         }
2917 
operator !=(Approx const & lhs,double rhs)2918         friend bool operator != ( Approx const& lhs, double rhs ) {
2919             return !operator==( rhs, lhs );
2920         }
2921 
operator <=(double lhs,Approx const & rhs)2922         friend bool operator <= ( double lhs, Approx const& rhs ) {
2923             return lhs < rhs.m_value || lhs == rhs;
2924         }
2925 
operator <=(Approx const & lhs,double rhs)2926         friend bool operator <= ( Approx const& lhs, double rhs ) {
2927             return lhs.m_value < rhs || lhs == rhs;
2928         }
2929 
operator >=(double lhs,Approx const & rhs)2930         friend bool operator >= ( double lhs, Approx const& rhs ) {
2931             return lhs > rhs.m_value || lhs == rhs;
2932         }
2933 
operator >=(Approx const & lhs,double rhs)2934         friend bool operator >= ( Approx const& lhs, double rhs ) {
2935             return lhs.m_value > rhs || lhs == rhs;
2936         }
2937 
epsilon(double newEpsilon)2938         Approx& epsilon( double newEpsilon ) {
2939             m_epsilon = newEpsilon;
2940             return *this;
2941         }
2942 
margin(double newMargin)2943         Approx& margin( double newMargin ) {
2944             m_margin = newMargin;
2945             return *this;
2946         }
2947 
scale(double newScale)2948         Approx& scale( double newScale ) {
2949             m_scale = newScale;
2950             return *this;
2951         }
2952 #endif
2953 
toString() const2954         std::string toString() const {
2955             std::ostringstream oss;
2956             oss << "Approx( " << Catch::toString( m_value ) << " )";
2957             return oss.str();
2958         }
2959 
2960     private:
2961         double m_epsilon;
2962         double m_margin;
2963         double m_scale;
2964         double m_value;
2965     };
2966 }
2967 
2968 template<>
toString(Detail::Approx const & value)2969 inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
2970     return value.toString();
2971 }
2972 
2973 } // end namespace Catch
2974 
2975 // #included from: internal/catch_matchers_string.h
2976 #define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
2977 
2978 namespace Catch {
2979 namespace Matchers {
2980 
2981     namespace StdString {
2982 
2983         struct CasedString
2984         {
2985             CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
2986             std::string adjustString( std::string const& str ) const;
2987             std::string caseSensitivitySuffix() const;
2988 
2989             CaseSensitive::Choice m_caseSensitivity;
2990             std::string m_str;
2991         };
2992 
2993         struct StringMatcherBase : MatcherBase<std::string> {
2994             StringMatcherBase( std::string const& operation, CasedString const& comparator );
2995             virtual std::string describe() const CATCH_OVERRIDE;
2996 
2997             CasedString m_comparator;
2998             std::string m_operation;
2999         };
3000 
3001         struct EqualsMatcher : StringMatcherBase {
3002             EqualsMatcher( CasedString const& comparator );
3003             virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
3004         };
3005         struct ContainsMatcher : StringMatcherBase {
3006             ContainsMatcher( CasedString const& comparator );
3007             virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
3008         };
3009         struct StartsWithMatcher : StringMatcherBase {
3010             StartsWithMatcher( CasedString const& comparator );
3011             virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
3012         };
3013         struct EndsWithMatcher : StringMatcherBase {
3014             EndsWithMatcher( CasedString const& comparator );
3015             virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
3016         };
3017 
3018     } // namespace StdString
3019 
3020     // The following functions create the actual matcher objects.
3021     // This allows the types to be inferred
3022 
3023     StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3024     StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3025     StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3026     StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3027 
3028 } // namespace Matchers
3029 } // namespace Catch
3030 
3031 // #included from: internal/catch_matchers_vector.h
3032 #define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
3033 
3034 namespace Catch {
3035 namespace Matchers {
3036 
3037     namespace Vector {
3038 
3039         template<typename T>
3040         struct ContainsElementMatcher : MatcherBase<std::vector<T>, T> {
3041 
ContainsElementMatcherCatch::Matchers::Vector::ContainsElementMatcher3042             ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
3043 
matchCatch::Matchers::Vector::ContainsElementMatcher3044             bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
3045                 return std::find(v.begin(), v.end(), m_comparator) != v.end();
3046             }
3047 
describeCatch::Matchers::Vector::ContainsElementMatcher3048             virtual std::string describe() const CATCH_OVERRIDE {
3049                 return "Contains: " + Catch::toString( m_comparator );
3050             }
3051 
3052             T const& m_comparator;
3053         };
3054 
3055         template<typename T>
3056         struct ContainsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
3057 
ContainsMatcherCatch::Matchers::Vector::ContainsMatcher3058             ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
3059 
matchCatch::Matchers::Vector::ContainsMatcher3060             bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
3061                 // !TBD: see note in EqualsMatcher
3062                 if (m_comparator.size() > v.size())
3063                     return false;
3064                 for (size_t i = 0; i < m_comparator.size(); ++i)
3065                     if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end())
3066                         return false;
3067                 return true;
3068             }
describeCatch::Matchers::Vector::ContainsMatcher3069             virtual std::string describe() const CATCH_OVERRIDE {
3070                 return "Contains: " + Catch::toString( m_comparator );
3071             }
3072 
3073             std::vector<T> const& m_comparator;
3074         };
3075 
3076         template<typename T>
3077         struct EqualsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
3078 
EqualsMatcherCatch::Matchers::Vector::EqualsMatcher3079             EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
3080 
matchCatch::Matchers::Vector::EqualsMatcher3081             bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
3082                 // !TBD: This currently works if all elements can be compared using !=
3083                 // - a more general approach would be via a compare template that defaults
3084                 // to using !=. but could be specialised for, e.g. std::vector<T> etc
3085                 // - then just call that directly
3086                 if (m_comparator.size() != v.size())
3087                     return false;
3088                 for (size_t i = 0; i < v.size(); ++i)
3089                     if (m_comparator[i] != v[i])
3090                         return false;
3091                 return true;
3092             }
describeCatch::Matchers::Vector::EqualsMatcher3093             virtual std::string describe() const CATCH_OVERRIDE {
3094                 return "Equals: " + Catch::toString( m_comparator );
3095             }
3096             std::vector<T> const& m_comparator;
3097         };
3098 
3099     } // namespace Vector
3100 
3101     // The following functions create the actual matcher objects.
3102     // This allows the types to be inferred
3103 
3104     template<typename T>
Contains(std::vector<T> const & comparator)3105     Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
3106         return Vector::ContainsMatcher<T>( comparator );
3107     }
3108 
3109     template<typename T>
VectorContains(T const & comparator)3110     Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
3111         return Vector::ContainsElementMatcher<T>( comparator );
3112     }
3113 
3114     template<typename T>
Equals(std::vector<T> const & comparator)3115     Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
3116         return Vector::EqualsMatcher<T>( comparator );
3117     }
3118 
3119 } // namespace Matchers
3120 } // namespace Catch
3121 
3122 // #included from: internal/catch_interfaces_tag_alias_registry.h
3123 #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
3124 
3125 // #included from: catch_tag_alias.h
3126 #define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
3127 
3128 #include <string>
3129 
3130 namespace Catch {
3131 
3132     struct TagAlias {
TagAliasCatch::TagAlias3133         TagAlias( std::string const& _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
3134 
3135         std::string tag;
3136         SourceLineInfo lineInfo;
3137     };
3138 
3139     struct RegistrarForTagAliases {
3140         RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
3141     };
3142 
3143 } // end namespace Catch
3144 
3145 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
3146 // #included from: catch_option.hpp
3147 #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
3148 
3149 namespace Catch {
3150 
3151     // An optional type
3152     template<typename T>
3153     class Option {
3154     public:
Option()3155         Option() : nullableValue( CATCH_NULL ) {}
Option(T const & _value)3156         Option( T const& _value )
3157         : nullableValue( new( storage ) T( _value ) )
3158         {}
Option(Option const & _other)3159         Option( Option const& _other )
3160         : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
3161         {}
3162 
~Option()3163         ~Option() {
3164             reset();
3165         }
3166 
operator =(Option const & _other)3167         Option& operator= ( Option const& _other ) {
3168             if( &_other != this ) {
3169                 reset();
3170                 if( _other )
3171                     nullableValue = new( storage ) T( *_other );
3172             }
3173             return *this;
3174         }
operator =(T const & _value)3175         Option& operator = ( T const& _value ) {
3176             reset();
3177             nullableValue = new( storage ) T( _value );
3178             return *this;
3179         }
3180 
reset()3181         void reset() {
3182             if( nullableValue )
3183                 nullableValue->~T();
3184             nullableValue = CATCH_NULL;
3185         }
3186 
operator *()3187         T& operator*() { return *nullableValue; }
operator *() const3188         T const& operator*() const { return *nullableValue; }
operator ->()3189         T* operator->() { return nullableValue; }
operator ->() const3190         const T* operator->() const { return nullableValue; }
3191 
valueOr(T const & defaultValue) const3192         T valueOr( T const& defaultValue ) const {
3193             return nullableValue ? *nullableValue : defaultValue;
3194         }
3195 
some() const3196         bool some() const { return nullableValue != CATCH_NULL; }
none() const3197         bool none() const { return nullableValue == CATCH_NULL; }
3198 
operator !() const3199         bool operator !() const { return nullableValue == CATCH_NULL; }
operator SafeBool::type() const3200         operator SafeBool::type() const {
3201             return SafeBool::makeSafe( some() );
3202         }
3203 
3204     private:
3205         T *nullableValue;
3206         union {
3207             char storage[sizeof(T)];
3208 
3209             // These are here to force alignment for the storage
3210             long double dummy1;
3211             void (*dummy2)();
3212             long double dummy3;
3213 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
3214             long long dummy4;
3215 #endif
3216         };
3217     };
3218 
3219 } // end namespace Catch
3220 
3221 namespace Catch {
3222 
3223     struct ITagAliasRegistry {
3224         virtual ~ITagAliasRegistry();
3225         virtual Option<TagAlias> find( std::string const& alias ) const = 0;
3226         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
3227 
3228         static ITagAliasRegistry const& get();
3229     };
3230 
3231 } // end namespace Catch
3232 
3233 // These files are included here so the single_include script doesn't put them
3234 // in the conditionally compiled sections
3235 // #included from: internal/catch_test_case_info.h
3236 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
3237 
3238 #include <string>
3239 #include <set>
3240 
3241 #ifdef __clang__
3242 #pragma clang diagnostic push
3243 #pragma clang diagnostic ignored "-Wpadded"
3244 #endif
3245 
3246 namespace Catch {
3247 
3248     struct ITestCase;
3249 
3250     struct TestCaseInfo {
3251         enum SpecialProperties{
3252             None = 0,
3253             IsHidden = 1 << 1,
3254             ShouldFail = 1 << 2,
3255             MayFail = 1 << 3,
3256             Throws = 1 << 4,
3257             NonPortable = 1 << 5
3258         };
3259 
3260         TestCaseInfo(   std::string const& _name,
3261                         std::string const& _className,
3262                         std::string const& _description,
3263                         std::set<std::string> const& _tags,
3264                         SourceLineInfo const& _lineInfo );
3265 
3266         TestCaseInfo( TestCaseInfo const& other );
3267 
3268         friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
3269 
3270         bool isHidden() const;
3271         bool throws() const;
3272         bool okToFail() const;
3273         bool expectedToFail() const;
3274 
3275         std::string name;
3276         std::string className;
3277         std::string description;
3278         std::set<std::string> tags;
3279         std::set<std::string> lcaseTags;
3280         std::string tagsAsString;
3281         SourceLineInfo lineInfo;
3282         SpecialProperties properties;
3283     };
3284 
3285     class TestCase : public TestCaseInfo {
3286     public:
3287 
3288         TestCase( ITestCase* testCase, TestCaseInfo const& info );
3289         TestCase( TestCase const& other );
3290 
3291         TestCase withName( std::string const& _newName ) const;
3292 
3293         void invoke() const;
3294 
3295         TestCaseInfo const& getTestCaseInfo() const;
3296 
3297         void swap( TestCase& other );
3298         bool operator == ( TestCase const& other ) const;
3299         bool operator < ( TestCase const& other ) const;
3300         TestCase& operator = ( TestCase const& other );
3301 
3302     private:
3303         Ptr<ITestCase> test;
3304     };
3305 
3306     TestCase makeTestCase(  ITestCase* testCase,
3307                             std::string const& className,
3308                             std::string const& name,
3309                             std::string const& description,
3310                             SourceLineInfo const& lineInfo );
3311 }
3312 
3313 #ifdef __clang__
3314 #pragma clang diagnostic pop
3315 #endif
3316 
3317 
3318 #ifdef __OBJC__
3319 // #included from: internal/catch_objc.hpp
3320 #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
3321 
3322 #import <objc/runtime.h>
3323 
3324 #include <string>
3325 
3326 // NB. Any general catch headers included here must be included
3327 // in catch.hpp first to make sure they are included by the single
3328 // header for non obj-usage
3329 
3330 ///////////////////////////////////////////////////////////////////////////////
3331 // This protocol is really only here for (self) documenting purposes, since
3332 // all its methods are optional.
3333 @protocol OcFixture
3334 
3335 @optional
3336 
3337 -(void) setUp;
3338 -(void) tearDown;
3339 
3340 @end
3341 
3342 namespace Catch {
3343 
3344     class OcMethod : public SharedImpl<ITestCase> {
3345 
3346     public:
OcMethod(Class cls,SEL sel)3347         OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
3348 
invoke() const3349         virtual void invoke() const {
3350             id obj = [[m_cls alloc] init];
3351 
3352             performOptionalSelector( obj, @selector(setUp)  );
3353             performOptionalSelector( obj, m_sel );
3354             performOptionalSelector( obj, @selector(tearDown)  );
3355 
3356             arcSafeRelease( obj );
3357         }
3358     private:
~OcMethod()3359         virtual ~OcMethod() {}
3360 
3361         Class m_cls;
3362         SEL m_sel;
3363     };
3364 
3365     namespace Detail{
3366 
getAnnotation(Class cls,std::string const & annotationName,std::string const & testCaseName)3367         inline std::string getAnnotation(   Class cls,
3368                                             std::string const& annotationName,
3369                                             std::string const& testCaseName ) {
3370             NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
3371             SEL sel = NSSelectorFromString( selStr );
3372             arcSafeRelease( selStr );
3373             id value = performOptionalSelector( cls, sel );
3374             if( value )
3375                 return [(NSString*)value UTF8String];
3376             return "";
3377         }
3378     }
3379 
registerTestMethods()3380     inline size_t registerTestMethods() {
3381         size_t noTestMethods = 0;
3382         int noClasses = objc_getClassList( CATCH_NULL, 0 );
3383 
3384         Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
3385         objc_getClassList( classes, noClasses );
3386 
3387         for( int c = 0; c < noClasses; c++ ) {
3388             Class cls = classes[c];
3389             {
3390                 u_int count;
3391                 Method* methods = class_copyMethodList( cls, &count );
3392                 for( u_int m = 0; m < count ; m++ ) {
3393                     SEL selector = method_getName(methods[m]);
3394                     std::string methodName = sel_getName(selector);
3395                     if( startsWith( methodName, "Catch_TestCase_" ) ) {
3396                         std::string testCaseName = methodName.substr( 15 );
3397                         std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
3398                         std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
3399                         const char* className = class_getName( cls );
3400 
3401                         getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
3402                         noTestMethods++;
3403                     }
3404                 }
3405                 free(methods);
3406             }
3407         }
3408         return noTestMethods;
3409     }
3410 
3411     namespace Matchers {
3412         namespace Impl {
3413         namespace NSStringMatchers {
3414 
3415             struct StringHolder : MatcherBase<NSString*>{
StringHolderCatch::Matchers::Impl::NSStringMatchers::StringHolder3416                 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
StringHolderCatch::Matchers::Impl::NSStringMatchers::StringHolder3417                 StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
StringHolderCatch::Matchers::Impl::NSStringMatchers::StringHolder3418                 StringHolder() {
3419                     arcSafeRelease( m_substr );
3420                 }
3421 
matchCatch::Matchers::Impl::NSStringMatchers::StringHolder3422                 virtual bool match( NSString* arg ) const CATCH_OVERRIDE {
3423                     return false;
3424                 }
3425 
3426                 NSString* m_substr;
3427             };
3428 
3429             struct Equals : StringHolder {
EqualsCatch::Matchers::Impl::NSStringMatchers::Equals3430                 Equals( NSString* substr ) : StringHolder( substr ){}
3431 
matchCatch::Matchers::Impl::NSStringMatchers::Equals3432                 virtual bool match( NSString* str ) const CATCH_OVERRIDE {
3433                     return  (str != nil || m_substr == nil ) &&
3434                             [str isEqualToString:m_substr];
3435                 }
3436 
describeCatch::Matchers::Impl::NSStringMatchers::Equals3437                 virtual std::string describe() const CATCH_OVERRIDE {
3438                     return "equals string: " + Catch::toString( m_substr );
3439                 }
3440             };
3441 
3442             struct Contains : StringHolder {
ContainsCatch::Matchers::Impl::NSStringMatchers::Contains3443                 Contains( NSString* substr ) : StringHolder( substr ){}
3444 
matchCatch::Matchers::Impl::NSStringMatchers::Contains3445                 virtual bool match( NSString* str ) const {
3446                     return  (str != nil || m_substr == nil ) &&
3447                             [str rangeOfString:m_substr].location != NSNotFound;
3448                 }
3449 
describeCatch::Matchers::Impl::NSStringMatchers::Contains3450                 virtual std::string describe() const CATCH_OVERRIDE {
3451                     return "contains string: " + Catch::toString( m_substr );
3452                 }
3453             };
3454 
3455             struct StartsWith : StringHolder {
StartsWithCatch::Matchers::Impl::NSStringMatchers::StartsWith3456                 StartsWith( NSString* substr ) : StringHolder( substr ){}
3457 
matchCatch::Matchers::Impl::NSStringMatchers::StartsWith3458                 virtual bool match( NSString* str ) const {
3459                     return  (str != nil || m_substr == nil ) &&
3460                             [str rangeOfString:m_substr].location == 0;
3461                 }
3462 
describeCatch::Matchers::Impl::NSStringMatchers::StartsWith3463                 virtual std::string describe() const CATCH_OVERRIDE {
3464                     return "starts with: " + Catch::toString( m_substr );
3465                 }
3466             };
3467             struct EndsWith : StringHolder {
EndsWithCatch::Matchers::Impl::NSStringMatchers::EndsWith3468                 EndsWith( NSString* substr ) : StringHolder( substr ){}
3469 
matchCatch::Matchers::Impl::NSStringMatchers::EndsWith3470                 virtual bool match( NSString* str ) const {
3471                     return  (str != nil || m_substr == nil ) &&
3472                             [str rangeOfString:m_substr].location == [str length] - [m_substr length];
3473                 }
3474 
describeCatch::Matchers::Impl::NSStringMatchers::EndsWith3475                 virtual std::string describe() const CATCH_OVERRIDE {
3476                     return "ends with: " + Catch::toString( m_substr );
3477                 }
3478             };
3479 
3480         } // namespace NSStringMatchers
3481         } // namespace Impl
3482 
3483         inline Impl::NSStringMatchers::Equals
Equals(NSString * substr)3484             Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
3485 
3486         inline Impl::NSStringMatchers::Contains
Contains(NSString * substr)3487             Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
3488 
3489         inline Impl::NSStringMatchers::StartsWith
StartsWith(NSString * substr)3490             StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
3491 
3492         inline Impl::NSStringMatchers::EndsWith
EndsWith(NSString * substr)3493             EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
3494 
3495     } // namespace Matchers
3496 
3497     using namespace Matchers;
3498 
3499 } // namespace Catch
3500 
3501 ///////////////////////////////////////////////////////////////////////////////
3502 #define OC_TEST_CASE( name, desc )\
3503 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
3504 {\
3505 return @ name; \
3506 }\
3507 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
3508 { \
3509 return @ desc; \
3510 } \
3511 -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
3512 
3513 #endif
3514 
3515 #ifdef CATCH_IMPL
3516 
3517 // !TBD: Move the leak detector code into a separate header
3518 #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
3519 #include <crtdbg.h>
3520 class LeakDetector {
3521 public:
LeakDetector()3522     LeakDetector() {
3523         int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
3524         flag |= _CRTDBG_LEAK_CHECK_DF;
3525         flag |= _CRTDBG_ALLOC_MEM_DF;
3526         _CrtSetDbgFlag(flag);
3527         _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
3528         _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
3529         // Change this to leaking allocation's number to break there
3530         _CrtSetBreakAlloc(-1);
3531     }
3532 };
3533 #else
3534 class LeakDetector {};
3535 #endif
3536 
3537 LeakDetector leakDetector;
3538 
3539 // #included from: internal/catch_impl.hpp
3540 #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
3541 
3542 // Collect all the implementation files together here
3543 // These are the equivalent of what would usually be cpp files
3544 
3545 #ifdef __clang__
3546 #pragma clang diagnostic push
3547 #pragma clang diagnostic ignored "-Wweak-vtables"
3548 #endif
3549 
3550 // #included from: ../catch_session.hpp
3551 #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
3552 
3553 // #included from: internal/catch_commandline.hpp
3554 #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
3555 
3556 // #included from: catch_config.hpp
3557 #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
3558 
3559 // #included from: catch_test_spec_parser.hpp
3560 #define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
3561 
3562 #ifdef __clang__
3563 #pragma clang diagnostic push
3564 #pragma clang diagnostic ignored "-Wpadded"
3565 #endif
3566 
3567 // #included from: catch_test_spec.hpp
3568 #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
3569 
3570 #ifdef __clang__
3571 #pragma clang diagnostic push
3572 #pragma clang diagnostic ignored "-Wpadded"
3573 #endif
3574 
3575 // #included from: catch_wildcard_pattern.hpp
3576 #define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3577 
3578 #include <stdexcept>
3579 
3580 namespace Catch
3581 {
3582     class WildcardPattern {
3583         enum WildcardPosition {
3584             NoWildcard = 0,
3585             WildcardAtStart = 1,
3586             WildcardAtEnd = 2,
3587             WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
3588         };
3589 
3590     public:
3591 
WildcardPattern(std::string const & pattern,CaseSensitive::Choice caseSensitivity)3592         WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
3593         :   m_caseSensitivity( caseSensitivity ),
3594             m_wildcard( NoWildcard ),
3595             m_pattern( adjustCase( pattern ) )
3596         {
3597             if( startsWith( m_pattern, '*' ) ) {
3598                 m_pattern = m_pattern.substr( 1 );
3599                 m_wildcard = WildcardAtStart;
3600             }
3601             if( endsWith( m_pattern, '*' ) ) {
3602                 m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
3603                 m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
3604             }
3605         }
3606         virtual ~WildcardPattern();
matches(std::string const & str) const3607         virtual bool matches( std::string const& str ) const {
3608             switch( m_wildcard ) {
3609                 case NoWildcard:
3610                     return m_pattern == adjustCase( str );
3611                 case WildcardAtStart:
3612                     return endsWith( adjustCase( str ), m_pattern );
3613                 case WildcardAtEnd:
3614                     return startsWith( adjustCase( str ), m_pattern );
3615                 case WildcardAtBothEnds:
3616                     return contains( adjustCase( str ), m_pattern );
3617             }
3618 
3619 #ifdef __clang__
3620 #pragma clang diagnostic push
3621 #pragma clang diagnostic ignored "-Wunreachable-code"
3622 #endif
3623             throw std::logic_error( "Unknown enum" );
3624 #ifdef __clang__
3625 #pragma clang diagnostic pop
3626 #endif
3627         }
3628     private:
adjustCase(std::string const & str) const3629         std::string adjustCase( std::string const& str ) const {
3630             return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
3631         }
3632         CaseSensitive::Choice m_caseSensitivity;
3633         WildcardPosition m_wildcard;
3634         std::string m_pattern;
3635     };
3636 }
3637 
3638 #include <string>
3639 #include <vector>
3640 
3641 namespace Catch {
3642 
3643     class TestSpec {
3644         struct Pattern : SharedImpl<> {
3645             virtual ~Pattern();
3646             virtual bool matches( TestCaseInfo const& testCase ) const = 0;
3647         };
3648         class NamePattern : public Pattern {
3649         public:
NamePattern(std::string const & name)3650             NamePattern( std::string const& name )
3651             : m_wildcardPattern( toLower( name ), CaseSensitive::No )
3652             {}
3653             virtual ~NamePattern();
matches(TestCaseInfo const & testCase) const3654             virtual bool matches( TestCaseInfo const& testCase ) const {
3655                 return m_wildcardPattern.matches( toLower( testCase.name ) );
3656             }
3657         private:
3658             WildcardPattern m_wildcardPattern;
3659         };
3660 
3661         class TagPattern : public Pattern {
3662         public:
TagPattern(std::string const & tag)3663             TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
3664             virtual ~TagPattern();
matches(TestCaseInfo const & testCase) const3665             virtual bool matches( TestCaseInfo const& testCase ) const {
3666                 return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
3667             }
3668         private:
3669             std::string m_tag;
3670         };
3671 
3672         class ExcludedPattern : public Pattern {
3673         public:
ExcludedPattern(Ptr<Pattern> const & underlyingPattern)3674             ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
3675             virtual ~ExcludedPattern();
matches(TestCaseInfo const & testCase) const3676             virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
3677         private:
3678             Ptr<Pattern> m_underlyingPattern;
3679         };
3680 
3681         struct Filter {
3682             std::vector<Ptr<Pattern> > m_patterns;
3683 
matchesCatch::TestSpec::Filter3684             bool matches( TestCaseInfo const& testCase ) const {
3685                 // All patterns in a filter must match for the filter to be a match
3686                 for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) {
3687                     if( !(*it)->matches( testCase ) )
3688                         return false;
3689                 }
3690                 return true;
3691             }
3692         };
3693 
3694     public:
hasFilters() const3695         bool hasFilters() const {
3696             return !m_filters.empty();
3697         }
matches(TestCaseInfo const & testCase) const3698         bool matches( TestCaseInfo const& testCase ) const {
3699             // A TestSpec matches if any filter matches
3700             for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
3701                 if( it->matches( testCase ) )
3702                     return true;
3703             return false;
3704         }
3705 
3706     private:
3707         std::vector<Filter> m_filters;
3708 
3709         friend class TestSpecParser;
3710     };
3711 }
3712 
3713 #ifdef __clang__
3714 #pragma clang diagnostic pop
3715 #endif
3716 
3717 namespace Catch {
3718 
3719     class TestSpecParser {
3720         enum Mode{ None, Name, QuotedName, Tag, EscapedName };
3721         Mode m_mode;
3722         bool m_exclusion;
3723         std::size_t m_start, m_pos;
3724         std::string m_arg;
3725         std::vector<std::size_t> m_escapeChars;
3726         TestSpec::Filter m_currentFilter;
3727         TestSpec m_testSpec;
3728         ITagAliasRegistry const* m_tagAliases;
3729 
3730     public:
TestSpecParser(ITagAliasRegistry const & tagAliases)3731         TestSpecParser( ITagAliasRegistry const& tagAliases ) :m_mode(None), m_exclusion(false), m_start(0), m_pos(0), m_tagAliases( &tagAliases ) {}
3732 
parse(std::string const & arg)3733         TestSpecParser& parse( std::string const& arg ) {
3734             m_mode = None;
3735             m_exclusion = false;
3736             m_start = std::string::npos;
3737             m_arg = m_tagAliases->expandAliases( arg );
3738             m_escapeChars.clear();
3739             for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
3740                 visitChar( m_arg[m_pos] );
3741             if( m_mode == Name )
3742                 addPattern<TestSpec::NamePattern>();
3743             return *this;
3744         }
testSpec()3745         TestSpec testSpec() {
3746             addFilter();
3747             return m_testSpec;
3748         }
3749     private:
visitChar(char c)3750         void visitChar( char c ) {
3751             if( m_mode == None ) {
3752                 switch( c ) {
3753                 case ' ': return;
3754                 case '~': m_exclusion = true; return;
3755                 case '[': return startNewMode( Tag, ++m_pos );
3756                 case '"': return startNewMode( QuotedName, ++m_pos );
3757                 case '\\': return escape();
3758                 default: startNewMode( Name, m_pos ); break;
3759                 }
3760             }
3761             if( m_mode == Name ) {
3762                 if( c == ',' ) {
3763                     addPattern<TestSpec::NamePattern>();
3764                     addFilter();
3765                 }
3766                 else if( c == '[' ) {
3767                     if( subString() == "exclude:" )
3768                         m_exclusion = true;
3769                     else
3770                         addPattern<TestSpec::NamePattern>();
3771                     startNewMode( Tag, ++m_pos );
3772                 }
3773                 else if( c == '\\' )
3774                     escape();
3775             }
3776             else if( m_mode == EscapedName )
3777                 m_mode = Name;
3778             else if( m_mode == QuotedName && c == '"' )
3779                 addPattern<TestSpec::NamePattern>();
3780             else if( m_mode == Tag && c == ']' )
3781                 addPattern<TestSpec::TagPattern>();
3782         }
startNewMode(Mode mode,std::size_t start)3783         void startNewMode( Mode mode, std::size_t start ) {
3784             m_mode = mode;
3785             m_start = start;
3786         }
escape()3787         void escape() {
3788             if( m_mode == None )
3789                 m_start = m_pos;
3790             m_mode = EscapedName;
3791             m_escapeChars.push_back( m_pos );
3792         }
subString() const3793         std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
3794         template<typename T>
addPattern()3795         void addPattern() {
3796             std::string token = subString();
3797             for( size_t i = 0; i < m_escapeChars.size(); ++i )
3798                 token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
3799             m_escapeChars.clear();
3800             if( startsWith( token, "exclude:" ) ) {
3801                 m_exclusion = true;
3802                 token = token.substr( 8 );
3803             }
3804             if( !token.empty() ) {
3805                 Ptr<TestSpec::Pattern> pattern = new T( token );
3806                 if( m_exclusion )
3807                     pattern = new TestSpec::ExcludedPattern( pattern );
3808                 m_currentFilter.m_patterns.push_back( pattern );
3809             }
3810             m_exclusion = false;
3811             m_mode = None;
3812         }
addFilter()3813         void addFilter() {
3814             if( !m_currentFilter.m_patterns.empty() ) {
3815                 m_testSpec.m_filters.push_back( m_currentFilter );
3816                 m_currentFilter = TestSpec::Filter();
3817             }
3818         }
3819     };
parseTestSpec(std::string const & arg)3820     inline TestSpec parseTestSpec( std::string const& arg ) {
3821         return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
3822     }
3823 
3824 } // namespace Catch
3825 
3826 #ifdef __clang__
3827 #pragma clang diagnostic pop
3828 #endif
3829 
3830 // #included from: catch_interfaces_config.h
3831 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
3832 
3833 #include <iosfwd>
3834 #include <string>
3835 #include <vector>
3836 
3837 namespace Catch {
3838 
3839     struct Verbosity { enum Level {
3840         NoOutput = 0,
3841         Quiet,
3842         Normal
3843     }; };
3844 
3845     struct WarnAbout { enum What {
3846         Nothing = 0x00,
3847         NoAssertions = 0x01
3848     }; };
3849 
3850     struct ShowDurations { enum OrNot {
3851         DefaultForReporter,
3852         Always,
3853         Never
3854     }; };
3855     struct RunTests { enum InWhatOrder {
3856         InDeclarationOrder,
3857         InLexicographicalOrder,
3858         InRandomOrder
3859     }; };
3860     struct UseColour { enum YesOrNo {
3861         Auto,
3862         Yes,
3863         No
3864     }; };
3865     struct WaitForKeypress { enum When {
3866         Never,
3867         BeforeStart = 1,
3868         BeforeExit = 2,
3869         BeforeStartAndExit = BeforeStart | BeforeExit
3870     }; };
3871 
3872     class TestSpec;
3873 
3874     struct IConfig : IShared {
3875 
3876         virtual ~IConfig();
3877 
3878         virtual bool allowThrows() const = 0;
3879         virtual std::ostream& stream() const = 0;
3880         virtual std::string name() const = 0;
3881         virtual bool includeSuccessfulResults() const = 0;
3882         virtual bool shouldDebugBreak() const = 0;
3883         virtual bool warnAboutMissingAssertions() const = 0;
3884         virtual int abortAfter() const = 0;
3885         virtual bool showInvisibles() const = 0;
3886         virtual ShowDurations::OrNot showDurations() const = 0;
3887         virtual TestSpec const& testSpec() const = 0;
3888         virtual RunTests::InWhatOrder runOrder() const = 0;
3889         virtual unsigned int rngSeed() const = 0;
3890         virtual UseColour::YesOrNo useColour() const = 0;
3891         virtual std::vector<std::string> const& getSectionsToRun() const = 0;
3892 
3893     };
3894 }
3895 
3896 // #included from: catch_stream.h
3897 #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
3898 
3899 // #included from: catch_streambuf.h
3900 #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
3901 
3902 #include <streambuf>
3903 
3904 namespace Catch {
3905 
3906     class StreamBufBase : public std::streambuf {
3907     public:
3908         virtual ~StreamBufBase() CATCH_NOEXCEPT;
3909     };
3910 }
3911 
3912 #include <streambuf>
3913 #include <ostream>
3914 #include <fstream>
3915 #include <memory>
3916 
3917 namespace Catch {
3918 
3919     std::ostream& cout();
3920     std::ostream& cerr();
3921     std::ostream& clog();
3922 
3923     struct IStream {
3924         virtual ~IStream() CATCH_NOEXCEPT;
3925         virtual std::ostream& stream() const = 0;
3926     };
3927 
3928     class FileStream : public IStream {
3929         mutable std::ofstream m_ofs;
3930     public:
3931         FileStream( std::string const& filename );
3932         virtual ~FileStream() CATCH_NOEXCEPT;
3933     public: // IStream
3934         virtual std::ostream& stream() const CATCH_OVERRIDE;
3935     };
3936 
3937     class CoutStream : public IStream {
3938         mutable std::ostream m_os;
3939     public:
3940         CoutStream();
3941         virtual ~CoutStream() CATCH_NOEXCEPT;
3942 
3943     public: // IStream
3944         virtual std::ostream& stream() const CATCH_OVERRIDE;
3945     };
3946 
3947     class DebugOutStream : public IStream {
3948         CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf;
3949         mutable std::ostream m_os;
3950     public:
3951         DebugOutStream();
3952         virtual ~DebugOutStream() CATCH_NOEXCEPT;
3953 
3954     public: // IStream
3955         virtual std::ostream& stream() const CATCH_OVERRIDE;
3956     };
3957 }
3958 
3959 #include <memory>
3960 #include <vector>
3961 #include <string>
3962 #include <stdexcept>
3963 
3964 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
3965 #define CATCH_CONFIG_CONSOLE_WIDTH 80
3966 #endif
3967 
3968 namespace Catch {
3969 
3970     struct ConfigData {
3971 
ConfigDataCatch::ConfigData3972         ConfigData()
3973         :   listTests( false ),
3974             listTags( false ),
3975             listReporters( false ),
3976             listTestNamesOnly( false ),
3977             listExtraInfo( false ),
3978             showSuccessfulTests( false ),
3979             shouldDebugBreak( false ),
3980             noThrow( false ),
3981             showHelp( false ),
3982             showInvisibles( false ),
3983             filenamesAsTags( false ),
3984             libIdentify( false ),
3985             abortAfter( -1 ),
3986             rngSeed( 0 ),
3987             verbosity( Verbosity::Normal ),
3988             warnings( WarnAbout::Nothing ),
3989             showDurations( ShowDurations::DefaultForReporter ),
3990             runOrder( RunTests::InDeclarationOrder ),
3991             useColour( UseColour::Auto ),
3992             waitForKeypress( WaitForKeypress::Never )
3993         {}
3994 
3995         bool listTests;
3996         bool listTags;
3997         bool listReporters;
3998         bool listTestNamesOnly;
3999         bool listExtraInfo;
4000 
4001         bool showSuccessfulTests;
4002         bool shouldDebugBreak;
4003         bool noThrow;
4004         bool showHelp;
4005         bool showInvisibles;
4006         bool filenamesAsTags;
4007         bool libIdentify;
4008 
4009         int abortAfter;
4010         unsigned int rngSeed;
4011 
4012         Verbosity::Level verbosity;
4013         WarnAbout::What warnings;
4014         ShowDurations::OrNot showDurations;
4015         RunTests::InWhatOrder runOrder;
4016         UseColour::YesOrNo useColour;
4017         WaitForKeypress::When waitForKeypress;
4018 
4019         std::string outputFilename;
4020         std::string name;
4021         std::string processName;
4022 
4023         std::vector<std::string> reporterNames;
4024         std::vector<std::string> testsOrTags;
4025         std::vector<std::string> sectionsToRun;
4026     };
4027 
4028     class Config : public SharedImpl<IConfig> {
4029     private:
4030         Config( Config const& other );
4031         Config& operator = ( Config const& other );
4032         virtual void dummy();
4033     public:
4034 
Config()4035         Config()
4036         {}
4037 
Config(ConfigData const & data)4038         Config( ConfigData const& data )
4039         :   m_data( data ),
4040             m_stream( openStream() )
4041         {
4042             if( !data.testsOrTags.empty() ) {
4043                 TestSpecParser parser( ITagAliasRegistry::get() );
4044                 for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
4045                     parser.parse( data.testsOrTags[i] );
4046                 m_testSpec = parser.testSpec();
4047             }
4048         }
4049 
~Config()4050         virtual ~Config() {}
4051 
getFilename() const4052         std::string const& getFilename() const {
4053             return m_data.outputFilename ;
4054         }
4055 
listTests() const4056         bool listTests() const { return m_data.listTests; }
listTestNamesOnly() const4057         bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
listTags() const4058         bool listTags() const { return m_data.listTags; }
listReporters() const4059         bool listReporters() const { return m_data.listReporters; }
listExtraInfo() const4060         bool listExtraInfo() const { return m_data.listExtraInfo; }
4061 
getProcessName() const4062         std::string getProcessName() const { return m_data.processName; }
4063 
getReporterNames() const4064         std::vector<std::string> const& getReporterNames() const { return m_data.reporterNames; }
getSectionsToRun() const4065         std::vector<std::string> const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; }
4066 
testSpec() const4067         virtual TestSpec const& testSpec() const CATCH_OVERRIDE { return m_testSpec; }
4068 
showHelp() const4069         bool showHelp() const { return m_data.showHelp; }
4070 
4071         // IConfig interface
allowThrows() const4072         virtual bool allowThrows() const CATCH_OVERRIDE                 { return !m_data.noThrow; }
stream() const4073         virtual std::ostream& stream() const CATCH_OVERRIDE             { return m_stream->stream(); }
name() const4074         virtual std::string name() const CATCH_OVERRIDE                 { return m_data.name.empty() ? m_data.processName : m_data.name; }
includeSuccessfulResults() const4075         virtual bool includeSuccessfulResults() const CATCH_OVERRIDE    { return m_data.showSuccessfulTests; }
warnAboutMissingAssertions() const4076         virtual bool warnAboutMissingAssertions() const CATCH_OVERRIDE  { return m_data.warnings & WarnAbout::NoAssertions; }
showDurations() const4077         virtual ShowDurations::OrNot showDurations() const CATCH_OVERRIDE { return m_data.showDurations; }
runOrder() const4078         virtual RunTests::InWhatOrder runOrder() const CATCH_OVERRIDE   { return m_data.runOrder; }
rngSeed() const4079         virtual unsigned int rngSeed() const CATCH_OVERRIDE             { return m_data.rngSeed; }
useColour() const4080         virtual UseColour::YesOrNo useColour() const CATCH_OVERRIDE     { return m_data.useColour; }
shouldDebugBreak() const4081         virtual bool shouldDebugBreak() const CATCH_OVERRIDE { return m_data.shouldDebugBreak; }
abortAfter() const4082         virtual int abortAfter() const CATCH_OVERRIDE { return m_data.abortAfter; }
showInvisibles() const4083         virtual bool showInvisibles() const CATCH_OVERRIDE { return m_data.showInvisibles; }
4084 
4085     private:
4086 
openStream()4087         IStream const* openStream() {
4088             if( m_data.outputFilename.empty() )
4089                 return new CoutStream();
4090             else if( m_data.outputFilename[0] == '%' ) {
4091                 if( m_data.outputFilename == "%debug" )
4092                     return new DebugOutStream();
4093                 else
4094                     throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
4095             }
4096             else
4097                 return new FileStream( m_data.outputFilename );
4098         }
4099         ConfigData m_data;
4100 
4101         CATCH_AUTO_PTR( IStream const ) m_stream;
4102         TestSpec m_testSpec;
4103     };
4104 
4105 } // end namespace Catch
4106 
4107 // #included from: catch_clara.h
4108 #define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
4109 
4110 // Use Catch's value for console width (store Clara's off to the side, if present)
4111 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
4112 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
4113 #undef CLARA_CONFIG_CONSOLE_WIDTH
4114 #endif
4115 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
4116 
4117 // Declare Clara inside the Catch namespace
4118 #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
4119 // #included from: ../external/clara.h
4120 
4121 // Version 0.0.2.4
4122 
4123 // Only use header guard if we are not using an outer namespace
4124 #if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
4125 
4126 #ifndef STITCH_CLARA_OPEN_NAMESPACE
4127 #define TWOBLUECUBES_CLARA_H_INCLUDED
4128 #define STITCH_CLARA_OPEN_NAMESPACE
4129 #define STITCH_CLARA_CLOSE_NAMESPACE
4130 #else
4131 #define STITCH_CLARA_CLOSE_NAMESPACE }
4132 #endif
4133 
4134 #define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
4135 
4136 // ----------- #included from tbc_text_format.h -----------
4137 
4138 // Only use header guard if we are not using an outer namespace
4139 #if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
4140 #ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4141 #define TBC_TEXT_FORMAT_H_INCLUDED
4142 #endif
4143 
4144 #include <string>
4145 #include <vector>
4146 #include <sstream>
4147 #include <algorithm>
4148 #include <cctype>
4149 
4150 // Use optional outer namespace
4151 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4152 namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
4153 #endif
4154 
4155 namespace Tbc {
4156 
4157 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
4158     const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
4159 #else
4160     const unsigned int consoleWidth = 80;
4161 #endif
4162 
4163     struct TextAttributes {
TextAttributesSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4164         TextAttributes()
4165         :   initialIndent( std::string::npos ),
4166             indent( 0 ),
4167             width( consoleWidth-1 ),
4168             tabChar( '\t' )
4169         {}
4170 
setInitialIndentSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4171         TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
setIndentSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4172         TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
setWidthSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4173         TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
setTabCharSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4174         TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }
4175 
4176         std::size_t initialIndent;  // indent of first line, or npos
4177         std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
4178         std::size_t width;          // maximum width of text, including indent. Longer text will wrap
4179         char tabChar;               // If this char is seen the indent is changed to current pos
4180     };
4181 
4182     class Text {
4183     public:
Text(std::string const & _str,TextAttributes const & _attr=TextAttributes ())4184         Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
4185         : attr( _attr )
4186         {
4187             std::string wrappableChars = " [({.,/|\\-";
4188             std::size_t indent = _attr.initialIndent != std::string::npos
4189                 ? _attr.initialIndent
4190                 : _attr.indent;
4191             std::string remainder = _str;
4192 
4193             while( !remainder.empty() ) {
4194                 if( lines.size() >= 1000 ) {
4195                     lines.push_back( "... message truncated due to excessive size" );
4196                     return;
4197                 }
4198                 std::size_t tabPos = std::string::npos;
4199                 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
4200                 std::size_t pos = remainder.find_first_of( '\n' );
4201                 if( pos <= width ) {
4202                     width = pos;
4203                 }
4204                 pos = remainder.find_last_of( _attr.tabChar, width );
4205                 if( pos != std::string::npos ) {
4206                     tabPos = pos;
4207                     if( remainder[width] == '\n' )
4208                         width--;
4209                     remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
4210                 }
4211 
4212                 if( width == remainder.size() ) {
4213                     spliceLine( indent, remainder, width );
4214                 }
4215                 else if( remainder[width] == '\n' ) {
4216                     spliceLine( indent, remainder, width );
4217                     if( width <= 1 || remainder.size() != 1 )
4218                         remainder = remainder.substr( 1 );
4219                     indent = _attr.indent;
4220                 }
4221                 else {
4222                     pos = remainder.find_last_of( wrappableChars, width );
4223                     if( pos != std::string::npos && pos > 0 ) {
4224                         spliceLine( indent, remainder, pos );
4225                         if( remainder[0] == ' ' )
4226                             remainder = remainder.substr( 1 );
4227                     }
4228                     else {
4229                         spliceLine( indent, remainder, width-1 );
4230                         lines.back() += "-";
4231                     }
4232                     if( lines.size() == 1 )
4233                         indent = _attr.indent;
4234                     if( tabPos != std::string::npos )
4235                         indent += tabPos;
4236                 }
4237             }
4238         }
4239 
spliceLine(std::size_t _indent,std::string & _remainder,std::size_t _pos)4240         void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
4241             lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
4242             _remainder = _remainder.substr( _pos );
4243         }
4244 
4245         typedef std::vector<std::string>::const_iterator const_iterator;
4246 
begin() const4247         const_iterator begin() const { return lines.begin(); }
end() const4248         const_iterator end() const { return lines.end(); }
last() const4249         std::string const& last() const { return lines.back(); }
size() const4250         std::size_t size() const { return lines.size(); }
operator [](std::size_t _index) const4251         std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
toString() const4252         std::string toString() const {
4253             std::ostringstream oss;
4254             oss << *this;
4255             return oss.str();
4256         }
4257 
operator <<(std::ostream & _stream,Text const & _text)4258         friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
4259             for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
4260                 it != itEnd; ++it ) {
4261                 if( it != _text.begin() )
4262                     _stream << "\n";
4263                 _stream << *it;
4264             }
4265             return _stream;
4266         }
4267 
4268     private:
4269         std::string str;
4270         TextAttributes attr;
4271         std::vector<std::string> lines;
4272     };
4273 
4274 } // end namespace Tbc
4275 
4276 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4277 } // end outer namespace
4278 #endif
4279 
4280 #endif // TBC_TEXT_FORMAT_H_INCLUDED
4281 
4282 // ----------- end of #include from tbc_text_format.h -----------
4283 // ........... back in clara.h
4284 
4285 #undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
4286 
4287 // ----------- #included from clara_compilers.h -----------
4288 
4289 #ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
4290 #define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
4291 
4292 // Detect a number of compiler features - mostly C++11/14 conformance - by compiler
4293 // The following features are defined:
4294 //
4295 // CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported?
4296 // CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
4297 // CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
4298 // CLARA_CONFIG_CPP11_OVERRIDE : is override supported?
4299 // CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
4300 
4301 // CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
4302 
4303 // CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported?
4304 
4305 // In general each macro has a _NO_<feature name> form
4306 // (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
4307 // Many features, at point of detection, define an _INTERNAL_ macro, so they
4308 // can be combined, en-mass, with the _NO_ forms later.
4309 
4310 // All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11
4311 
4312 #ifdef __clang__
4313 
4314 #if __has_feature(cxx_nullptr)
4315 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
4316 #endif
4317 
4318 #if __has_feature(cxx_noexcept)
4319 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
4320 #endif
4321 
4322 #endif // __clang__
4323 
4324 ////////////////////////////////////////////////////////////////////////////////
4325 // GCC
4326 #ifdef __GNUC__
4327 
4328 #if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
4329 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
4330 #endif
4331 
4332 // - otherwise more recent versions define __cplusplus >= 201103L
4333 // and will get picked up below
4334 
4335 #endif // __GNUC__
4336 
4337 ////////////////////////////////////////////////////////////////////////////////
4338 // Visual C++
4339 #ifdef _MSC_VER
4340 
4341 #if (_MSC_VER >= 1600)
4342 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
4343 #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
4344 #endif
4345 
4346 #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
4347 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
4348 #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
4349 #endif
4350 
4351 #endif // _MSC_VER
4352 
4353 ////////////////////////////////////////////////////////////////////////////////
4354 // C++ language feature support
4355 
4356 // catch all support for C++11
4357 #if defined(__cplusplus) && __cplusplus >= 201103L
4358 
4359 #define CLARA_CPP11_OR_GREATER
4360 
4361 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)
4362 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
4363 #endif
4364 
4365 #ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
4366 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
4367 #endif
4368 
4369 #ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
4370 #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
4371 #endif
4372 
4373 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)
4374 #define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE
4375 #endif
4376 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
4377 #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
4378 #endif
4379 
4380 #endif // __cplusplus >= 201103L
4381 
4382 // Now set the actual defines based on the above + anything the user has configured
4383 #if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)
4384 #define CLARA_CONFIG_CPP11_NULLPTR
4385 #endif
4386 #if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)
4387 #define CLARA_CONFIG_CPP11_NOEXCEPT
4388 #endif
4389 #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)
4390 #define CLARA_CONFIG_CPP11_GENERATED_METHODS
4391 #endif
4392 #if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)
4393 #define CLARA_CONFIG_CPP11_OVERRIDE
4394 #endif
4395 #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)
4396 #define CLARA_CONFIG_CPP11_UNIQUE_PTR
4397 #endif
4398 
4399 // noexcept support:
4400 #if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)
4401 #define CLARA_NOEXCEPT noexcept
4402 #  define CLARA_NOEXCEPT_IS(x) noexcept(x)
4403 #else
4404 #define CLARA_NOEXCEPT throw()
4405 #  define CLARA_NOEXCEPT_IS(x)
4406 #endif
4407 
4408 // nullptr support
4409 #ifdef CLARA_CONFIG_CPP11_NULLPTR
4410 #define CLARA_NULL nullptr
4411 #else
4412 #define CLARA_NULL NULL
4413 #endif
4414 
4415 // override support
4416 #ifdef CLARA_CONFIG_CPP11_OVERRIDE
4417 #define CLARA_OVERRIDE override
4418 #else
4419 #define CLARA_OVERRIDE
4420 #endif
4421 
4422 // unique_ptr support
4423 #ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR
4424 #   define CLARA_AUTO_PTR( T ) std::unique_ptr<T>
4425 #else
4426 #   define CLARA_AUTO_PTR( T ) std::auto_ptr<T>
4427 #endif
4428 
4429 #endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
4430 
4431 // ----------- end of #include from clara_compilers.h -----------
4432 // ........... back in clara.h
4433 
4434 #include <map>
4435 #include <stdexcept>
4436 #include <memory>
4437 
4438 #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
4439 #define CLARA_PLATFORM_WINDOWS
4440 #endif
4441 
4442 // Use optional outer namespace
4443 #ifdef STITCH_CLARA_OPEN_NAMESPACE
4444 STITCH_CLARA_OPEN_NAMESPACE
4445 #endif
4446 
4447 namespace Clara {
4448 
4449     struct UnpositionalTag {};
4450 
4451     extern UnpositionalTag _;
4452 
4453 #ifdef CLARA_CONFIG_MAIN
4454     UnpositionalTag _;
4455 #endif
4456 
4457     namespace Detail {
4458 
4459 #ifdef CLARA_CONSOLE_WIDTH
4460     const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
4461 #else
4462     const unsigned int consoleWidth = 80;
4463 #endif
4464 
4465         using namespace Tbc;
4466 
startsWith(std::string const & str,std::string const & prefix)4467         inline bool startsWith( std::string const& str, std::string const& prefix ) {
4468             return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
4469         }
4470 
4471         template<typename T> struct RemoveConstRef{ typedef T type; };
4472         template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
4473         template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
4474         template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
4475 
4476         template<typename T>    struct IsBool       { static const bool value = false; };
4477         template<>              struct IsBool<bool> { static const bool value = true; };
4478 
4479         template<typename T>
convertInto(std::string const & _source,T & _dest)4480         void convertInto( std::string const& _source, T& _dest ) {
4481             std::stringstream ss;
4482             ss << _source;
4483             ss >> _dest;
4484             if( ss.fail() )
4485                 throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
4486         }
convertInto(std::string const & _source,std::string & _dest)4487         inline void convertInto( std::string const& _source, std::string& _dest ) {
4488             _dest = _source;
4489         }
toLowerCh(char c)4490         char toLowerCh(char c) {
4491             return static_cast<char>( std::tolower( c ) );
4492         }
convertInto(std::string const & _source,bool & _dest)4493         inline void convertInto( std::string const& _source, bool& _dest ) {
4494             std::string sourceLC = _source;
4495             std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh );
4496             if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
4497                 _dest = true;
4498             else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
4499                 _dest = false;
4500             else
4501                 throw std::runtime_error( "Expected a boolean value but did not recognise:\n  '" + _source + "'" );
4502         }
4503 
4504         template<typename ConfigT>
4505         struct IArgFunction {
~IArgFunctionClara::Detail::IArgFunction4506             virtual ~IArgFunction() {}
4507 #ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS
4508             IArgFunction()                      = default;
4509             IArgFunction( IArgFunction const& ) = default;
4510 #endif
4511             virtual void set( ConfigT& config, std::string const& value ) const = 0;
4512             virtual bool takesArg() const = 0;
4513             virtual IArgFunction* clone() const = 0;
4514         };
4515 
4516         template<typename ConfigT>
4517         class BoundArgFunction {
4518         public:
BoundArgFunction()4519             BoundArgFunction() : functionObj( CLARA_NULL ) {}
BoundArgFunction(IArgFunction<ConfigT> * _functionObj)4520             BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
BoundArgFunction(BoundArgFunction const & other)4521             BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
operator =(BoundArgFunction const & other)4522             BoundArgFunction& operator = ( BoundArgFunction const& other ) {
4523                 IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
4524                 delete functionObj;
4525                 functionObj = newFunctionObj;
4526                 return *this;
4527             }
~BoundArgFunction()4528             ~BoundArgFunction() { delete functionObj; }
4529 
set(ConfigT & config,std::string const & value) const4530             void set( ConfigT& config, std::string const& value ) const {
4531                 functionObj->set( config, value );
4532             }
takesArg() const4533             bool takesArg() const { return functionObj->takesArg(); }
4534 
isSet() const4535             bool isSet() const {
4536                 return functionObj != CLARA_NULL;
4537             }
4538         private:
4539             IArgFunction<ConfigT>* functionObj;
4540         };
4541 
4542         template<typename C>
4543         struct NullBinder : IArgFunction<C>{
setClara::Detail::NullBinder4544             virtual void set( C&, std::string const& ) const {}
takesArgClara::Detail::NullBinder4545             virtual bool takesArg() const { return true; }
cloneClara::Detail::NullBinder4546             virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
4547         };
4548 
4549         template<typename C, typename M>
4550         struct BoundDataMember : IArgFunction<C>{
BoundDataMemberClara::Detail::BoundDataMember4551             BoundDataMember( M C::* _member ) : member( _member ) {}
setClara::Detail::BoundDataMember4552             virtual void set( C& p, std::string const& stringValue ) const {
4553                 convertInto( stringValue, p.*member );
4554             }
takesArgClara::Detail::BoundDataMember4555             virtual bool takesArg() const { return !IsBool<M>::value; }
cloneClara::Detail::BoundDataMember4556             virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
4557             M C::* member;
4558         };
4559         template<typename C, typename M>
4560         struct BoundUnaryMethod : IArgFunction<C>{
BoundUnaryMethodClara::Detail::BoundUnaryMethod4561             BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
setClara::Detail::BoundUnaryMethod4562             virtual void set( C& p, std::string const& stringValue ) const {
4563                 typename RemoveConstRef<M>::type value;
4564                 convertInto( stringValue, value );
4565                 (p.*member)( value );
4566             }
takesArgClara::Detail::BoundUnaryMethod4567             virtual bool takesArg() const { return !IsBool<M>::value; }
cloneClara::Detail::BoundUnaryMethod4568             virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
4569             void (C::*member)( M );
4570         };
4571         template<typename C>
4572         struct BoundNullaryMethod : IArgFunction<C>{
BoundNullaryMethodClara::Detail::BoundNullaryMethod4573             BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
setClara::Detail::BoundNullaryMethod4574             virtual void set( C& p, std::string const& stringValue ) const {
4575                 bool value;
4576                 convertInto( stringValue, value );
4577                 if( value )
4578                     (p.*member)();
4579             }
takesArgClara::Detail::BoundNullaryMethod4580             virtual bool takesArg() const { return false; }
cloneClara::Detail::BoundNullaryMethod4581             virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
4582             void (C::*member)();
4583         };
4584 
4585         template<typename C>
4586         struct BoundUnaryFunction : IArgFunction<C>{
BoundUnaryFunctionClara::Detail::BoundUnaryFunction4587             BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
setClara::Detail::BoundUnaryFunction4588             virtual void set( C& obj, std::string const& stringValue ) const {
4589                 bool value;
4590                 convertInto( stringValue, value );
4591                 if( value )
4592                     function( obj );
4593             }
takesArgClara::Detail::BoundUnaryFunction4594             virtual bool takesArg() const { return false; }
cloneClara::Detail::BoundUnaryFunction4595             virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
4596             void (*function)( C& );
4597         };
4598 
4599         template<typename C, typename T>
4600         struct BoundBinaryFunction : IArgFunction<C>{
BoundBinaryFunctionClara::Detail::BoundBinaryFunction4601             BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
setClara::Detail::BoundBinaryFunction4602             virtual void set( C& obj, std::string const& stringValue ) const {
4603                 typename RemoveConstRef<T>::type value;
4604                 convertInto( stringValue, value );
4605                 function( obj, value );
4606             }
takesArgClara::Detail::BoundBinaryFunction4607             virtual bool takesArg() const { return !IsBool<T>::value; }
cloneClara::Detail::BoundBinaryFunction4608             virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
4609             void (*function)( C&, T );
4610         };
4611 
4612     } // namespace Detail
4613 
argsToVector(int argc,char const * const * const argv)4614     inline std::vector<std::string> argsToVector( int argc, char const* const* const argv ) {
4615         std::vector<std::string> args( static_cast<std::size_t>( argc ) );
4616         for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )
4617             args[i] = argv[i];
4618 
4619         return args;
4620     }
4621 
4622     class Parser {
4623         enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };
4624         Mode mode;
4625         std::size_t from;
4626         bool inQuotes;
4627     public:
4628 
4629         struct Token {
4630             enum Type { Positional, ShortOpt, LongOpt };
TokenClara::Parser::Token4631             Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
4632             Type type;
4633             std::string data;
4634         };
4635 
Parser()4636         Parser() : mode( None ), from( 0 ), inQuotes( false ){}
4637 
parseIntoTokens(std::vector<std::string> const & args,std::vector<Token> & tokens)4638         void parseIntoTokens( std::vector<std::string> const& args, std::vector<Token>& tokens ) {
4639             const std::string doubleDash = "--";
4640             for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )
4641                 parseIntoTokens( args[i], tokens);
4642         }
4643 
parseIntoTokens(std::string const & arg,std::vector<Token> & tokens)4644         void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {
4645             for( std::size_t i = 0; i < arg.size(); ++i ) {
4646                 char c = arg[i];
4647                 if( c == '"' )
4648                     inQuotes = !inQuotes;
4649                 mode = handleMode( i, c, arg, tokens );
4650             }
4651             mode = handleMode( arg.size(), '\0', arg, tokens );
4652         }
handleMode(std::size_t i,char c,std::string const & arg,std::vector<Token> & tokens)4653         Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
4654             switch( mode ) {
4655                 case None: return handleNone( i, c );
4656                 case MaybeShortOpt: return handleMaybeShortOpt( i, c );
4657                 case ShortOpt:
4658                 case LongOpt:
4659                 case SlashOpt: return handleOpt( i, c, arg, tokens );
4660                 case Positional: return handlePositional( i, c, arg, tokens );
4661                 default: throw std::logic_error( "Unknown mode" );
4662             }
4663         }
4664 
handleNone(std::size_t i,char c)4665         Mode handleNone( std::size_t i, char c ) {
4666             if( inQuotes ) {
4667                 from = i;
4668                 return Positional;
4669             }
4670             switch( c ) {
4671                 case '-': return MaybeShortOpt;
4672 #ifdef CLARA_PLATFORM_WINDOWS
4673                 case '/': from = i+1; return SlashOpt;
4674 #endif
4675                 default: from = i; return Positional;
4676             }
4677         }
handleMaybeShortOpt(std::size_t i,char c)4678         Mode handleMaybeShortOpt( std::size_t i, char c ) {
4679             switch( c ) {
4680                 case '-': from = i+1; return LongOpt;
4681                 default: from = i; return ShortOpt;
4682             }
4683         }
4684 
handleOpt(std::size_t i,char c,std::string const & arg,std::vector<Token> & tokens)4685         Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
4686             if( std::string( ":=\0", 3 ).find( c ) == std::string::npos )
4687                 return mode;
4688 
4689             std::string optName = arg.substr( from, i-from );
4690             if( mode == ShortOpt )
4691                 for( std::size_t j = 0; j < optName.size(); ++j )
4692                     tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) );
4693             else if( mode == SlashOpt && optName.size() == 1 )
4694                 tokens.push_back( Token( Token::ShortOpt, optName ) );
4695             else
4696                 tokens.push_back( Token( Token::LongOpt, optName ) );
4697             return None;
4698         }
handlePositional(std::size_t i,char c,std::string const & arg,std::vector<Token> & tokens)4699         Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
4700             if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos )
4701                 return mode;
4702 
4703             std::string data = arg.substr( from, i-from );
4704             tokens.push_back( Token( Token::Positional, data ) );
4705             return None;
4706         }
4707     };
4708 
4709     template<typename ConfigT>
4710     struct CommonArgProperties {
CommonArgPropertiesClara::CommonArgProperties4711         CommonArgProperties() {}
CommonArgPropertiesClara::CommonArgProperties4712         CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
4713 
4714         Detail::BoundArgFunction<ConfigT> boundField;
4715         std::string description;
4716         std::string detail;
4717         std::string placeholder; // Only value if boundField takes an arg
4718 
takesArgClara::CommonArgProperties4719         bool takesArg() const {
4720             return !placeholder.empty();
4721         }
validateClara::CommonArgProperties4722         void validate() const {
4723             if( !boundField.isSet() )
4724                 throw std::logic_error( "option not bound" );
4725         }
4726     };
4727     struct OptionArgProperties {
4728         std::vector<std::string> shortNames;
4729         std::string longName;
4730 
hasShortNameClara::OptionArgProperties4731         bool hasShortName( std::string const& shortName ) const {
4732             return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
4733         }
hasLongNameClara::OptionArgProperties4734         bool hasLongName( std::string const& _longName ) const {
4735             return _longName == longName;
4736         }
4737     };
4738     struct PositionalArgProperties {
PositionalArgPropertiesClara::PositionalArgProperties4739         PositionalArgProperties() : position( -1 ) {}
4740         int position; // -1 means non-positional (floating)
4741 
isFixedPositionalClara::PositionalArgProperties4742         bool isFixedPositional() const {
4743             return position != -1;
4744         }
4745     };
4746 
4747     template<typename ConfigT>
4748     class CommandLine {
4749 
4750         struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
ArgClara::CommandLine::Arg4751             Arg() {}
ArgClara::CommandLine::Arg4752             Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
4753 
4754             using CommonArgProperties<ConfigT>::placeholder; // !TBD
4755 
dbgNameClara::CommandLine::Arg4756             std::string dbgName() const {
4757                 if( !longName.empty() )
4758                     return "--" + longName;
4759                 if( !shortNames.empty() )
4760                     return "-" + shortNames[0];
4761                 return "positional args";
4762             }
commandsClara::CommandLine::Arg4763             std::string commands() const {
4764                 std::ostringstream oss;
4765                 bool first = true;
4766                 std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
4767                 for(; it != itEnd; ++it ) {
4768                     if( first )
4769                         first = false;
4770                     else
4771                         oss << ", ";
4772                     oss << "-" << *it;
4773                 }
4774                 if( !longName.empty() ) {
4775                     if( !first )
4776                         oss << ", ";
4777                     oss << "--" << longName;
4778                 }
4779                 if( !placeholder.empty() )
4780                     oss << " <" << placeholder << ">";
4781                 return oss.str();
4782             }
4783         };
4784 
4785         typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
4786 
addOptName(Arg & arg,std::string const & optName)4787         friend void addOptName( Arg& arg, std::string const& optName )
4788         {
4789             if( optName.empty() )
4790                 return;
4791             if( Detail::startsWith( optName, "--" ) ) {
4792                 if( !arg.longName.empty() )
4793                     throw std::logic_error( "Only one long opt may be specified. '"
4794                         + arg.longName
4795                         + "' already specified, now attempting to add '"
4796                         + optName + "'" );
4797                 arg.longName = optName.substr( 2 );
4798             }
4799             else if( Detail::startsWith( optName, "-" ) )
4800                 arg.shortNames.push_back( optName.substr( 1 ) );
4801             else
4802                 throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
4803         }
setPositionalArg(Arg & arg,int position)4804         friend void setPositionalArg( Arg& arg, int position )
4805         {
4806             arg.position = position;
4807         }
4808 
4809         class ArgBuilder {
4810         public:
ArgBuilder(Arg * arg)4811             ArgBuilder( Arg* arg ) : m_arg( arg ) {}
4812 
4813             // Bind a non-boolean data member (requires placeholder string)
4814             template<typename C, typename M>
bind(M C::* field,std::string const & placeholder)4815             void bind( M C::* field, std::string const& placeholder ) {
4816                 m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
4817                 m_arg->placeholder = placeholder;
4818             }
4819             // Bind a boolean data member (no placeholder required)
4820             template<typename C>
bind(bool C::* field)4821             void bind( bool C::* field ) {
4822                 m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
4823             }
4824 
4825             // Bind a method taking a single, non-boolean argument (requires a placeholder string)
4826             template<typename C, typename M>
bind(void (C::* unaryMethod)(M),std::string const & placeholder)4827             void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
4828                 m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
4829                 m_arg->placeholder = placeholder;
4830             }
4831 
4832             // Bind a method taking a single, boolean argument (no placeholder string required)
4833             template<typename C>
bind(void (C::* unaryMethod)(bool))4834             void bind( void (C::* unaryMethod)( bool ) ) {
4835                 m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
4836             }
4837 
4838             // Bind a method that takes no arguments (will be called if opt is present)
4839             template<typename C>
bind(void (C::* nullaryMethod)())4840             void bind( void (C::* nullaryMethod)() ) {
4841                 m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
4842             }
4843 
4844             // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
4845             template<typename C>
bind(void (* unaryFunction)(C &))4846             void bind( void (* unaryFunction)( C& ) ) {
4847                 m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
4848             }
4849 
4850             // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
4851             template<typename C, typename T>
bind(void (* binaryFunction)(C &,T),std::string const & placeholder)4852             void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
4853                 m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
4854                 m_arg->placeholder = placeholder;
4855             }
4856 
describe(std::string const & description)4857             ArgBuilder& describe( std::string const& description ) {
4858                 m_arg->description = description;
4859                 return *this;
4860             }
detail(std::string const & detail)4861             ArgBuilder& detail( std::string const& detail ) {
4862                 m_arg->detail = detail;
4863                 return *this;
4864             }
4865 
4866         protected:
4867             Arg* m_arg;
4868         };
4869 
4870         class OptBuilder : public ArgBuilder {
4871         public:
OptBuilder(Arg * arg)4872             OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
OptBuilder(OptBuilder & other)4873             OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
4874 
operator [](std::string const & optName)4875             OptBuilder& operator[]( std::string const& optName ) {
4876                 addOptName( *ArgBuilder::m_arg, optName );
4877                 return *this;
4878             }
4879         };
4880 
4881     public:
4882 
CommandLine()4883         CommandLine()
4884         :   m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
4885             m_highestSpecifiedArgPosition( 0 ),
4886             m_throwOnUnrecognisedTokens( false )
4887         {}
CommandLine(CommandLine const & other)4888         CommandLine( CommandLine const& other )
4889         :   m_boundProcessName( other.m_boundProcessName ),
4890             m_options ( other.m_options ),
4891             m_positionalArgs( other.m_positionalArgs ),
4892             m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
4893             m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
4894         {
4895             if( other.m_floatingArg.get() )
4896                 m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
4897         }
4898 
setThrowOnUnrecognisedTokens(bool shouldThrow=true)4899         CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
4900             m_throwOnUnrecognisedTokens = shouldThrow;
4901             return *this;
4902         }
4903 
operator [](std::string const & optName)4904         OptBuilder operator[]( std::string const& optName ) {
4905             m_options.push_back( Arg() );
4906             addOptName( m_options.back(), optName );
4907             OptBuilder builder( &m_options.back() );
4908             return builder;
4909         }
4910 
operator [](int position)4911         ArgBuilder operator[]( int position ) {
4912             m_positionalArgs.insert( std::make_pair( position, Arg() ) );
4913             if( position > m_highestSpecifiedArgPosition )
4914                 m_highestSpecifiedArgPosition = position;
4915             setPositionalArg( m_positionalArgs[position], position );
4916             ArgBuilder builder( &m_positionalArgs[position] );
4917             return builder;
4918         }
4919 
4920         // Invoke this with the _ instance
operator [](UnpositionalTag)4921         ArgBuilder operator[]( UnpositionalTag ) {
4922             if( m_floatingArg.get() )
4923                 throw std::logic_error( "Only one unpositional argument can be added" );
4924             m_floatingArg.reset( new Arg() );
4925             ArgBuilder builder( m_floatingArg.get() );
4926             return builder;
4927         }
4928 
4929         template<typename C, typename M>
bindProcessName(M C::* field)4930         void bindProcessName( M C::* field ) {
4931             m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
4932         }
4933         template<typename C, typename M>
bindProcessName(void (C::* _unaryMethod)(M))4934         void bindProcessName( void (C::*_unaryMethod)( M ) ) {
4935             m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
4936         }
4937 
optUsage(std::ostream & os,std::size_t indent=0,std::size_t width=Detail::consoleWidth) const4938         void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
4939             typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
4940             std::size_t maxWidth = 0;
4941             for( it = itBegin; it != itEnd; ++it )
4942                 maxWidth = (std::max)( maxWidth, it->commands().size() );
4943 
4944             for( it = itBegin; it != itEnd; ++it ) {
4945                 Detail::Text usage( it->commands(), Detail::TextAttributes()
4946                                                         .setWidth( maxWidth+indent )
4947                                                         .setIndent( indent ) );
4948                 Detail::Text desc( it->description, Detail::TextAttributes()
4949                                                         .setWidth( width - maxWidth - 3 ) );
4950 
4951                 for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
4952                     std::string usageCol = i < usage.size() ? usage[i] : "";
4953                     os << usageCol;
4954 
4955                     if( i < desc.size() && !desc[i].empty() )
4956                         os  << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
4957                             << desc[i];
4958                     os << "\n";
4959                 }
4960             }
4961         }
optUsage() const4962         std::string optUsage() const {
4963             std::ostringstream oss;
4964             optUsage( oss );
4965             return oss.str();
4966         }
4967 
argSynopsis(std::ostream & os) const4968         void argSynopsis( std::ostream& os ) const {
4969             for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
4970                 if( i > 1 )
4971                     os << " ";
4972                 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
4973                 if( it != m_positionalArgs.end() )
4974                     os << "<" << it->second.placeholder << ">";
4975                 else if( m_floatingArg.get() )
4976                     os << "<" << m_floatingArg->placeholder << ">";
4977                 else
4978                     throw std::logic_error( "non consecutive positional arguments with no floating args" );
4979             }
4980             // !TBD No indication of mandatory args
4981             if( m_floatingArg.get() ) {
4982                 if( m_highestSpecifiedArgPosition > 1 )
4983                     os << " ";
4984                 os << "[<" << m_floatingArg->placeholder << "> ...]";
4985             }
4986         }
argSynopsis() const4987         std::string argSynopsis() const {
4988             std::ostringstream oss;
4989             argSynopsis( oss );
4990             return oss.str();
4991         }
4992 
usage(std::ostream & os,std::string const & procName) const4993         void usage( std::ostream& os, std::string const& procName ) const {
4994             validate();
4995             os << "usage:\n  " << procName << " ";
4996             argSynopsis( os );
4997             if( !m_options.empty() ) {
4998                 os << " [options]\n\nwhere options are: \n";
4999                 optUsage( os, 2 );
5000             }
5001             os << "\n";
5002         }
usage(std::string const & procName) const5003         std::string usage( std::string const& procName ) const {
5004             std::ostringstream oss;
5005             usage( oss, procName );
5006             return oss.str();
5007         }
5008 
parse(std::vector<std::string> const & args) const5009         ConfigT parse( std::vector<std::string> const& args ) const {
5010             ConfigT config;
5011             parseInto( args, config );
5012             return config;
5013         }
5014 
parseInto(std::vector<std::string> const & args,ConfigT & config) const5015         std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {
5016             std::string processName = args.empty() ? std::string() : args[0];
5017             std::size_t lastSlash = processName.find_last_of( "/\\" );
5018             if( lastSlash != std::string::npos )
5019                 processName = processName.substr( lastSlash+1 );
5020             m_boundProcessName.set( config, processName );
5021             std::vector<Parser::Token> tokens;
5022             Parser parser;
5023             parser.parseIntoTokens( args, tokens );
5024             return populate( tokens, config );
5025         }
5026 
populate(std::vector<Parser::Token> const & tokens,ConfigT & config) const5027         std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
5028             validate();
5029             std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
5030             unusedTokens = populateFixedArgs( unusedTokens, config );
5031             unusedTokens = populateFloatingArgs( unusedTokens, config );
5032             return unusedTokens;
5033         }
5034 
populateOptions(std::vector<Parser::Token> const & tokens,ConfigT & config) const5035         std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
5036             std::vector<Parser::Token> unusedTokens;
5037             std::vector<std::string> errors;
5038             for( std::size_t i = 0; i < tokens.size(); ++i ) {
5039                 Parser::Token const& token = tokens[i];
5040                 typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
5041                 for(; it != itEnd; ++it ) {
5042                     Arg const& arg = *it;
5043 
5044                     try {
5045                         if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
5046                             ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
5047                             if( arg.takesArg() ) {
5048                                 if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
5049                                     errors.push_back( "Expected argument to option: " + token.data );
5050                                 else
5051                                     arg.boundField.set( config, tokens[++i].data );
5052                             }
5053                             else {
5054                                 arg.boundField.set( config, "true" );
5055                             }
5056                             break;
5057                         }
5058                     }
5059                     catch( std::exception& ex ) {
5060                         errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
5061                     }
5062                 }
5063                 if( it == itEnd ) {
5064                     if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
5065                         unusedTokens.push_back( token );
5066                     else if( errors.empty() && m_throwOnUnrecognisedTokens )
5067                         errors.push_back( "unrecognised option: " + token.data );
5068                 }
5069             }
5070             if( !errors.empty() ) {
5071                 std::ostringstream oss;
5072                 for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
5073                         it != itEnd;
5074                         ++it ) {
5075                     if( it != errors.begin() )
5076                         oss << "\n";
5077                     oss << *it;
5078                 }
5079                 throw std::runtime_error( oss.str() );
5080             }
5081             return unusedTokens;
5082         }
populateFixedArgs(std::vector<Parser::Token> const & tokens,ConfigT & config) const5083         std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
5084             std::vector<Parser::Token> unusedTokens;
5085             int position = 1;
5086             for( std::size_t i = 0; i < tokens.size(); ++i ) {
5087                 Parser::Token const& token = tokens[i];
5088                 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
5089                 if( it != m_positionalArgs.end() )
5090                     it->second.boundField.set( config, token.data );
5091                 else
5092                     unusedTokens.push_back( token );
5093                 if( token.type == Parser::Token::Positional )
5094                     position++;
5095             }
5096             return unusedTokens;
5097         }
populateFloatingArgs(std::vector<Parser::Token> const & tokens,ConfigT & config) const5098         std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
5099             if( !m_floatingArg.get() )
5100                 return tokens;
5101             std::vector<Parser::Token> unusedTokens;
5102             for( std::size_t i = 0; i < tokens.size(); ++i ) {
5103                 Parser::Token const& token = tokens[i];
5104                 if( token.type == Parser::Token::Positional )
5105                     m_floatingArg->boundField.set( config, token.data );
5106                 else
5107                     unusedTokens.push_back( token );
5108             }
5109             return unusedTokens;
5110         }
5111 
validate() const5112         void validate() const
5113         {
5114             if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
5115                 throw std::logic_error( "No options or arguments specified" );
5116 
5117             for( typename std::vector<Arg>::const_iterator  it = m_options.begin(),
5118                                                             itEnd = m_options.end();
5119                     it != itEnd; ++it )
5120                 it->validate();
5121         }
5122 
5123     private:
5124         Detail::BoundArgFunction<ConfigT> m_boundProcessName;
5125         std::vector<Arg> m_options;
5126         std::map<int, Arg> m_positionalArgs;
5127         ArgAutoPtr m_floatingArg;
5128         int m_highestSpecifiedArgPosition;
5129         bool m_throwOnUnrecognisedTokens;
5130     };
5131 
5132 } // end namespace Clara
5133 
5134 STITCH_CLARA_CLOSE_NAMESPACE
5135 #undef STITCH_CLARA_OPEN_NAMESPACE
5136 #undef STITCH_CLARA_CLOSE_NAMESPACE
5137 
5138 #endif // TWOBLUECUBES_CLARA_H_INCLUDED
5139 #undef STITCH_CLARA_OPEN_NAMESPACE
5140 
5141 // Restore Clara's value for console width, if present
5142 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
5143 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
5144 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
5145 #endif
5146 
5147 #include <fstream>
5148 #include <ctime>
5149 
5150 namespace Catch {
5151 
abortAfterFirst(ConfigData & config)5152     inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
abortAfterX(ConfigData & config,int x)5153     inline void abortAfterX( ConfigData& config, int x ) {
5154         if( x < 1 )
5155             throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
5156         config.abortAfter = x;
5157     }
addTestOrTags(ConfigData & config,std::string const & _testSpec)5158     inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
addSectionToRun(ConfigData & config,std::string const & sectionName)5159     inline void addSectionToRun( ConfigData& config, std::string const& sectionName ) { config.sectionsToRun.push_back( sectionName ); }
addReporterName(ConfigData & config,std::string const & _reporterName)5160     inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
5161 
addWarning(ConfigData & config,std::string const & _warning)5162     inline void addWarning( ConfigData& config, std::string const& _warning ) {
5163         if( _warning == "NoAssertions" )
5164             config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
5165         else
5166             throw std::runtime_error( "Unrecognised warning: '" + _warning + '\'' );
5167     }
setOrder(ConfigData & config,std::string const & order)5168     inline void setOrder( ConfigData& config, std::string const& order ) {
5169         if( startsWith( "declared", order ) )
5170             config.runOrder = RunTests::InDeclarationOrder;
5171         else if( startsWith( "lexical", order ) )
5172             config.runOrder = RunTests::InLexicographicalOrder;
5173         else if( startsWith( "random", order ) )
5174             config.runOrder = RunTests::InRandomOrder;
5175         else
5176             throw std::runtime_error( "Unrecognised ordering: '" + order + '\'' );
5177     }
setRngSeed(ConfigData & config,std::string const & seed)5178     inline void setRngSeed( ConfigData& config, std::string const& seed ) {
5179         if( seed == "time" ) {
5180             config.rngSeed = static_cast<unsigned int>( std::time(0) );
5181         }
5182         else {
5183             std::stringstream ss;
5184             ss << seed;
5185             ss >> config.rngSeed;
5186             if( ss.fail() )
5187                 throw std::runtime_error( "Argument to --rng-seed should be the word 'time' or a number" );
5188         }
5189     }
setVerbosity(ConfigData & config,int level)5190     inline void setVerbosity( ConfigData& config, int level ) {
5191         // !TBD: accept strings?
5192         config.verbosity = static_cast<Verbosity::Level>( level );
5193     }
setShowDurations(ConfigData & config,bool _showDurations)5194     inline void setShowDurations( ConfigData& config, bool _showDurations ) {
5195         config.showDurations = _showDurations
5196             ? ShowDurations::Always
5197             : ShowDurations::Never;
5198     }
setUseColour(ConfigData & config,std::string const & value)5199     inline void setUseColour( ConfigData& config, std::string const& value ) {
5200         std::string mode = toLower( value );
5201 
5202         if( mode == "yes" )
5203             config.useColour = UseColour::Yes;
5204         else if( mode == "no" )
5205             config.useColour = UseColour::No;
5206         else if( mode == "auto" )
5207             config.useColour = UseColour::Auto;
5208         else
5209             throw std::runtime_error( "colour mode must be one of: auto, yes or no" );
5210     }
setWaitForKeypress(ConfigData & config,std::string const & keypress)5211     inline void setWaitForKeypress( ConfigData& config, std::string const& keypress ) {
5212         std::string keypressLc = toLower( keypress );
5213         if( keypressLc == "start" )
5214             config.waitForKeypress = WaitForKeypress::BeforeStart;
5215         else if( keypressLc == "exit" )
5216             config.waitForKeypress = WaitForKeypress::BeforeExit;
5217         else if( keypressLc == "both" )
5218             config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
5219         else
5220             throw std::runtime_error( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
5221     };
5222 
forceColour(ConfigData & config)5223     inline void forceColour( ConfigData& config ) {
5224         config.useColour = UseColour::Yes;
5225     }
loadTestNamesFromFile(ConfigData & config,std::string const & _filename)5226     inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
5227         std::ifstream f( _filename.c_str() );
5228         if( !f.is_open() )
5229             throw std::domain_error( "Unable to load input file: " + _filename );
5230 
5231         std::string line;
5232         while( std::getline( f, line ) ) {
5233             line = trim(line);
5234             if( !line.empty() && !startsWith( line, '#' ) ) {
5235                 if( !startsWith( line, '"' ) )
5236                     line = '"' + line + '"';
5237                 addTestOrTags( config, line + ',' );
5238             }
5239         }
5240     }
5241 
makeCommandLineParser()5242     inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
5243 
5244         using namespace Clara;
5245         CommandLine<ConfigData> cli;
5246 
5247         cli.bindProcessName( &ConfigData::processName );
5248 
5249         cli["-?"]["-h"]["--help"]
5250             .describe( "display usage information" )
5251             .bind( &ConfigData::showHelp );
5252 
5253         cli["-l"]["--list-tests"]
5254             .describe( "list all/matching test cases" )
5255             .bind( &ConfigData::listTests );
5256 
5257         cli["-t"]["--list-tags"]
5258             .describe( "list all/matching tags" )
5259             .bind( &ConfigData::listTags );
5260 
5261         cli["-s"]["--success"]
5262             .describe( "include successful tests in output" )
5263             .bind( &ConfigData::showSuccessfulTests );
5264 
5265         cli["-b"]["--break"]
5266             .describe( "break into debugger on failure" )
5267             .bind( &ConfigData::shouldDebugBreak );
5268 
5269         cli["-e"]["--nothrow"]
5270             .describe( "skip exception tests" )
5271             .bind( &ConfigData::noThrow );
5272 
5273         cli["-i"]["--invisibles"]
5274             .describe( "show invisibles (tabs, newlines)" )
5275             .bind( &ConfigData::showInvisibles );
5276 
5277         cli["-o"]["--out"]
5278             .describe( "output filename" )
5279             .bind( &ConfigData::outputFilename, "filename" );
5280 
5281         cli["-r"]["--reporter"]
5282 //            .placeholder( "name[:filename]" )
5283             .describe( "reporter to use (defaults to console)" )
5284             .bind( &addReporterName, "name" );
5285 
5286         cli["-n"]["--name"]
5287             .describe( "suite name" )
5288             .bind( &ConfigData::name, "name" );
5289 
5290         cli["-a"]["--abort"]
5291             .describe( "abort at first failure" )
5292             .bind( &abortAfterFirst );
5293 
5294         cli["-x"]["--abortx"]
5295             .describe( "abort after x failures" )
5296             .bind( &abortAfterX, "no. failures" );
5297 
5298         cli["-w"]["--warn"]
5299             .describe( "enable warnings" )
5300             .bind( &addWarning, "warning name" );
5301 
5302 // - needs updating if reinstated
5303 //        cli.into( &setVerbosity )
5304 //            .describe( "level of verbosity (0=no output)" )
5305 //            .shortOpt( "v")
5306 //            .longOpt( "verbosity" )
5307 //            .placeholder( "level" );
5308 
5309         cli[_]
5310             .describe( "which test or tests to use" )
5311             .bind( &addTestOrTags, "test name, pattern or tags" );
5312 
5313         cli["-d"]["--durations"]
5314             .describe( "show test durations" )
5315             .bind( &setShowDurations, "yes|no" );
5316 
5317         cli["-f"]["--input-file"]
5318             .describe( "load test names to run from a file" )
5319             .bind( &loadTestNamesFromFile, "filename" );
5320 
5321         cli["-#"]["--filenames-as-tags"]
5322             .describe( "adds a tag for the filename" )
5323             .bind( &ConfigData::filenamesAsTags );
5324 
5325         cli["-c"]["--section"]
5326                 .describe( "specify section to run" )
5327                 .bind( &addSectionToRun, "section name" );
5328 
5329         // Less common commands which don't have a short form
5330         cli["--list-test-names-only"]
5331             .describe( "list all/matching test cases names only" )
5332             .bind( &ConfigData::listTestNamesOnly );
5333 
5334         cli["--list-extra-info"]
5335             .describe( "list all/matching test cases with more info" )
5336             .bind( &ConfigData::listExtraInfo );
5337 
5338         cli["--list-reporters"]
5339             .describe( "list all reporters" )
5340             .bind( &ConfigData::listReporters );
5341 
5342         cli["--order"]
5343             .describe( "test case order (defaults to decl)" )
5344             .bind( &setOrder, "decl|lex|rand" );
5345 
5346         cli["--rng-seed"]
5347             .describe( "set a specific seed for random numbers" )
5348             .bind( &setRngSeed, "'time'|number" );
5349 
5350         cli["--force-colour"]
5351             .describe( "force colourised output (deprecated)" )
5352             .bind( &forceColour );
5353 
5354         cli["--use-colour"]
5355             .describe( "should output be colourised" )
5356             .bind( &setUseColour, "yes|no" );
5357 
5358         cli["--libidentify"]
5359             .describe( "report name and version according to libidentify standard" )
5360             .bind( &ConfigData::libIdentify );
5361 
5362         cli["--wait-for-keypress"]
5363                 .describe( "waits for a keypress before exiting" )
5364                 .bind( &setWaitForKeypress, "start|exit|both" );
5365 
5366         return cli;
5367     }
5368 
5369 } // end namespace Catch
5370 
5371 // #included from: internal/catch_list.hpp
5372 #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
5373 
5374 // #included from: catch_text.h
5375 #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
5376 
5377 #define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
5378 
5379 #define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
5380 // #included from: ../external/tbc_text_format.h
5381 // Only use header guard if we are not using an outer namespace
5382 #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
5383 # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
5384 #  ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
5385 #   define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
5386 #  endif
5387 # else
5388 #  define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
5389 # endif
5390 #endif
5391 #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
5392 #include <string>
5393 #include <vector>
5394 #include <sstream>
5395 
5396 // Use optional outer namespace
5397 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
5398 namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
5399 #endif
5400 
5401 namespace Tbc {
5402 
5403 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
5404     const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
5405 #else
5406     const unsigned int consoleWidth = 80;
5407 #endif
5408 
5409     struct TextAttributes {
TextAttributesCLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes5410         TextAttributes()
5411         :   initialIndent( std::string::npos ),
5412             indent( 0 ),
5413             width( consoleWidth-1 )
5414         {}
5415 
setInitialIndentCLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes5416         TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
setIndentCLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes5417         TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
setWidthCLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes5418         TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
5419 
5420         std::size_t initialIndent;  // indent of first line, or npos
5421         std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
5422         std::size_t width;          // maximum width of text, including indent. Longer text will wrap
5423     };
5424 
5425     class Text {
5426     public:
Text(std::string const & _str,TextAttributes const & _attr=TextAttributes ())5427         Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
5428         : attr( _attr )
5429         {
5430             const std::string wrappableBeforeChars = "[({<\t";
5431             const std::string wrappableAfterChars = "])}>-,./|\\";
5432             const std::string wrappableInsteadOfChars = " \n\r";
5433             std::string indent = _attr.initialIndent != std::string::npos
5434                 ? std::string( _attr.initialIndent, ' ' )
5435                 : std::string( _attr.indent, ' ' );
5436 
5437             typedef std::string::const_iterator iterator;
5438             iterator it = _str.begin();
5439             const iterator strEnd = _str.end();
5440 
5441             while( it != strEnd ) {
5442 
5443                 if( lines.size() >= 1000 ) {
5444                     lines.push_back( "... message truncated due to excessive size" );
5445                     return;
5446                 }
5447 
5448                 std::string suffix;
5449                 std::size_t width = (std::min)( static_cast<size_t>( strEnd-it ), _attr.width-static_cast<size_t>( indent.size() ) );
5450                 iterator itEnd = it+width;
5451                 iterator itNext = _str.end();
5452 
5453                 iterator itNewLine = std::find( it, itEnd, '\n' );
5454                 if( itNewLine != itEnd )
5455                     itEnd = itNewLine;
5456 
5457                 if( itEnd != strEnd  ) {
5458                     bool foundWrapPoint = false;
5459                     iterator findIt = itEnd;
5460                     do {
5461                         if( wrappableAfterChars.find( *findIt ) != std::string::npos && findIt != itEnd ) {
5462                             itEnd = findIt+1;
5463                             itNext = findIt+1;
5464                             foundWrapPoint = true;
5465                         }
5466                         else if( findIt > it && wrappableBeforeChars.find( *findIt ) != std::string::npos ) {
5467                             itEnd = findIt;
5468                             itNext = findIt;
5469                             foundWrapPoint = true;
5470                         }
5471                         else if( wrappableInsteadOfChars.find( *findIt ) != std::string::npos ) {
5472                             itNext = findIt+1;
5473                             itEnd = findIt;
5474                             foundWrapPoint = true;
5475                         }
5476                         if( findIt == it )
5477                             break;
5478                         else
5479                             --findIt;
5480                     }
5481                     while( !foundWrapPoint );
5482 
5483                     if( !foundWrapPoint ) {
5484                         // No good wrap char, so we'll break mid word and add a hyphen
5485                         --itEnd;
5486                         itNext = itEnd;
5487                         suffix = "-";
5488                     }
5489                     else {
5490                         while( itEnd > it && wrappableInsteadOfChars.find( *(itEnd-1) ) != std::string::npos )
5491                             --itEnd;
5492                     }
5493                 }
5494                 lines.push_back( indent + std::string( it, itEnd ) + suffix );
5495 
5496                 if( indent.size() != _attr.indent )
5497                     indent = std::string( _attr.indent, ' ' );
5498                 it = itNext;
5499             }
5500         }
5501 
5502         typedef std::vector<std::string>::const_iterator const_iterator;
5503 
begin() const5504         const_iterator begin() const { return lines.begin(); }
end() const5505         const_iterator end() const { return lines.end(); }
last() const5506         std::string const& last() const { return lines.back(); }
size() const5507         std::size_t size() const { return lines.size(); }
operator [](std::size_t _index) const5508         std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
toString() const5509         std::string toString() const {
5510             std::ostringstream oss;
5511             oss << *this;
5512             return oss.str();
5513         }
5514 
operator <<(std::ostream & _stream,Text const & _text)5515         inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
5516             for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
5517                 it != itEnd; ++it ) {
5518                 if( it != _text.begin() )
5519                     _stream << "\n";
5520                 _stream << *it;
5521             }
5522             return _stream;
5523         }
5524 
5525     private:
5526         std::string str;
5527         TextAttributes attr;
5528         std::vector<std::string> lines;
5529     };
5530 
5531 } // end namespace Tbc
5532 
5533 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
5534 } // end outer namespace
5535 #endif
5536 
5537 #endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
5538 #undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
5539 
5540 namespace Catch {
5541     using Tbc::Text;
5542     using Tbc::TextAttributes;
5543 }
5544 
5545 // #included from: catch_console_colour.hpp
5546 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
5547 
5548 namespace Catch {
5549 
5550     struct Colour {
5551         enum Code {
5552             None = 0,
5553 
5554             White,
5555             Red,
5556             Green,
5557             Blue,
5558             Cyan,
5559             Yellow,
5560             Grey,
5561 
5562             Bright = 0x10,
5563 
5564             BrightRed = Bright | Red,
5565             BrightGreen = Bright | Green,
5566             LightGrey = Bright | Grey,
5567             BrightWhite = Bright | White,
5568 
5569             // By intention
5570             FileName = LightGrey,
5571             Warning = Yellow,
5572             ResultError = BrightRed,
5573             ResultSuccess = BrightGreen,
5574             ResultExpectedFailure = Warning,
5575 
5576             Error = BrightRed,
5577             Success = Green,
5578 
5579             OriginalExpression = Cyan,
5580             ReconstructedExpression = Yellow,
5581 
5582             SecondaryText = LightGrey,
5583             Headers = White
5584         };
5585 
5586         // Use constructed object for RAII guard
5587         Colour( Code _colourCode );
5588         Colour( Colour const& other );
5589         ~Colour();
5590 
5591         // Use static method for one-shot changes
5592         static void use( Code _colourCode );
5593 
5594     private:
5595         bool m_moved;
5596     };
5597 
operator <<(std::ostream & os,Colour const &)5598     inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
5599 
5600 } // end namespace Catch
5601 
5602 // #included from: catch_interfaces_reporter.h
5603 #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
5604 
5605 #include <string>
5606 #include <ostream>
5607 #include <map>
5608 
5609 namespace Catch
5610 {
5611     struct ReporterConfig {
ReporterConfigCatch::ReporterConfig5612         explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
5613         :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
5614 
ReporterConfigCatch::ReporterConfig5615         ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
5616         :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
5617 
streamCatch::ReporterConfig5618         std::ostream& stream() const    { return *m_stream; }
fullConfigCatch::ReporterConfig5619         Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
5620 
5621     private:
5622         std::ostream* m_stream;
5623         Ptr<IConfig const> m_fullConfig;
5624     };
5625 
5626     struct ReporterPreferences {
ReporterPreferencesCatch::ReporterPreferences5627         ReporterPreferences()
5628         : shouldRedirectStdOut( false )
5629         {}
5630 
5631         bool shouldRedirectStdOut;
5632     };
5633 
5634     template<typename T>
5635     struct LazyStat : Option<T> {
LazyStatCatch::LazyStat5636         LazyStat() : used( false ) {}
operator =Catch::LazyStat5637         LazyStat& operator=( T const& _value ) {
5638             Option<T>::operator=( _value );
5639             used = false;
5640             return *this;
5641         }
resetCatch::LazyStat5642         void reset() {
5643             Option<T>::reset();
5644             used = false;
5645         }
5646         bool used;
5647     };
5648 
5649     struct TestRunInfo {
TestRunInfoCatch::TestRunInfo5650         TestRunInfo( std::string const& _name ) : name( _name ) {}
5651         std::string name;
5652     };
5653     struct GroupInfo {
GroupInfoCatch::GroupInfo5654         GroupInfo(  std::string const& _name,
5655                     std::size_t _groupIndex,
5656                     std::size_t _groupsCount )
5657         :   name( _name ),
5658             groupIndex( _groupIndex ),
5659             groupsCounts( _groupsCount )
5660         {}
5661 
5662         std::string name;
5663         std::size_t groupIndex;
5664         std::size_t groupsCounts;
5665     };
5666 
5667     struct AssertionStats {
AssertionStatsCatch::AssertionStats5668         AssertionStats( AssertionResult const& _assertionResult,
5669                         std::vector<MessageInfo> const& _infoMessages,
5670                         Totals const& _totals )
5671         :   assertionResult( _assertionResult ),
5672             infoMessages( _infoMessages ),
5673             totals( _totals )
5674         {
5675             if( assertionResult.hasMessage() ) {
5676                 // Copy message into messages list.
5677                 // !TBD This should have been done earlier, somewhere
5678                 MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
5679                 builder << assertionResult.getMessage();
5680                 builder.m_info.message = builder.m_stream.str();
5681 
5682                 infoMessages.push_back( builder.m_info );
5683             }
5684         }
5685         virtual ~AssertionStats();
5686 
5687 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5688         AssertionStats( AssertionStats const& )              = default;
5689         AssertionStats( AssertionStats && )                  = default;
5690         AssertionStats& operator = ( AssertionStats const& ) = default;
5691         AssertionStats& operator = ( AssertionStats && )     = default;
5692 #  endif
5693 
5694         AssertionResult assertionResult;
5695         std::vector<MessageInfo> infoMessages;
5696         Totals totals;
5697     };
5698 
5699     struct SectionStats {
SectionStatsCatch::SectionStats5700         SectionStats(   SectionInfo const& _sectionInfo,
5701                         Counts const& _assertions,
5702                         double _durationInSeconds,
5703                         bool _missingAssertions )
5704         :   sectionInfo( _sectionInfo ),
5705             assertions( _assertions ),
5706             durationInSeconds( _durationInSeconds ),
5707             missingAssertions( _missingAssertions )
5708         {}
5709         virtual ~SectionStats();
5710 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5711         SectionStats( SectionStats const& )              = default;
5712         SectionStats( SectionStats && )                  = default;
5713         SectionStats& operator = ( SectionStats const& ) = default;
5714         SectionStats& operator = ( SectionStats && )     = default;
5715 #  endif
5716 
5717         SectionInfo sectionInfo;
5718         Counts assertions;
5719         double durationInSeconds;
5720         bool missingAssertions;
5721     };
5722 
5723     struct TestCaseStats {
TestCaseStatsCatch::TestCaseStats5724         TestCaseStats(  TestCaseInfo const& _testInfo,
5725                         Totals const& _totals,
5726                         std::string const& _stdOut,
5727                         std::string const& _stdErr,
5728                         bool _aborting )
5729         : testInfo( _testInfo ),
5730             totals( _totals ),
5731             stdOut( _stdOut ),
5732             stdErr( _stdErr ),
5733             aborting( _aborting )
5734         {}
5735         virtual ~TestCaseStats();
5736 
5737 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5738         TestCaseStats( TestCaseStats const& )              = default;
5739         TestCaseStats( TestCaseStats && )                  = default;
5740         TestCaseStats& operator = ( TestCaseStats const& ) = default;
5741         TestCaseStats& operator = ( TestCaseStats && )     = default;
5742 #  endif
5743 
5744         TestCaseInfo testInfo;
5745         Totals totals;
5746         std::string stdOut;
5747         std::string stdErr;
5748         bool aborting;
5749     };
5750 
5751     struct TestGroupStats {
TestGroupStatsCatch::TestGroupStats5752         TestGroupStats( GroupInfo const& _groupInfo,
5753                         Totals const& _totals,
5754                         bool _aborting )
5755         :   groupInfo( _groupInfo ),
5756             totals( _totals ),
5757             aborting( _aborting )
5758         {}
TestGroupStatsCatch::TestGroupStats5759         TestGroupStats( GroupInfo const& _groupInfo )
5760         :   groupInfo( _groupInfo ),
5761             aborting( false )
5762         {}
5763         virtual ~TestGroupStats();
5764 
5765 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5766         TestGroupStats( TestGroupStats const& )              = default;
5767         TestGroupStats( TestGroupStats && )                  = default;
5768         TestGroupStats& operator = ( TestGroupStats const& ) = default;
5769         TestGroupStats& operator = ( TestGroupStats && )     = default;
5770 #  endif
5771 
5772         GroupInfo groupInfo;
5773         Totals totals;
5774         bool aborting;
5775     };
5776 
5777     struct TestRunStats {
TestRunStatsCatch::TestRunStats5778         TestRunStats(   TestRunInfo const& _runInfo,
5779                         Totals const& _totals,
5780                         bool _aborting )
5781         :   runInfo( _runInfo ),
5782             totals( _totals ),
5783             aborting( _aborting )
5784         {}
5785         virtual ~TestRunStats();
5786 
5787 #  ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
TestRunStatsCatch::TestRunStats5788         TestRunStats( TestRunStats const& _other )
5789         :   runInfo( _other.runInfo ),
5790             totals( _other.totals ),
5791             aborting( _other.aborting )
5792         {}
5793 #  else
5794         TestRunStats( TestRunStats const& )              = default;
5795         TestRunStats( TestRunStats && )                  = default;
5796         TestRunStats& operator = ( TestRunStats const& ) = default;
5797         TestRunStats& operator = ( TestRunStats && )     = default;
5798 #  endif
5799 
5800         TestRunInfo runInfo;
5801         Totals totals;
5802         bool aborting;
5803     };
5804 
5805     class MultipleReporters;
5806 
5807     struct IStreamingReporter : IShared {
5808         virtual ~IStreamingReporter();
5809 
5810         // Implementing class must also provide the following static method:
5811         // static std::string getDescription();
5812 
5813         virtual ReporterPreferences getPreferences() const = 0;
5814 
5815         virtual void noMatchingTestCases( std::string const& spec ) = 0;
5816 
5817         virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
5818         virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
5819 
5820         virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
5821         virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
5822 
5823         virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
5824 
5825         // The return value indicates if the messages buffer should be cleared:
5826         virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
5827 
5828         virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
5829         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
5830         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
5831         virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
5832 
5833         virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
5834 
tryAsMultiCatch::IStreamingReporter5835         virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }
5836     };
5837 
5838     struct IReporterFactory : IShared {
5839         virtual ~IReporterFactory();
5840         virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
5841         virtual std::string getDescription() const = 0;
5842     };
5843 
5844     struct IReporterRegistry {
5845         typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
5846         typedef std::vector<Ptr<IReporterFactory> > Listeners;
5847 
5848         virtual ~IReporterRegistry();
5849         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
5850         virtual FactoryMap const& getFactories() const = 0;
5851         virtual Listeners const& getListeners() const = 0;
5852     };
5853 
5854     Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
5855 
5856 }
5857 
5858 #include <limits>
5859 #include <algorithm>
5860 
5861 namespace Catch {
5862 
listTests(Config const & config)5863     inline std::size_t listTests( Config const& config ) {
5864 
5865         TestSpec testSpec = config.testSpec();
5866         if( config.testSpec().hasFilters() )
5867             Catch::cout() << "Matching test cases:\n";
5868         else {
5869             Catch::cout() << "All available test cases:\n";
5870             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5871         }
5872 
5873         std::size_t matchedTests = 0;
5874         TextAttributes nameAttr, descAttr, tagsAttr;
5875         nameAttr.setInitialIndent( 2 ).setIndent( 4 );
5876         descAttr.setIndent( 4 );
5877         tagsAttr.setIndent( 6 );
5878 
5879         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5880         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5881                 it != itEnd;
5882                 ++it ) {
5883             matchedTests++;
5884             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
5885             Colour::Code colour = testCaseInfo.isHidden()
5886                 ? Colour::SecondaryText
5887                 : Colour::None;
5888             Colour colourGuard( colour );
5889 
5890             Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
5891             if( config.listExtraInfo() ) {
5892                 Catch::cout() << "    " << testCaseInfo.lineInfo << std::endl;
5893                 std::string description = testCaseInfo.description;
5894                 if( description.empty() )
5895                     description = "(NO DESCRIPTION)";
5896                 Catch::cout() << Text( description, descAttr ) << std::endl;
5897             }
5898             if( !testCaseInfo.tags.empty() )
5899                 Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
5900         }
5901 
5902         if( !config.testSpec().hasFilters() )
5903             Catch::cout() << pluralise( matchedTests, "test case" ) << '\n' << std::endl;
5904         else
5905             Catch::cout() << pluralise( matchedTests, "matching test case" ) << '\n' << std::endl;
5906         return matchedTests;
5907     }
5908 
listTestsNamesOnly(Config const & config)5909     inline std::size_t listTestsNamesOnly( Config const& config ) {
5910         TestSpec testSpec = config.testSpec();
5911         if( !config.testSpec().hasFilters() )
5912             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5913         std::size_t matchedTests = 0;
5914         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5915         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5916                 it != itEnd;
5917                 ++it ) {
5918             matchedTests++;
5919             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
5920             if( startsWith( testCaseInfo.name, '#' ) )
5921                Catch::cout() << '"' << testCaseInfo.name << '"';
5922             else
5923                Catch::cout() << testCaseInfo.name;
5924             if ( config.listExtraInfo() )
5925                 Catch::cout() << "\t@" << testCaseInfo.lineInfo;
5926             Catch::cout() << std::endl;
5927         }
5928         return matchedTests;
5929     }
5930 
5931     struct TagInfo {
TagInfoCatch::TagInfo5932         TagInfo() : count ( 0 ) {}
addCatch::TagInfo5933         void add( std::string const& spelling ) {
5934             ++count;
5935             spellings.insert( spelling );
5936         }
allCatch::TagInfo5937         std::string all() const {
5938             std::string out;
5939             for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
5940                         it != itEnd;
5941                         ++it )
5942                 out += "[" + *it + "]";
5943             return out;
5944         }
5945         std::set<std::string> spellings;
5946         std::size_t count;
5947     };
5948 
listTags(Config const & config)5949     inline std::size_t listTags( Config const& config ) {
5950         TestSpec testSpec = config.testSpec();
5951         if( config.testSpec().hasFilters() )
5952             Catch::cout() << "Tags for matching test cases:\n";
5953         else {
5954             Catch::cout() << "All available tags:\n";
5955             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5956         }
5957 
5958         std::map<std::string, TagInfo> tagCounts;
5959 
5960         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5961         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5962                 it != itEnd;
5963                 ++it ) {
5964             for( std::set<std::string>::const_iterator  tagIt = it->getTestCaseInfo().tags.begin(),
5965                                                         tagItEnd = it->getTestCaseInfo().tags.end();
5966                     tagIt != tagItEnd;
5967                     ++tagIt ) {
5968                 std::string tagName = *tagIt;
5969                 std::string lcaseTagName = toLower( tagName );
5970                 std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
5971                 if( countIt == tagCounts.end() )
5972                     countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
5973                 countIt->second.add( tagName );
5974             }
5975         }
5976 
5977         for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
5978                                                             countItEnd = tagCounts.end();
5979                 countIt != countItEnd;
5980                 ++countIt ) {
5981             std::ostringstream oss;
5982             oss << "  " << std::setw(2) << countIt->second.count << "  ";
5983             Text wrapper( countIt->second.all(), TextAttributes()
5984                                                     .setInitialIndent( 0 )
5985                                                     .setIndent( oss.str().size() )
5986                                                     .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
5987             Catch::cout() << oss.str() << wrapper << '\n';
5988         }
5989         Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
5990         return tagCounts.size();
5991     }
5992 
listReporters(Config const &)5993     inline std::size_t listReporters( Config const& /*config*/ ) {
5994         Catch::cout() << "Available reporters:\n";
5995         IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
5996         IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
5997         std::size_t maxNameLen = 0;
5998         for(it = itBegin; it != itEnd; ++it )
5999             maxNameLen = (std::max)( maxNameLen, it->first.size() );
6000 
6001         for(it = itBegin; it != itEnd; ++it ) {
6002             Text wrapper( it->second->getDescription(), TextAttributes()
6003                                                         .setInitialIndent( 0 )
6004                                                         .setIndent( 7+maxNameLen )
6005                                                         .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
6006             Catch::cout() << "  "
6007                     << it->first
6008                     << ':'
6009                     << std::string( maxNameLen - it->first.size() + 2, ' ' )
6010                     << wrapper << '\n';
6011         }
6012         Catch::cout() << std::endl;
6013         return factories.size();
6014     }
6015 
list(Config const & config)6016     inline Option<std::size_t> list( Config const& config ) {
6017         Option<std::size_t> listedCount;
6018         if( config.listTests() || ( config.listExtraInfo() && !config.listTestNamesOnly() ) )
6019             listedCount = listedCount.valueOr(0) + listTests( config );
6020         if( config.listTestNamesOnly() )
6021             listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
6022         if( config.listTags() )
6023             listedCount = listedCount.valueOr(0) + listTags( config );
6024         if( config.listReporters() )
6025             listedCount = listedCount.valueOr(0) + listReporters( config );
6026         return listedCount;
6027     }
6028 
6029 } // end namespace Catch
6030 
6031 // #included from: internal/catch_run_context.hpp
6032 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
6033 
6034 // #included from: catch_test_case_tracker.hpp
6035 #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
6036 
6037 #include <algorithm>
6038 #include <string>
6039 #include <assert.h>
6040 #include <vector>
6041 #include <stdexcept>
6042 
6043 CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS
6044 
6045 namespace Catch {
6046 namespace TestCaseTracking {
6047 
6048     struct NameAndLocation {
6049         std::string name;
6050         SourceLineInfo location;
6051 
NameAndLocationCatch::TestCaseTracking::NameAndLocation6052         NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
6053         :   name( _name ),
6054             location( _location )
6055         {}
6056     };
6057 
6058     struct ITracker : SharedImpl<> {
6059         virtual ~ITracker();
6060 
6061         // static queries
6062         virtual NameAndLocation const& nameAndLocation() const = 0;
6063 
6064         // dynamic queries
6065         virtual bool isComplete() const = 0; // Successfully completed or failed
6066         virtual bool isSuccessfullyCompleted() const = 0;
6067         virtual bool isOpen() const = 0; // Started but not complete
6068         virtual bool hasChildren() const = 0;
6069 
6070         virtual ITracker& parent() = 0;
6071 
6072         // actions
6073         virtual void close() = 0; // Successfully complete
6074         virtual void fail() = 0;
6075         virtual void markAsNeedingAnotherRun() = 0;
6076 
6077         virtual void addChild( Ptr<ITracker> const& child ) = 0;
6078         virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0;
6079         virtual void openChild() = 0;
6080 
6081         // Debug/ checking
6082         virtual bool isSectionTracker() const = 0;
6083         virtual bool isIndexTracker() const = 0;
6084     };
6085 
6086     class  TrackerContext {
6087 
6088         enum RunState {
6089             NotStarted,
6090             Executing,
6091             CompletedCycle
6092         };
6093 
6094         Ptr<ITracker> m_rootTracker;
6095         ITracker* m_currentTracker;
6096         RunState m_runState;
6097 
6098     public:
6099 
instance()6100         static TrackerContext& instance() {
6101             static TrackerContext s_instance;
6102             return s_instance;
6103         }
6104 
TrackerContext()6105         TrackerContext()
6106         :   m_currentTracker( CATCH_NULL ),
6107             m_runState( NotStarted )
6108         {}
6109 
6110         ITracker& startRun();
6111 
endRun()6112         void endRun() {
6113             m_rootTracker.reset();
6114             m_currentTracker = CATCH_NULL;
6115             m_runState = NotStarted;
6116         }
6117 
startCycle()6118         void startCycle() {
6119             m_currentTracker = m_rootTracker.get();
6120             m_runState = Executing;
6121         }
completeCycle()6122         void completeCycle() {
6123             m_runState = CompletedCycle;
6124         }
6125 
completedCycle() const6126         bool completedCycle() const {
6127             return m_runState == CompletedCycle;
6128         }
currentTracker()6129         ITracker& currentTracker() {
6130             return *m_currentTracker;
6131         }
setCurrentTracker(ITracker * tracker)6132         void setCurrentTracker( ITracker* tracker ) {
6133             m_currentTracker = tracker;
6134         }
6135     };
6136 
6137     class TrackerBase : public ITracker {
6138     protected:
6139         enum CycleState {
6140             NotStarted,
6141             Executing,
6142             ExecutingChildren,
6143             NeedsAnotherRun,
6144             CompletedSuccessfully,
6145             Failed
6146         };
6147         class TrackerHasName {
6148             NameAndLocation m_nameAndLocation;
6149         public:
TrackerHasName(NameAndLocation const & nameAndLocation)6150             TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
operator ()(Ptr<ITracker> const & tracker)6151             bool operator ()( Ptr<ITracker> const& tracker ) {
6152                 return
6153                     tracker->nameAndLocation().name == m_nameAndLocation.name &&
6154                     tracker->nameAndLocation().location == m_nameAndLocation.location;
6155             }
6156         };
6157         typedef std::vector<Ptr<ITracker> > Children;
6158         NameAndLocation m_nameAndLocation;
6159         TrackerContext& m_ctx;
6160         ITracker* m_parent;
6161         Children m_children;
6162         CycleState m_runState;
6163     public:
TrackerBase(NameAndLocation const & nameAndLocation,TrackerContext & ctx,ITracker * parent)6164         TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
6165         :   m_nameAndLocation( nameAndLocation ),
6166             m_ctx( ctx ),
6167             m_parent( parent ),
6168             m_runState( NotStarted )
6169         {}
6170         virtual ~TrackerBase();
6171 
nameAndLocation() const6172         virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE {
6173             return m_nameAndLocation;
6174         }
isComplete() const6175         virtual bool isComplete() const CATCH_OVERRIDE {
6176             return m_runState == CompletedSuccessfully || m_runState == Failed;
6177         }
isSuccessfullyCompleted() const6178         virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {
6179             return m_runState == CompletedSuccessfully;
6180         }
isOpen() const6181         virtual bool isOpen() const CATCH_OVERRIDE {
6182             return m_runState != NotStarted && !isComplete();
6183         }
hasChildren() const6184         virtual bool hasChildren() const CATCH_OVERRIDE {
6185             return !m_children.empty();
6186         }
6187 
addChild(Ptr<ITracker> const & child)6188         virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
6189             m_children.push_back( child );
6190         }
6191 
findChild(NameAndLocation const & nameAndLocation)6192         virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE {
6193             Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
6194             return( it != m_children.end() )
6195                 ? it->get()
6196                 : CATCH_NULL;
6197         }
parent()6198         virtual ITracker& parent() CATCH_OVERRIDE {
6199             assert( m_parent ); // Should always be non-null except for root
6200             return *m_parent;
6201         }
6202 
openChild()6203         virtual void openChild() CATCH_OVERRIDE {
6204             if( m_runState != ExecutingChildren ) {
6205                 m_runState = ExecutingChildren;
6206                 if( m_parent )
6207                     m_parent->openChild();
6208             }
6209         }
6210 
isSectionTracker() const6211         virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }
isIndexTracker() const6212         virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }
6213 
open()6214         void open() {
6215             m_runState = Executing;
6216             moveToThis();
6217             if( m_parent )
6218                 m_parent->openChild();
6219         }
6220 
close()6221         virtual void close() CATCH_OVERRIDE {
6222 
6223             // Close any still open children (e.g. generators)
6224             while( &m_ctx.currentTracker() != this )
6225                 m_ctx.currentTracker().close();
6226 
6227             switch( m_runState ) {
6228                 case NotStarted:
6229                 case CompletedSuccessfully:
6230                 case Failed:
6231                     throw std::logic_error( "Illogical state" );
6232 
6233                 case NeedsAnotherRun:
6234                     break;;
6235 
6236                 case Executing:
6237                     m_runState = CompletedSuccessfully;
6238                     break;
6239                 case ExecutingChildren:
6240                     if( m_children.empty() || m_children.back()->isComplete() )
6241                         m_runState = CompletedSuccessfully;
6242                     break;
6243 
6244                 default:
6245                     throw std::logic_error( "Unexpected state" );
6246             }
6247             moveToParent();
6248             m_ctx.completeCycle();
6249         }
fail()6250         virtual void fail() CATCH_OVERRIDE {
6251             m_runState = Failed;
6252             if( m_parent )
6253                 m_parent->markAsNeedingAnotherRun();
6254             moveToParent();
6255             m_ctx.completeCycle();
6256         }
markAsNeedingAnotherRun()6257         virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
6258             m_runState = NeedsAnotherRun;
6259         }
6260     private:
moveToParent()6261         void moveToParent() {
6262             assert( m_parent );
6263             m_ctx.setCurrentTracker( m_parent );
6264         }
moveToThis()6265         void moveToThis() {
6266             m_ctx.setCurrentTracker( this );
6267         }
6268     };
6269 
6270     class SectionTracker : public TrackerBase {
6271         std::vector<std::string> m_filters;
6272     public:
SectionTracker(NameAndLocation const & nameAndLocation,TrackerContext & ctx,ITracker * parent)6273         SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
6274         :   TrackerBase( nameAndLocation, ctx, parent )
6275         {
6276             if( parent ) {
6277                 while( !parent->isSectionTracker() )
6278                     parent = &parent->parent();
6279 
6280                 SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
6281                 addNextFilters( parentSection.m_filters );
6282             }
6283         }
6284         virtual ~SectionTracker();
6285 
isSectionTracker() const6286         virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
6287 
acquire(TrackerContext & ctx,NameAndLocation const & nameAndLocation)6288         static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
6289             SectionTracker* section = CATCH_NULL;
6290 
6291             ITracker& currentTracker = ctx.currentTracker();
6292             if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
6293                 assert( childTracker );
6294                 assert( childTracker->isSectionTracker() );
6295                 section = static_cast<SectionTracker*>( childTracker );
6296             }
6297             else {
6298                 section = new SectionTracker( nameAndLocation, ctx, &currentTracker );
6299                 currentTracker.addChild( section );
6300             }
6301             if( !ctx.completedCycle() )
6302                 section->tryOpen();
6303             return *section;
6304         }
6305 
tryOpen()6306         void tryOpen() {
6307             if( !isComplete() && (m_filters.empty() || m_filters[0].empty() ||  m_filters[0] == m_nameAndLocation.name ) )
6308                 open();
6309         }
6310 
addInitialFilters(std::vector<std::string> const & filters)6311         void addInitialFilters( std::vector<std::string> const& filters ) {
6312             if( !filters.empty() ) {
6313                 m_filters.push_back(""); // Root - should never be consulted
6314                 m_filters.push_back(""); // Test Case - not a section filter
6315                 m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
6316             }
6317         }
addNextFilters(std::vector<std::string> const & filters)6318         void addNextFilters( std::vector<std::string> const& filters ) {
6319             if( filters.size() > 1 )
6320                 m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
6321         }
6322     };
6323 
6324     class IndexTracker : public TrackerBase {
6325         int m_size;
6326         int m_index;
6327     public:
IndexTracker(NameAndLocation const & nameAndLocation,TrackerContext & ctx,ITracker * parent,int size)6328         IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size )
6329         :   TrackerBase( nameAndLocation, ctx, parent ),
6330             m_size( size ),
6331             m_index( -1 )
6332         {}
6333         virtual ~IndexTracker();
6334 
isIndexTracker() const6335         virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
6336 
acquire(TrackerContext & ctx,NameAndLocation const & nameAndLocation,int size)6337         static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) {
6338             IndexTracker* tracker = CATCH_NULL;
6339 
6340             ITracker& currentTracker = ctx.currentTracker();
6341             if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
6342                 assert( childTracker );
6343                 assert( childTracker->isIndexTracker() );
6344                 tracker = static_cast<IndexTracker*>( childTracker );
6345             }
6346             else {
6347                 tracker = new IndexTracker( nameAndLocation, ctx, &currentTracker, size );
6348                 currentTracker.addChild( tracker );
6349             }
6350 
6351             if( !ctx.completedCycle() && !tracker->isComplete() ) {
6352                 if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
6353                     tracker->moveNext();
6354                 tracker->open();
6355             }
6356 
6357             return *tracker;
6358         }
6359 
index() const6360         int index() const { return m_index; }
6361 
moveNext()6362         void moveNext() {
6363             m_index++;
6364             m_children.clear();
6365         }
6366 
close()6367         virtual void close() CATCH_OVERRIDE {
6368             TrackerBase::close();
6369             if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
6370                 m_runState = Executing;
6371         }
6372     };
6373 
startRun()6374     inline ITracker& TrackerContext::startRun() {
6375         m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL );
6376         m_currentTracker = CATCH_NULL;
6377         m_runState = Executing;
6378         return *m_rootTracker;
6379     }
6380 
6381 } // namespace TestCaseTracking
6382 
6383 using TestCaseTracking::ITracker;
6384 using TestCaseTracking::TrackerContext;
6385 using TestCaseTracking::SectionTracker;
6386 using TestCaseTracking::IndexTracker;
6387 
6388 } // namespace Catch
6389 
6390 CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
6391 
6392 // #included from: catch_fatal_condition.hpp
6393 #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
6394 
6395 namespace Catch {
6396 
6397     // Report the error condition
reportFatal(std::string const & message)6398     inline void reportFatal( std::string const& message ) {
6399         IContext& context = Catch::getCurrentContext();
6400         IResultCapture* resultCapture = context.getResultCapture();
6401         resultCapture->handleFatalErrorCondition( message );
6402     }
6403 
6404 } // namespace Catch
6405 
6406 #if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
6407 // #included from: catch_windows_h_proxy.h
6408 
6409 #define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED
6410 
6411 #ifdef CATCH_DEFINES_NOMINMAX
6412 #  define NOMINMAX
6413 #endif
6414 #ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
6415 #  define WIN32_LEAN_AND_MEAN
6416 #endif
6417 
6418 #ifdef __AFXDLL
6419 #include <AfxWin.h>
6420 #else
6421 #include <windows.h>
6422 #endif
6423 
6424 #ifdef CATCH_DEFINES_NOMINMAX
6425 #  undef NOMINMAX
6426 #endif
6427 #ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
6428 #  undef WIN32_LEAN_AND_MEAN
6429 #endif
6430 
6431 
6432 #  if !defined ( CATCH_CONFIG_WINDOWS_SEH )
6433 
6434 namespace Catch {
6435     struct FatalConditionHandler {
resetCatch::FatalConditionHandler6436         void reset() {}
6437     };
6438 }
6439 
6440 #  else // CATCH_CONFIG_WINDOWS_SEH is defined
6441 
6442 namespace Catch {
6443 
6444     struct SignalDefs { DWORD id; const char* name; };
6445     extern SignalDefs signalDefs[];
6446     // There is no 1-1 mapping between signals and windows exceptions.
6447     // Windows can easily distinguish between SO and SigSegV,
6448     // but SigInt, SigTerm, etc are handled differently.
6449     SignalDefs signalDefs[] = {
6450         { EXCEPTION_ILLEGAL_INSTRUCTION,  "SIGILL - Illegal instruction signal" },
6451         { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
6452         { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
6453         { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
6454     };
6455 
6456     struct FatalConditionHandler {
6457 
handleVectoredExceptionCatch::FatalConditionHandler6458         static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
6459             for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
6460                 if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
6461                     reportFatal(signalDefs[i].name);
6462                 }
6463             }
6464             // If its not an exception we care about, pass it along.
6465             // This stops us from eating debugger breaks etc.
6466             return EXCEPTION_CONTINUE_SEARCH;
6467         }
6468 
FatalConditionHandlerCatch::FatalConditionHandler6469         FatalConditionHandler() {
6470             isSet = true;
6471             // 32k seems enough for Catch to handle stack overflow,
6472             // but the value was found experimentally, so there is no strong guarantee
6473             guaranteeSize = 32 * 1024;
6474             exceptionHandlerHandle = CATCH_NULL;
6475             // Register as first handler in current chain
6476             exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
6477             // Pass in guarantee size to be filled
6478             SetThreadStackGuarantee(&guaranteeSize);
6479         }
6480 
resetCatch::FatalConditionHandler6481         static void reset() {
6482             if (isSet) {
6483                 // Unregister handler and restore the old guarantee
6484                 RemoveVectoredExceptionHandler(exceptionHandlerHandle);
6485                 SetThreadStackGuarantee(&guaranteeSize);
6486                 exceptionHandlerHandle = CATCH_NULL;
6487                 isSet = false;
6488             }
6489         }
6490 
~FatalConditionHandlerCatch::FatalConditionHandler6491         ~FatalConditionHandler() {
6492             reset();
6493         }
6494     private:
6495         static bool isSet;
6496         static ULONG guaranteeSize;
6497         static PVOID exceptionHandlerHandle;
6498     };
6499 
6500     bool FatalConditionHandler::isSet = false;
6501     ULONG FatalConditionHandler::guaranteeSize = 0;
6502     PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL;
6503 
6504 } // namespace Catch
6505 
6506 #  endif // CATCH_CONFIG_WINDOWS_SEH
6507 
6508 #else // Not Windows - assumed to be POSIX compatible //////////////////////////
6509 
6510 #  if !defined(CATCH_CONFIG_POSIX_SIGNALS)
6511 
6512 namespace Catch {
6513     struct FatalConditionHandler {
resetCatch::FatalConditionHandler6514         void reset() {}
6515     };
6516 }
6517 
6518 #  else // CATCH_CONFIG_POSIX_SIGNALS is defined
6519 
6520 #include <signal.h>
6521 
6522 namespace Catch {
6523 
6524     struct SignalDefs {
6525         int id;
6526         const char* name;
6527     };
6528     extern SignalDefs signalDefs[];
6529     SignalDefs signalDefs[] = {
6530             { SIGINT,  "SIGINT - Terminal interrupt signal" },
6531             { SIGILL,  "SIGILL - Illegal instruction signal" },
6532             { SIGFPE,  "SIGFPE - Floating point error signal" },
6533             { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
6534             { SIGTERM, "SIGTERM - Termination request signal" },
6535             { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
6536     };
6537 
6538     struct FatalConditionHandler {
6539 
6540         static bool isSet;
6541         static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)];
6542         static stack_t oldSigStack;
6543         static char altStackMem[SIGSTKSZ];
6544 
handleSignalCatch::FatalConditionHandler6545         static void handleSignal( int sig ) {
6546             std::string name = "<unknown signal>";
6547             for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
6548                 SignalDefs &def = signalDefs[i];
6549                 if (sig == def.id) {
6550                     name = def.name;
6551                     break;
6552                 }
6553             }
6554             reset();
6555             reportFatal(name);
6556             raise( sig );
6557         }
6558 
FatalConditionHandlerCatch::FatalConditionHandler6559         FatalConditionHandler() {
6560             isSet = true;
6561             stack_t sigStack;
6562             sigStack.ss_sp = altStackMem;
6563             sigStack.ss_size = SIGSTKSZ;
6564             sigStack.ss_flags = 0;
6565             sigaltstack(&sigStack, &oldSigStack);
6566             struct sigaction sa = { 0 };
6567 
6568             sa.sa_handler = handleSignal;
6569             sa.sa_flags = SA_ONSTACK;
6570             for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
6571                 sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
6572             }
6573         }
6574 
~FatalConditionHandlerCatch::FatalConditionHandler6575         ~FatalConditionHandler() {
6576             reset();
6577         }
resetCatch::FatalConditionHandler6578         static void reset() {
6579             if( isSet ) {
6580                 // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
6581                 for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
6582                     sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL);
6583                 }
6584                 // Return the old stack
6585                 sigaltstack(&oldSigStack, CATCH_NULL);
6586                 isSet = false;
6587             }
6588         }
6589     };
6590 
6591     bool FatalConditionHandler::isSet = false;
6592     struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
6593     stack_t FatalConditionHandler::oldSigStack = {};
6594     char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
6595 
6596 } // namespace Catch
6597 
6598 #  endif // CATCH_CONFIG_POSIX_SIGNALS
6599 
6600 #endif // not Windows
6601 
6602 #include <set>
6603 #include <string>
6604 
6605 namespace Catch {
6606 
6607     class StreamRedirect {
6608 
6609     public:
StreamRedirect(std::ostream & stream,std::string & targetString)6610         StreamRedirect( std::ostream& stream, std::string& targetString )
6611         :   m_stream( stream ),
6612             m_prevBuf( stream.rdbuf() ),
6613             m_targetString( targetString )
6614         {
6615             stream.rdbuf( m_oss.rdbuf() );
6616         }
6617 
~StreamRedirect()6618         ~StreamRedirect() {
6619             m_targetString += m_oss.str();
6620             m_stream.rdbuf( m_prevBuf );
6621         }
6622 
6623     private:
6624         std::ostream& m_stream;
6625         std::streambuf* m_prevBuf;
6626         std::ostringstream m_oss;
6627         std::string& m_targetString;
6628     };
6629 
6630     // StdErr has two constituent streams in C++, std::cerr and std::clog
6631     // This means that we need to redirect 2 streams into 1 to keep proper
6632     // order of writes and cannot use StreamRedirect on its own
6633     class StdErrRedirect {
6634     public:
StdErrRedirect(std::string & targetString)6635         StdErrRedirect(std::string& targetString)
6636         :m_cerrBuf( cerr().rdbuf() ), m_clogBuf(clog().rdbuf()),
6637         m_targetString(targetString){
6638             cerr().rdbuf(m_oss.rdbuf());
6639             clog().rdbuf(m_oss.rdbuf());
6640         }
~StdErrRedirect()6641         ~StdErrRedirect() {
6642             m_targetString += m_oss.str();
6643             cerr().rdbuf(m_cerrBuf);
6644             clog().rdbuf(m_clogBuf);
6645         }
6646     private:
6647         std::streambuf* m_cerrBuf;
6648         std::streambuf* m_clogBuf;
6649         std::ostringstream m_oss;
6650         std::string& m_targetString;
6651     };
6652 
6653     ///////////////////////////////////////////////////////////////////////////
6654 
6655     class RunContext : public IResultCapture, public IRunner {
6656 
6657         RunContext( RunContext const& );
6658         void operator =( RunContext const& );
6659 
6660     public:
6661 
RunContext(Ptr<IConfig const> const & _config,Ptr<IStreamingReporter> const & reporter)6662         explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )
6663         :   m_runInfo( _config->name() ),
6664             m_context( getCurrentMutableContext() ),
6665             m_activeTestCase( CATCH_NULL ),
6666             m_config( _config ),
6667             m_reporter( reporter ),
6668             m_shouldReportUnexpected ( true )
6669         {
6670             m_context.setRunner( this );
6671             m_context.setConfig( m_config );
6672             m_context.setResultCapture( this );
6673             m_reporter->testRunStarting( m_runInfo );
6674         }
6675 
~RunContext()6676         virtual ~RunContext() {
6677             m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
6678         }
6679 
testGroupStarting(std::string const & testSpec,std::size_t groupIndex,std::size_t groupsCount)6680         void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
6681             m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
6682         }
testGroupEnded(std::string const & testSpec,Totals const & totals,std::size_t groupIndex,std::size_t groupsCount)6683         void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
6684             m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
6685         }
6686 
runTest(TestCase const & testCase)6687         Totals runTest( TestCase const& testCase ) {
6688             Totals prevTotals = m_totals;
6689 
6690             std::string redirectedCout;
6691             std::string redirectedCerr;
6692 
6693             TestCaseInfo testInfo = testCase.getTestCaseInfo();
6694 
6695             m_reporter->testCaseStarting( testInfo );
6696 
6697             m_activeTestCase = &testCase;
6698 
6699             do {
6700                 ITracker& rootTracker = m_trackerContext.startRun();
6701                 assert( rootTracker.isSectionTracker() );
6702                 static_cast<SectionTracker&>( rootTracker ).addInitialFilters( m_config->getSectionsToRun() );
6703                 do {
6704                     m_trackerContext.startCycle();
6705                     m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) );
6706                     runCurrentTest( redirectedCout, redirectedCerr );
6707                 }
6708                 while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
6709             }
6710             // !TBD: deprecated - this will be replaced by indexed trackers
6711             while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
6712 
6713             Totals deltaTotals = m_totals.delta( prevTotals );
6714             if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {
6715                 deltaTotals.assertions.failed++;
6716                 deltaTotals.testCases.passed--;
6717                 deltaTotals.testCases.failed++;
6718             }
6719             m_totals.testCases += deltaTotals.testCases;
6720             m_reporter->testCaseEnded( TestCaseStats(   testInfo,
6721                                                         deltaTotals,
6722                                                         redirectedCout,
6723                                                         redirectedCerr,
6724                                                         aborting() ) );
6725 
6726             m_activeTestCase = CATCH_NULL;
6727             m_testCaseTracker = CATCH_NULL;
6728 
6729             return deltaTotals;
6730         }
6731 
config() const6732         Ptr<IConfig const> config() const {
6733             return m_config;
6734         }
6735 
6736     private: // IResultCapture
6737 
assertionEnded(AssertionResult const & result)6738         virtual void assertionEnded( AssertionResult const& result ) {
6739             if( result.getResultType() == ResultWas::Ok ) {
6740                 m_totals.assertions.passed++;
6741             }
6742             else if( !result.isOk() ) {
6743                 if( m_activeTestCase->getTestCaseInfo().okToFail() )
6744                     m_totals.assertions.failedButOk++;
6745                 else
6746                     m_totals.assertions.failed++;
6747             }
6748 
6749             // We have no use for the return value (whether messages should be cleared), because messages were made scoped
6750             // and should be let to clear themselves out.
6751             static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
6752 
6753             // Reset working state
6754             m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
6755             m_lastResult = result;
6756         }
6757 
lastAssertionPassed()6758         virtual bool lastAssertionPassed()
6759         {
6760             return m_totals.assertions.passed == (m_prevPassed + 1);
6761         }
6762 
assertionPassed()6763         virtual void assertionPassed()
6764         {
6765             m_totals.assertions.passed++;
6766             m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}";
6767             m_lastAssertionInfo.macroName = "";
6768         }
6769 
assertionRun()6770         virtual void assertionRun()
6771         {
6772             m_prevPassed = m_totals.assertions.passed;
6773         }
6774 
sectionStarted(SectionInfo const & sectionInfo,Counts & assertions)6775         virtual bool sectionStarted (
6776             SectionInfo const& sectionInfo,
6777             Counts& assertions
6778         )
6779         {
6780             ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( sectionInfo.name, sectionInfo.lineInfo ) );
6781             if( !sectionTracker.isOpen() )
6782                 return false;
6783             m_activeSections.push_back( &sectionTracker );
6784 
6785             m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
6786 
6787             m_reporter->sectionStarting( sectionInfo );
6788 
6789             assertions = m_totals.assertions;
6790 
6791             return true;
6792         }
testForMissingAssertions(Counts & assertions)6793         bool testForMissingAssertions( Counts& assertions ) {
6794             if( assertions.total() != 0 )
6795                 return false;
6796             if( !m_config->warnAboutMissingAssertions() )
6797                 return false;
6798             if( m_trackerContext.currentTracker().hasChildren() )
6799                 return false;
6800             m_totals.assertions.failed++;
6801             assertions.failed++;
6802             return true;
6803         }
6804 
sectionEnded(SectionEndInfo const & endInfo)6805         virtual void sectionEnded( SectionEndInfo const& endInfo ) {
6806             Counts assertions = m_totals.assertions - endInfo.prevAssertions;
6807             bool missingAssertions = testForMissingAssertions( assertions );
6808 
6809             if( !m_activeSections.empty() ) {
6810                 m_activeSections.back()->close();
6811                 m_activeSections.pop_back();
6812             }
6813 
6814             m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
6815             m_messages.clear();
6816         }
6817 
sectionEndedEarly(SectionEndInfo const & endInfo)6818         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
6819             if( m_unfinishedSections.empty() )
6820                 m_activeSections.back()->fail();
6821             else
6822                 m_activeSections.back()->close();
6823             m_activeSections.pop_back();
6824 
6825             m_unfinishedSections.push_back( endInfo );
6826         }
6827 
pushScopedMessage(MessageInfo const & message)6828         virtual void pushScopedMessage( MessageInfo const& message ) {
6829             m_messages.push_back( message );
6830         }
6831 
popScopedMessage(MessageInfo const & message)6832         virtual void popScopedMessage( MessageInfo const& message ) {
6833             m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
6834         }
6835 
getCurrentTestName() const6836         virtual std::string getCurrentTestName() const {
6837             return m_activeTestCase
6838                 ? m_activeTestCase->getTestCaseInfo().name
6839                 : std::string();
6840         }
6841 
getLastResult() const6842         virtual const AssertionResult* getLastResult() const {
6843             return &m_lastResult;
6844         }
6845 
exceptionEarlyReported()6846         virtual void exceptionEarlyReported() {
6847             m_shouldReportUnexpected = false;
6848         }
6849 
handleFatalErrorCondition(std::string const & message)6850         virtual void handleFatalErrorCondition( std::string const& message ) {
6851             // Don't rebuild the result -- the stringification itself can cause more fatal errors
6852             // Instead, fake a result data.
6853             AssertionResultData tempResult;
6854             tempResult.resultType = ResultWas::FatalErrorCondition;
6855             tempResult.message = message;
6856             AssertionResult result(m_lastAssertionInfo, tempResult);
6857 
6858             getResultCapture().assertionEnded(result);
6859 
6860             handleUnfinishedSections();
6861 
6862             // Recreate section for test case (as we will lose the one that was in scope)
6863             TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
6864             SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
6865 
6866             Counts assertions;
6867             assertions.failed = 1;
6868             SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
6869             m_reporter->sectionEnded( testCaseSectionStats );
6870 
6871             TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
6872 
6873             Totals deltaTotals;
6874             deltaTotals.testCases.failed = 1;
6875             deltaTotals.assertions.failed = 1;
6876             m_reporter->testCaseEnded( TestCaseStats(   testInfo,
6877                                                         deltaTotals,
6878                                                         std::string(),
6879                                                         std::string(),
6880                                                         false ) );
6881             m_totals.testCases.failed++;
6882             testGroupEnded( std::string(), m_totals, 1, 1 );
6883             m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
6884         }
6885 
6886     public:
6887         // !TBD We need to do this another way!
aborting() const6888         bool aborting() const {
6889             return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
6890         }
6891 
6892     private:
6893 
runCurrentTest(std::string & redirectedCout,std::string & redirectedCerr)6894         void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
6895             TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
6896             SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
6897             m_reporter->sectionStarting( testCaseSection );
6898             Counts prevAssertions = m_totals.assertions;
6899             double duration = 0;
6900             m_shouldReportUnexpected = true;
6901             try {
6902                 m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
6903 
6904                 seedRng( *m_config );
6905 
6906                 Timer timer;
6907                 timer.start();
6908                 if( m_reporter->getPreferences().shouldRedirectStdOut ) {
6909                     StreamRedirect coutRedir( Catch::cout(), redirectedCout );
6910                     StdErrRedirect errRedir( redirectedCerr );
6911                     invokeActiveTestCase();
6912                 }
6913                 else {
6914                     invokeActiveTestCase();
6915                 }
6916                 duration = timer.getElapsedSeconds();
6917             }
6918             catch( TestFailureException& ) {
6919                 // This just means the test was aborted due to failure
6920             }
6921             catch(...) {
6922                 // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
6923                 // are reported without translation at the point of origin.
6924                 if (m_shouldReportUnexpected) {
6925                     makeUnexpectedResultBuilder().useActiveException();
6926                 }
6927             }
6928             m_testCaseTracker->close();
6929             handleUnfinishedSections();
6930             m_messages.clear();
6931 
6932             Counts assertions = m_totals.assertions - prevAssertions;
6933             bool missingAssertions = testForMissingAssertions( assertions );
6934 
6935             SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
6936             m_reporter->sectionEnded( testCaseSectionStats );
6937         }
6938 
invokeActiveTestCase()6939         void invokeActiveTestCase() {
6940             FatalConditionHandler fatalConditionHandler; // Handle signals
6941             m_activeTestCase->invoke();
6942             fatalConditionHandler.reset();
6943         }
6944 
6945     private:
6946 
makeUnexpectedResultBuilder() const6947         ResultBuilder makeUnexpectedResultBuilder() const {
6948             return ResultBuilder(   m_lastAssertionInfo.macroName,
6949                                     m_lastAssertionInfo.lineInfo,
6950                                     m_lastAssertionInfo.capturedExpression,
6951                                     m_lastAssertionInfo.resultDisposition );
6952         }
6953 
handleUnfinishedSections()6954         void handleUnfinishedSections() {
6955             // If sections ended prematurely due to an exception we stored their
6956             // infos here so we can tear them down outside the unwind process.
6957             for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
6958                         itEnd = m_unfinishedSections.rend();
6959                     it != itEnd;
6960                     ++it )
6961                 sectionEnded( *it );
6962             m_unfinishedSections.clear();
6963         }
6964 
6965         TestRunInfo m_runInfo;
6966         IMutableContext& m_context;
6967         TestCase const* m_activeTestCase;
6968         ITracker* m_testCaseTracker;
6969         ITracker* m_currentSectionTracker;
6970         AssertionResult m_lastResult;
6971 
6972         Ptr<IConfig const> m_config;
6973         Totals m_totals;
6974         Ptr<IStreamingReporter> m_reporter;
6975         std::vector<MessageInfo> m_messages;
6976         AssertionInfo m_lastAssertionInfo;
6977         std::vector<SectionEndInfo> m_unfinishedSections;
6978         std::vector<ITracker*> m_activeSections;
6979         TrackerContext m_trackerContext;
6980         size_t m_prevPassed;
6981         bool m_shouldReportUnexpected;
6982     };
6983 
getResultCapture()6984     IResultCapture& getResultCapture() {
6985         if( IResultCapture* capture = getCurrentContext().getResultCapture() )
6986             return *capture;
6987         else
6988             throw std::logic_error( "No result capture instance" );
6989     }
6990 
6991 } // end namespace Catch
6992 
6993 // #included from: internal/catch_version.h
6994 #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
6995 
6996 namespace Catch {
6997 
6998     // Versioning information
6999     struct Version {
7000         Version(    unsigned int _majorVersion,
7001                     unsigned int _minorVersion,
7002                     unsigned int _patchNumber,
7003                     char const * const _branchName,
7004                     unsigned int _buildNumber );
7005 
7006         unsigned int const majorVersion;
7007         unsigned int const minorVersion;
7008         unsigned int const patchNumber;
7009 
7010         // buildNumber is only used if branchName is not null
7011         char const * const branchName;
7012         unsigned int const buildNumber;
7013 
7014         friend std::ostream& operator << ( std::ostream& os, Version const& version );
7015 
7016     private:
7017         void operator=( Version const& );
7018     };
7019 
7020     inline Version libraryVersion();
7021 }
7022 
7023 #include <fstream>
7024 #include <stdlib.h>
7025 #include <limits>
7026 
7027 namespace Catch {
7028 
createReporter(std::string const & reporterName,Ptr<Config> const & config)7029     Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
7030         Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
7031         if( !reporter ) {
7032             std::ostringstream oss;
7033             oss << "No reporter registered with name: '" << reporterName << "'";
7034             throw std::domain_error( oss.str() );
7035         }
7036         return reporter;
7037     }
7038 
7039 #if !defined(CATCH_CONFIG_DEFAULT_REPORTER)
7040 #define CATCH_CONFIG_DEFAULT_REPORTER "console"
7041 #endif
7042 
makeReporter(Ptr<Config> const & config)7043     Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
7044         std::vector<std::string> reporters = config->getReporterNames();
7045         if( reporters.empty() )
7046             reporters.push_back( CATCH_CONFIG_DEFAULT_REPORTER );
7047 
7048         Ptr<IStreamingReporter> reporter;
7049         for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
7050                 it != itEnd;
7051                 ++it )
7052             reporter = addReporter( reporter, createReporter( *it, config ) );
7053         return reporter;
7054     }
addListeners(Ptr<IConfig const> const & config,Ptr<IStreamingReporter> reporters)7055     Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
7056         IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
7057         for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
7058                 it != itEnd;
7059                 ++it )
7060             reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
7061         return reporters;
7062     }
7063 
runTests(Ptr<Config> const & config)7064     Totals runTests( Ptr<Config> const& config ) {
7065 
7066         Ptr<IConfig const> iconfig = config.get();
7067 
7068         Ptr<IStreamingReporter> reporter = makeReporter( config );
7069         reporter = addListeners( iconfig, reporter );
7070 
7071         RunContext context( iconfig, reporter );
7072 
7073         Totals totals;
7074 
7075         context.testGroupStarting( config->name(), 1, 1 );
7076 
7077         TestSpec testSpec = config->testSpec();
7078         if( !testSpec.hasFilters() )
7079             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
7080 
7081         std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
7082         for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
7083                 it != itEnd;
7084                 ++it ) {
7085             if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
7086                 totals += context.runTest( *it );
7087             else
7088                 reporter->skipTest( *it );
7089         }
7090 
7091         context.testGroupEnded( iconfig->name(), totals, 1, 1 );
7092         return totals;
7093     }
7094 
applyFilenamesAsTags(IConfig const & config)7095     void applyFilenamesAsTags( IConfig const& config ) {
7096         std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
7097         for(std::size_t i = 0; i < tests.size(); ++i ) {
7098             TestCase& test = const_cast<TestCase&>( tests[i] );
7099             std::set<std::string> tags = test.tags;
7100 
7101             std::string filename = test.lineInfo.file;
7102             std::string::size_type lastSlash = filename.find_last_of( "\\/" );
7103             if( lastSlash != std::string::npos )
7104                 filename = filename.substr( lastSlash+1 );
7105 
7106             std::string::size_type lastDot = filename.find_last_of( '.' );
7107             if( lastDot != std::string::npos )
7108                 filename = filename.substr( 0, lastDot );
7109 
7110             tags.insert( '#' + filename );
7111             setTags( test, tags );
7112         }
7113     }
7114 
7115     class Session : NonCopyable {
7116         static bool alreadyInstantiated;
7117 
7118     public:
7119 
7120         struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
7121 
Session()7122         Session()
7123         : m_cli( makeCommandLineParser() ) {
7124             if( alreadyInstantiated ) {
7125                 std::string msg = "Only one instance of Catch::Session can ever be used";
7126                 Catch::cerr() << msg << std::endl;
7127                 throw std::logic_error( msg );
7128             }
7129             alreadyInstantiated = true;
7130         }
~Session()7131         ~Session() {
7132             Catch::cleanUp();
7133         }
7134 
showHelp(std::string const & processName)7135         void showHelp( std::string const& processName ) {
7136             Catch::cout() << "\nCatch v" << libraryVersion() << "\n";
7137 
7138             m_cli.usage( Catch::cout(), processName );
7139             Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
7140         }
libIdentify()7141         void libIdentify() {
7142             Catch::cout()
7143                     << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
7144                     << std::left << std::setw(16) << "category: " << "testframework\n"
7145                     << std::left << std::setw(16) << "framework: " << "Catch Test\n"
7146                     << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
7147         }
7148 
applyCommandLine(int argc,char const * const * const argv,OnUnusedOptions::DoWhat unusedOptionBehaviour=OnUnusedOptions::Fail)7149         int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
7150             try {
7151                 m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
7152                 m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );
7153                 if( m_configData.showHelp )
7154                     showHelp( m_configData.processName );
7155                 if( m_configData.libIdentify )
7156                     libIdentify();
7157                 m_config.reset();
7158             }
7159             catch( std::exception& ex ) {
7160                 {
7161                     Colour colourGuard( Colour::Red );
7162                     Catch::cerr()
7163                         << "\nError(s) in input:\n"
7164                         << Text( ex.what(), TextAttributes().setIndent(2) )
7165                         << "\n\n";
7166                 }
7167                 m_cli.usage( Catch::cout(), m_configData.processName );
7168                 return (std::numeric_limits<int>::max)();
7169             }
7170             return 0;
7171         }
7172 
useConfigData(ConfigData const & _configData)7173         void useConfigData( ConfigData const& _configData ) {
7174             m_configData = _configData;
7175             m_config.reset();
7176         }
7177 
run(int argc,char const * const * const argv)7178         int run( int argc, char const* const* const argv ) {
7179 
7180             int returnCode = applyCommandLine( argc, argv );
7181             if( returnCode == 0 )
7182                 returnCode = run();
7183             return returnCode;
7184         }
7185 
7186     #if defined(WIN32) && defined(UNICODE)
run(int argc,wchar_t const * const * const argv)7187         int run( int argc, wchar_t const* const* const argv ) {
7188 
7189             char **utf8Argv = new char *[ argc ];
7190 
7191             for ( int i = 0; i < argc; ++i ) {
7192                 int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
7193 
7194                 utf8Argv[ i ] = new char[ bufSize ];
7195 
7196                 WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
7197             }
7198 
7199             int returnCode = applyCommandLine( argc, utf8Argv );
7200             if( returnCode == 0 )
7201                 returnCode = run();
7202 
7203             for ( int i = 0; i < argc; ++i )
7204                 delete [] utf8Argv[ i ];
7205 
7206             delete [] utf8Argv;
7207 
7208             return returnCode;
7209         }
7210     #endif
7211 
run()7212         int run() {
7213             if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
7214                 Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
7215                 static_cast<void>(std::getchar());
7216             }
7217             int exitCode = runInternal();
7218             if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
7219                 Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
7220                 static_cast<void>(std::getchar());
7221             }
7222             return exitCode;
7223         }
7224 
cli() const7225         Clara::CommandLine<ConfigData> const& cli() const {
7226             return m_cli;
7227         }
unusedTokens() const7228         std::vector<Clara::Parser::Token> const& unusedTokens() const {
7229             return m_unusedTokens;
7230         }
configData()7231         ConfigData& configData() {
7232             return m_configData;
7233         }
config()7234         Config& config() {
7235             if( !m_config )
7236                 m_config = new Config( m_configData );
7237             return *m_config;
7238         }
7239     private:
7240 
runInternal()7241         int runInternal() {
7242             if( m_configData.showHelp || m_configData.libIdentify )
7243                 return 0;
7244 
7245             try
7246             {
7247                 config(); // Force config to be constructed
7248 
7249                 seedRng( *m_config );
7250 
7251                 if( m_configData.filenamesAsTags )
7252                     applyFilenamesAsTags( *m_config );
7253 
7254                 // Handle list request
7255                 if( Option<std::size_t> listed = list( config() ) )
7256                     return static_cast<int>( *listed );
7257 
7258                 return static_cast<int>( runTests( m_config ).assertions.failed );
7259             }
7260             catch( std::exception& ex ) {
7261                 Catch::cerr() << ex.what() << std::endl;
7262                 return (std::numeric_limits<int>::max)();
7263             }
7264         }
7265 
7266         Clara::CommandLine<ConfigData> m_cli;
7267         std::vector<Clara::Parser::Token> m_unusedTokens;
7268         ConfigData m_configData;
7269         Ptr<Config> m_config;
7270     };
7271 
7272     bool Session::alreadyInstantiated = false;
7273 
7274 } // end namespace Catch
7275 
7276 // #included from: catch_registry_hub.hpp
7277 #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
7278 
7279 // #included from: catch_test_case_registry_impl.hpp
7280 #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
7281 
7282 #include <vector>
7283 #include <set>
7284 #include <sstream>
7285 #include <algorithm>
7286 
7287 namespace Catch {
7288 
7289     struct RandomNumberGenerator {
7290         typedef unsigned int result_type;
7291 
operator ()Catch::RandomNumberGenerator7292         result_type operator()( result_type n ) const { return std::rand() % n; }
7293 
7294 #ifdef CATCH_CONFIG_CPP11_SHUFFLE
minCatch::RandomNumberGenerator7295         static constexpr result_type min() { return 0; }
maxCatch::RandomNumberGenerator7296         static constexpr result_type max() { return 1000000; }
operator ()Catch::RandomNumberGenerator7297         result_type operator()() const { return std::rand() % max(); }
7298 #endif
7299         template<typename V>
shuffleCatch::RandomNumberGenerator7300         static void shuffle( V& vector ) {
7301             RandomNumberGenerator rng;
7302 #ifdef CATCH_CONFIG_CPP11_SHUFFLE
7303             std::shuffle( vector.begin(), vector.end(), rng );
7304 #else
7305             std::random_shuffle( vector.begin(), vector.end(), rng );
7306 #endif
7307         }
7308     };
7309 
sortTests(IConfig const & config,std::vector<TestCase> const & unsortedTestCases)7310     inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
7311 
7312         std::vector<TestCase> sorted = unsortedTestCases;
7313 
7314         switch( config.runOrder() ) {
7315             case RunTests::InLexicographicalOrder:
7316                 std::sort( sorted.begin(), sorted.end() );
7317                 break;
7318             case RunTests::InRandomOrder:
7319                 {
7320                     seedRng( config );
7321                     RandomNumberGenerator::shuffle( sorted );
7322                 }
7323                 break;
7324             case RunTests::InDeclarationOrder:
7325                 // already in declaration order
7326                 break;
7327         }
7328         return sorted;
7329     }
matchTest(TestCase const & testCase,TestSpec const & testSpec,IConfig const & config)7330     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
7331         return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
7332     }
7333 
enforceNoDuplicateTestCases(std::vector<TestCase> const & functions)7334     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
7335         std::set<TestCase> seenFunctions;
7336         for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
7337             it != itEnd;
7338             ++it ) {
7339             std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
7340             if( !prev.second ) {
7341                 std::ostringstream ss;
7342 
7343                 ss  << Colour( Colour::Red )
7344                     << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
7345                     << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << '\n'
7346                     << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
7347 
7348                 throw std::runtime_error(ss.str());
7349             }
7350         }
7351     }
7352 
filterTests(std::vector<TestCase> const & testCases,TestSpec const & testSpec,IConfig const & config)7353     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
7354         std::vector<TestCase> filtered;
7355         filtered.reserve( testCases.size() );
7356         for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
7357                 it != itEnd;
7358                 ++it )
7359             if( matchTest( *it, testSpec, config ) )
7360                 filtered.push_back( *it );
7361         return filtered;
7362     }
getAllTestCasesSorted(IConfig const & config)7363     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
7364         return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
7365     }
7366 
7367     class TestRegistry : public ITestCaseRegistry {
7368     public:
TestRegistry()7369         TestRegistry()
7370         :   m_currentSortOrder( RunTests::InDeclarationOrder ),
7371             m_unnamedCount( 0 )
7372         {}
7373         virtual ~TestRegistry();
7374 
registerTest(TestCase const & testCase)7375         virtual void registerTest( TestCase const& testCase ) {
7376             std::string name = testCase.getTestCaseInfo().name;
7377             if( name.empty() ) {
7378                 std::ostringstream oss;
7379                 oss << "Anonymous test case " << ++m_unnamedCount;
7380                 return registerTest( testCase.withName( oss.str() ) );
7381             }
7382             m_functions.push_back( testCase );
7383         }
7384 
getAllTests() const7385         virtual std::vector<TestCase> const& getAllTests() const {
7386             return m_functions;
7387         }
getAllTestsSorted(IConfig const & config) const7388         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
7389             if( m_sortedFunctions.empty() )
7390                 enforceNoDuplicateTestCases( m_functions );
7391 
7392             if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
7393                 m_sortedFunctions = sortTests( config, m_functions );
7394                 m_currentSortOrder = config.runOrder();
7395             }
7396             return m_sortedFunctions;
7397         }
7398 
7399     private:
7400         std::vector<TestCase> m_functions;
7401         mutable RunTests::InWhatOrder m_currentSortOrder;
7402         mutable std::vector<TestCase> m_sortedFunctions;
7403         size_t m_unnamedCount;
7404         std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
7405     };
7406 
7407     ///////////////////////////////////////////////////////////////////////////
7408 
7409     class FreeFunctionTestCase : public SharedImpl<ITestCase> {
7410     public:
7411 
FreeFunctionTestCase(TestFunction fun)7412         FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
7413 
invoke() const7414         virtual void invoke() const {
7415             m_fun();
7416         }
7417 
7418     private:
7419         virtual ~FreeFunctionTestCase();
7420 
7421         TestFunction m_fun;
7422     };
7423 
extractClassName(std::string const & classOrQualifiedMethodName)7424     inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
7425         std::string className = classOrQualifiedMethodName;
7426         if( startsWith( className, '&' ) )
7427         {
7428             std::size_t lastColons = className.rfind( "::" );
7429             std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
7430             if( penultimateColons == std::string::npos )
7431                 penultimateColons = 1;
7432             className = className.substr( penultimateColons, lastColons-penultimateColons );
7433         }
7434         return className;
7435     }
7436 
registerTestCase(ITestCase * testCase,char const * classOrQualifiedMethodName,NameAndDesc const & nameAndDesc,SourceLineInfo const & lineInfo)7437     void registerTestCase
7438         (   ITestCase* testCase,
7439             char const* classOrQualifiedMethodName,
7440             NameAndDesc const& nameAndDesc,
7441             SourceLineInfo const& lineInfo ) {
7442 
7443         getMutableRegistryHub().registerTest
7444             ( makeTestCase
7445                 (   testCase,
7446                     extractClassName( classOrQualifiedMethodName ),
7447                     nameAndDesc.name,
7448                     nameAndDesc.description,
7449                     lineInfo ) );
7450     }
registerTestCaseFunction(TestFunction function,SourceLineInfo const & lineInfo,NameAndDesc const & nameAndDesc)7451     void registerTestCaseFunction
7452         (   TestFunction function,
7453             SourceLineInfo const& lineInfo,
7454             NameAndDesc const& nameAndDesc ) {
7455         registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
7456     }
7457 
7458     ///////////////////////////////////////////////////////////////////////////
7459 
AutoReg(TestFunction function,SourceLineInfo const & lineInfo,NameAndDesc const & nameAndDesc)7460     AutoReg::AutoReg
7461         (   TestFunction function,
7462             SourceLineInfo const& lineInfo,
7463             NameAndDesc const& nameAndDesc ) {
7464         registerTestCaseFunction( function, lineInfo, nameAndDesc );
7465     }
7466 
~AutoReg()7467     AutoReg::~AutoReg() {}
7468 
7469 } // end namespace Catch
7470 
7471 // #included from: catch_reporter_registry.hpp
7472 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
7473 
7474 #include <map>
7475 
7476 namespace Catch {
7477 
7478     class ReporterRegistry : public IReporterRegistry {
7479 
7480     public:
7481 
~ReporterRegistry()7482         virtual ~ReporterRegistry() CATCH_OVERRIDE {}
7483 
create(std::string const & name,Ptr<IConfig const> const & config) const7484         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
7485             FactoryMap::const_iterator it =  m_factories.find( name );
7486             if( it == m_factories.end() )
7487                 return CATCH_NULL;
7488             return it->second->create( ReporterConfig( config ) );
7489         }
7490 
registerReporter(std::string const & name,Ptr<IReporterFactory> const & factory)7491         void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
7492             m_factories.insert( std::make_pair( name, factory ) );
7493         }
registerListener(Ptr<IReporterFactory> const & factory)7494         void registerListener( Ptr<IReporterFactory> const& factory ) {
7495             m_listeners.push_back( factory );
7496         }
7497 
getFactories() const7498         virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {
7499             return m_factories;
7500         }
getListeners() const7501         virtual Listeners const& getListeners() const CATCH_OVERRIDE {
7502             return m_listeners;
7503         }
7504 
7505     private:
7506         FactoryMap m_factories;
7507         Listeners m_listeners;
7508     };
7509 }
7510 
7511 // #included from: catch_exception_translator_registry.hpp
7512 #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
7513 
7514 #ifdef __OBJC__
7515 #import "Foundation/Foundation.h"
7516 #endif
7517 
7518 namespace Catch {
7519 
7520     class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
7521     public:
~ExceptionTranslatorRegistry()7522         ~ExceptionTranslatorRegistry() {
7523             deleteAll( m_translators );
7524         }
7525 
registerTranslator(const IExceptionTranslator * translator)7526         virtual void registerTranslator( const IExceptionTranslator* translator ) {
7527             m_translators.push_back( translator );
7528         }
7529 
translateActiveException() const7530         virtual std::string translateActiveException() const {
7531             try {
7532 #ifdef __OBJC__
7533                 // In Objective-C try objective-c exceptions first
7534                 @try {
7535                     return tryTranslators();
7536                 }
7537                 @catch (NSException *exception) {
7538                     return Catch::toString( [exception description] );
7539                 }
7540 #else
7541                 return tryTranslators();
7542 #endif
7543             }
7544             catch( TestFailureException& ) {
7545                 throw;
7546             }
7547             catch( std::exception& ex ) {
7548                 return ex.what();
7549             }
7550             catch( std::string& msg ) {
7551                 return msg;
7552             }
7553             catch( const char* msg ) {
7554                 return msg;
7555             }
7556             catch(...) {
7557                 return "Unknown exception";
7558             }
7559         }
7560 
tryTranslators() const7561         std::string tryTranslators() const {
7562             if( m_translators.empty() )
7563                 throw;
7564             else
7565                 return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
7566         }
7567 
7568     private:
7569         std::vector<const IExceptionTranslator*> m_translators;
7570     };
7571 }
7572 
7573 // #included from: catch_tag_alias_registry.h
7574 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
7575 
7576 #include <map>
7577 
7578 namespace Catch {
7579 
7580     class TagAliasRegistry : public ITagAliasRegistry {
7581     public:
7582         virtual ~TagAliasRegistry();
7583         virtual Option<TagAlias> find( std::string const& alias ) const;
7584         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
7585         void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
7586 
7587     private:
7588         std::map<std::string, TagAlias> m_registry;
7589     };
7590 
7591 } // end namespace Catch
7592 
7593 namespace Catch {
7594 
7595     namespace {
7596 
7597         class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
7598 
7599             RegistryHub( RegistryHub const& );
7600             void operator=( RegistryHub const& );
7601 
7602         public: // IRegistryHub
RegistryHub()7603             RegistryHub() {
7604             }
getReporterRegistry() const7605             virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {
7606                 return m_reporterRegistry;
7607             }
getTestCaseRegistry() const7608             virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {
7609                 return m_testCaseRegistry;
7610             }
getExceptionTranslatorRegistry()7611             virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
7612                 return m_exceptionTranslatorRegistry;
7613             }
getTagAliasRegistry() const7614             virtual ITagAliasRegistry const& getTagAliasRegistry() const CATCH_OVERRIDE {
7615                 return m_tagAliasRegistry;
7616             }
7617 
7618         public: // IMutableRegistryHub
registerReporter(std::string const & name,Ptr<IReporterFactory> const & factory)7619             virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
7620                 m_reporterRegistry.registerReporter( name, factory );
7621             }
registerListener(Ptr<IReporterFactory> const & factory)7622             virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
7623                 m_reporterRegistry.registerListener( factory );
7624             }
registerTest(TestCase const & testInfo)7625             virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {
7626                 m_testCaseRegistry.registerTest( testInfo );
7627             }
registerTranslator(const IExceptionTranslator * translator)7628             virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
7629                 m_exceptionTranslatorRegistry.registerTranslator( translator );
7630             }
registerTagAlias(std::string const & alias,std::string const & tag,SourceLineInfo const & lineInfo)7631             virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) CATCH_OVERRIDE {
7632                 m_tagAliasRegistry.add( alias, tag, lineInfo );
7633             }
7634 
7635         private:
7636             TestRegistry m_testCaseRegistry;
7637             ReporterRegistry m_reporterRegistry;
7638             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
7639             TagAliasRegistry m_tagAliasRegistry;
7640         };
7641 
7642         // Single, global, instance
getTheRegistryHub()7643         inline RegistryHub*& getTheRegistryHub() {
7644             static RegistryHub* theRegistryHub = CATCH_NULL;
7645             if( !theRegistryHub )
7646                 theRegistryHub = new RegistryHub();
7647             return theRegistryHub;
7648         }
7649     }
7650 
getRegistryHub()7651     IRegistryHub& getRegistryHub() {
7652         return *getTheRegistryHub();
7653     }
getMutableRegistryHub()7654     IMutableRegistryHub& getMutableRegistryHub() {
7655         return *getTheRegistryHub();
7656     }
cleanUp()7657     void cleanUp() {
7658         delete getTheRegistryHub();
7659         getTheRegistryHub() = CATCH_NULL;
7660         cleanUpContext();
7661     }
translateActiveException()7662     std::string translateActiveException() {
7663         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
7664     }
7665 
7666 } // end namespace Catch
7667 
7668 // #included from: catch_notimplemented_exception.hpp
7669 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
7670 
7671 #include <sstream>
7672 
7673 namespace Catch {
7674 
NotImplementedException(SourceLineInfo const & lineInfo)7675     NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
7676     :   m_lineInfo( lineInfo ) {
7677         std::ostringstream oss;
7678         oss << lineInfo << ": function ";
7679         oss << "not implemented";
7680         m_what = oss.str();
7681     }
7682 
what() const7683     const char* NotImplementedException::what() const CATCH_NOEXCEPT {
7684         return m_what.c_str();
7685     }
7686 
7687 } // end namespace Catch
7688 
7689 // #included from: catch_context_impl.hpp
7690 #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
7691 
7692 // #included from: catch_stream.hpp
7693 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
7694 
7695 #include <stdexcept>
7696 #include <cstdio>
7697 #include <iostream>
7698 
7699 namespace Catch {
7700 
7701     template<typename WriterF, size_t bufferSize=256>
7702     class StreamBufImpl : public StreamBufBase {
7703         char data[bufferSize];
7704         WriterF m_writer;
7705 
7706     public:
StreamBufImpl()7707         StreamBufImpl() {
7708             setp( data, data + sizeof(data) );
7709         }
7710 
~StreamBufImpl()7711         ~StreamBufImpl() CATCH_NOEXCEPT {
7712             sync();
7713         }
7714 
7715     private:
overflow(int c)7716         int overflow( int c ) {
7717             sync();
7718 
7719             if( c != EOF ) {
7720                 if( pbase() == epptr() )
7721                     m_writer( std::string( 1, static_cast<char>( c ) ) );
7722                 else
7723                     sputc( static_cast<char>( c ) );
7724             }
7725             return 0;
7726         }
7727 
sync()7728         int sync() {
7729             if( pbase() != pptr() ) {
7730                 m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
7731                 setp( pbase(), epptr() );
7732             }
7733             return 0;
7734         }
7735     };
7736 
7737     ///////////////////////////////////////////////////////////////////////////
7738 
FileStream(std::string const & filename)7739     FileStream::FileStream( std::string const& filename ) {
7740         m_ofs.open( filename.c_str() );
7741         if( m_ofs.fail() ) {
7742             std::ostringstream oss;
7743             oss << "Unable to open file: '" << filename << '\'';
7744             throw std::domain_error( oss.str() );
7745         }
7746     }
7747 
stream() const7748     std::ostream& FileStream::stream() const {
7749         return m_ofs;
7750     }
7751 
7752     struct OutputDebugWriter {
7753 
operator ()Catch::OutputDebugWriter7754         void operator()( std::string const&str ) {
7755             writeToDebugConsole( str );
7756         }
7757     };
7758 
DebugOutStream()7759     DebugOutStream::DebugOutStream()
7760     :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
7761         m_os( m_streamBuf.get() )
7762     {}
7763 
stream() const7764     std::ostream& DebugOutStream::stream() const {
7765         return m_os;
7766     }
7767 
7768     // Store the streambuf from cout up-front because
7769     // cout may get redirected when running tests
CoutStream()7770     CoutStream::CoutStream()
7771     :   m_os( Catch::cout().rdbuf() )
7772     {}
7773 
stream() const7774     std::ostream& CoutStream::stream() const {
7775         return m_os;
7776     }
7777 
7778 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
cout()7779     std::ostream& cout() {
7780         return std::cout;
7781     }
cerr()7782     std::ostream& cerr() {
7783         return std::cerr;
7784     }
clog()7785     std::ostream& clog() {
7786         return std::clog;
7787     }
7788 #endif
7789 }
7790 
7791 namespace Catch {
7792 
7793     class Context : public IMutableContext {
7794 
Context()7795         Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
7796         Context( Context const& );
7797         void operator=( Context const& );
7798 
7799     public:
~Context()7800         virtual ~Context() {
7801             deleteAllValues( m_generatorsByTestName );
7802         }
7803 
7804     public: // IContext
getResultCapture()7805         virtual IResultCapture* getResultCapture() {
7806             return m_resultCapture;
7807         }
getRunner()7808         virtual IRunner* getRunner() {
7809             return m_runner;
7810         }
getGeneratorIndex(std::string const & fileInfo,size_t totalSize)7811         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
7812             return getGeneratorsForCurrentTest()
7813             .getGeneratorInfo( fileInfo, totalSize )
7814             .getCurrentIndex();
7815         }
advanceGeneratorsForCurrentTest()7816         virtual bool advanceGeneratorsForCurrentTest() {
7817             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
7818             return generators && generators->moveNext();
7819         }
7820 
getConfig() const7821         virtual Ptr<IConfig const> getConfig() const {
7822             return m_config;
7823         }
7824 
7825     public: // IMutableContext
setResultCapture(IResultCapture * resultCapture)7826         virtual void setResultCapture( IResultCapture* resultCapture ) {
7827             m_resultCapture = resultCapture;
7828         }
setRunner(IRunner * runner)7829         virtual void setRunner( IRunner* runner ) {
7830             m_runner = runner;
7831         }
setConfig(Ptr<IConfig const> const & config)7832         virtual void setConfig( Ptr<IConfig const> const& config ) {
7833             m_config = config;
7834         }
7835 
7836         friend IMutableContext& getCurrentMutableContext();
7837 
7838     private:
findGeneratorsForCurrentTest()7839         IGeneratorsForTest* findGeneratorsForCurrentTest() {
7840             std::string testName = getResultCapture()->getCurrentTestName();
7841 
7842             std::map<std::string, IGeneratorsForTest*>::const_iterator it =
7843                 m_generatorsByTestName.find( testName );
7844             return it != m_generatorsByTestName.end()
7845                 ? it->second
7846                 : CATCH_NULL;
7847         }
7848 
getGeneratorsForCurrentTest()7849         IGeneratorsForTest& getGeneratorsForCurrentTest() {
7850             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
7851             if( !generators ) {
7852                 std::string testName = getResultCapture()->getCurrentTestName();
7853                 generators = createGeneratorsForTest();
7854                 m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
7855             }
7856             return *generators;
7857         }
7858 
7859     private:
7860         Ptr<IConfig const> m_config;
7861         IRunner* m_runner;
7862         IResultCapture* m_resultCapture;
7863         std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
7864     };
7865 
7866     namespace {
7867         Context* currentContext = CATCH_NULL;
7868     }
getCurrentMutableContext()7869     IMutableContext& getCurrentMutableContext() {
7870         if( !currentContext )
7871             currentContext = new Context();
7872         return *currentContext;
7873     }
getCurrentContext()7874     IContext& getCurrentContext() {
7875         return getCurrentMutableContext();
7876     }
7877 
cleanUpContext()7878     void cleanUpContext() {
7879         delete currentContext;
7880         currentContext = CATCH_NULL;
7881     }
7882 }
7883 
7884 // #included from: catch_console_colour_impl.hpp
7885 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
7886 
7887 // #included from: catch_errno_guard.hpp
7888 #define TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
7889 
7890 #include <cerrno>
7891 
7892 namespace Catch {
7893 
7894     class ErrnoGuard {
7895     public:
ErrnoGuard()7896         ErrnoGuard():m_oldErrno(errno){}
~ErrnoGuard()7897         ~ErrnoGuard() { errno = m_oldErrno; }
7898     private:
7899         int m_oldErrno;
7900     };
7901 
7902 }
7903 
7904 namespace Catch {
7905     namespace {
7906 
7907         struct IColourImpl {
~IColourImplCatch::__anon1fb25a6a0511::IColourImpl7908             virtual ~IColourImpl() {}
7909             virtual void use( Colour::Code _colourCode ) = 0;
7910         };
7911 
7912         struct NoColourImpl : IColourImpl {
useCatch::__anon1fb25a6a0511::NoColourImpl7913             void use( Colour::Code ) {}
7914 
instanceCatch::__anon1fb25a6a0511::NoColourImpl7915             static IColourImpl* instance() {
7916                 static NoColourImpl s_instance;
7917                 return &s_instance;
7918             }
7919         };
7920 
7921     } // anon namespace
7922 } // namespace Catch
7923 
7924 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
7925 #   ifdef CATCH_PLATFORM_WINDOWS
7926 #       define CATCH_CONFIG_COLOUR_WINDOWS
7927 #   else
7928 #       define CATCH_CONFIG_COLOUR_ANSI
7929 #   endif
7930 #endif
7931 
7932 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
7933 
7934 namespace Catch {
7935 namespace {
7936 
7937     class Win32ColourImpl : public IColourImpl {
7938     public:
Win32ColourImpl()7939         Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
7940         {
7941             CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
7942             GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
7943             originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
7944             originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
7945         }
7946 
use(Colour::Code _colourCode)7947         virtual void use( Colour::Code _colourCode ) {
7948             switch( _colourCode ) {
7949                 case Colour::None:      return setTextAttribute( originalForegroundAttributes );
7950                 case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7951                 case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
7952                 case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
7953                 case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
7954                 case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
7955                 case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
7956                 case Colour::Grey:      return setTextAttribute( 0 );
7957 
7958                 case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
7959                 case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
7960                 case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
7961                 case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7962 
7963                 case Colour::Bright: throw std::logic_error( "not a colour" );
7964             }
7965         }
7966 
7967     private:
setTextAttribute(WORD _textAttribute)7968         void setTextAttribute( WORD _textAttribute ) {
7969             SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
7970         }
7971         HANDLE stdoutHandle;
7972         WORD originalForegroundAttributes;
7973         WORD originalBackgroundAttributes;
7974     };
7975 
platformColourInstance()7976     IColourImpl* platformColourInstance() {
7977         static Win32ColourImpl s_instance;
7978 
7979         Ptr<IConfig const> config = getCurrentContext().getConfig();
7980         UseColour::YesOrNo colourMode = config
7981             ? config->useColour()
7982             : UseColour::Auto;
7983         if( colourMode == UseColour::Auto )
7984             colourMode = !isDebuggerActive()
7985                 ? UseColour::Yes
7986                 : UseColour::No;
7987         return colourMode == UseColour::Yes
7988             ? &s_instance
7989             : NoColourImpl::instance();
7990     }
7991 
7992 } // end anon namespace
7993 } // end namespace Catch
7994 
7995 #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
7996 
7997 #include <unistd.h>
7998 
7999 namespace Catch {
8000 namespace {
8001 
8002     // use POSIX/ ANSI console terminal codes
8003     // Thanks to Adam Strzelecki for original contribution
8004     // (http://github.com/nanoant)
8005     // https://github.com/philsquared/Catch/pull/131
8006     class PosixColourImpl : public IColourImpl {
8007     public:
use(Colour::Code _colourCode)8008         virtual void use( Colour::Code _colourCode ) {
8009             switch( _colourCode ) {
8010                 case Colour::None:
8011                 case Colour::White:     return setColour( "[0m" );
8012                 case Colour::Red:       return setColour( "[0;31m" );
8013                 case Colour::Green:     return setColour( "[0;32m" );
8014                 case Colour::Blue:      return setColour( "[0;34m" );
8015                 case Colour::Cyan:      return setColour( "[0;36m" );
8016                 case Colour::Yellow:    return setColour( "[0;33m" );
8017                 case Colour::Grey:      return setColour( "[1;30m" );
8018 
8019                 case Colour::LightGrey:     return setColour( "[0;37m" );
8020                 case Colour::BrightRed:     return setColour( "[1;31m" );
8021                 case Colour::BrightGreen:   return setColour( "[1;32m" );
8022                 case Colour::BrightWhite:   return setColour( "[1;37m" );
8023 
8024                 case Colour::Bright: throw std::logic_error( "not a colour" );
8025             }
8026         }
instance()8027         static IColourImpl* instance() {
8028             static PosixColourImpl s_instance;
8029             return &s_instance;
8030         }
8031 
8032     private:
setColour(const char * _escapeCode)8033         void setColour( const char* _escapeCode ) {
8034             Catch::cout() << '\033' << _escapeCode;
8035         }
8036     };
8037 
platformColourInstance()8038     IColourImpl* platformColourInstance() {
8039         ErrnoGuard guard;
8040         Ptr<IConfig const> config = getCurrentContext().getConfig();
8041         UseColour::YesOrNo colourMode = config
8042             ? config->useColour()
8043             : UseColour::Auto;
8044         if( colourMode == UseColour::Auto )
8045             colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )
8046                 ? UseColour::Yes
8047                 : UseColour::No;
8048         return colourMode == UseColour::Yes
8049             ? PosixColourImpl::instance()
8050             : NoColourImpl::instance();
8051     }
8052 
8053 } // end anon namespace
8054 } // end namespace Catch
8055 
8056 #else  // not Windows or ANSI ///////////////////////////////////////////////
8057 
8058 namespace Catch {
8059 
platformColourInstance()8060     static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
8061 
8062 } // end namespace Catch
8063 
8064 #endif // Windows/ ANSI/ None
8065 
8066 namespace Catch {
8067 
Colour(Code _colourCode)8068     Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
Colour(Colour const & _other)8069     Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
~Colour()8070     Colour::~Colour(){ if( !m_moved ) use( None ); }
8071 
use(Code _colourCode)8072     void Colour::use( Code _colourCode ) {
8073         static IColourImpl* impl = platformColourInstance();
8074         impl->use( _colourCode );
8075     }
8076 
8077 } // end namespace Catch
8078 
8079 // #included from: catch_generators_impl.hpp
8080 #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
8081 
8082 #include <vector>
8083 #include <string>
8084 #include <map>
8085 
8086 namespace Catch {
8087 
8088     struct GeneratorInfo : IGeneratorInfo {
8089 
GeneratorInfoCatch::GeneratorInfo8090         GeneratorInfo( std::size_t size )
8091         :   m_size( size ),
8092             m_currentIndex( 0 )
8093         {}
8094 
moveNextCatch::GeneratorInfo8095         bool moveNext() {
8096             if( ++m_currentIndex == m_size ) {
8097                 m_currentIndex = 0;
8098                 return false;
8099             }
8100             return true;
8101         }
8102 
getCurrentIndexCatch::GeneratorInfo8103         std::size_t getCurrentIndex() const {
8104             return m_currentIndex;
8105         }
8106 
8107         std::size_t m_size;
8108         std::size_t m_currentIndex;
8109     };
8110 
8111     ///////////////////////////////////////////////////////////////////////////
8112 
8113     class GeneratorsForTest : public IGeneratorsForTest {
8114 
8115     public:
~GeneratorsForTest()8116         ~GeneratorsForTest() {
8117             deleteAll( m_generatorsInOrder );
8118         }
8119 
getGeneratorInfo(std::string const & fileInfo,std::size_t size)8120         IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
8121             std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
8122             if( it == m_generatorsByName.end() ) {
8123                 IGeneratorInfo* info = new GeneratorInfo( size );
8124                 m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
8125                 m_generatorsInOrder.push_back( info );
8126                 return *info;
8127             }
8128             return *it->second;
8129         }
8130 
moveNext()8131         bool moveNext() {
8132             std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
8133             std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
8134             for(; it != itEnd; ++it ) {
8135                 if( (*it)->moveNext() )
8136                     return true;
8137             }
8138             return false;
8139         }
8140 
8141     private:
8142         std::map<std::string, IGeneratorInfo*> m_generatorsByName;
8143         std::vector<IGeneratorInfo*> m_generatorsInOrder;
8144     };
8145 
createGeneratorsForTest()8146     IGeneratorsForTest* createGeneratorsForTest()
8147     {
8148         return new GeneratorsForTest();
8149     }
8150 
8151 } // end namespace Catch
8152 
8153 // #included from: catch_assertionresult.hpp
8154 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
8155 
8156 namespace Catch {
8157 
AssertionInfo()8158     AssertionInfo::AssertionInfo():macroName(""), capturedExpression(""), resultDisposition(ResultDisposition::Normal), secondArg(""){}
8159 
AssertionInfo(char const * _macroName,SourceLineInfo const & _lineInfo,char const * _capturedExpression,ResultDisposition::Flags _resultDisposition,char const * _secondArg)8160     AssertionInfo::AssertionInfo(   char const * _macroName,
8161                                     SourceLineInfo const& _lineInfo,
8162                                     char const * _capturedExpression,
8163                                     ResultDisposition::Flags _resultDisposition,
8164                                     char const * _secondArg)
8165     :   macroName( _macroName ),
8166         lineInfo( _lineInfo ),
8167         capturedExpression( _capturedExpression ),
8168         resultDisposition( _resultDisposition ),
8169         secondArg( _secondArg )
8170     {}
8171 
AssertionResult()8172     AssertionResult::AssertionResult() {}
8173 
AssertionResult(AssertionInfo const & info,AssertionResultData const & data)8174     AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
8175     :   m_info( info ),
8176         m_resultData( data )
8177     {}
8178 
~AssertionResult()8179     AssertionResult::~AssertionResult() {}
8180 
8181     // Result was a success
succeeded() const8182     bool AssertionResult::succeeded() const {
8183         return Catch::isOk( m_resultData.resultType );
8184     }
8185 
8186     // Result was a success, or failure is suppressed
isOk() const8187     bool AssertionResult::isOk() const {
8188         return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
8189     }
8190 
getResultType() const8191     ResultWas::OfType AssertionResult::getResultType() const {
8192         return m_resultData.resultType;
8193     }
8194 
hasExpression() const8195     bool AssertionResult::hasExpression() const {
8196         return m_info.capturedExpression[0] != 0;
8197     }
8198 
hasMessage() const8199     bool AssertionResult::hasMessage() const {
8200         return !m_resultData.message.empty();
8201     }
8202 
capturedExpressionWithSecondArgument(char const * capturedExpression,char const * secondArg)8203     std::string capturedExpressionWithSecondArgument( char const * capturedExpression, char const * secondArg ) {
8204         return (secondArg[0] == 0 || secondArg[0] == '"' && secondArg[1] == '"')
8205             ? capturedExpression
8206             : std::string(capturedExpression) + ", " + secondArg;
8207     }
8208 
getExpression() const8209     std::string AssertionResult::getExpression() const {
8210         if( isFalseTest( m_info.resultDisposition ) )
8211             return "!(" + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + ")";
8212         else
8213             return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg);
8214     }
getExpressionInMacro() const8215     std::string AssertionResult::getExpressionInMacro() const {
8216         if( m_info.macroName[0] == 0 )
8217             return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg);
8218         else
8219             return std::string(m_info.macroName) + "( " + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + " )";
8220     }
8221 
hasExpandedExpression() const8222     bool AssertionResult::hasExpandedExpression() const {
8223         return hasExpression() && getExpandedExpression() != getExpression();
8224     }
8225 
getExpandedExpression() const8226     std::string AssertionResult::getExpandedExpression() const {
8227         return m_resultData.reconstructExpression();
8228     }
8229 
getMessage() const8230     std::string AssertionResult::getMessage() const {
8231         return m_resultData.message;
8232     }
getSourceInfo() const8233     SourceLineInfo AssertionResult::getSourceInfo() const {
8234         return m_info.lineInfo;
8235     }
8236 
getTestMacroName() const8237     std::string AssertionResult::getTestMacroName() const {
8238         return m_info.macroName;
8239     }
8240 
discardDecomposedExpression() const8241     void AssertionResult::discardDecomposedExpression() const {
8242         m_resultData.decomposedExpression = CATCH_NULL;
8243     }
8244 
expandDecomposedExpression() const8245     void AssertionResult::expandDecomposedExpression() const {
8246         m_resultData.reconstructExpression();
8247     }
8248 
8249 } // end namespace Catch
8250 
8251 // #included from: catch_test_case_info.hpp
8252 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
8253 
8254 #include <cctype>
8255 
8256 namespace Catch {
8257 
parseSpecialTag(std::string const & tag)8258     inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
8259         if( startsWith( tag, '.' ) ||
8260             tag == "hide" ||
8261             tag == "!hide" )
8262             return TestCaseInfo::IsHidden;
8263         else if( tag == "!throws" )
8264             return TestCaseInfo::Throws;
8265         else if( tag == "!shouldfail" )
8266             return TestCaseInfo::ShouldFail;
8267         else if( tag == "!mayfail" )
8268             return TestCaseInfo::MayFail;
8269         else if( tag == "!nonportable" )
8270             return TestCaseInfo::NonPortable;
8271         else
8272             return TestCaseInfo::None;
8273     }
isReservedTag(std::string const & tag)8274     inline bool isReservedTag( std::string const& tag ) {
8275         return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] );
8276     }
enforceNotReservedTag(std::string const & tag,SourceLineInfo const & _lineInfo)8277     inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
8278         if( isReservedTag( tag ) ) {
8279             std::ostringstream ss;
8280             ss << Colour(Colour::Red)
8281                << "Tag name [" << tag << "] not allowed.\n"
8282                << "Tag names starting with non alpha-numeric characters are reserved\n"
8283                << Colour(Colour::FileName)
8284                << _lineInfo << '\n';
8285             throw std::runtime_error(ss.str());
8286         }
8287     }
8288 
makeTestCase(ITestCase * _testCase,std::string const & _className,std::string const & _name,std::string const & _descOrTags,SourceLineInfo const & _lineInfo)8289     TestCase makeTestCase(  ITestCase* _testCase,
8290                             std::string const& _className,
8291                             std::string const& _name,
8292                             std::string const& _descOrTags,
8293                             SourceLineInfo const& _lineInfo )
8294     {
8295         bool isHidden( startsWith( _name, "./" ) ); // Legacy support
8296 
8297         // Parse out tags
8298         std::set<std::string> tags;
8299         std::string desc, tag;
8300         bool inTag = false;
8301         for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
8302             char c = _descOrTags[i];
8303             if( !inTag ) {
8304                 if( c == '[' )
8305                     inTag = true;
8306                 else
8307                     desc += c;
8308             }
8309             else {
8310                 if( c == ']' ) {
8311                     TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
8312                     if( prop == TestCaseInfo::IsHidden )
8313                         isHidden = true;
8314                     else if( prop == TestCaseInfo::None )
8315                         enforceNotReservedTag( tag, _lineInfo );
8316 
8317                     tags.insert( tag );
8318                     tag.clear();
8319                     inTag = false;
8320                 }
8321                 else
8322                     tag += c;
8323             }
8324         }
8325         if( isHidden ) {
8326             tags.insert( "hide" );
8327             tags.insert( "." );
8328         }
8329 
8330         TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
8331         return TestCase( _testCase, info );
8332     }
8333 
setTags(TestCaseInfo & testCaseInfo,std::set<std::string> const & tags)8334     void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )
8335     {
8336         testCaseInfo.tags = tags;
8337         testCaseInfo.lcaseTags.clear();
8338 
8339         std::ostringstream oss;
8340         for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
8341             oss << '[' << *it << ']';
8342             std::string lcaseTag = toLower( *it );
8343             testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
8344             testCaseInfo.lcaseTags.insert( lcaseTag );
8345         }
8346         testCaseInfo.tagsAsString = oss.str();
8347     }
8348 
TestCaseInfo(std::string const & _name,std::string const & _className,std::string const & _description,std::set<std::string> const & _tags,SourceLineInfo const & _lineInfo)8349     TestCaseInfo::TestCaseInfo( std::string const& _name,
8350                                 std::string const& _className,
8351                                 std::string const& _description,
8352                                 std::set<std::string> const& _tags,
8353                                 SourceLineInfo const& _lineInfo )
8354     :   name( _name ),
8355         className( _className ),
8356         description( _description ),
8357         lineInfo( _lineInfo ),
8358         properties( None )
8359     {
8360         setTags( *this, _tags );
8361     }
8362 
TestCaseInfo(TestCaseInfo const & other)8363     TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
8364     :   name( other.name ),
8365         className( other.className ),
8366         description( other.description ),
8367         tags( other.tags ),
8368         lcaseTags( other.lcaseTags ),
8369         tagsAsString( other.tagsAsString ),
8370         lineInfo( other.lineInfo ),
8371         properties( other.properties )
8372     {}
8373 
isHidden() const8374     bool TestCaseInfo::isHidden() const {
8375         return ( properties & IsHidden ) != 0;
8376     }
throws() const8377     bool TestCaseInfo::throws() const {
8378         return ( properties & Throws ) != 0;
8379     }
okToFail() const8380     bool TestCaseInfo::okToFail() const {
8381         return ( properties & (ShouldFail | MayFail ) ) != 0;
8382     }
expectedToFail() const8383     bool TestCaseInfo::expectedToFail() const {
8384         return ( properties & (ShouldFail ) ) != 0;
8385     }
8386 
TestCase(ITestCase * testCase,TestCaseInfo const & info)8387     TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
8388 
TestCase(TestCase const & other)8389     TestCase::TestCase( TestCase const& other )
8390     :   TestCaseInfo( other ),
8391         test( other.test )
8392     {}
8393 
withName(std::string const & _newName) const8394     TestCase TestCase::withName( std::string const& _newName ) const {
8395         TestCase other( *this );
8396         other.name = _newName;
8397         return other;
8398     }
8399 
swap(TestCase & other)8400     void TestCase::swap( TestCase& other ) {
8401         test.swap( other.test );
8402         name.swap( other.name );
8403         className.swap( other.className );
8404         description.swap( other.description );
8405         tags.swap( other.tags );
8406         lcaseTags.swap( other.lcaseTags );
8407         tagsAsString.swap( other.tagsAsString );
8408         std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
8409         std::swap( lineInfo, other.lineInfo );
8410     }
8411 
invoke() const8412     void TestCase::invoke() const {
8413         test->invoke();
8414     }
8415 
operator ==(TestCase const & other) const8416     bool TestCase::operator == ( TestCase const& other ) const {
8417         return  test.get() == other.test.get() &&
8418                 name == other.name &&
8419                 className == other.className;
8420     }
8421 
operator <(TestCase const & other) const8422     bool TestCase::operator < ( TestCase const& other ) const {
8423         return name < other.name;
8424     }
operator =(TestCase const & other)8425     TestCase& TestCase::operator = ( TestCase const& other ) {
8426         TestCase temp( other );
8427         swap( temp );
8428         return *this;
8429     }
8430 
getTestCaseInfo() const8431     TestCaseInfo const& TestCase::getTestCaseInfo() const
8432     {
8433         return *this;
8434     }
8435 
8436 } // end namespace Catch
8437 
8438 // #included from: catch_version.hpp
8439 #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
8440 
8441 namespace Catch {
8442 
Version(unsigned int _majorVersion,unsigned int _minorVersion,unsigned int _patchNumber,char const * const _branchName,unsigned int _buildNumber)8443     Version::Version
8444         (   unsigned int _majorVersion,
8445             unsigned int _minorVersion,
8446             unsigned int _patchNumber,
8447             char const * const _branchName,
8448             unsigned int _buildNumber )
8449     :   majorVersion( _majorVersion ),
8450         minorVersion( _minorVersion ),
8451         patchNumber( _patchNumber ),
8452         branchName( _branchName ),
8453         buildNumber( _buildNumber )
8454     {}
8455 
operator <<(std::ostream & os,Version const & version)8456     std::ostream& operator << ( std::ostream& os, Version const& version ) {
8457         os  << version.majorVersion << '.'
8458             << version.minorVersion << '.'
8459             << version.patchNumber;
8460         // branchName is never null -> 0th char is \0 if it is empty
8461         if (version.branchName[0]) {
8462             os << '-' << version.branchName
8463                << '.' << version.buildNumber;
8464         }
8465         return os;
8466     }
8467 
libraryVersion()8468     inline Version libraryVersion() {
8469         static Version version( 1, 12, 0, "", 0 );
8470         return version;
8471     }
8472 
8473 }
8474 
8475 // #included from: catch_message.hpp
8476 #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
8477 
8478 namespace Catch {
8479 
MessageInfo(std::string const & _macroName,SourceLineInfo const & _lineInfo,ResultWas::OfType _type)8480     MessageInfo::MessageInfo(   std::string const& _macroName,
8481                                 SourceLineInfo const& _lineInfo,
8482                                 ResultWas::OfType _type )
8483     :   macroName( _macroName ),
8484         lineInfo( _lineInfo ),
8485         type( _type ),
8486         sequence( ++globalCount )
8487     {}
8488 
8489     // This may need protecting if threading support is added
8490     unsigned int MessageInfo::globalCount = 0;
8491 
8492     ////////////////////////////////////////////////////////////////////////////
8493 
ScopedMessage(MessageBuilder const & builder)8494     ScopedMessage::ScopedMessage( MessageBuilder const& builder )
8495     : m_info( builder.m_info )
8496     {
8497         m_info.message = builder.m_stream.str();
8498         getResultCapture().pushScopedMessage( m_info );
8499     }
ScopedMessage(ScopedMessage const & other)8500     ScopedMessage::ScopedMessage( ScopedMessage const& other )
8501     : m_info( other.m_info )
8502     {}
8503 
~ScopedMessage()8504     ScopedMessage::~ScopedMessage() {
8505         if ( !std::uncaught_exception() ){
8506             getResultCapture().popScopedMessage(m_info);
8507         }
8508     }
8509 
8510 } // end namespace Catch
8511 
8512 // #included from: catch_legacy_reporter_adapter.hpp
8513 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
8514 
8515 // #included from: catch_legacy_reporter_adapter.h
8516 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
8517 
8518 namespace Catch
8519 {
8520     // Deprecated
8521     struct IReporter : IShared {
8522         virtual ~IReporter();
8523 
8524         virtual bool shouldRedirectStdout() const = 0;
8525 
8526         virtual void StartTesting() = 0;
8527         virtual void EndTesting( Totals const& totals ) = 0;
8528         virtual void StartGroup( std::string const& groupName ) = 0;
8529         virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
8530         virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
8531         virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
8532         virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
8533         virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
8534         virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
8535         virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
8536         virtual void Aborted() = 0;
8537         virtual void Result( AssertionResult const& result ) = 0;
8538     };
8539 
8540     class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
8541     {
8542     public:
8543         LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
8544         virtual ~LegacyReporterAdapter();
8545 
8546         virtual ReporterPreferences getPreferences() const;
8547         virtual void noMatchingTestCases( std::string const& );
8548         virtual void testRunStarting( TestRunInfo const& );
8549         virtual void testGroupStarting( GroupInfo const& groupInfo );
8550         virtual void testCaseStarting( TestCaseInfo const& testInfo );
8551         virtual void sectionStarting( SectionInfo const& sectionInfo );
8552         virtual void assertionStarting( AssertionInfo const& );
8553         virtual bool assertionEnded( AssertionStats const& assertionStats );
8554         virtual void sectionEnded( SectionStats const& sectionStats );
8555         virtual void testCaseEnded( TestCaseStats const& testCaseStats );
8556         virtual void testGroupEnded( TestGroupStats const& testGroupStats );
8557         virtual void testRunEnded( TestRunStats const& testRunStats );
8558         virtual void skipTest( TestCaseInfo const& );
8559 
8560     private:
8561         Ptr<IReporter> m_legacyReporter;
8562     };
8563 }
8564 
8565 namespace Catch
8566 {
LegacyReporterAdapter(Ptr<IReporter> const & legacyReporter)8567     LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
8568     :   m_legacyReporter( legacyReporter )
8569     {}
~LegacyReporterAdapter()8570     LegacyReporterAdapter::~LegacyReporterAdapter() {}
8571 
getPreferences() const8572     ReporterPreferences LegacyReporterAdapter::getPreferences() const {
8573         ReporterPreferences prefs;
8574         prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
8575         return prefs;
8576     }
8577 
noMatchingTestCases(std::string const &)8578     void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
testRunStarting(TestRunInfo const &)8579     void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
8580         m_legacyReporter->StartTesting();
8581     }
testGroupStarting(GroupInfo const & groupInfo)8582     void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
8583         m_legacyReporter->StartGroup( groupInfo.name );
8584     }
testCaseStarting(TestCaseInfo const & testInfo)8585     void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
8586         m_legacyReporter->StartTestCase( testInfo );
8587     }
sectionStarting(SectionInfo const & sectionInfo)8588     void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
8589         m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
8590     }
assertionStarting(AssertionInfo const &)8591     void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
8592         // Not on legacy interface
8593     }
8594 
assertionEnded(AssertionStats const & assertionStats)8595     bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
8596         if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
8597             for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
8598                     it != itEnd;
8599                     ++it ) {
8600                 if( it->type == ResultWas::Info ) {
8601                     ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
8602                     rb << it->message;
8603                     rb.setResultType( ResultWas::Info );
8604                     AssertionResult result = rb.build();
8605                     m_legacyReporter->Result( result );
8606                 }
8607             }
8608         }
8609         m_legacyReporter->Result( assertionStats.assertionResult );
8610         return true;
8611     }
sectionEnded(SectionStats const & sectionStats)8612     void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
8613         if( sectionStats.missingAssertions )
8614             m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
8615         m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
8616     }
testCaseEnded(TestCaseStats const & testCaseStats)8617     void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
8618         m_legacyReporter->EndTestCase
8619             (   testCaseStats.testInfo,
8620                 testCaseStats.totals,
8621                 testCaseStats.stdOut,
8622                 testCaseStats.stdErr );
8623     }
testGroupEnded(TestGroupStats const & testGroupStats)8624     void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
8625         if( testGroupStats.aborting )
8626             m_legacyReporter->Aborted();
8627         m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
8628     }
testRunEnded(TestRunStats const & testRunStats)8629     void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
8630         m_legacyReporter->EndTesting( testRunStats.totals );
8631     }
skipTest(TestCaseInfo const &)8632     void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
8633     }
8634 }
8635 
8636 // #included from: catch_timer.hpp
8637 
8638 #ifdef __clang__
8639 #pragma clang diagnostic push
8640 #pragma clang diagnostic ignored "-Wc++11-long-long"
8641 #endif
8642 
8643 #ifdef CATCH_PLATFORM_WINDOWS
8644 
8645 #else
8646 
8647 #include <sys/time.h>
8648 
8649 #endif
8650 
8651 namespace Catch {
8652 
8653     namespace {
8654 #ifdef CATCH_PLATFORM_WINDOWS
getCurrentTicks()8655         UInt64 getCurrentTicks() {
8656             static UInt64 hz=0, hzo=0;
8657             if (!hz) {
8658                 QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
8659                 QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
8660             }
8661             UInt64 t;
8662             QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
8663             return ((t-hzo)*1000000)/hz;
8664         }
8665 #else
8666         UInt64 getCurrentTicks() {
8667             timeval t;
8668             gettimeofday(&t,CATCH_NULL);
8669             return static_cast<UInt64>( t.tv_sec ) * 1000000ull + static_cast<UInt64>( t.tv_usec );
8670         }
8671 #endif
8672     }
8673 
start()8674     void Timer::start() {
8675         m_ticks = getCurrentTicks();
8676     }
getElapsedMicroseconds() const8677     unsigned int Timer::getElapsedMicroseconds() const {
8678         return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
8679     }
getElapsedMilliseconds() const8680     unsigned int Timer::getElapsedMilliseconds() const {
8681         return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
8682     }
getElapsedSeconds() const8683     double Timer::getElapsedSeconds() const {
8684         return getElapsedMicroseconds()/1000000.0;
8685     }
8686 
8687 } // namespace Catch
8688 
8689 #ifdef __clang__
8690 #pragma clang diagnostic pop
8691 #endif
8692 // #included from: catch_common.hpp
8693 #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
8694 
8695 #include <cstring>
8696 #include <cctype>
8697 
8698 namespace Catch {
8699 
startsWith(std::string const & s,std::string const & prefix)8700     bool startsWith( std::string const& s, std::string const& prefix ) {
8701         return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
8702     }
startsWith(std::string const & s,char prefix)8703     bool startsWith( std::string const& s, char prefix ) {
8704         return !s.empty() && s[0] == prefix;
8705     }
endsWith(std::string const & s,std::string const & suffix)8706     bool endsWith( std::string const& s, std::string const& suffix ) {
8707         return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
8708     }
endsWith(std::string const & s,char suffix)8709     bool endsWith( std::string const& s, char suffix ) {
8710         return !s.empty() && s[s.size()-1] == suffix;
8711     }
contains(std::string const & s,std::string const & infix)8712     bool contains( std::string const& s, std::string const& infix ) {
8713         return s.find( infix ) != std::string::npos;
8714     }
toLowerCh(char c)8715     char toLowerCh(char c) {
8716         return static_cast<char>( std::tolower( c ) );
8717     }
toLowerInPlace(std::string & s)8718     void toLowerInPlace( std::string& s ) {
8719         std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
8720     }
toLower(std::string const & s)8721     std::string toLower( std::string const& s ) {
8722         std::string lc = s;
8723         toLowerInPlace( lc );
8724         return lc;
8725     }
trim(std::string const & str)8726     std::string trim( std::string const& str ) {
8727         static char const* whitespaceChars = "\n\r\t ";
8728         std::string::size_type start = str.find_first_not_of( whitespaceChars );
8729         std::string::size_type end = str.find_last_not_of( whitespaceChars );
8730 
8731         return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
8732     }
8733 
replaceInPlace(std::string & str,std::string const & replaceThis,std::string const & withThis)8734     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
8735         bool replaced = false;
8736         std::size_t i = str.find( replaceThis );
8737         while( i != std::string::npos ) {
8738             replaced = true;
8739             str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
8740             if( i < str.size()-withThis.size() )
8741                 i = str.find( replaceThis, i+withThis.size() );
8742             else
8743                 i = std::string::npos;
8744         }
8745         return replaced;
8746     }
8747 
pluralise(std::size_t count,std::string const & label)8748     pluralise::pluralise( std::size_t count, std::string const& label )
8749     :   m_count( count ),
8750         m_label( label )
8751     {}
8752 
operator <<(std::ostream & os,pluralise const & pluraliser)8753     std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
8754         os << pluraliser.m_count << ' ' << pluraliser.m_label;
8755         if( pluraliser.m_count != 1 )
8756             os << 's';
8757         return os;
8758     }
8759 
SourceLineInfo()8760     SourceLineInfo::SourceLineInfo() : file(""), line( 0 ){}
SourceLineInfo(char const * _file,std::size_t _line)8761     SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
8762     :   file( _file ),
8763         line( _line )
8764     {}
empty() const8765     bool SourceLineInfo::empty() const {
8766         return file[0] == '\0';
8767     }
operator ==(SourceLineInfo const & other) const8768     bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
8769         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
8770     }
operator <(SourceLineInfo const & other) const8771     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
8772         return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0));
8773     }
8774 
seedRng(IConfig const & config)8775     void seedRng( IConfig const& config ) {
8776         if( config.rngSeed() != 0 )
8777             std::srand( config.rngSeed() );
8778     }
rngSeed()8779     unsigned int rngSeed() {
8780         return getCurrentContext().getConfig()->rngSeed();
8781     }
8782 
operator <<(std::ostream & os,SourceLineInfo const & info)8783     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
8784 #ifndef __GNUG__
8785         os << info.file << '(' << info.line << ')';
8786 #else
8787         os << info.file << ':' << info.line;
8788 #endif
8789         return os;
8790     }
8791 
throwLogicError(std::string const & message,SourceLineInfo const & locationInfo)8792     void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
8793         std::ostringstream oss;
8794         oss << locationInfo << ": Internal Catch error: '" << message << '\'';
8795         if( alwaysTrue() )
8796             throw std::logic_error( oss.str() );
8797     }
8798 }
8799 
8800 // #included from: catch_section.hpp
8801 #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
8802 
8803 namespace Catch {
8804 
SectionInfo(SourceLineInfo const & _lineInfo,std::string const & _name,std::string const & _description)8805     SectionInfo::SectionInfo
8806         (   SourceLineInfo const& _lineInfo,
8807             std::string const& _name,
8808             std::string const& _description )
8809     :   name( _name ),
8810         description( _description ),
8811         lineInfo( _lineInfo )
8812     {}
8813 
Section(SectionInfo const & info)8814     Section::Section( SectionInfo const& info )
8815     :   m_info( info ),
8816         m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
8817     {
8818         m_timer.start();
8819     }
8820 
8821 #if defined(_MSC_VER)
8822 #pragma warning(push)
8823 #pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
8824 #endif
~Section()8825     Section::~Section() {
8826         if( m_sectionIncluded ) {
8827             SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
8828             if( std::uncaught_exception() )
8829                 getResultCapture().sectionEndedEarly( endInfo );
8830             else
8831                 getResultCapture().sectionEnded( endInfo );
8832         }
8833     }
8834 #if defined(_MSC_VER)
8835 #pragma warning(pop)
8836 #endif
8837 
8838     // This indicates whether the section should be executed or not
operator bool() const8839     Section::operator bool() const {
8840         return m_sectionIncluded;
8841     }
8842 
8843 } // end namespace Catch
8844 
8845 // #included from: catch_debugger.hpp
8846 #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
8847 
8848 #ifdef CATCH_PLATFORM_MAC
8849 
8850     #include <assert.h>
8851     #include <stdbool.h>
8852     #include <sys/types.h>
8853     #include <unistd.h>
8854     #include <sys/sysctl.h>
8855 
8856     namespace Catch{
8857 
8858         // The following function is taken directly from the following technical note:
8859         // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
8860 
8861         // Returns true if the current process is being debugged (either
8862         // running under the debugger or has a debugger attached post facto).
isDebuggerActive()8863         bool isDebuggerActive(){
8864 
8865             int                 mib[4];
8866             struct kinfo_proc   info;
8867             size_t              size;
8868 
8869             // Initialize the flags so that, if sysctl fails for some bizarre
8870             // reason, we get a predictable result.
8871 
8872             info.kp_proc.p_flag = 0;
8873 
8874             // Initialize mib, which tells sysctl the info we want, in this case
8875             // we're looking for information about a specific process ID.
8876 
8877             mib[0] = CTL_KERN;
8878             mib[1] = KERN_PROC;
8879             mib[2] = KERN_PROC_PID;
8880             mib[3] = getpid();
8881 
8882             // Call sysctl.
8883 
8884             size = sizeof(info);
8885             if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
8886                 Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
8887                 return false;
8888             }
8889 
8890             // We're being debugged if the P_TRACED flag is set.
8891 
8892             return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
8893         }
8894     } // namespace Catch
8895 
8896 #elif defined(CATCH_PLATFORM_LINUX)
8897     #include <fstream>
8898     #include <string>
8899 
8900     namespace Catch{
8901         // The standard POSIX way of detecting a debugger is to attempt to
8902         // ptrace() the process, but this needs to be done from a child and not
8903         // this process itself to still allow attaching to this process later
8904         // if wanted, so is rather heavy. Under Linux we have the PID of the
8905         // "debugger" (which doesn't need to be gdb, of course, it could also
8906         // be strace, for example) in /proc/$PID/status, so just get it from
8907         // there instead.
isDebuggerActive()8908         bool isDebuggerActive(){
8909             // Libstdc++ has a bug, where std::ifstream sets errno to 0
8910             // This way our users can properly assert over errno values
8911             ErrnoGuard guard;
8912             std::ifstream in("/proc/self/status");
8913             for( std::string line; std::getline(in, line); ) {
8914                 static const int PREFIX_LEN = 11;
8915                 if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
8916                     // We're traced if the PID is not 0 and no other PID starts
8917                     // with 0 digit, so it's enough to check for just a single
8918                     // character.
8919                     return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
8920                 }
8921             }
8922 
8923             return false;
8924         }
8925     } // namespace Catch
8926 #elif defined(_MSC_VER)
8927     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
8928     namespace Catch {
isDebuggerActive()8929         bool isDebuggerActive() {
8930             return IsDebuggerPresent() != 0;
8931         }
8932     }
8933 #elif defined(__MINGW32__)
8934     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
8935     namespace Catch {
isDebuggerActive()8936         bool isDebuggerActive() {
8937             return IsDebuggerPresent() != 0;
8938         }
8939     }
8940 #else
8941     namespace Catch {
isDebuggerActive()8942        inline bool isDebuggerActive() { return false; }
8943     }
8944 #endif // Platform
8945 
8946 #ifdef CATCH_PLATFORM_WINDOWS
8947 
8948     namespace Catch {
writeToDebugConsole(std::string const & text)8949         void writeToDebugConsole( std::string const& text ) {
8950             ::OutputDebugStringA( text.c_str() );
8951         }
8952     }
8953 #else
8954     namespace Catch {
writeToDebugConsole(std::string const & text)8955         void writeToDebugConsole( std::string const& text ) {
8956             // !TBD: Need a version for Mac/ XCode and other IDEs
8957             Catch::cout() << text;
8958         }
8959     }
8960 #endif // Platform
8961 
8962 // #included from: catch_tostring.hpp
8963 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
8964 
8965 namespace Catch {
8966 
8967 namespace Detail {
8968 
8969     const std::string unprintableString = "{?}";
8970 
8971     namespace {
8972         const int hexThreshold = 255;
8973 
8974         struct Endianness {
8975             enum Arch { Big, Little };
8976 
whichCatch::Detail::__anon1fb25a6a0911::Endianness8977             static Arch which() {
8978                 union _{
8979                     int asInt;
8980                     char asChar[sizeof (int)];
8981                 } u;
8982 
8983                 u.asInt = 1;
8984                 return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
8985             }
8986         };
8987     }
8988 
rawMemoryToString(const void * object,std::size_t size)8989     std::string rawMemoryToString( const void *object, std::size_t size )
8990     {
8991         // Reverse order for little endian architectures
8992         int i = 0, end = static_cast<int>( size ), inc = 1;
8993         if( Endianness::which() == Endianness::Little ) {
8994             i = end-1;
8995             end = inc = -1;
8996         }
8997 
8998         unsigned char const *bytes = static_cast<unsigned char const *>(object);
8999         std::ostringstream os;
9000         os << "0x" << std::setfill('0') << std::hex;
9001         for( ; i != end; i += inc )
9002              os << std::setw(2) << static_cast<unsigned>(bytes[i]);
9003        return os.str();
9004     }
9005 }
9006 
toString(std::string const & value)9007 std::string toString( std::string const& value ) {
9008     std::string s = value;
9009     if( getCurrentContext().getConfig()->showInvisibles() ) {
9010         for(size_t i = 0; i < s.size(); ++i ) {
9011             std::string subs;
9012             switch( s[i] ) {
9013             case '\n': subs = "\\n"; break;
9014             case '\t': subs = "\\t"; break;
9015             default: break;
9016             }
9017             if( !subs.empty() ) {
9018                 s = s.substr( 0, i ) + subs + s.substr( i+1 );
9019                 ++i;
9020             }
9021         }
9022     }
9023     return '"' + s + '"';
9024 }
toString(std::wstring const & value)9025 std::string toString( std::wstring const& value ) {
9026 
9027     std::string s;
9028     s.reserve( value.size() );
9029     for(size_t i = 0; i < value.size(); ++i )
9030         s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
9031     return Catch::toString( s );
9032 }
9033 
toString(const char * const value)9034 std::string toString( const char* const value ) {
9035     return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
9036 }
9037 
toString(char * const value)9038 std::string toString( char* const value ) {
9039     return Catch::toString( static_cast<const char*>( value ) );
9040 }
9041 
toString(const wchar_t * const value)9042 std::string toString( const wchar_t* const value )
9043 {
9044     return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
9045 }
9046 
toString(wchar_t * const value)9047 std::string toString( wchar_t* const value )
9048 {
9049     return Catch::toString( static_cast<const wchar_t*>( value ) );
9050 }
9051 
toString(int value)9052 std::string toString( int value ) {
9053     std::ostringstream oss;
9054     oss << value;
9055     if( value > Detail::hexThreshold )
9056         oss << " (0x" << std::hex << value << ')';
9057     return oss.str();
9058 }
9059 
toString(unsigned long value)9060 std::string toString( unsigned long value ) {
9061     std::ostringstream oss;
9062     oss << value;
9063     if( value > Detail::hexThreshold )
9064         oss << " (0x" << std::hex << value << ')';
9065     return oss.str();
9066 }
9067 
toString(unsigned int value)9068 std::string toString( unsigned int value ) {
9069     return Catch::toString( static_cast<unsigned long>( value ) );
9070 }
9071 
9072 template<typename T>
fpToString(T value,int precision)9073 std::string fpToString( T value, int precision ) {
9074     std::ostringstream oss;
9075     oss << std::setprecision( precision )
9076         << std::fixed
9077         << value;
9078     std::string d = oss.str();
9079     std::size_t i = d.find_last_not_of( '0' );
9080     if( i != std::string::npos && i != d.size()-1 ) {
9081         if( d[i] == '.' )
9082             i++;
9083         d = d.substr( 0, i+1 );
9084     }
9085     return d;
9086 }
9087 
toString(const double value)9088 std::string toString( const double value ) {
9089     return fpToString( value, 10 );
9090 }
toString(const float value)9091 std::string toString( const float value ) {
9092     return fpToString( value, 5 ) + 'f';
9093 }
9094 
toString(bool value)9095 std::string toString( bool value ) {
9096     return value ? "true" : "false";
9097 }
9098 
toString(char value)9099 std::string toString( char value ) {
9100     if ( value == '\r' )
9101         return "'\\r'";
9102     if ( value == '\f' )
9103         return "'\\f'";
9104     if ( value == '\n' )
9105         return "'\\n'";
9106     if ( value == '\t' )
9107         return "'\\t'";
9108     if ( '\0' <= value && value < ' ' )
9109         return toString( static_cast<unsigned int>( value ) );
9110     char chstr[] = "' '";
9111     chstr[1] = value;
9112     return chstr;
9113 }
9114 
toString(signed char value)9115 std::string toString( signed char value ) {
9116     return toString( static_cast<char>( value ) );
9117 }
9118 
toString(unsigned char value)9119 std::string toString( unsigned char value ) {
9120     return toString( static_cast<char>( value ) );
9121 }
9122 
9123 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
toString(long long value)9124 std::string toString( long long value ) {
9125     std::ostringstream oss;
9126     oss << value;
9127     if( value > Detail::hexThreshold )
9128         oss << " (0x" << std::hex << value << ')';
9129     return oss.str();
9130 }
toString(unsigned long long value)9131 std::string toString( unsigned long long value ) {
9132     std::ostringstream oss;
9133     oss << value;
9134     if( value > Detail::hexThreshold )
9135         oss << " (0x" << std::hex << value << ')';
9136     return oss.str();
9137 }
9138 #endif
9139 
9140 #ifdef CATCH_CONFIG_CPP11_NULLPTR
toString(std::nullptr_t)9141 std::string toString( std::nullptr_t ) {
9142     return "nullptr";
9143 }
9144 #endif
9145 
9146 #ifdef __OBJC__
toString(NSString const * const & nsstring)9147     std::string toString( NSString const * const& nsstring ) {
9148         if( !nsstring )
9149             return "nil";
9150         return "@" + toString([nsstring UTF8String]);
9151     }
toString(NSString * CATCH_ARC_STRONG & nsstring)9152     std::string toString( NSString * CATCH_ARC_STRONG & nsstring ) {
9153         if( !nsstring )
9154             return "nil";
9155         return "@" + toString([nsstring UTF8String]);
9156     }
toString(NSObject * const & nsObject)9157     std::string toString( NSObject* const& nsObject ) {
9158         return toString( [nsObject description] );
9159     }
9160 #endif
9161 
9162 } // end namespace Catch
9163 
9164 // #included from: catch_result_builder.hpp
9165 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
9166 
9167 namespace Catch {
9168 
ResultBuilder(char const * macroName,SourceLineInfo const & lineInfo,char const * capturedExpression,ResultDisposition::Flags resultDisposition,char const * secondArg)9169     ResultBuilder::ResultBuilder(   char const* macroName,
9170                                     SourceLineInfo const& lineInfo,
9171                                     char const* capturedExpression,
9172                                     ResultDisposition::Flags resultDisposition,
9173                                     char const* secondArg )
9174     :   m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition, secondArg ),
9175         m_shouldDebugBreak( false ),
9176         m_shouldThrow( false ),
9177         m_guardException( false ),
9178         m_usedStream( false )
9179     {}
9180 
~ResultBuilder()9181     ResultBuilder::~ResultBuilder() {
9182 #if defined(CATCH_CONFIG_FAST_COMPILE)
9183         if ( m_guardException ) {
9184             stream().oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
9185             captureResult( ResultWas::ThrewException );
9186             getCurrentContext().getResultCapture()->exceptionEarlyReported();
9187         }
9188 #endif
9189     }
9190 
setResultType(ResultWas::OfType result)9191     ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
9192         m_data.resultType = result;
9193         return *this;
9194     }
setResultType(bool result)9195     ResultBuilder& ResultBuilder::setResultType( bool result ) {
9196         m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
9197         return *this;
9198     }
9199 
endExpression(DecomposedExpression const & expr)9200     void ResultBuilder::endExpression( DecomposedExpression const& expr ) {
9201         // Flip bool results if FalseTest flag is set
9202         if( isFalseTest( m_assertionInfo.resultDisposition ) ) {
9203             m_data.negate( expr.isBinaryExpression() );
9204         }
9205 
9206         getResultCapture().assertionRun();
9207 
9208         if(getCurrentContext().getConfig()->includeSuccessfulResults() || m_data.resultType != ResultWas::Ok)
9209         {
9210             AssertionResult result = build( expr );
9211             handleResult( result );
9212         }
9213         else
9214             getResultCapture().assertionPassed();
9215     }
9216 
useActiveException(ResultDisposition::Flags resultDisposition)9217     void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
9218         m_assertionInfo.resultDisposition = resultDisposition;
9219         stream().oss << Catch::translateActiveException();
9220         captureResult( ResultWas::ThrewException );
9221     }
9222 
captureResult(ResultWas::OfType resultType)9223     void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
9224         setResultType( resultType );
9225         captureExpression();
9226     }
9227 
captureExpectedException(std::string const & expectedMessage)9228     void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
9229         if( expectedMessage.empty() )
9230             captureExpectedException( Matchers::Impl::MatchAllOf<std::string>() );
9231         else
9232             captureExpectedException( Matchers::Equals( expectedMessage ) );
9233     }
9234 
captureExpectedException(Matchers::Impl::MatcherBase<std::string> const & matcher)9235     void ResultBuilder::captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher ) {
9236 
9237         assert( !isFalseTest( m_assertionInfo.resultDisposition ) );
9238         AssertionResultData data = m_data;
9239         data.resultType = ResultWas::Ok;
9240         data.reconstructedExpression = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg);
9241 
9242         std::string actualMessage = Catch::translateActiveException();
9243         if( !matcher.match( actualMessage ) ) {
9244             data.resultType = ResultWas::ExpressionFailed;
9245             data.reconstructedExpression = actualMessage;
9246         }
9247         AssertionResult result( m_assertionInfo, data );
9248         handleResult( result );
9249     }
9250 
captureExpression()9251     void ResultBuilder::captureExpression() {
9252         AssertionResult result = build();
9253         handleResult( result );
9254     }
9255 
handleResult(AssertionResult const & result)9256     void ResultBuilder::handleResult( AssertionResult const& result )
9257     {
9258         getResultCapture().assertionEnded( result );
9259 
9260         if( !result.isOk() ) {
9261             if( getCurrentContext().getConfig()->shouldDebugBreak() )
9262                 m_shouldDebugBreak = true;
9263             if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
9264                 m_shouldThrow = true;
9265         }
9266     }
9267 
react()9268     void ResultBuilder::react() {
9269 #if defined(CATCH_CONFIG_FAST_COMPILE)
9270         if (m_shouldDebugBreak) {
9271             ///////////////////////////////////////////////////////////////////
9272             // To inspect the state during test, you need to go one level up the callstack
9273             // To go back to the test and change execution, jump over the throw statement
9274             ///////////////////////////////////////////////////////////////////
9275             CATCH_BREAK_INTO_DEBUGGER();
9276         }
9277 #endif
9278         if( m_shouldThrow )
9279             throw Catch::TestFailureException();
9280     }
9281 
shouldDebugBreak() const9282     bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
allowThrows() const9283     bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
9284 
build() const9285     AssertionResult ResultBuilder::build() const
9286     {
9287         return build( *this );
9288     }
9289 
9290     // CAVEAT: The returned AssertionResult stores a pointer to the argument expr,
9291     //         a temporary DecomposedExpression, which in turn holds references to
9292     //         operands, possibly temporary as well.
9293     //         It should immediately be passed to handleResult; if the expression
9294     //         needs to be reported, its string expansion must be composed before
9295     //         the temporaries are destroyed.
build(DecomposedExpression const & expr) const9296     AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const
9297     {
9298         assert( m_data.resultType != ResultWas::Unknown );
9299         AssertionResultData data = m_data;
9300 
9301         if(m_usedStream)
9302             data.message = m_stream().oss.str();
9303         data.decomposedExpression = &expr; // for lazy reconstruction
9304         return AssertionResult( m_assertionInfo, data );
9305     }
9306 
reconstructExpression(std::string & dest) const9307     void ResultBuilder::reconstructExpression( std::string& dest ) const {
9308         dest = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg);
9309     }
9310 
setExceptionGuard()9311     void ResultBuilder::setExceptionGuard() {
9312         m_guardException = true;
9313     }
unsetExceptionGuard()9314     void ResultBuilder::unsetExceptionGuard() {
9315         m_guardException = false;
9316     }
9317 
9318 } // end namespace Catch
9319 
9320 // #included from: catch_tag_alias_registry.hpp
9321 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
9322 
9323 namespace Catch {
9324 
~TagAliasRegistry()9325     TagAliasRegistry::~TagAliasRegistry() {}
9326 
find(std::string const & alias) const9327     Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
9328         std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
9329         if( it != m_registry.end() )
9330             return it->second;
9331         else
9332             return Option<TagAlias>();
9333     }
9334 
expandAliases(std::string const & unexpandedTestSpec) const9335     std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
9336         std::string expandedTestSpec = unexpandedTestSpec;
9337         for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
9338                 it != itEnd;
9339                 ++it ) {
9340             std::size_t pos = expandedTestSpec.find( it->first );
9341             if( pos != std::string::npos ) {
9342                 expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
9343                                     it->second.tag +
9344                                     expandedTestSpec.substr( pos + it->first.size() );
9345             }
9346         }
9347         return expandedTestSpec;
9348     }
9349 
add(std::string const & alias,std::string const & tag,SourceLineInfo const & lineInfo)9350     void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
9351 
9352         if( !startsWith( alias, "[@" ) || !endsWith( alias, ']' ) ) {
9353             std::ostringstream oss;
9354             oss << Colour( Colour::Red )
9355                 << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n"
9356                 << Colour( Colour::FileName )
9357                 << lineInfo << '\n';
9358             throw std::domain_error( oss.str().c_str() );
9359         }
9360         if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
9361             std::ostringstream oss;
9362             oss << Colour( Colour::Red )
9363                 << "error: tag alias, \"" << alias << "\" already registered.\n"
9364                 << "\tFirst seen at "
9365                 << Colour( Colour::Red ) << find(alias)->lineInfo << '\n'
9366                 << Colour( Colour::Red ) << "\tRedefined at "
9367                 << Colour( Colour::FileName) << lineInfo << '\n';
9368             throw std::domain_error( oss.str().c_str() );
9369         }
9370     }
9371 
~ITagAliasRegistry()9372     ITagAliasRegistry::~ITagAliasRegistry() {}
9373 
get()9374     ITagAliasRegistry const& ITagAliasRegistry::get() {
9375         return getRegistryHub().getTagAliasRegistry();
9376     }
9377 
RegistrarForTagAliases(char const * alias,char const * tag,SourceLineInfo const & lineInfo)9378     RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
9379         getMutableRegistryHub().registerTagAlias( alias, tag, lineInfo );
9380     }
9381 
9382 } // end namespace Catch
9383 
9384 // #included from: catch_matchers_string.hpp
9385 
9386 namespace Catch {
9387 namespace Matchers {
9388 
9389     namespace StdString {
9390 
CasedString(std::string const & str,CaseSensitive::Choice caseSensitivity)9391         CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
9392         :   m_caseSensitivity( caseSensitivity ),
9393             m_str( adjustString( str ) )
9394         {}
adjustString(std::string const & str) const9395         std::string CasedString::adjustString( std::string const& str ) const {
9396             return m_caseSensitivity == CaseSensitive::No
9397                    ? toLower( str )
9398                    : str;
9399         }
caseSensitivitySuffix() const9400         std::string CasedString::caseSensitivitySuffix() const {
9401             return m_caseSensitivity == CaseSensitive::No
9402                    ? " (case insensitive)"
9403                    : std::string();
9404         }
9405 
StringMatcherBase(std::string const & operation,CasedString const & comparator)9406         StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
9407         : m_comparator( comparator ),
9408           m_operation( operation ) {
9409         }
9410 
describe() const9411         std::string StringMatcherBase::describe() const {
9412             std::string description;
9413             description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
9414                                         m_comparator.caseSensitivitySuffix().size());
9415             description += m_operation;
9416             description += ": \"";
9417             description += m_comparator.m_str;
9418             description += "\"";
9419             description += m_comparator.caseSensitivitySuffix();
9420             return description;
9421         }
9422 
EqualsMatcher(CasedString const & comparator)9423         EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
9424 
match(std::string const & source) const9425         bool EqualsMatcher::match( std::string const& source ) const {
9426             return m_comparator.adjustString( source ) == m_comparator.m_str;
9427         }
9428 
ContainsMatcher(CasedString const & comparator)9429         ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
9430 
match(std::string const & source) const9431         bool ContainsMatcher::match( std::string const& source ) const {
9432             return contains( m_comparator.adjustString( source ), m_comparator.m_str );
9433         }
9434 
StartsWithMatcher(CasedString const & comparator)9435         StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
9436 
match(std::string const & source) const9437         bool StartsWithMatcher::match( std::string const& source ) const {
9438             return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
9439         }
9440 
EndsWithMatcher(CasedString const & comparator)9441         EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
9442 
match(std::string const & source) const9443         bool EndsWithMatcher::match( std::string const& source ) const {
9444             return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
9445         }
9446 
9447     } // namespace StdString
9448 
Equals(std::string const & str,CaseSensitive::Choice caseSensitivity)9449     StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
9450         return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
9451     }
Contains(std::string const & str,CaseSensitive::Choice caseSensitivity)9452     StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
9453         return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
9454     }
EndsWith(std::string const & str,CaseSensitive::Choice caseSensitivity)9455     StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
9456         return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
9457     }
StartsWith(std::string const & str,CaseSensitive::Choice caseSensitivity)9458     StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
9459         return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
9460     }
9461 
9462 } // namespace Matchers
9463 } // namespace Catch
9464 // #included from: ../reporters/catch_reporter_multi.hpp
9465 #define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
9466 
9467 namespace Catch {
9468 
9469 class MultipleReporters : public SharedImpl<IStreamingReporter> {
9470     typedef std::vector<Ptr<IStreamingReporter> > Reporters;
9471     Reporters m_reporters;
9472 
9473 public:
add(Ptr<IStreamingReporter> const & reporter)9474     void add( Ptr<IStreamingReporter> const& reporter ) {
9475         m_reporters.push_back( reporter );
9476     }
9477 
9478 public: // IStreamingReporter
9479 
getPreferences() const9480     virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
9481         return m_reporters[0]->getPreferences();
9482     }
9483 
noMatchingTestCases(std::string const & spec)9484     virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
9485         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
9486                 it != itEnd;
9487                 ++it )
9488             (*it)->noMatchingTestCases( spec );
9489     }
9490 
testRunStarting(TestRunInfo const & testRunInfo)9491     virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
9492         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
9493                 it != itEnd;
9494                 ++it )
9495             (*it)->testRunStarting( testRunInfo );
9496     }
9497 
testGroupStarting(GroupInfo const & groupInfo)9498     virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
9499         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
9500                 it != itEnd;
9501                 ++it )
9502             (*it)->testGroupStarting( groupInfo );
9503     }
9504 
testCaseStarting(TestCaseInfo const & testInfo)9505     virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
9506         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
9507                 it != itEnd;
9508                 ++it )
9509             (*it)->testCaseStarting( testInfo );
9510     }
9511 
sectionStarting(SectionInfo const & sectionInfo)9512     virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
9513         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
9514                 it != itEnd;
9515                 ++it )
9516             (*it)->sectionStarting( sectionInfo );
9517     }
9518 
assertionStarting(AssertionInfo const & assertionInfo)9519     virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
9520         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
9521                 it != itEnd;
9522                 ++it )
9523             (*it)->assertionStarting( assertionInfo );
9524     }
9525 
9526     // The return value indicates if the messages buffer should be cleared:
assertionEnded(AssertionStats const & assertionStats)9527     virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
9528         bool clearBuffer = false;
9529         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
9530                 it != itEnd;
9531                 ++it )
9532             clearBuffer |= (*it)->assertionEnded( assertionStats );
9533         return clearBuffer;
9534     }
9535 
sectionEnded(SectionStats const & sectionStats)9536     virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
9537         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
9538                 it != itEnd;
9539                 ++it )
9540             (*it)->sectionEnded( sectionStats );
9541     }
9542 
testCaseEnded(TestCaseStats const & testCaseStats)9543     virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
9544         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
9545                 it != itEnd;
9546                 ++it )
9547             (*it)->testCaseEnded( testCaseStats );
9548     }
9549 
testGroupEnded(TestGroupStats const & testGroupStats)9550     virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
9551         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
9552                 it != itEnd;
9553                 ++it )
9554             (*it)->testGroupEnded( testGroupStats );
9555     }
9556 
testRunEnded(TestRunStats const & testRunStats)9557     virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
9558         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
9559                 it != itEnd;
9560                 ++it )
9561             (*it)->testRunEnded( testRunStats );
9562     }
9563 
skipTest(TestCaseInfo const & testInfo)9564     virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
9565         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
9566                 it != itEnd;
9567                 ++it )
9568             (*it)->skipTest( testInfo );
9569     }
9570 
tryAsMulti()9571     virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {
9572         return this;
9573     }
9574 
9575 };
9576 
addReporter(Ptr<IStreamingReporter> const & existingReporter,Ptr<IStreamingReporter> const & additionalReporter)9577 Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
9578     Ptr<IStreamingReporter> resultingReporter;
9579 
9580     if( existingReporter ) {
9581         MultipleReporters* multi = existingReporter->tryAsMulti();
9582         if( !multi ) {
9583             multi = new MultipleReporters;
9584             resultingReporter = Ptr<IStreamingReporter>( multi );
9585             if( existingReporter )
9586                 multi->add( existingReporter );
9587         }
9588         else
9589             resultingReporter = existingReporter;
9590         multi->add( additionalReporter );
9591     }
9592     else
9593         resultingReporter = additionalReporter;
9594 
9595     return resultingReporter;
9596 }
9597 
9598 } // end namespace Catch
9599 
9600 // #included from: ../reporters/catch_reporter_xml.hpp
9601 #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
9602 
9603 // #included from: catch_reporter_bases.hpp
9604 #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
9605 
9606 #include <cstring>
9607 #include <cfloat>
9608 #include <cstdio>
9609 #include <assert.h>
9610 
9611 namespace Catch {
9612 
9613     namespace {
9614         // Because formatting using c++ streams is stateful, drop down to C is required
9615         // Alternatively we could use stringstream, but its performance is... not good.
getFormattedDuration(double duration)9616         std::string getFormattedDuration( double duration ) {
9617             // Max exponent + 1 is required to represent the whole part
9618             // + 1 for decimal point
9619             // + 3 for the 3 decimal places
9620             // + 1 for null terminator
9621             const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
9622             char buffer[maxDoubleSize];
9623 
9624             // Save previous errno, to prevent sprintf from overwriting it
9625             ErrnoGuard guard;
9626 #ifdef _MSC_VER
9627             sprintf_s(buffer, "%.3f", duration);
9628 #else
9629             sprintf(buffer, "%.3f", duration);
9630 #endif
9631             return std::string(buffer);
9632         }
9633     }
9634 
9635     struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
9636 
StreamingReporterBaseCatch::StreamingReporterBase9637         StreamingReporterBase( ReporterConfig const& _config )
9638         :   m_config( _config.fullConfig() ),
9639             stream( _config.stream() )
9640         {
9641             m_reporterPrefs.shouldRedirectStdOut = false;
9642         }
9643 
getPreferencesCatch::StreamingReporterBase9644         virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
9645             return m_reporterPrefs;
9646         }
9647 
9648         virtual ~StreamingReporterBase() CATCH_OVERRIDE;
9649 
noMatchingTestCasesCatch::StreamingReporterBase9650         virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
9651 
testRunStartingCatch::StreamingReporterBase9652         virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {
9653             currentTestRunInfo = _testRunInfo;
9654         }
testGroupStartingCatch::StreamingReporterBase9655         virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {
9656             currentGroupInfo = _groupInfo;
9657         }
9658 
testCaseStartingCatch::StreamingReporterBase9659         virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
9660             currentTestCaseInfo = _testInfo;
9661         }
sectionStartingCatch::StreamingReporterBase9662         virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
9663             m_sectionStack.push_back( _sectionInfo );
9664         }
9665 
sectionEndedCatch::StreamingReporterBase9666         virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {
9667             m_sectionStack.pop_back();
9668         }
testCaseEndedCatch::StreamingReporterBase9669         virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {
9670             currentTestCaseInfo.reset();
9671         }
testGroupEndedCatch::StreamingReporterBase9672         virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {
9673             currentGroupInfo.reset();
9674         }
testRunEndedCatch::StreamingReporterBase9675         virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {
9676             currentTestCaseInfo.reset();
9677             currentGroupInfo.reset();
9678             currentTestRunInfo.reset();
9679         }
9680 
skipTestCatch::StreamingReporterBase9681         virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {
9682             // Don't do anything with this by default.
9683             // It can optionally be overridden in the derived class.
9684         }
9685 
9686         Ptr<IConfig const> m_config;
9687         std::ostream& stream;
9688 
9689         LazyStat<TestRunInfo> currentTestRunInfo;
9690         LazyStat<GroupInfo> currentGroupInfo;
9691         LazyStat<TestCaseInfo> currentTestCaseInfo;
9692 
9693         std::vector<SectionInfo> m_sectionStack;
9694         ReporterPreferences m_reporterPrefs;
9695     };
9696 
9697     struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
9698         template<typename T, typename ChildNodeT>
9699         struct Node : SharedImpl<> {
NodeCatch::CumulativeReporterBase::Node9700             explicit Node( T const& _value ) : value( _value ) {}
~NodeCatch::CumulativeReporterBase::Node9701             virtual ~Node() {}
9702 
9703             typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
9704             T value;
9705             ChildNodes children;
9706         };
9707         struct SectionNode : SharedImpl<> {
SectionNodeCatch::CumulativeReporterBase::SectionNode9708             explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
9709             virtual ~SectionNode();
9710 
operator ==Catch::CumulativeReporterBase::SectionNode9711             bool operator == ( SectionNode const& other ) const {
9712                 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
9713             }
operator ==Catch::CumulativeReporterBase::SectionNode9714             bool operator == ( Ptr<SectionNode> const& other ) const {
9715                 return operator==( *other );
9716             }
9717 
9718             SectionStats stats;
9719             typedef std::vector<Ptr<SectionNode> > ChildSections;
9720             typedef std::vector<AssertionStats> Assertions;
9721             ChildSections childSections;
9722             Assertions assertions;
9723             std::string stdOut;
9724             std::string stdErr;
9725         };
9726 
9727         struct BySectionInfo {
BySectionInfoCatch::CumulativeReporterBase::BySectionInfo9728             BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
BySectionInfoCatch::CumulativeReporterBase::BySectionInfo9729             BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
operator ()Catch::CumulativeReporterBase::BySectionInfo9730             bool operator() ( Ptr<SectionNode> const& node ) const {
9731                 return ((node->stats.sectionInfo.name == m_other.name) &&
9732                         (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
9733             }
9734         private:
9735             void operator=( BySectionInfo const& );
9736             SectionInfo const& m_other;
9737         };
9738 
9739         typedef Node<TestCaseStats, SectionNode> TestCaseNode;
9740         typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
9741         typedef Node<TestRunStats, TestGroupNode> TestRunNode;
9742 
CumulativeReporterBaseCatch::CumulativeReporterBase9743         CumulativeReporterBase( ReporterConfig const& _config )
9744         :   m_config( _config.fullConfig() ),
9745             stream( _config.stream() )
9746         {
9747             m_reporterPrefs.shouldRedirectStdOut = false;
9748         }
9749         ~CumulativeReporterBase();
9750 
getPreferencesCatch::CumulativeReporterBase9751         virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
9752             return m_reporterPrefs;
9753         }
9754 
testRunStartingCatch::CumulativeReporterBase9755         virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}
testGroupStartingCatch::CumulativeReporterBase9756         virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}
9757 
testCaseStartingCatch::CumulativeReporterBase9758         virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}
9759 
sectionStartingCatch::CumulativeReporterBase9760         virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
9761             SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
9762             Ptr<SectionNode> node;
9763             if( m_sectionStack.empty() ) {
9764                 if( !m_rootSection )
9765                     m_rootSection = new SectionNode( incompleteStats );
9766                 node = m_rootSection;
9767             }
9768             else {
9769                 SectionNode& parentNode = *m_sectionStack.back();
9770                 SectionNode::ChildSections::const_iterator it =
9771                     std::find_if(   parentNode.childSections.begin(),
9772                                     parentNode.childSections.end(),
9773                                     BySectionInfo( sectionInfo ) );
9774                 if( it == parentNode.childSections.end() ) {
9775                     node = new SectionNode( incompleteStats );
9776                     parentNode.childSections.push_back( node );
9777                 }
9778                 else
9779                     node = *it;
9780             }
9781             m_sectionStack.push_back( node );
9782             m_deepestSection = node;
9783         }
9784 
assertionStartingCatch::CumulativeReporterBase9785         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
9786 
assertionEndedCatch::CumulativeReporterBase9787         virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
9788             assert( !m_sectionStack.empty() );
9789             SectionNode& sectionNode = *m_sectionStack.back();
9790             sectionNode.assertions.push_back( assertionStats );
9791             // AssertionResult holds a pointer to a temporary DecomposedExpression,
9792             // which getExpandedExpression() calls to build the expression string.
9793             // Our section stack copy of the assertionResult will likely outlive the
9794             // temporary, so it must be expanded or discarded now to avoid calling
9795             // a destroyed object later.
9796             prepareExpandedExpression( sectionNode.assertions.back().assertionResult );
9797             return true;
9798         }
sectionEndedCatch::CumulativeReporterBase9799         virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
9800             assert( !m_sectionStack.empty() );
9801             SectionNode& node = *m_sectionStack.back();
9802             node.stats = sectionStats;
9803             m_sectionStack.pop_back();
9804         }
testCaseEndedCatch::CumulativeReporterBase9805         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
9806             Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
9807             assert( m_sectionStack.size() == 0 );
9808             node->children.push_back( m_rootSection );
9809             m_testCases.push_back( node );
9810             m_rootSection.reset();
9811 
9812             assert( m_deepestSection );
9813             m_deepestSection->stdOut = testCaseStats.stdOut;
9814             m_deepestSection->stdErr = testCaseStats.stdErr;
9815         }
testGroupEndedCatch::CumulativeReporterBase9816         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
9817             Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
9818             node->children.swap( m_testCases );
9819             m_testGroups.push_back( node );
9820         }
testRunEndedCatch::CumulativeReporterBase9821         virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
9822             Ptr<TestRunNode> node = new TestRunNode( testRunStats );
9823             node->children.swap( m_testGroups );
9824             m_testRuns.push_back( node );
9825             testRunEndedCumulative();
9826         }
9827         virtual void testRunEndedCumulative() = 0;
9828 
skipTestCatch::CumulativeReporterBase9829         virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
9830 
prepareExpandedExpressionCatch::CumulativeReporterBase9831         virtual void prepareExpandedExpression( AssertionResult& result ) const {
9832             if( result.isOk() )
9833                 result.discardDecomposedExpression();
9834             else
9835                 result.expandDecomposedExpression();
9836         }
9837 
9838         Ptr<IConfig const> m_config;
9839         std::ostream& stream;
9840         std::vector<AssertionStats> m_assertions;
9841         std::vector<std::vector<Ptr<SectionNode> > > m_sections;
9842         std::vector<Ptr<TestCaseNode> > m_testCases;
9843         std::vector<Ptr<TestGroupNode> > m_testGroups;
9844 
9845         std::vector<Ptr<TestRunNode> > m_testRuns;
9846 
9847         Ptr<SectionNode> m_rootSection;
9848         Ptr<SectionNode> m_deepestSection;
9849         std::vector<Ptr<SectionNode> > m_sectionStack;
9850         ReporterPreferences m_reporterPrefs;
9851 
9852     };
9853 
9854     template<char C>
getLineOfChars()9855     char const* getLineOfChars() {
9856         static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
9857         if( !*line ) {
9858             std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
9859             line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
9860         }
9861         return line;
9862     }
9863 
9864     struct TestEventListenerBase : StreamingReporterBase {
TestEventListenerBaseCatch::TestEventListenerBase9865         TestEventListenerBase( ReporterConfig const& _config )
9866         :   StreamingReporterBase( _config )
9867         {}
9868 
assertionStartingCatch::TestEventListenerBase9869         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
assertionEndedCatch::TestEventListenerBase9870         virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {
9871             return false;
9872         }
9873     };
9874 
9875 } // end namespace Catch
9876 
9877 // #included from: ../internal/catch_reporter_registrars.hpp
9878 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
9879 
9880 namespace Catch {
9881 
9882     template<typename T>
9883     class LegacyReporterRegistrar {
9884 
9885         class ReporterFactory : public IReporterFactory {
create(ReporterConfig const & config) const9886             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
9887                 return new LegacyReporterAdapter( new T( config ) );
9888             }
9889 
getDescription() const9890             virtual std::string getDescription() const {
9891                 return T::getDescription();
9892             }
9893         };
9894 
9895     public:
9896 
LegacyReporterRegistrar(std::string const & name)9897         LegacyReporterRegistrar( std::string const& name ) {
9898             getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
9899         }
9900     };
9901 
9902     template<typename T>
9903     class ReporterRegistrar {
9904 
9905         class ReporterFactory : public SharedImpl<IReporterFactory> {
9906 
9907             // *** Please Note ***:
9908             // - If you end up here looking at a compiler error because it's trying to register
9909             // your custom reporter class be aware that the native reporter interface has changed
9910             // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
9911             // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
9912             // However please consider updating to the new interface as the old one is now
9913             // deprecated and will probably be removed quite soon!
9914             // Please contact me via github if you have any questions at all about this.
9915             // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
9916             // no idea who is actually using custom reporters at all (possibly no-one!).
9917             // The new interface is designed to minimise exposure to interface changes in the future.
create(ReporterConfig const & config) const9918             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
9919                 return new T( config );
9920             }
9921 
getDescription() const9922             virtual std::string getDescription() const {
9923                 return T::getDescription();
9924             }
9925         };
9926 
9927     public:
9928 
ReporterRegistrar(std::string const & name)9929         ReporterRegistrar( std::string const& name ) {
9930             getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
9931         }
9932     };
9933 
9934     template<typename T>
9935     class ListenerRegistrar {
9936 
9937         class ListenerFactory : public SharedImpl<IReporterFactory> {
9938 
create(ReporterConfig const & config) const9939             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
9940                 return new T( config );
9941             }
getDescription() const9942             virtual std::string getDescription() const {
9943                 return std::string();
9944             }
9945         };
9946 
9947     public:
9948 
ListenerRegistrar()9949         ListenerRegistrar() {
9950             getMutableRegistryHub().registerListener( new ListenerFactory() );
9951         }
9952     };
9953 }
9954 
9955 #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
9956     namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
9957 
9958 #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
9959     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
9960 
9961 // Deprecated - use the form without INTERNAL_
9962 #define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
9963     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
9964 
9965 #define CATCH_REGISTER_LISTENER( listenerType ) \
9966     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
9967 
9968 // #included from: ../internal/catch_xmlwriter.hpp
9969 #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
9970 
9971 #include <sstream>
9972 #include <string>
9973 #include <vector>
9974 #include <iomanip>
9975 
9976 namespace Catch {
9977 
9978     class XmlEncode {
9979     public:
9980         enum ForWhat { ForTextNodes, ForAttributes };
9981 
XmlEncode(std::string const & str,ForWhat forWhat=ForTextNodes)9982         XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
9983         :   m_str( str ),
9984             m_forWhat( forWhat )
9985         {}
9986 
encodeTo(std::ostream & os) const9987         void encodeTo( std::ostream& os ) const {
9988 
9989             // Apostrophe escaping not necessary if we always use " to write attributes
9990             // (see: http://www.w3.org/TR/xml/#syntax)
9991 
9992             for( std::size_t i = 0; i < m_str.size(); ++ i ) {
9993                 char c = m_str[i];
9994                 switch( c ) {
9995                     case '<':   os << "&lt;"; break;
9996                     case '&':   os << "&amp;"; break;
9997 
9998                     case '>':
9999                         // See: http://www.w3.org/TR/xml/#syntax
10000                         if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
10001                             os << "&gt;";
10002                         else
10003                             os << c;
10004                         break;
10005 
10006                     case '\"':
10007                         if( m_forWhat == ForAttributes )
10008                             os << "&quot;";
10009                         else
10010                             os << c;
10011                         break;
10012 
10013                     default:
10014                         // Escape control chars - based on contribution by @espenalb in PR #465 and
10015                         // by @mrpi PR #588
10016                         if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) {
10017                             // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
10018                             os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
10019                                << static_cast<int>( c );
10020                         }
10021                         else
10022                             os << c;
10023                 }
10024             }
10025         }
10026 
operator <<(std::ostream & os,XmlEncode const & xmlEncode)10027         friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
10028             xmlEncode.encodeTo( os );
10029             return os;
10030         }
10031 
10032     private:
10033         std::string m_str;
10034         ForWhat m_forWhat;
10035     };
10036 
10037     class XmlWriter {
10038     public:
10039 
10040         class ScopedElement {
10041         public:
ScopedElement(XmlWriter * writer)10042             ScopedElement( XmlWriter* writer )
10043             :   m_writer( writer )
10044             {}
10045 
ScopedElement(ScopedElement const & other)10046             ScopedElement( ScopedElement const& other )
10047             :   m_writer( other.m_writer ){
10048                 other.m_writer = CATCH_NULL;
10049             }
10050 
~ScopedElement()10051             ~ScopedElement() {
10052                 if( m_writer )
10053                     m_writer->endElement();
10054             }
10055 
writeText(std::string const & text,bool indent=true)10056             ScopedElement& writeText( std::string const& text, bool indent = true ) {
10057                 m_writer->writeText( text, indent );
10058                 return *this;
10059             }
10060 
10061             template<typename T>
writeAttribute(std::string const & name,T const & attribute)10062             ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
10063                 m_writer->writeAttribute( name, attribute );
10064                 return *this;
10065             }
10066 
10067         private:
10068             mutable XmlWriter* m_writer;
10069         };
10070 
XmlWriter()10071         XmlWriter()
10072         :   m_tagIsOpen( false ),
10073             m_needsNewline( false ),
10074             m_os( Catch::cout() )
10075         {
10076             writeDeclaration();
10077         }
10078 
XmlWriter(std::ostream & os)10079         XmlWriter( std::ostream& os )
10080         :   m_tagIsOpen( false ),
10081             m_needsNewline( false ),
10082             m_os( os )
10083         {
10084             writeDeclaration();
10085         }
10086 
~XmlWriter()10087         ~XmlWriter() {
10088             while( !m_tags.empty() )
10089                 endElement();
10090         }
10091 
startElement(std::string const & name)10092         XmlWriter& startElement( std::string const& name ) {
10093             ensureTagClosed();
10094             newlineIfNecessary();
10095             m_os << m_indent << '<' << name;
10096             m_tags.push_back( name );
10097             m_indent += "  ";
10098             m_tagIsOpen = true;
10099             return *this;
10100         }
10101 
scopedElement(std::string const & name)10102         ScopedElement scopedElement( std::string const& name ) {
10103             ScopedElement scoped( this );
10104             startElement( name );
10105             return scoped;
10106         }
10107 
endElement()10108         XmlWriter& endElement() {
10109             newlineIfNecessary();
10110             m_indent = m_indent.substr( 0, m_indent.size()-2 );
10111             if( m_tagIsOpen ) {
10112                 m_os << "/>";
10113                 m_tagIsOpen = false;
10114             }
10115             else {
10116                 m_os << m_indent << "</" << m_tags.back() << ">";
10117             }
10118             m_os << std::endl;
10119             m_tags.pop_back();
10120             return *this;
10121         }
10122 
writeAttribute(std::string const & name,std::string const & attribute)10123         XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
10124             if( !name.empty() && !attribute.empty() )
10125                 m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
10126             return *this;
10127         }
10128 
writeAttribute(std::string const & name,bool attribute)10129         XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
10130             m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
10131             return *this;
10132         }
10133 
10134         template<typename T>
writeAttribute(std::string const & name,T const & attribute)10135         XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
10136             std::ostringstream oss;
10137             oss << attribute;
10138             return writeAttribute( name, oss.str() );
10139         }
10140 
writeText(std::string const & text,bool indent=true)10141         XmlWriter& writeText( std::string const& text, bool indent = true ) {
10142             if( !text.empty() ){
10143                 bool tagWasOpen = m_tagIsOpen;
10144                 ensureTagClosed();
10145                 if( tagWasOpen && indent )
10146                     m_os << m_indent;
10147                 m_os << XmlEncode( text );
10148                 m_needsNewline = true;
10149             }
10150             return *this;
10151         }
10152 
writeComment(std::string const & text)10153         XmlWriter& writeComment( std::string const& text ) {
10154             ensureTagClosed();
10155             m_os << m_indent << "<!--" << text << "-->";
10156             m_needsNewline = true;
10157             return *this;
10158         }
10159 
writeStylesheetRef(std::string const & url)10160         void writeStylesheetRef( std::string const& url ) {
10161             m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
10162         }
10163 
writeBlankLine()10164         XmlWriter& writeBlankLine() {
10165             ensureTagClosed();
10166             m_os << '\n';
10167             return *this;
10168         }
10169 
ensureTagClosed()10170         void ensureTagClosed() {
10171             if( m_tagIsOpen ) {
10172                 m_os << ">" << std::endl;
10173                 m_tagIsOpen = false;
10174             }
10175         }
10176 
10177     private:
10178         XmlWriter( XmlWriter const& );
10179         void operator=( XmlWriter const& );
10180 
writeDeclaration()10181         void writeDeclaration() {
10182             m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
10183         }
10184 
newlineIfNecessary()10185         void newlineIfNecessary() {
10186             if( m_needsNewline ) {
10187                 m_os << std::endl;
10188                 m_needsNewline = false;
10189             }
10190         }
10191 
10192         bool m_tagIsOpen;
10193         bool m_needsNewline;
10194         std::vector<std::string> m_tags;
10195         std::string m_indent;
10196         std::ostream& m_os;
10197     };
10198 
10199 }
10200 
10201 namespace Catch {
10202     class XmlReporter : public StreamingReporterBase {
10203     public:
XmlReporter(ReporterConfig const & _config)10204         XmlReporter( ReporterConfig const& _config )
10205         :   StreamingReporterBase( _config ),
10206             m_xml(_config.stream()),
10207             m_sectionDepth( 0 )
10208         {
10209             m_reporterPrefs.shouldRedirectStdOut = true;
10210         }
10211 
10212         virtual ~XmlReporter() CATCH_OVERRIDE;
10213 
getDescription()10214         static std::string getDescription() {
10215             return "Reports test results as an XML document";
10216         }
10217 
getStylesheetRef() const10218         virtual std::string getStylesheetRef() const {
10219             return std::string();
10220         }
10221 
writeSourceInfo(SourceLineInfo const & sourceInfo)10222         void writeSourceInfo( SourceLineInfo const& sourceInfo ) {
10223             m_xml
10224                 .writeAttribute( "filename", sourceInfo.file )
10225                 .writeAttribute( "line", sourceInfo.line );
10226         }
10227 
10228     public: // StreamingReporterBase
10229 
noMatchingTestCases(std::string const & s)10230         virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
10231             StreamingReporterBase::noMatchingTestCases( s );
10232         }
10233 
testRunStarting(TestRunInfo const & testInfo)10234         virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
10235             StreamingReporterBase::testRunStarting( testInfo );
10236             std::string stylesheetRef = getStylesheetRef();
10237             if( !stylesheetRef.empty() )
10238                 m_xml.writeStylesheetRef( stylesheetRef );
10239             m_xml.startElement( "Catch" );
10240             if( !m_config->name().empty() )
10241                 m_xml.writeAttribute( "name", m_config->name() );
10242         }
10243 
testGroupStarting(GroupInfo const & groupInfo)10244         virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
10245             StreamingReporterBase::testGroupStarting( groupInfo );
10246             m_xml.startElement( "Group" )
10247                 .writeAttribute( "name", groupInfo.name );
10248         }
10249 
testCaseStarting(TestCaseInfo const & testInfo)10250         virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
10251             StreamingReporterBase::testCaseStarting(testInfo);
10252             m_xml.startElement( "TestCase" )
10253                 .writeAttribute( "name", trim( testInfo.name ) )
10254                 .writeAttribute( "description", testInfo.description )
10255                 .writeAttribute( "tags", testInfo.tagsAsString );
10256 
10257             writeSourceInfo( testInfo.lineInfo );
10258 
10259             if ( m_config->showDurations() == ShowDurations::Always )
10260                 m_testCaseTimer.start();
10261             m_xml.ensureTagClosed();
10262         }
10263 
sectionStarting(SectionInfo const & sectionInfo)10264         virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
10265             StreamingReporterBase::sectionStarting( sectionInfo );
10266             if( m_sectionDepth++ > 0 ) {
10267                 m_xml.startElement( "Section" )
10268                     .writeAttribute( "name", trim( sectionInfo.name ) )
10269                     .writeAttribute( "description", sectionInfo.description );
10270                 writeSourceInfo( sectionInfo.lineInfo );
10271                 m_xml.ensureTagClosed();
10272             }
10273         }
10274 
assertionStarting(AssertionInfo const &)10275         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
10276 
assertionEnded(AssertionStats const & assertionStats)10277         virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
10278 
10279             AssertionResult const& result = assertionStats.assertionResult;
10280 
10281             bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
10282 
10283             if( includeResults || result.getResultType() == ResultWas::Warning ) {
10284                 // Print any info messages in <Info> tags.
10285                 for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
10286                      it != itEnd;
10287                      ++it ) {
10288                     if( it->type == ResultWas::Info && includeResults ) {
10289                         m_xml.scopedElement( "Info" )
10290                                 .writeText( it->message );
10291                     } else if ( it->type == ResultWas::Warning ) {
10292                         m_xml.scopedElement( "Warning" )
10293                                 .writeText( it->message );
10294                     }
10295                 }
10296             }
10297 
10298             // Drop out if result was successful but we're not printing them.
10299             if( !includeResults && result.getResultType() != ResultWas::Warning )
10300                 return true;
10301 
10302             // Print the expression if there is one.
10303             if( result.hasExpression() ) {
10304                 m_xml.startElement( "Expression" )
10305                     .writeAttribute( "success", result.succeeded() )
10306                     .writeAttribute( "type", result.getTestMacroName() );
10307 
10308                 writeSourceInfo( result.getSourceInfo() );
10309 
10310                 m_xml.scopedElement( "Original" )
10311                     .writeText( result.getExpression() );
10312                 m_xml.scopedElement( "Expanded" )
10313                     .writeText( result.getExpandedExpression() );
10314             }
10315 
10316             // And... Print a result applicable to each result type.
10317             switch( result.getResultType() ) {
10318                 case ResultWas::ThrewException:
10319                     m_xml.startElement( "Exception" );
10320                     writeSourceInfo( result.getSourceInfo() );
10321                     m_xml.writeText( result.getMessage() );
10322                     m_xml.endElement();
10323                     break;
10324                 case ResultWas::FatalErrorCondition:
10325                     m_xml.startElement( "FatalErrorCondition" );
10326                     writeSourceInfo( result.getSourceInfo() );
10327                     m_xml.writeText( result.getMessage() );
10328                     m_xml.endElement();
10329                     break;
10330                 case ResultWas::Info:
10331                     m_xml.scopedElement( "Info" )
10332                         .writeText( result.getMessage() );
10333                     break;
10334                 case ResultWas::Warning:
10335                     // Warning will already have been written
10336                     break;
10337                 case ResultWas::ExplicitFailure:
10338                     m_xml.startElement( "Failure" );
10339                     writeSourceInfo( result.getSourceInfo() );
10340                     m_xml.writeText( result.getMessage() );
10341                     m_xml.endElement();
10342                     break;
10343                 default:
10344                     break;
10345             }
10346 
10347             if( result.hasExpression() )
10348                 m_xml.endElement();
10349 
10350             return true;
10351         }
10352 
sectionEnded(SectionStats const & sectionStats)10353         virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
10354             StreamingReporterBase::sectionEnded( sectionStats );
10355             if( --m_sectionDepth > 0 ) {
10356                 XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
10357                 e.writeAttribute( "successes", sectionStats.assertions.passed );
10358                 e.writeAttribute( "failures", sectionStats.assertions.failed );
10359                 e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
10360 
10361                 if ( m_config->showDurations() == ShowDurations::Always )
10362                     e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
10363 
10364                 m_xml.endElement();
10365             }
10366         }
10367 
testCaseEnded(TestCaseStats const & testCaseStats)10368         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
10369             StreamingReporterBase::testCaseEnded( testCaseStats );
10370             XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
10371             e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
10372 
10373             if ( m_config->showDurations() == ShowDurations::Always )
10374                 e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
10375 
10376             if( !testCaseStats.stdOut.empty() )
10377                 m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
10378             if( !testCaseStats.stdErr.empty() )
10379                 m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
10380 
10381             m_xml.endElement();
10382         }
10383 
testGroupEnded(TestGroupStats const & testGroupStats)10384         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
10385             StreamingReporterBase::testGroupEnded( testGroupStats );
10386             // TODO: Check testGroupStats.aborting and act accordingly.
10387             m_xml.scopedElement( "OverallResults" )
10388                 .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
10389                 .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
10390                 .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
10391             m_xml.endElement();
10392         }
10393 
testRunEnded(TestRunStats const & testRunStats)10394         virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
10395             StreamingReporterBase::testRunEnded( testRunStats );
10396             m_xml.scopedElement( "OverallResults" )
10397                 .writeAttribute( "successes", testRunStats.totals.assertions.passed )
10398                 .writeAttribute( "failures", testRunStats.totals.assertions.failed )
10399                 .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
10400             m_xml.endElement();
10401         }
10402 
10403     private:
10404         Timer m_testCaseTimer;
10405         XmlWriter m_xml;
10406         int m_sectionDepth;
10407     };
10408 
10409      INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
10410 
10411 } // end namespace Catch
10412 
10413 // #included from: ../reporters/catch_reporter_junit.hpp
10414 #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
10415 
10416 #include <assert.h>
10417 
10418 namespace Catch {
10419 
10420     namespace {
getCurrentTimestamp()10421         std::string getCurrentTimestamp() {
10422             // Beware, this is not reentrant because of backward compatibility issues
10423             // Also, UTC only, again because of backward compatibility (%z is C++11)
10424             time_t rawtime;
10425             std::time(&rawtime);
10426             const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z");
10427 
10428 #ifdef _MSC_VER
10429             std::tm timeInfo = {};
10430             gmtime_s(&timeInfo, &rawtime);
10431 #else
10432             std::tm* timeInfo;
10433             timeInfo = std::gmtime(&rawtime);
10434 #endif
10435 
10436             char timeStamp[timeStampSize];
10437             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
10438 
10439 #ifdef _MSC_VER
10440             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
10441 #else
10442             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
10443 #endif
10444             return std::string(timeStamp);
10445         }
10446 
10447     }
10448 
10449     class JunitReporter : public CumulativeReporterBase {
10450     public:
JunitReporter(ReporterConfig const & _config)10451         JunitReporter( ReporterConfig const& _config )
10452         :   CumulativeReporterBase( _config ),
10453             xml( _config.stream() ),
10454             unexpectedExceptions( 0 ),
10455             m_okToFail( false )
10456         {
10457             m_reporterPrefs.shouldRedirectStdOut = true;
10458         }
10459 
10460         virtual ~JunitReporter() CATCH_OVERRIDE;
10461 
getDescription()10462         static std::string getDescription() {
10463             return "Reports test results in an XML format that looks like Ant's junitreport target";
10464         }
10465 
noMatchingTestCases(std::string const &)10466         virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}
10467 
testRunStarting(TestRunInfo const & runInfo)10468         virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {
10469             CumulativeReporterBase::testRunStarting( runInfo );
10470             xml.startElement( "testsuites" );
10471         }
10472 
testGroupStarting(GroupInfo const & groupInfo)10473         virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
10474             suiteTimer.start();
10475             stdOutForSuite.str("");
10476             stdErrForSuite.str("");
10477             unexpectedExceptions = 0;
10478             CumulativeReporterBase::testGroupStarting( groupInfo );
10479         }
10480 
testCaseStarting(TestCaseInfo const & testCaseInfo)10481         virtual void testCaseStarting( TestCaseInfo const& testCaseInfo ) CATCH_OVERRIDE {
10482             m_okToFail = testCaseInfo.okToFail();
10483         }
assertionEnded(AssertionStats const & assertionStats)10484         virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
10485             if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
10486                 unexpectedExceptions++;
10487             return CumulativeReporterBase::assertionEnded( assertionStats );
10488         }
10489 
testCaseEnded(TestCaseStats const & testCaseStats)10490         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
10491             stdOutForSuite << testCaseStats.stdOut;
10492             stdErrForSuite << testCaseStats.stdErr;
10493             CumulativeReporterBase::testCaseEnded( testCaseStats );
10494         }
10495 
testGroupEnded(TestGroupStats const & testGroupStats)10496         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
10497             double suiteTime = suiteTimer.getElapsedSeconds();
10498             CumulativeReporterBase::testGroupEnded( testGroupStats );
10499             writeGroup( *m_testGroups.back(), suiteTime );
10500         }
10501 
testRunEndedCumulative()10502         virtual void testRunEndedCumulative() CATCH_OVERRIDE {
10503             xml.endElement();
10504         }
10505 
writeGroup(TestGroupNode const & groupNode,double suiteTime)10506         void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
10507             XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
10508             TestGroupStats const& stats = groupNode.value;
10509             xml.writeAttribute( "name", stats.groupInfo.name );
10510             xml.writeAttribute( "errors", unexpectedExceptions );
10511             xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
10512             xml.writeAttribute( "tests", stats.totals.assertions.total() );
10513             xml.writeAttribute( "hostname", "tbd" ); // !TBD
10514             if( m_config->showDurations() == ShowDurations::Never )
10515                 xml.writeAttribute( "time", "" );
10516             else
10517                 xml.writeAttribute( "time", suiteTime );
10518             xml.writeAttribute( "timestamp", getCurrentTimestamp() );
10519 
10520             // Write test cases
10521             for( TestGroupNode::ChildNodes::const_iterator
10522                     it = groupNode.children.begin(), itEnd = groupNode.children.end();
10523                     it != itEnd;
10524                     ++it )
10525                 writeTestCase( **it );
10526 
10527             xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
10528             xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
10529         }
10530 
writeTestCase(TestCaseNode const & testCaseNode)10531         void writeTestCase( TestCaseNode const& testCaseNode ) {
10532             TestCaseStats const& stats = testCaseNode.value;
10533 
10534             // All test cases have exactly one section - which represents the
10535             // test case itself. That section may have 0-n nested sections
10536             assert( testCaseNode.children.size() == 1 );
10537             SectionNode const& rootSection = *testCaseNode.children.front();
10538 
10539             std::string className = stats.testInfo.className;
10540 
10541             if( className.empty() ) {
10542                 if( rootSection.childSections.empty() )
10543                     className = "global";
10544             }
10545             writeSection( className, "", rootSection );
10546         }
10547 
writeSection(std::string const & className,std::string const & rootName,SectionNode const & sectionNode)10548         void writeSection(  std::string const& className,
10549                             std::string const& rootName,
10550                             SectionNode const& sectionNode ) {
10551             std::string name = trim( sectionNode.stats.sectionInfo.name );
10552             if( !rootName.empty() )
10553                 name = rootName + '/' + name;
10554 
10555             if( !sectionNode.assertions.empty() ||
10556                 !sectionNode.stdOut.empty() ||
10557                 !sectionNode.stdErr.empty() ) {
10558                 XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
10559                 if( className.empty() ) {
10560                     xml.writeAttribute( "classname", name );
10561                     xml.writeAttribute( "name", "root" );
10562                 }
10563                 else {
10564                     xml.writeAttribute( "classname", className );
10565                     xml.writeAttribute( "name", name );
10566                 }
10567                 xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
10568 
10569                 writeAssertions( sectionNode );
10570 
10571                 if( !sectionNode.stdOut.empty() )
10572                     xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
10573                 if( !sectionNode.stdErr.empty() )
10574                     xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
10575             }
10576             for( SectionNode::ChildSections::const_iterator
10577                     it = sectionNode.childSections.begin(),
10578                     itEnd = sectionNode.childSections.end();
10579                     it != itEnd;
10580                     ++it )
10581                 if( className.empty() )
10582                     writeSection( name, "", **it );
10583                 else
10584                     writeSection( className, name, **it );
10585         }
10586 
writeAssertions(SectionNode const & sectionNode)10587         void writeAssertions( SectionNode const& sectionNode ) {
10588             for( SectionNode::Assertions::const_iterator
10589                     it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
10590                     it != itEnd;
10591                     ++it )
10592                 writeAssertion( *it );
10593         }
writeAssertion(AssertionStats const & stats)10594         void writeAssertion( AssertionStats const& stats ) {
10595             AssertionResult const& result = stats.assertionResult;
10596             if( !result.isOk() ) {
10597                 std::string elementName;
10598                 switch( result.getResultType() ) {
10599                     case ResultWas::ThrewException:
10600                     case ResultWas::FatalErrorCondition:
10601                         elementName = "error";
10602                         break;
10603                     case ResultWas::ExplicitFailure:
10604                         elementName = "failure";
10605                         break;
10606                     case ResultWas::ExpressionFailed:
10607                         elementName = "failure";
10608                         break;
10609                     case ResultWas::DidntThrowException:
10610                         elementName = "failure";
10611                         break;
10612 
10613                     // We should never see these here:
10614                     case ResultWas::Info:
10615                     case ResultWas::Warning:
10616                     case ResultWas::Ok:
10617                     case ResultWas::Unknown:
10618                     case ResultWas::FailureBit:
10619                     case ResultWas::Exception:
10620                         elementName = "internalError";
10621                         break;
10622                 }
10623 
10624                 XmlWriter::ScopedElement e = xml.scopedElement( elementName );
10625 
10626                 xml.writeAttribute( "message", result.getExpandedExpression() );
10627                 xml.writeAttribute( "type", result.getTestMacroName() );
10628 
10629                 std::ostringstream oss;
10630                 if( !result.getMessage().empty() )
10631                     oss << result.getMessage() << '\n';
10632                 for( std::vector<MessageInfo>::const_iterator
10633                         it = stats.infoMessages.begin(),
10634                         itEnd = stats.infoMessages.end();
10635                             it != itEnd;
10636                             ++it )
10637                     if( it->type == ResultWas::Info )
10638                         oss << it->message << '\n';
10639 
10640                 oss << "at " << result.getSourceInfo();
10641                 xml.writeText( oss.str(), false );
10642             }
10643         }
10644 
10645         XmlWriter xml;
10646         Timer suiteTimer;
10647         std::ostringstream stdOutForSuite;
10648         std::ostringstream stdErrForSuite;
10649         unsigned int unexpectedExceptions;
10650         bool m_okToFail;
10651     };
10652 
10653     INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
10654 
10655 } // end namespace Catch
10656 
10657 // #included from: ../reporters/catch_reporter_console.hpp
10658 #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
10659 
10660 #include <cfloat>
10661 #include <cstdio>
10662 
10663 namespace Catch {
10664 
10665     struct ConsoleReporter : StreamingReporterBase {
ConsoleReporterCatch::ConsoleReporter10666         ConsoleReporter( ReporterConfig const& _config )
10667         :   StreamingReporterBase( _config ),
10668             m_headerPrinted( false )
10669         {}
10670 
10671         virtual ~ConsoleReporter() CATCH_OVERRIDE;
getDescriptionCatch::ConsoleReporter10672         static std::string getDescription() {
10673             return "Reports test results as plain lines of text";
10674         }
10675 
noMatchingTestCasesCatch::ConsoleReporter10676         virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
10677             stream << "No test cases matched '" << spec << '\'' << std::endl;
10678         }
10679 
assertionStartingCatch::ConsoleReporter10680         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
10681         }
10682 
assertionEndedCatch::ConsoleReporter10683         virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
10684             AssertionResult const& result = _assertionStats.assertionResult;
10685 
10686             bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
10687 
10688             // Drop out if result was successful but we're not printing them.
10689             if( !includeResults && result.getResultType() != ResultWas::Warning )
10690                 return false;
10691 
10692             lazyPrint();
10693 
10694             AssertionPrinter printer( stream, _assertionStats, includeResults );
10695             printer.print();
10696             stream << std::endl;
10697             return true;
10698         }
10699 
sectionStartingCatch::ConsoleReporter10700         virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
10701             m_headerPrinted = false;
10702             StreamingReporterBase::sectionStarting( _sectionInfo );
10703         }
sectionEndedCatch::ConsoleReporter10704         virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
10705             if( _sectionStats.missingAssertions ) {
10706                 lazyPrint();
10707                 Colour colour( Colour::ResultError );
10708                 if( m_sectionStack.size() > 1 )
10709                     stream << "\nNo assertions in section";
10710                 else
10711                     stream << "\nNo assertions in test case";
10712                 stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
10713             }
10714             if( m_config->showDurations() == ShowDurations::Always ) {
10715                 stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
10716             }
10717             if( m_headerPrinted ) {
10718                 m_headerPrinted = false;
10719             }
10720             StreamingReporterBase::sectionEnded( _sectionStats );
10721         }
10722 
testCaseEndedCatch::ConsoleReporter10723         virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
10724             StreamingReporterBase::testCaseEnded( _testCaseStats );
10725             m_headerPrinted = false;
10726         }
testGroupEndedCatch::ConsoleReporter10727         virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
10728             if( currentGroupInfo.used ) {
10729                 printSummaryDivider();
10730                 stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
10731                 printTotals( _testGroupStats.totals );
10732                 stream << '\n' << std::endl;
10733             }
10734             StreamingReporterBase::testGroupEnded( _testGroupStats );
10735         }
testRunEndedCatch::ConsoleReporter10736         virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
10737             printTotalsDivider( _testRunStats.totals );
10738             printTotals( _testRunStats.totals );
10739             stream << std::endl;
10740             StreamingReporterBase::testRunEnded( _testRunStats );
10741         }
10742 
10743     private:
10744 
10745         class AssertionPrinter {
10746             void operator= ( AssertionPrinter const& );
10747         public:
AssertionPrinter(std::ostream & _stream,AssertionStats const & _stats,bool _printInfoMessages)10748             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
10749             :   stream( _stream ),
10750                 stats( _stats ),
10751                 result( _stats.assertionResult ),
10752                 colour( Colour::None ),
10753                 message( result.getMessage() ),
10754                 messages( _stats.infoMessages ),
10755                 printInfoMessages( _printInfoMessages )
10756             {
10757                 switch( result.getResultType() ) {
10758                     case ResultWas::Ok:
10759                         colour = Colour::Success;
10760                         passOrFail = "PASSED";
10761                         //if( result.hasMessage() )
10762                         if( _stats.infoMessages.size() == 1 )
10763                             messageLabel = "with message";
10764                         if( _stats.infoMessages.size() > 1 )
10765                             messageLabel = "with messages";
10766                         break;
10767                     case ResultWas::ExpressionFailed:
10768                         if( result.isOk() ) {
10769                             colour = Colour::Success;
10770                             passOrFail = "FAILED - but was ok";
10771                         }
10772                         else {
10773                             colour = Colour::Error;
10774                             passOrFail = "FAILED";
10775                         }
10776                         if( _stats.infoMessages.size() == 1 )
10777                             messageLabel = "with message";
10778                         if( _stats.infoMessages.size() > 1 )
10779                             messageLabel = "with messages";
10780                         break;
10781                     case ResultWas::ThrewException:
10782                         colour = Colour::Error;
10783                         passOrFail = "FAILED";
10784                         messageLabel = "due to unexpected exception with ";
10785                         if (_stats.infoMessages.size() == 1)
10786                             messageLabel += "message";
10787                         if (_stats.infoMessages.size() > 1)
10788                             messageLabel += "messages";
10789                         break;
10790                     case ResultWas::FatalErrorCondition:
10791                         colour = Colour::Error;
10792                         passOrFail = "FAILED";
10793                         messageLabel = "due to a fatal error condition";
10794                         break;
10795                     case ResultWas::DidntThrowException:
10796                         colour = Colour::Error;
10797                         passOrFail = "FAILED";
10798                         messageLabel = "because no exception was thrown where one was expected";
10799                         break;
10800                     case ResultWas::Info:
10801                         messageLabel = "info";
10802                         break;
10803                     case ResultWas::Warning:
10804                         messageLabel = "warning";
10805                         break;
10806                     case ResultWas::ExplicitFailure:
10807                         passOrFail = "FAILED";
10808                         colour = Colour::Error;
10809                         if( _stats.infoMessages.size() == 1 )
10810                             messageLabel = "explicitly with message";
10811                         if( _stats.infoMessages.size() > 1 )
10812                             messageLabel = "explicitly with messages";
10813                         break;
10814                     // These cases are here to prevent compiler warnings
10815                     case ResultWas::Unknown:
10816                     case ResultWas::FailureBit:
10817                     case ResultWas::Exception:
10818                         passOrFail = "** internal error **";
10819                         colour = Colour::Error;
10820                         break;
10821                 }
10822             }
10823 
print() const10824             void print() const {
10825                 printSourceInfo();
10826                 if( stats.totals.assertions.total() > 0 ) {
10827                     if( result.isOk() )
10828                         stream << '\n';
10829                     printResultType();
10830                     printOriginalExpression();
10831                     printReconstructedExpression();
10832                 }
10833                 else {
10834                     stream << '\n';
10835                 }
10836                 printMessage();
10837             }
10838 
10839         private:
printResultType() const10840             void printResultType() const {
10841                 if( !passOrFail.empty() ) {
10842                     Colour colourGuard( colour );
10843                     stream << passOrFail << ":\n";
10844                 }
10845             }
printOriginalExpression() const10846             void printOriginalExpression() const {
10847                 if( result.hasExpression() ) {
10848                     Colour colourGuard( Colour::OriginalExpression );
10849                     stream  << "  ";
10850                     stream << result.getExpressionInMacro();
10851                     stream << '\n';
10852                 }
10853             }
printReconstructedExpression() const10854             void printReconstructedExpression() const {
10855                 if( result.hasExpandedExpression() ) {
10856                     stream << "with expansion:\n";
10857                     Colour colourGuard( Colour::ReconstructedExpression );
10858                     stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << '\n';
10859                 }
10860             }
printMessage() const10861             void printMessage() const {
10862                 if( !messageLabel.empty() )
10863                     stream << messageLabel << ':' << '\n';
10864                 for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
10865                         it != itEnd;
10866                         ++it ) {
10867                     // If this assertion is a warning ignore any INFO messages
10868                     if( printInfoMessages || it->type != ResultWas::Info )
10869                         stream << Text( it->message, TextAttributes().setIndent(2) ) << '\n';
10870                 }
10871             }
printSourceInfo() const10872             void printSourceInfo() const {
10873                 Colour colourGuard( Colour::FileName );
10874                 stream << result.getSourceInfo() << ": ";
10875             }
10876 
10877             std::ostream& stream;
10878             AssertionStats const& stats;
10879             AssertionResult const& result;
10880             Colour::Code colour;
10881             std::string passOrFail;
10882             std::string messageLabel;
10883             std::string message;
10884             std::vector<MessageInfo> messages;
10885             bool printInfoMessages;
10886         };
10887 
lazyPrintCatch::ConsoleReporter10888         void lazyPrint() {
10889 
10890             if( !currentTestRunInfo.used )
10891                 lazyPrintRunInfo();
10892             if( !currentGroupInfo.used )
10893                 lazyPrintGroupInfo();
10894 
10895             if( !m_headerPrinted ) {
10896                 printTestCaseAndSectionHeader();
10897                 m_headerPrinted = true;
10898             }
10899         }
lazyPrintRunInfoCatch::ConsoleReporter10900         void lazyPrintRunInfo() {
10901             stream  << '\n' << getLineOfChars<'~'>() << '\n';
10902             Colour colour( Colour::SecondaryText );
10903             stream  << currentTestRunInfo->name
10904                     << " is a Catch v"  << libraryVersion() << " host application.\n"
10905                     << "Run with -? for options\n\n";
10906 
10907             if( m_config->rngSeed() != 0 )
10908                 stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
10909 
10910             currentTestRunInfo.used = true;
10911         }
lazyPrintGroupInfoCatch::ConsoleReporter10912         void lazyPrintGroupInfo() {
10913             if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
10914                 printClosedHeader( "Group: " + currentGroupInfo->name );
10915                 currentGroupInfo.used = true;
10916             }
10917         }
printTestCaseAndSectionHeaderCatch::ConsoleReporter10918         void printTestCaseAndSectionHeader() {
10919             assert( !m_sectionStack.empty() );
10920             printOpenHeader( currentTestCaseInfo->name );
10921 
10922             if( m_sectionStack.size() > 1 ) {
10923                 Colour colourGuard( Colour::Headers );
10924 
10925                 std::vector<SectionInfo>::const_iterator
10926                     it = m_sectionStack.begin()+1, // Skip first section (test case)
10927                     itEnd = m_sectionStack.end();
10928                 for( ; it != itEnd; ++it )
10929                     printHeaderString( it->name, 2 );
10930             }
10931 
10932             SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
10933 
10934             if( !lineInfo.empty() ){
10935                 stream << getLineOfChars<'-'>() << '\n';
10936                 Colour colourGuard( Colour::FileName );
10937                 stream << lineInfo << '\n';
10938             }
10939             stream << getLineOfChars<'.'>() << '\n' << std::endl;
10940         }
10941 
printClosedHeaderCatch::ConsoleReporter10942         void printClosedHeader( std::string const& _name ) {
10943             printOpenHeader( _name );
10944             stream << getLineOfChars<'.'>() << '\n';
10945         }
printOpenHeaderCatch::ConsoleReporter10946         void printOpenHeader( std::string const& _name ) {
10947             stream  << getLineOfChars<'-'>() << '\n';
10948             {
10949                 Colour colourGuard( Colour::Headers );
10950                 printHeaderString( _name );
10951             }
10952         }
10953 
10954         // if string has a : in first line will set indent to follow it on
10955         // subsequent lines
printHeaderStringCatch::ConsoleReporter10956         void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
10957             std::size_t i = _string.find( ": " );
10958             if( i != std::string::npos )
10959                 i+=2;
10960             else
10961                 i = 0;
10962             stream << Text( _string, TextAttributes()
10963                                         .setIndent( indent+i)
10964                                         .setInitialIndent( indent ) ) << '\n';
10965         }
10966 
10967         struct SummaryColumn {
10968 
SummaryColumnCatch::ConsoleReporter::SummaryColumn10969             SummaryColumn( std::string const& _label, Colour::Code _colour )
10970             :   label( _label ),
10971                 colour( _colour )
10972             {}
addRowCatch::ConsoleReporter::SummaryColumn10973             SummaryColumn addRow( std::size_t count ) {
10974                 std::ostringstream oss;
10975                 oss << count;
10976                 std::string row = oss.str();
10977                 for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
10978                     while( it->size() < row.size() )
10979                         *it = ' ' + *it;
10980                     while( it->size() > row.size() )
10981                         row = ' ' + row;
10982                 }
10983                 rows.push_back( row );
10984                 return *this;
10985             }
10986 
10987             std::string label;
10988             Colour::Code colour;
10989             std::vector<std::string> rows;
10990 
10991         };
10992 
printTotalsCatch::ConsoleReporter10993         void printTotals( Totals const& totals ) {
10994             if( totals.testCases.total() == 0 ) {
10995                 stream << Colour( Colour::Warning ) << "No tests ran\n";
10996             }
10997             else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
10998                 stream << Colour( Colour::ResultSuccess ) << "All tests passed";
10999                 stream << " ("
11000                         << pluralise( totals.assertions.passed, "assertion" ) << " in "
11001                         << pluralise( totals.testCases.passed, "test case" ) << ')'
11002                         << '\n';
11003             }
11004             else {
11005 
11006                 std::vector<SummaryColumn> columns;
11007                 columns.push_back( SummaryColumn( "", Colour::None )
11008                                         .addRow( totals.testCases.total() )
11009                                         .addRow( totals.assertions.total() ) );
11010                 columns.push_back( SummaryColumn( "passed", Colour::Success )
11011                                         .addRow( totals.testCases.passed )
11012                                         .addRow( totals.assertions.passed ) );
11013                 columns.push_back( SummaryColumn( "failed", Colour::ResultError )
11014                                         .addRow( totals.testCases.failed )
11015                                         .addRow( totals.assertions.failed ) );
11016                 columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
11017                                         .addRow( totals.testCases.failedButOk )
11018                                         .addRow( totals.assertions.failedButOk ) );
11019 
11020                 printSummaryRow( "test cases", columns, 0 );
11021                 printSummaryRow( "assertions", columns, 1 );
11022             }
11023         }
printSummaryRowCatch::ConsoleReporter11024         void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
11025             for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
11026                 std::string value = it->rows[row];
11027                 if( it->label.empty() ) {
11028                     stream << label << ": ";
11029                     if( value != "0" )
11030                         stream << value;
11031                     else
11032                         stream << Colour( Colour::Warning ) << "- none -";
11033                 }
11034                 else if( value != "0" ) {
11035                     stream  << Colour( Colour::LightGrey ) << " | ";
11036                     stream  << Colour( it->colour )
11037                             << value << ' ' << it->label;
11038                 }
11039             }
11040             stream << '\n';
11041         }
11042 
makeRatioCatch::ConsoleReporter11043         static std::size_t makeRatio( std::size_t number, std::size_t total ) {
11044             std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
11045             return ( ratio == 0 && number > 0 ) ? 1 : ratio;
11046         }
findMaxCatch::ConsoleReporter11047         static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
11048             if( i > j && i > k )
11049                 return i;
11050             else if( j > k )
11051                 return j;
11052             else
11053                 return k;
11054         }
11055 
printTotalsDividerCatch::ConsoleReporter11056         void printTotalsDivider( Totals const& totals ) {
11057             if( totals.testCases.total() > 0 ) {
11058                 std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
11059                 std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
11060                 std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
11061                 while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
11062                     findMax( failedRatio, failedButOkRatio, passedRatio )++;
11063                 while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
11064                     findMax( failedRatio, failedButOkRatio, passedRatio )--;
11065 
11066                 stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
11067                 stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
11068                 if( totals.testCases.allPassed() )
11069                     stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
11070                 else
11071                     stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
11072             }
11073             else {
11074                 stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
11075             }
11076             stream << '\n';
11077         }
printSummaryDividerCatch::ConsoleReporter11078         void printSummaryDivider() {
11079             stream << getLineOfChars<'-'>() << '\n';
11080         }
11081 
11082     private:
11083         bool m_headerPrinted;
11084     };
11085 
11086     INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
11087 
11088 } // end namespace Catch
11089 
11090 // #included from: ../reporters/catch_reporter_compact.hpp
11091 #define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
11092 
11093 namespace Catch {
11094 
11095     struct CompactReporter : StreamingReporterBase {
11096 
CompactReporterCatch::CompactReporter11097         CompactReporter( ReporterConfig const& _config )
11098         : StreamingReporterBase( _config )
11099         {}
11100 
11101         virtual ~CompactReporter();
11102 
getDescriptionCatch::CompactReporter11103         static std::string getDescription() {
11104             return "Reports test results on a single line, suitable for IDEs";
11105         }
11106 
getPreferencesCatch::CompactReporter11107         virtual ReporterPreferences getPreferences() const {
11108             ReporterPreferences prefs;
11109             prefs.shouldRedirectStdOut = false;
11110             return prefs;
11111         }
11112 
noMatchingTestCasesCatch::CompactReporter11113         virtual void noMatchingTestCases( std::string const& spec ) {
11114             stream << "No test cases matched '" << spec << '\'' << std::endl;
11115         }
11116 
assertionStartingCatch::CompactReporter11117         virtual void assertionStarting( AssertionInfo const& ) {}
11118 
assertionEndedCatch::CompactReporter11119         virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
11120             AssertionResult const& result = _assertionStats.assertionResult;
11121 
11122             bool printInfoMessages = true;
11123 
11124             // Drop out if result was successful and we're not printing those
11125             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
11126                 if( result.getResultType() != ResultWas::Warning )
11127                     return false;
11128                 printInfoMessages = false;
11129             }
11130 
11131             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
11132             printer.print();
11133 
11134             stream << std::endl;
11135             return true;
11136         }
11137 
sectionEndedCatch::CompactReporter11138         virtual void sectionEnded(SectionStats const& _sectionStats) CATCH_OVERRIDE {
11139             if (m_config->showDurations() == ShowDurations::Always) {
11140                 stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
11141             }
11142         }
11143 
testRunEndedCatch::CompactReporter11144         virtual void testRunEnded( TestRunStats const& _testRunStats ) {
11145             printTotals( _testRunStats.totals );
11146             stream << '\n' << std::endl;
11147             StreamingReporterBase::testRunEnded( _testRunStats );
11148         }
11149 
11150     private:
11151         class AssertionPrinter {
11152             void operator= ( AssertionPrinter const& );
11153         public:
AssertionPrinter(std::ostream & _stream,AssertionStats const & _stats,bool _printInfoMessages)11154             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
11155             : stream( _stream )
11156             , stats( _stats )
11157             , result( _stats.assertionResult )
11158             , messages( _stats.infoMessages )
11159             , itMessage( _stats.infoMessages.begin() )
11160             , printInfoMessages( _printInfoMessages )
11161             {}
11162 
print()11163             void print() {
11164                 printSourceInfo();
11165 
11166                 itMessage = messages.begin();
11167 
11168                 switch( result.getResultType() ) {
11169                     case ResultWas::Ok:
11170                         printResultType( Colour::ResultSuccess, passedString() );
11171                         printOriginalExpression();
11172                         printReconstructedExpression();
11173                         if ( ! result.hasExpression() )
11174                             printRemainingMessages( Colour::None );
11175                         else
11176                             printRemainingMessages();
11177                         break;
11178                     case ResultWas::ExpressionFailed:
11179                         if( result.isOk() )
11180                             printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
11181                         else
11182                             printResultType( Colour::Error, failedString() );
11183                         printOriginalExpression();
11184                         printReconstructedExpression();
11185                         printRemainingMessages();
11186                         break;
11187                     case ResultWas::ThrewException:
11188                         printResultType( Colour::Error, failedString() );
11189                         printIssue( "unexpected exception with message:" );
11190                         printMessage();
11191                         printExpressionWas();
11192                         printRemainingMessages();
11193                         break;
11194                     case ResultWas::FatalErrorCondition:
11195                         printResultType( Colour::Error, failedString() );
11196                         printIssue( "fatal error condition with message:" );
11197                         printMessage();
11198                         printExpressionWas();
11199                         printRemainingMessages();
11200                         break;
11201                     case ResultWas::DidntThrowException:
11202                         printResultType( Colour::Error, failedString() );
11203                         printIssue( "expected exception, got none" );
11204                         printExpressionWas();
11205                         printRemainingMessages();
11206                         break;
11207                     case ResultWas::Info:
11208                         printResultType( Colour::None, "info" );
11209                         printMessage();
11210                         printRemainingMessages();
11211                         break;
11212                     case ResultWas::Warning:
11213                         printResultType( Colour::None, "warning" );
11214                         printMessage();
11215                         printRemainingMessages();
11216                         break;
11217                     case ResultWas::ExplicitFailure:
11218                         printResultType( Colour::Error, failedString() );
11219                         printIssue( "explicitly" );
11220                         printRemainingMessages( Colour::None );
11221                         break;
11222                     // These cases are here to prevent compiler warnings
11223                     case ResultWas::Unknown:
11224                     case ResultWas::FailureBit:
11225                     case ResultWas::Exception:
11226                         printResultType( Colour::Error, "** internal error **" );
11227                         break;
11228                 }
11229             }
11230 
11231         private:
11232             // Colour::LightGrey
11233 
dimColour()11234             static Colour::Code dimColour() { return Colour::FileName; }
11235 
11236 #ifdef CATCH_PLATFORM_MAC
failedString()11237             static const char* failedString() { return "FAILED"; }
passedString()11238             static const char* passedString() { return "PASSED"; }
11239 #else
failedString()11240             static const char* failedString() { return "failed"; }
passedString()11241             static const char* passedString() { return "passed"; }
11242 #endif
11243 
printSourceInfo() const11244             void printSourceInfo() const {
11245                 Colour colourGuard( Colour::FileName );
11246                 stream << result.getSourceInfo() << ':';
11247             }
11248 
printResultType(Colour::Code colour,std::string const & passOrFail) const11249             void printResultType( Colour::Code colour, std::string const& passOrFail ) const {
11250                 if( !passOrFail.empty() ) {
11251                     {
11252                         Colour colourGuard( colour );
11253                         stream << ' ' << passOrFail;
11254                     }
11255                     stream << ':';
11256                 }
11257             }
11258 
printIssue(std::string const & issue) const11259             void printIssue( std::string const& issue ) const {
11260                 stream << ' ' << issue;
11261             }
11262 
printExpressionWas()11263             void printExpressionWas() {
11264                 if( result.hasExpression() ) {
11265                     stream << ';';
11266                     {
11267                         Colour colour( dimColour() );
11268                         stream << " expression was:";
11269                     }
11270                     printOriginalExpression();
11271                 }
11272             }
11273 
printOriginalExpression() const11274             void printOriginalExpression() const {
11275                 if( result.hasExpression() ) {
11276                     stream << ' ' << result.getExpression();
11277                 }
11278             }
11279 
printReconstructedExpression() const11280             void printReconstructedExpression() const {
11281                 if( result.hasExpandedExpression() ) {
11282                     {
11283                         Colour colour( dimColour() );
11284                         stream << " for: ";
11285                     }
11286                     stream << result.getExpandedExpression();
11287                 }
11288             }
11289 
printMessage()11290             void printMessage() {
11291                 if ( itMessage != messages.end() ) {
11292                     stream << " '" << itMessage->message << '\'';
11293                     ++itMessage;
11294                 }
11295             }
11296 
printRemainingMessages(Colour::Code colour=dimColour ())11297             void printRemainingMessages( Colour::Code colour = dimColour() ) {
11298                 if ( itMessage == messages.end() )
11299                     return;
11300 
11301                 // using messages.end() directly yields compilation error:
11302                 std::vector<MessageInfo>::const_iterator itEnd = messages.end();
11303                 const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
11304 
11305                 {
11306                     Colour colourGuard( colour );
11307                     stream << " with " << pluralise( N, "message" ) << ':';
11308                 }
11309 
11310                 for(; itMessage != itEnd; ) {
11311                     // If this assertion is a warning ignore any INFO messages
11312                     if( printInfoMessages || itMessage->type != ResultWas::Info ) {
11313                         stream << " '" << itMessage->message << '\'';
11314                         if ( ++itMessage != itEnd ) {
11315                             Colour colourGuard( dimColour() );
11316                             stream << " and";
11317                         }
11318                     }
11319                 }
11320             }
11321 
11322         private:
11323             std::ostream& stream;
11324             AssertionStats const& stats;
11325             AssertionResult const& result;
11326             std::vector<MessageInfo> messages;
11327             std::vector<MessageInfo>::const_iterator itMessage;
11328             bool printInfoMessages;
11329         };
11330 
11331         // Colour, message variants:
11332         // - white: No tests ran.
11333         // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
11334         // - white: Passed [both/all] N test cases (no assertions).
11335         // -   red: Failed N tests cases, failed M assertions.
11336         // - green: Passed [both/all] N tests cases with M assertions.
11337 
bothOrAllCatch::CompactReporter11338         std::string bothOrAll( std::size_t count ) const {
11339             return count == 1 ? std::string() : count == 2 ? "both " : "all " ;
11340         }
11341 
printTotalsCatch::CompactReporter11342         void printTotals( const Totals& totals ) const {
11343             if( totals.testCases.total() == 0 ) {
11344                 stream << "No tests ran.";
11345             }
11346             else if( totals.testCases.failed == totals.testCases.total() ) {
11347                 Colour colour( Colour::ResultError );
11348                 const std::string qualify_assertions_failed =
11349                     totals.assertions.failed == totals.assertions.total() ?
11350                         bothOrAll( totals.assertions.failed ) : std::string();
11351                 stream <<
11352                     "Failed " << bothOrAll( totals.testCases.failed )
11353                               << pluralise( totals.testCases.failed, "test case"  ) << ", "
11354                     "failed " << qualify_assertions_failed <<
11355                                  pluralise( totals.assertions.failed, "assertion" ) << '.';
11356             }
11357             else if( totals.assertions.total() == 0 ) {
11358                 stream <<
11359                     "Passed " << bothOrAll( totals.testCases.total() )
11360                               << pluralise( totals.testCases.total(), "test case" )
11361                               << " (no assertions).";
11362             }
11363             else if( totals.assertions.failed ) {
11364                 Colour colour( Colour::ResultError );
11365                 stream <<
11366                     "Failed " << pluralise( totals.testCases.failed, "test case"  ) << ", "
11367                     "failed " << pluralise( totals.assertions.failed, "assertion" ) << '.';
11368             }
11369             else {
11370                 Colour colour( Colour::ResultSuccess );
11371                 stream <<
11372                     "Passed " << bothOrAll( totals.testCases.passed )
11373                               << pluralise( totals.testCases.passed, "test case"  ) <<
11374                     " with "  << pluralise( totals.assertions.passed, "assertion" ) << '.';
11375             }
11376         }
11377     };
11378 
11379     INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
11380 
11381 } // end namespace Catch
11382 
11383 namespace Catch {
11384     // These are all here to avoid warnings about not having any out of line
11385     // virtual methods
~NonCopyable()11386     NonCopyable::~NonCopyable() {}
~IShared()11387     IShared::~IShared() {}
~IStream()11388     IStream::~IStream() CATCH_NOEXCEPT {}
~FileStream()11389     FileStream::~FileStream() CATCH_NOEXCEPT {}
~CoutStream()11390     CoutStream::~CoutStream() CATCH_NOEXCEPT {}
~DebugOutStream()11391     DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
~StreamBufBase()11392     StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
~IContext()11393     IContext::~IContext() {}
~IResultCapture()11394     IResultCapture::~IResultCapture() {}
~ITestCase()11395     ITestCase::~ITestCase() {}
~ITestCaseRegistry()11396     ITestCaseRegistry::~ITestCaseRegistry() {}
~IRegistryHub()11397     IRegistryHub::~IRegistryHub() {}
~IMutableRegistryHub()11398     IMutableRegistryHub::~IMutableRegistryHub() {}
~IExceptionTranslator()11399     IExceptionTranslator::~IExceptionTranslator() {}
~IExceptionTranslatorRegistry()11400     IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
~IReporter()11401     IReporter::~IReporter() {}
~IReporterFactory()11402     IReporterFactory::~IReporterFactory() {}
~IReporterRegistry()11403     IReporterRegistry::~IReporterRegistry() {}
~IStreamingReporter()11404     IStreamingReporter::~IStreamingReporter() {}
~AssertionStats()11405     AssertionStats::~AssertionStats() {}
~SectionStats()11406     SectionStats::~SectionStats() {}
~TestCaseStats()11407     TestCaseStats::~TestCaseStats() {}
~TestGroupStats()11408     TestGroupStats::~TestGroupStats() {}
~TestRunStats()11409     TestRunStats::~TestRunStats() {}
~SectionNode()11410     CumulativeReporterBase::SectionNode::~SectionNode() {}
~CumulativeReporterBase()11411     CumulativeReporterBase::~CumulativeReporterBase() {}
11412 
~StreamingReporterBase()11413     StreamingReporterBase::~StreamingReporterBase() {}
~ConsoleReporter()11414     ConsoleReporter::~ConsoleReporter() {}
~CompactReporter()11415     CompactReporter::~CompactReporter() {}
~IRunner()11416     IRunner::~IRunner() {}
~IMutableContext()11417     IMutableContext::~IMutableContext() {}
~IConfig()11418     IConfig::~IConfig() {}
~XmlReporter()11419     XmlReporter::~XmlReporter() {}
~JunitReporter()11420     JunitReporter::~JunitReporter() {}
~TestRegistry()11421     TestRegistry::~TestRegistry() {}
~FreeFunctionTestCase()11422     FreeFunctionTestCase::~FreeFunctionTestCase() {}
~IGeneratorInfo()11423     IGeneratorInfo::~IGeneratorInfo() {}
~IGeneratorsForTest()11424     IGeneratorsForTest::~IGeneratorsForTest() {}
~WildcardPattern()11425     WildcardPattern::~WildcardPattern() {}
~Pattern()11426     TestSpec::Pattern::~Pattern() {}
~NamePattern()11427     TestSpec::NamePattern::~NamePattern() {}
~TagPattern()11428     TestSpec::TagPattern::~TagPattern() {}
~ExcludedPattern()11429     TestSpec::ExcludedPattern::~ExcludedPattern() {}
~MatcherUntypedBase()11430     Matchers::Impl::MatcherUntypedBase::~MatcherUntypedBase() {}
11431 
dummy()11432     void Config::dummy() {}
11433 
11434     namespace TestCaseTracking {
~ITracker()11435         ITracker::~ITracker() {}
~TrackerBase()11436         TrackerBase::~TrackerBase() {}
~SectionTracker()11437         SectionTracker::~SectionTracker() {}
~IndexTracker()11438         IndexTracker::~IndexTracker() {}
11439     }
11440 }
11441 
11442 #ifdef __clang__
11443 #pragma clang diagnostic pop
11444 #endif
11445 
11446 #endif
11447 
11448 #ifdef CATCH_CONFIG_MAIN
11449 // #included from: internal/catch_default_main.hpp
11450 #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
11451 
11452 #ifndef __OBJC__
11453 
11454 #if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
11455 // Standard C/C++ Win32 Unicode wmain entry point
wmain(int argc,wchar_t * argv[],wchar_t * [])11456 extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
11457 #else
11458 // Standard C/C++ main entry point
11459 int main (int argc, char * argv[]) {
11460 #endif
11461 
11462     int result = Catch::Session().run( argc, argv );
11463     return ( result < 0xff ? result : 0xff );
11464 }
11465 
11466 #else // __OBJC__
11467 
11468 // Objective-C entry point
11469 int main (int argc, char * const argv[]) {
11470 #if !CATCH_ARC_ENABLED
11471     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
11472 #endif
11473 
11474     Catch::registerTestMethods();
11475     int result = Catch::Session().run( argc, (char* const*)argv );
11476 
11477 #if !CATCH_ARC_ENABLED
11478     [pool drain];
11479 #endif
11480 
11481     return ( result < 0xff ? result : 0xff );
11482 }
11483 
11484 #endif // __OBJC__
11485 
11486 #endif
11487 
11488 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
11489 #  undef CLARA_CONFIG_MAIN
11490 #endif
11491 
11492 //////
11493 
11494 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
11495 #ifdef CATCH_CONFIG_PREFIX_ALL
11496 
11497 #if defined(CATCH_CONFIG_FAST_COMPILE)
11498 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr )
11499 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
11500 #else
11501 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr )
11502 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr  )
11503 #endif
11504 
11505 #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr )
11506 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
11507 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
11508 #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr )
11509 
11510 #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, expr )
11511 #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr )
11512 #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr )
11513 #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr )
11514 #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr )
11515 
11516 #define CATCH_CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr )
11517 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
11518 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
11519 #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr )
11520 
11521 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
11522 
11523 #if defined(CATCH_CONFIG_FAST_COMPILE)
11524 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
11525 #else
11526 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
11527 #endif
11528 
11529 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
11530 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
11531 #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
11532 #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) )
11533 #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) )
11534 
11535 #ifdef CATCH_CONFIG_VARIADIC_MACROS
11536     #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
11537     #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
11538     #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
11539     #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
11540     #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
11541     #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
11542     #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
11543     #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
11544 #else
11545     #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
11546     #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
11547     #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
11548     #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
11549     #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
11550     #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg )
11551     #define CATCH_FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg )
11552     #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg )
11553 #endif
11554 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
11555 
11556 #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
11557 #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
11558 
11559 #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
11560 
11561 // "BDD-style" convenience wrappers
11562 #ifdef CATCH_CONFIG_VARIADIC_MACROS
11563 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
11564 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
11565 #else
11566 #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
11567 #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
11568 #endif
11569 #define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc, "" )
11570 #define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc, "" )
11571 #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
11572 #define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc, "" )
11573 #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
11574 
11575 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
11576 #else
11577 
11578 #if defined(CATCH_CONFIG_FAST_COMPILE)
11579 #define REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE", Catch::ResultDisposition::Normal, expr )
11580 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
11581 
11582 #else
11583 #define REQUIRE( expr ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, expr  )
11584 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
11585 #endif
11586 
11587 #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr )
11588 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
11589 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
11590 #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr )
11591 
11592 #define CHECK( expr ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, expr )
11593 #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr )
11594 #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr )
11595 #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr )
11596 #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr )
11597 
11598 #define CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr )
11599 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
11600 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
11601 #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr )
11602 
11603 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
11604 
11605 #if defined(CATCH_CONFIG_FAST_COMPILE)
11606 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
11607 #else
11608 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
11609 #endif
11610 
11611 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
11612 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
11613 #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
11614 #define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) )
11615 #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) )
11616 
11617 #ifdef CATCH_CONFIG_VARIADIC_MACROS
11618 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
11619 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
11620 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
11621 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
11622 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
11623 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
11624 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
11625 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
11626 #else
11627 #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
11628     #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
11629     #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
11630     #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
11631     #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
11632     #define FAIL( msg ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg )
11633     #define FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg )
11634     #define SUCCEED( msg ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg )
11635 #endif
11636 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
11637 
11638 #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
11639 #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
11640 
11641 #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
11642 
11643 #endif
11644 
11645 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
11646 
11647 // "BDD-style" convenience wrappers
11648 #ifdef CATCH_CONFIG_VARIADIC_MACROS
11649 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
11650 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
11651 #else
11652 #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
11653 #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
11654 #endif
11655 #define GIVEN( desc )    SECTION( std::string("   Given: ") + desc, "" )
11656 #define WHEN( desc )     SECTION( std::string("    When: ") + desc, "" )
11657 #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
11658 #define THEN( desc )     SECTION( std::string("    Then: ") + desc, "" )
11659 #define AND_THEN( desc ) SECTION( std::string("     And: ") + desc, "" )
11660 
11661 using Catch::Detail::Approx;
11662 
11663 // #included from: internal/catch_reenable_warnings.h
11664 
11665 #define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
11666 
11667 #ifdef __clang__
11668 #    ifdef __ICC // icpc defines the __clang__ macro
11669 #        pragma warning(pop)
11670 #    else
11671 #        pragma clang diagnostic pop
11672 #    endif
11673 #elif defined __GNUC__
11674 #    pragma GCC diagnostic pop
11675 #endif
11676 
11677 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
11678 
11679