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