1 /*
2  *  Catch v1.12.2
3  *  Generated: 2018-05-14 15:10:01.112442
4  *  ----------------------------------------------------------
5  *  This file has been merged from multiple headers. Please don't edit it directly
6  *  Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
7  *
8  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
9  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10  */
11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
13 
14 #define TWOBLUECUBES_CATCH_HPP_INCLUDED
15 
16 #ifdef __clang__
17 #    pragma clang system_header
18 #elif defined __GNUC__
19 #    pragma GCC system_header
20 #endif
21 
22 // #included from: internal/catch_suppress_warnings.h
23 
24 #ifdef __clang__
25 #   ifdef __ICC // icpc defines the __clang__ macro
26 #       pragma warning(push)
27 #       pragma warning(disable: 161 1682)
28 #   else // __ICC
29 #       pragma clang diagnostic ignored "-Wglobal-constructors"
30 #       pragma clang diagnostic ignored "-Wvariadic-macros"
31 #       pragma clang diagnostic ignored "-Wc99-extensions"
32 #       pragma clang diagnostic ignored "-Wunused-variable"
33 #       pragma clang diagnostic push
34 #       pragma clang diagnostic ignored "-Wpadded"
35 #       pragma clang diagnostic ignored "-Wc++98-compat"
36 #       pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
37 #       pragma clang diagnostic ignored "-Wswitch-enum"
38 #       pragma clang diagnostic ignored "-Wcovered-switch-default"
39 #    endif
40 #elif defined __GNUC__
41 #    pragma GCC diagnostic ignored "-Wvariadic-macros"
42 #    pragma GCC diagnostic ignored "-Wunused-variable"
43 #    pragma GCC diagnostic ignored "-Wparentheses"
44 
45 #    pragma GCC diagnostic push
46 #    pragma GCC diagnostic ignored "-Wpadded"
47 #endif
48 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
49 #  define CATCH_IMPL
50 #endif
51 
52 #ifdef CATCH_IMPL
53 #  ifndef CLARA_CONFIG_MAIN
54 #    define CLARA_CONFIG_MAIN_NOT_DEFINED
55 #    define CLARA_CONFIG_MAIN
56 #  endif
57 #endif
58 
59 // #included from: internal/catch_notimplemented_exception.h
60 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
61 
62 // #included from: catch_common.h
63 #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
64 
65 // #included from: catch_compiler_capabilities.h
66 #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
67 
68 // Detect a number of compiler features - mostly C++11/14 conformance - by compiler
69 // The following features are defined:
70 //
71 // CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
72 // CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
73 // CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
74 // CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
75 // CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
76 // CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
77 // CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
78 // CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
79 // CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported?
80 // CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported?
81 
82 // CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
83 
84 // CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
85 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
86 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
87 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
88 // ****************
89 // Note to maintainers: if new toggles are added please document them
90 // in configuration.md, too
91 // ****************
92 
93 // In general each macro has a _NO_<feature name> form
94 // (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
95 // Many features, at point of detection, define an _INTERNAL_ macro, so they
96 // can be combined, en-mass, with the _NO_ forms later.
97 
98 // All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
99 
100 #ifdef __cplusplus
101 
102 #  if __cplusplus >= 201103L
103 #    define CATCH_CPP11_OR_GREATER
104 #  endif
105 
106 #  if __cplusplus >= 201402L
107 #    define CATCH_CPP14_OR_GREATER
108 #  endif
109 
110 #endif
111 
112 #ifdef __clang__
113 
114 #  if __has_feature(cxx_nullptr)
115 #    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
116 #  endif
117 
118 #  if __has_feature(cxx_noexcept)
119 #    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
120 #  endif
121 
122 #   if defined(CATCH_CPP11_OR_GREATER)
123 #       define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
124             _Pragma( "clang diagnostic push" ) \
125             _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" )
126 #       define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
127             _Pragma( "clang diagnostic pop" )
128 
129 #       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
130             _Pragma( "clang diagnostic push" ) \
131             _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
132 #       define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
133             _Pragma( "clang diagnostic pop" )
134 #   endif
135 
136 #endif // __clang__
137 
138 ////////////////////////////////////////////////////////////////////////////////
139 // We know some environments not to support full POSIX signals
140 #if defined(__CYGWIN__) || defined(__QNX__)
141 
142 #   if !defined(CATCH_CONFIG_POSIX_SIGNALS)
143 #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
144 #   endif
145 
146 #endif
147 
148 #ifdef __OS400__
149 #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
150 #       define CATCH_CONFIG_COLOUR_NONE
151 #endif
152 
153 ////////////////////////////////////////////////////////////////////////////////
154 // Cygwin
155 #ifdef __CYGWIN__
156 
157 // Required for some versions of Cygwin to declare gettimeofday
158 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
159 #   define _BSD_SOURCE
160 
161 #endif // __CYGWIN__
162 
163 ////////////////////////////////////////////////////////////////////////////////
164 // Borland
165 #ifdef __BORLANDC__
166 
167 #endif // __BORLANDC__
168 
169 ////////////////////////////////////////////////////////////////////////////////
170 // EDG
171 #ifdef __EDG_VERSION__
172 
173 #endif // __EDG_VERSION__
174 
175 ////////////////////////////////////////////////////////////////////////////////
176 // Digital Mars
177 #ifdef __DMC__
178 
179 #endif // __DMC__
180 
181 ////////////////////////////////////////////////////////////////////////////////
182 // GCC
183 #ifdef __GNUC__
184 
185 #   if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
186 #       define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
187 #   endif
188 
189 // - otherwise more recent versions define __cplusplus >= 201103L
190 // and will get picked up below
191 
192 #endif // __GNUC__
193 
194 ////////////////////////////////////////////////////////////////////////////////
195 // Visual C++
196 #ifdef _MSC_VER
197 
198 #define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
199 
200 #if (_MSC_VER >= 1600)
201 #   define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
202 #   define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
203 #endif
204 
205 #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
206 #define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
207 #define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
208 #define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
209 #define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
210 #endif
211 
212 #endif // _MSC_VER
213 
214 ////////////////////////////////////////////////////////////////////////////////
215 
216 // Use variadic macros if the compiler supports them
217 #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
218     ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
219     ( defined __GNUC__ && __GNUC__ >= 3 ) || \
220     ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
221 
222 #define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
223 
224 #endif
225 
226 // Use __COUNTER__ if the compiler supports it
227 #if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
228     ( defined __GNUC__  && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \
229     ( defined __clang__ && __clang_major__ >= 3 )
230 
231 // Use of __COUNTER__ is suppressed during code analysis in CLion/AppCode 2017.2.x and former,
232 // because __COUNTER__ is not properly handled by it.
233 // This does not affect compilation
234 #if ( !defined __JETBRAINS_IDE__ || __JETBRAINS_IDE__ >= 20170300L )
235     #define CATCH_INTERNAL_CONFIG_COUNTER
236 #endif
237 
238 #endif
239 
240 ////////////////////////////////////////////////////////////////////////////////
241 // C++ language feature support
242 
243 // catch all support for C++11
244 #if defined(CATCH_CPP11_OR_GREATER)
245 
246 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
247 #    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
248 #  endif
249 
250 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
251 #    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
252 #  endif
253 
254 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
255 #    define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
256 #  endif
257 
258 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
259 #    define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
260 #  endif
261 
262 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
263 #    define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
264 #  endif
265 
266 #  ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
267 #    define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
268 #  endif
269 
270 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
271 #    define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
272 #  endif
273 
274 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
275 #    define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
276 #  endif
277 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
278 #    define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
279 #  endif
280 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE)
281 #   define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
282 #  endif
283 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS)
284 #  define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
285 # endif
286 
287 #endif // __cplusplus >= 201103L
288 
289 // Now set the actual defines based on the above + anything the user has configured
290 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
291 #   define CATCH_CONFIG_CPP11_NULLPTR
292 #endif
293 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
294 #   define CATCH_CONFIG_CPP11_NOEXCEPT
295 #endif
296 #if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
297 #   define CATCH_CONFIG_CPP11_GENERATED_METHODS
298 #endif
299 #if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
300 #   define CATCH_CONFIG_CPP11_IS_ENUM
301 #endif
302 #if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
303 #   define CATCH_CONFIG_CPP11_TUPLE
304 #endif
305 #if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
306 #   define CATCH_CONFIG_VARIADIC_MACROS
307 #endif
308 #if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
309 #   define CATCH_CONFIG_CPP11_LONG_LONG
310 #endif
311 #if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
312 #   define CATCH_CONFIG_CPP11_OVERRIDE
313 #endif
314 #if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
315 #   define CATCH_CONFIG_CPP11_UNIQUE_PTR
316 #endif
317 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
318 #   define CATCH_CONFIG_COUNTER
319 #endif
320 #if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)
321 #   define CATCH_CONFIG_CPP11_SHUFFLE
322 #endif
323 # if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11)
324 #  define CATCH_CONFIG_CPP11_TYPE_TRAITS
325 # endif
326 #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
327 #   define CATCH_CONFIG_WINDOWS_SEH
328 #endif
329 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
330 #if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
331 #   define CATCH_CONFIG_POSIX_SIGNALS
332 #endif
333 
334 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
335 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
336 #   define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
337 #endif
338 #if !defined(CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS)
339 #   define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS
340 #   define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
341 #endif
342 
343 // noexcept support:
344 #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
345 #  define CATCH_NOEXCEPT noexcept
346 #  define CATCH_NOEXCEPT_IS(x) noexcept(x)
347 #else
348 #  define CATCH_NOEXCEPT throw()
349 #  define CATCH_NOEXCEPT_IS(x)
350 #endif
351 
352 // nullptr support
353 #ifdef CATCH_CONFIG_CPP11_NULLPTR
354 #   define CATCH_NULL nullptr
355 #else
356 #   define CATCH_NULL NULL
357 #endif
358 
359 // override support
360 #ifdef CATCH_CONFIG_CPP11_OVERRIDE
361 #   define CATCH_OVERRIDE override
362 #else
363 #   define CATCH_OVERRIDE
364 #endif
365 
366 // unique_ptr support
367 #ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
368 #   define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
369 #else
370 #   define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
371 #endif
372 
373 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
374 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
375 #ifdef CATCH_CONFIG_COUNTER
376 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
377 #else
378 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
379 #endif
380 
381 #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
382 #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
383 
384 #include <sstream>
385 #include <algorithm>
386 
387 namespace Catch {
388 
389     struct IConfig;
390 
391     struct CaseSensitive { enum Choice {
392         Yes,
393         No
394     }; };
395 
396     class NonCopyable {
397 #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
398         NonCopyable( NonCopyable const& )              = delete;
399         NonCopyable( NonCopyable && )                  = delete;
400         NonCopyable& operator = ( NonCopyable const& ) = delete;
401         NonCopyable& operator = ( NonCopyable && )     = delete;
402 #else
403         NonCopyable( NonCopyable const& info );
404         NonCopyable& operator = ( NonCopyable const& );
405 #endif
406 
407     protected:
NonCopyable()408         NonCopyable() {}
409         virtual ~NonCopyable();
410     };
411 
412     class SafeBool {
413     public:
414         typedef void (SafeBool::*type)() const;
415 
makeSafe(bool value)416         static type makeSafe( bool value ) {
417             return value ? &SafeBool::trueValue : 0;
418         }
419     private:
trueValue() const420         void trueValue() const {}
421     };
422 
423     template<typename ContainerT>
deleteAll(ContainerT & container)424     void deleteAll( ContainerT& container ) {
425         typename ContainerT::const_iterator it = container.begin();
426         typename ContainerT::const_iterator itEnd = container.end();
427         for(; it != itEnd; ++it )
428             delete *it;
429     }
430     template<typename AssociativeContainerT>
deleteAllValues(AssociativeContainerT & container)431     void deleteAllValues( AssociativeContainerT& container ) {
432         typename AssociativeContainerT::const_iterator it = container.begin();
433         typename AssociativeContainerT::const_iterator itEnd = container.end();
434         for(; it != itEnd; ++it )
435             delete it->second;
436     }
437 
438     bool startsWith( std::string const& s, std::string const& prefix );
439     bool startsWith( std::string const& s, char prefix );
440     bool endsWith( std::string const& s, std::string const& suffix );
441     bool endsWith( std::string const& s, char suffix );
442     bool contains( std::string const& s, std::string const& infix );
443     void toLowerInPlace( std::string& s );
444     std::string toLower( std::string const& s );
445     std::string trim( std::string const& str );
446     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
447 
448     struct pluralise {
449         pluralise( std::size_t count, std::string const& label );
450 
451         friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
452 
453         std::size_t m_count;
454         std::string m_label;
455     };
456 
457     struct SourceLineInfo {
458 
459         SourceLineInfo();
460         SourceLineInfo( char const* _file, std::size_t _line );
461 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
462         SourceLineInfo(SourceLineInfo const& other)          = default;
463         SourceLineInfo( SourceLineInfo && )                  = default;
464         SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
465         SourceLineInfo& operator = ( SourceLineInfo && )     = default;
466 #  endif
467         bool empty() const;
468         bool operator == ( SourceLineInfo const& other ) const;
469         bool operator < ( SourceLineInfo const& other ) const;
470 
471         char const* file;
472         std::size_t line;
473     };
474 
475     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
476 
477     // This is just here to avoid compiler warnings with macro constants and boolean literals
isTrue(bool value)478     inline bool isTrue( bool value ){ return value; }
alwaysTrue()479     inline bool alwaysTrue() { return true; }
alwaysFalse()480     inline bool alwaysFalse() { return false; }
481 
482     void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
483 
484     void seedRng( IConfig const& config );
485     unsigned int rngSeed();
486 
487     // Use this in variadic streaming macros to allow
488     //    >> +StreamEndStop
489     // as well as
490     //    >> stuff +StreamEndStop
491     struct StreamEndStop {
operator +Catch::StreamEndStop492         std::string operator+() {
493             return std::string();
494         }
495     };
496     template<typename T>
operator +(T const & value,StreamEndStop)497     T const& operator + ( T const& value, StreamEndStop ) {
498         return value;
499     }
500 }
501 
502 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
503 #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
504 
505 namespace Catch {
506 
507     class NotImplementedException : public std::exception
508     {
509     public:
510         NotImplementedException( SourceLineInfo const& lineInfo );
511 
~NotImplementedException()512         virtual ~NotImplementedException() CATCH_NOEXCEPT {}
513 
514         virtual const char* what() const CATCH_NOEXCEPT;
515 
516     private:
517         std::string m_what;
518         SourceLineInfo m_lineInfo;
519     };
520 
521 } // end namespace Catch
522 
523 ///////////////////////////////////////////////////////////////////////////////
524 #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
525 
526 // #included from: internal/catch_context.h
527 #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
528 
529 // #included from: catch_interfaces_generators.h
530 #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
531 
532 #include <string>
533 
534 namespace Catch {
535 
536     struct IGeneratorInfo {
537         virtual ~IGeneratorInfo();
538         virtual bool moveNext() = 0;
539         virtual std::size_t getCurrentIndex() const = 0;
540     };
541 
542     struct IGeneratorsForTest {
543         virtual ~IGeneratorsForTest();
544 
545         virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
546         virtual bool moveNext() = 0;
547     };
548 
549     IGeneratorsForTest* createGeneratorsForTest();
550 
551 } // end namespace Catch
552 
553 // #included from: catch_ptr.hpp
554 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
555 
556 #ifdef __clang__
557 #pragma clang diagnostic push
558 #pragma clang diagnostic ignored "-Wpadded"
559 #endif
560 
561 namespace Catch {
562 
563     // An intrusive reference counting smart pointer.
564     // T must implement addRef() and release() methods
565     // typically implementing the IShared interface
566     template<typename T>
567     class Ptr {
568     public:
Ptr()569         Ptr() : m_p( CATCH_NULL ){}
Ptr(T * p)570         Ptr( T* p ) : m_p( p ){
571             if( m_p )
572                 m_p->addRef();
573         }
Ptr(Ptr const & other)574         Ptr( Ptr const& other ) : m_p( other.m_p ){
575             if( m_p )
576                 m_p->addRef();
577         }
~Ptr()578         ~Ptr(){
579             if( m_p )
580                 m_p->release();
581         }
reset()582         void reset() {
583             if( m_p )
584                 m_p->release();
585             m_p = CATCH_NULL;
586         }
operator =(T * p)587         Ptr& operator = ( T* p ){
588             Ptr temp( p );
589             swap( temp );
590             return *this;
591         }
operator =(Ptr const & other)592         Ptr& operator = ( Ptr const& other ){
593             Ptr temp( other );
594             swap( temp );
595             return *this;
596         }
swap(Ptr & other)597         void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
get() const598         T* get() const{ return m_p; }
operator *() const599         T& operator*() const { return *m_p; }
operator ->() const600         T* operator->() const { return m_p; }
operator !() const601         bool operator !() const { return m_p == CATCH_NULL; }
operator SafeBool::type() const602         operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
603 
604     private:
605         T* m_p;
606     };
607 
608     struct IShared : NonCopyable {
609         virtual ~IShared();
610         virtual void addRef() const = 0;
611         virtual void release() const = 0;
612     };
613 
614     template<typename T = IShared>
615     struct SharedImpl : T {
616 
SharedImplCatch::SharedImpl617         SharedImpl() : m_rc( 0 ){}
618 
addRefCatch::SharedImpl619         virtual void addRef() const {
620             ++m_rc;
621         }
releaseCatch::SharedImpl622         virtual void release() const {
623             if( --m_rc == 0 )
624                 delete this;
625         }
626 
627         mutable unsigned int m_rc;
628     };
629 
630 } // end namespace Catch
631 
632 #ifdef __clang__
633 #pragma clang diagnostic pop
634 #endif
635 
636 namespace Catch {
637 
638     class TestCase;
639     class Stream;
640     struct IResultCapture;
641     struct IRunner;
642     struct IGeneratorsForTest;
643     struct IConfig;
644 
645     struct IContext
646     {
647         virtual ~IContext();
648 
649         virtual IResultCapture* getResultCapture() = 0;
650         virtual IRunner* getRunner() = 0;
651         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
652         virtual bool advanceGeneratorsForCurrentTest() = 0;
653         virtual Ptr<IConfig const> getConfig() const = 0;
654     };
655 
656     struct IMutableContext : IContext
657     {
658         virtual ~IMutableContext();
659         virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
660         virtual void setRunner( IRunner* runner ) = 0;
661         virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
662     };
663 
664     IContext& getCurrentContext();
665     IMutableContext& getCurrentMutableContext();
666     void cleanUpContext();
667     Stream createStream( std::string const& streamName );
668 
669 }
670 
671 // #included from: internal/catch_test_registry.hpp
672 #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
673 
674 // #included from: catch_interfaces_testcase.h
675 #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
676 
677 #include <vector>
678 
679 namespace Catch {
680 
681     class TestSpec;
682 
683     struct ITestCase : IShared {
684         virtual void invoke () const = 0;
685     protected:
686         virtual ~ITestCase();
687     };
688 
689     class TestCase;
690     struct IConfig;
691 
692     struct ITestCaseRegistry {
693         virtual ~ITestCaseRegistry();
694         virtual std::vector<TestCase> const& getAllTests() const = 0;
695         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
696     };
697 
698     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
699     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
700     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
701 
702 }
703 
704 namespace Catch {
705 
706 template<typename C>
707 class MethodTestCase : public SharedImpl<ITestCase> {
708 
709 public:
MethodTestCase(void (C::* method)())710     MethodTestCase( void (C::*method)() ) : m_method( method ) {}
711 
invoke() const712     virtual void invoke() const {
713         C obj;
714         (obj.*m_method)();
715     }
716 
717 private:
~MethodTestCase()718     virtual ~MethodTestCase() {}
719 
720     void (C::*m_method)();
721 };
722 
723 typedef void(*TestFunction)();
724 
725 struct NameAndDesc {
NameAndDescCatch::NameAndDesc726     NameAndDesc( const char* _name = "", const char* _description= "" )
727     : name( _name ), description( _description )
728     {}
729 
730     const char* name;
731     const char* description;
732 };
733 
734 void registerTestCase
735     (   ITestCase* testCase,
736         char const* className,
737         NameAndDesc const& nameAndDesc,
738         SourceLineInfo const& lineInfo );
739 
740 struct AutoReg {
741 
742     AutoReg
743         (   TestFunction function,
744             SourceLineInfo const& lineInfo,
745             NameAndDesc const& nameAndDesc );
746 
747     template<typename C>
AutoRegCatch::AutoReg748     AutoReg
749         (   void (C::*method)(),
750             char const* className,
751             NameAndDesc const& nameAndDesc,
752             SourceLineInfo const& lineInfo ) {
753 
754         registerTestCase
755             (   new MethodTestCase<C>( method ),
756                 className,
757                 nameAndDesc,
758                 lineInfo );
759     }
760 
761     ~AutoReg();
762 
763 private:
764     AutoReg( AutoReg const& );
765     void operator= ( AutoReg const& );
766 };
767 
768 void registerTestCaseFunction
769     (   TestFunction function,
770         SourceLineInfo const& lineInfo,
771         NameAndDesc const& nameAndDesc );
772 
773 } // end namespace Catch
774 
775 #ifdef CATCH_CONFIG_VARIADIC_MACROS
776     ///////////////////////////////////////////////////////////////////////////////
777     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
778         static void TestName(); \
779         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
780         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); } /* NOLINT */ \
781         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
782         static void TestName()
783     #define INTERNAL_CATCH_TESTCASE( ... ) \
784         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
785 
786     ///////////////////////////////////////////////////////////////////////////////
787     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
788         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
789         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \
790         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
791 
792     ///////////////////////////////////////////////////////////////////////////////
793     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
794         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
795         namespace{ \
796             struct TestName : ClassName{ \
797                 void test(); \
798             }; \
799             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \
800         } \
801         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
802         void TestName::test()
803     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
804         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
805 
806     ///////////////////////////////////////////////////////////////////////////////
807     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
808         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
809         Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); /* NOLINT */ \
810         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
811 
812 #else
813     ///////////////////////////////////////////////////////////////////////////////
814     #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
815         static void TestName(); \
816         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
817         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); } /* NOLINT */ \
818         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
819         static void TestName()
820     #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
821         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
822 
823     ///////////////////////////////////////////////////////////////////////////////
824     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
825         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
826         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \
827         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
828 
829     ///////////////////////////////////////////////////////////////////////////////
830     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
831         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
832         namespace{ \
833             struct TestCaseName : ClassName{ \
834                 void test(); \
835             }; \
836             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \
837         } \
838         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
839         void TestCaseName::test()
840     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
841         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
842 
843     ///////////////////////////////////////////////////////////////////////////////
844     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
845         CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
846         Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); /* NOLINT */ \
847         CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
848 
849 #endif
850 
851 // #included from: internal/catch_capture.hpp
852 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
853 
854 // #included from: catch_result_builder.h
855 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
856 
857 // #included from: catch_result_type.h
858 #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
859 
860 namespace Catch {
861 
862     // ResultWas::OfType enum
863     struct ResultWas { enum OfType {
864         Unknown = -1,
865         Ok = 0,
866         Info = 1,
867         Warning = 2,
868 
869         FailureBit = 0x10,
870 
871         ExpressionFailed = FailureBit | 1,
872         ExplicitFailure = FailureBit | 2,
873 
874         Exception = 0x100 | FailureBit,
875 
876         ThrewException = Exception | 1,
877         DidntThrowException = Exception | 2,
878 
879         FatalErrorCondition = 0x200 | FailureBit
880 
881     }; };
882 
isOk(ResultWas::OfType resultType)883     inline bool isOk( ResultWas::OfType resultType ) {
884         return ( resultType & ResultWas::FailureBit ) == 0;
885     }
isJustInfo(int flags)886     inline bool isJustInfo( int flags ) {
887         return flags == ResultWas::Info;
888     }
889 
890     // ResultDisposition::Flags enum
891     struct ResultDisposition { enum Flags {
892         Normal = 0x01,
893 
894         ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
895         FalseTest = 0x04,           // Prefix expression with !
896         SuppressFail = 0x08         // Failures are reported but do not fail the test
897     }; };
898 
operator |(ResultDisposition::Flags lhs,ResultDisposition::Flags rhs)899     inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
900         return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
901     }
902 
shouldContinueOnFailure(int flags)903     inline bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
isFalseTest(int flags)904     inline bool isFalseTest( int flags )                { return ( flags & ResultDisposition::FalseTest ) != 0; }
shouldSuppressFailure(int flags)905     inline bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
906 
907 } // end namespace Catch
908 
909 // #included from: catch_assertionresult.h
910 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
911 
912 #include <string>
913 
914 namespace Catch {
915 
916     struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
917 
918     struct DecomposedExpression
919     {
~DecomposedExpressionCatch::DecomposedExpression920         virtual ~DecomposedExpression() {}
isBinaryExpressionCatch::DecomposedExpression921         virtual bool isBinaryExpression() const {
922             return false;
923         }
924         virtual void reconstructExpression( std::string& dest ) const = 0;
925 
926         // Only simple binary comparisons can be decomposed.
927         // If more complex check is required then wrap sub-expressions in parentheses.
928         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& );
929         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& );
930         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& );
931         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& );
932         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& );
933         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& );
934         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& );
935 
936     private:
937         DecomposedExpression& operator = (DecomposedExpression const&);
938     };
939 
940     struct AssertionInfo
941     {
942         AssertionInfo();
943         AssertionInfo(  char const * _macroName,
944                         SourceLineInfo const& _lineInfo,
945                         char const * _capturedExpression,
946                         ResultDisposition::Flags _resultDisposition,
947                         char const * _secondArg = "");
948 
949         char const * macroName;
950         SourceLineInfo lineInfo;
951         char const * capturedExpression;
952         ResultDisposition::Flags resultDisposition;
953         char const * secondArg;
954     };
955 
956     struct AssertionResultData
957     {
AssertionResultDataCatch::AssertionResultData958         AssertionResultData() : decomposedExpression( CATCH_NULL )
959                               , resultType( ResultWas::Unknown )
960                               , negated( false )
961                               , parenthesized( false ) {}
962 
negateCatch::AssertionResultData963         void negate( bool parenthesize ) {
964             negated = !negated;
965             parenthesized = parenthesize;
966             if( resultType == ResultWas::Ok )
967                 resultType = ResultWas::ExpressionFailed;
968             else if( resultType == ResultWas::ExpressionFailed )
969                 resultType = ResultWas::Ok;
970         }
971 
reconstructExpressionCatch::AssertionResultData972         std::string const& reconstructExpression() const {
973             if( decomposedExpression != CATCH_NULL ) {
974                 decomposedExpression->reconstructExpression( reconstructedExpression );
975                 if( parenthesized ) {
976                     reconstructedExpression.insert( 0, 1, '(' );
977                     reconstructedExpression.append( 1, ')' );
978                 }
979                 if( negated ) {
980                     reconstructedExpression.insert( 0, 1, '!' );
981                 }
982                 decomposedExpression = CATCH_NULL;
983             }
984             return reconstructedExpression;
985         }
986 
987         mutable DecomposedExpression const* decomposedExpression;
988         mutable std::string reconstructedExpression;
989         std::string message;
990         ResultWas::OfType resultType;
991         bool negated;
992         bool parenthesized;
993     };
994 
995     class AssertionResult {
996     public:
997         AssertionResult();
998         AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
999         ~AssertionResult();
1000 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
1001          AssertionResult( AssertionResult const& )              = default;
1002          AssertionResult( AssertionResult && )                  = default;
1003          AssertionResult& operator = ( AssertionResult const& ) = default;
1004          AssertionResult& operator = ( AssertionResult && )     = default;
1005 #  endif
1006 
1007         bool isOk() const;
1008         bool succeeded() const;
1009         ResultWas::OfType getResultType() const;
1010         bool hasExpression() const;
1011         bool hasMessage() const;
1012         std::string getExpression() const;
1013         std::string getExpressionInMacro() const;
1014         bool hasExpandedExpression() const;
1015         std::string getExpandedExpression() const;
1016         std::string getMessage() const;
1017         SourceLineInfo getSourceInfo() const;
1018         std::string getTestMacroName() const;
1019         void discardDecomposedExpression() const;
1020         void expandDecomposedExpression() const;
1021 
1022     protected:
1023         AssertionInfo m_info;
1024         AssertionResultData m_resultData;
1025     };
1026 
1027 } // end namespace Catch
1028 
1029 // #included from: catch_matchers.hpp
1030 #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
1031 
1032 namespace Catch {
1033 namespace Matchers {
1034     namespace Impl {
1035 
1036         template<typename ArgT> struct MatchAllOf;
1037         template<typename ArgT> struct MatchAnyOf;
1038         template<typename ArgT> struct MatchNotOf;
1039 
1040         class MatcherUntypedBase {
1041         public:
toString() const1042             std::string toString() const {
1043                 if( m_cachedToString.empty() )
1044                     m_cachedToString = describe();
1045                 return m_cachedToString;
1046             }
1047 
1048         protected:
1049             virtual ~MatcherUntypedBase();
1050             virtual std::string describe() const = 0;
1051             mutable std::string m_cachedToString;
1052         private:
1053             MatcherUntypedBase& operator = ( MatcherUntypedBase const& );
1054         };
1055 
1056         template<typename ObjectT>
1057         struct MatcherMethod {
1058             virtual bool match( ObjectT const& arg ) const = 0;
1059         };
1060         template<typename PtrT>
1061         struct MatcherMethod<PtrT*> {
1062             virtual bool match( PtrT* arg ) const = 0;
1063         };
1064 
1065         template<typename ObjectT, typename ComparatorT = ObjectT>
1066         struct MatcherBase : MatcherUntypedBase, MatcherMethod<ObjectT> {
1067 
1068             MatchAllOf<ComparatorT> operator && ( MatcherBase const& other ) const;
1069             MatchAnyOf<ComparatorT> operator || ( MatcherBase const& other ) const;
1070             MatchNotOf<ComparatorT> operator ! () const;
1071         };
1072 
1073         template<typename ArgT>
1074         struct MatchAllOf : MatcherBase<ArgT> {
matchCatch::Matchers::Impl::MatchAllOf1075             virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
1076                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
1077                     if (!m_matchers[i]->match(arg))
1078                         return false;
1079                 }
1080                 return true;
1081             }
describeCatch::Matchers::Impl::MatchAllOf1082             virtual std::string describe() const CATCH_OVERRIDE {
1083                 std::string description;
1084                 description.reserve( 4 + m_matchers.size()*32 );
1085                 description += "( ";
1086                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
1087                     if( i != 0 )
1088                         description += " and ";
1089                     description += m_matchers[i]->toString();
1090                 }
1091                 description += " )";
1092                 return description;
1093             }
1094 
operator &&Catch::Matchers::Impl::MatchAllOf1095             MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
1096                 m_matchers.push_back( &other );
1097                 return *this;
1098             }
1099 
1100             std::vector<MatcherBase<ArgT> const*> m_matchers;
1101         };
1102         template<typename ArgT>
1103         struct MatchAnyOf : MatcherBase<ArgT> {
1104 
matchCatch::Matchers::Impl::MatchAnyOf1105             virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
1106                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
1107                     if (m_matchers[i]->match(arg))
1108                         return true;
1109                 }
1110                 return false;
1111             }
describeCatch::Matchers::Impl::MatchAnyOf1112             virtual std::string describe() const CATCH_OVERRIDE {
1113                 std::string description;
1114                 description.reserve( 4 + m_matchers.size()*32 );
1115                 description += "( ";
1116                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
1117                     if( i != 0 )
1118                         description += " or ";
1119                     description += m_matchers[i]->toString();
1120                 }
1121                 description += " )";
1122                 return description;
1123             }
1124 
operator ||Catch::Matchers::Impl::MatchAnyOf1125             MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
1126                 m_matchers.push_back( &other );
1127                 return *this;
1128             }
1129 
1130             std::vector<MatcherBase<ArgT> const*> m_matchers;
1131         };
1132 
1133         template<typename ArgT>
1134         struct MatchNotOf : MatcherBase<ArgT> {
1135 
MatchNotOfCatch::Matchers::Impl::MatchNotOf1136             MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
1137 
matchCatch::Matchers::Impl::MatchNotOf1138             virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
1139                 return !m_underlyingMatcher.match( arg );
1140             }
1141 
describeCatch::Matchers::Impl::MatchNotOf1142             virtual std::string describe() const CATCH_OVERRIDE {
1143                 return "not " + m_underlyingMatcher.toString();
1144             }
1145             MatcherBase<ArgT> const& m_underlyingMatcher;
1146         };
1147 
1148         template<typename ObjectT, typename ComparatorT>
operator &&(MatcherBase const & other) const1149         MatchAllOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator && ( MatcherBase const& other ) const {
1150             return MatchAllOf<ComparatorT>() && *this && other;
1151         }
1152         template<typename ObjectT, typename ComparatorT>
operator ||(MatcherBase const & other) const1153         MatchAnyOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator || ( MatcherBase const& other ) const {
1154             return MatchAnyOf<ComparatorT>() || *this || other;
1155         }
1156         template<typename ObjectT, typename ComparatorT>
operator !() const1157         MatchNotOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator ! () const {
1158             return MatchNotOf<ComparatorT>( *this );
1159         }
1160 
1161     } // namespace Impl
1162 
1163     // The following functions create the actual matcher objects.
1164     // This allows the types to be inferred
1165     // - deprecated: prefer ||, && and !
1166     template<typename T>
Not(Impl::MatcherBase<T> const & underlyingMatcher)1167     Impl::MatchNotOf<T> Not( Impl::MatcherBase<T> const& underlyingMatcher ) {
1168         return Impl::MatchNotOf<T>( underlyingMatcher );
1169     }
1170     template<typename T>
AllOf(Impl::MatcherBase<T> const & m1,Impl::MatcherBase<T> const & m2)1171     Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
1172         return Impl::MatchAllOf<T>() && m1 && m2;
1173     }
1174     template<typename T>
AllOf(Impl::MatcherBase<T> const & m1,Impl::MatcherBase<T> const & m2,Impl::MatcherBase<T> const & m3)1175     Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
1176         return Impl::MatchAllOf<T>() && m1 && m2 && m3;
1177     }
1178     template<typename T>
AnyOf(Impl::MatcherBase<T> const & m1,Impl::MatcherBase<T> const & m2)1179     Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
1180         return Impl::MatchAnyOf<T>() || m1 || m2;
1181     }
1182     template<typename T>
AnyOf(Impl::MatcherBase<T> const & m1,Impl::MatcherBase<T> const & m2,Impl::MatcherBase<T> const & m3)1183     Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
1184         return Impl::MatchAnyOf<T>() || m1 || m2 || m3;
1185     }
1186 
1187 } // namespace Matchers
1188 
1189 using namespace Matchers;
1190 using Matchers::Impl::MatcherBase;
1191 
1192 } // namespace Catch
1193 
1194 namespace Catch {
1195 
1196     struct TestFailureException{};
1197 
1198     template<typename T> class ExpressionLhs;
1199 
1200     struct CopyableStream {
CopyableStreamCatch::CopyableStream1201         CopyableStream() {}
CopyableStreamCatch::CopyableStream1202         CopyableStream( CopyableStream const& other ) {
1203             oss << other.oss.str();
1204         }
operator =Catch::CopyableStream1205         CopyableStream& operator=( CopyableStream const& other ) {
1206             oss.str(std::string());
1207             oss << other.oss.str();
1208             return *this;
1209         }
1210         std::ostringstream oss;
1211     };
1212 
1213     class ResultBuilder : public DecomposedExpression {
1214     public:
1215         ResultBuilder(  char const* macroName,
1216                         SourceLineInfo const& lineInfo,
1217                         char const* capturedExpression,
1218                         ResultDisposition::Flags resultDisposition,
1219                         char const* secondArg = "" );
1220         ~ResultBuilder();
1221 
1222         template<typename T>
1223         ExpressionLhs<T const&> operator <= ( T const& operand );
1224         ExpressionLhs<bool> operator <= ( bool value );
1225 
1226         template<typename T>
operator <<(T const & value)1227         ResultBuilder& operator << ( T const& value ) {
1228             stream().oss << value;
1229             return *this;
1230         }
1231 
1232         ResultBuilder& setResultType( ResultWas::OfType result );
1233         ResultBuilder& setResultType( bool result );
1234 
1235         void endExpression( DecomposedExpression const& expr );
1236 
1237         virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE;
1238 
1239         AssertionResult build() const;
1240         AssertionResult build( DecomposedExpression const& expr ) const;
1241 
1242         void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
1243         void captureResult( ResultWas::OfType resultType );
1244         void captureExpression();
1245         void captureExpectedException( std::string const& expectedMessage );
1246         void captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher );
1247         void handleResult( AssertionResult const& result );
1248         void react();
1249         bool shouldDebugBreak() const;
1250         bool allowThrows() const;
1251 
1252         template<typename ArgT, typename MatcherT>
1253         void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString );
1254 
1255         void setExceptionGuard();
1256         void unsetExceptionGuard();
1257 
1258     private:
1259         AssertionInfo m_assertionInfo;
1260         AssertionResultData m_data;
1261 
stream()1262         CopyableStream &stream()
1263         {
1264             if(!m_usedStream)
1265             {
1266                 m_usedStream = true;
1267                 m_stream().oss.str("");
1268             }
1269             return m_stream();
1270         }
1271 
m_stream()1272         static CopyableStream &m_stream()
1273         {
1274             static CopyableStream s;
1275             return s;
1276         }
1277 
1278         bool m_shouldDebugBreak;
1279         bool m_shouldThrow;
1280         bool m_guardException;
1281         bool m_usedStream;
1282     };
1283 
1284 } // namespace Catch
1285 
1286 // Include after due to circular dependency:
1287 // #included from: catch_expression_lhs.hpp
1288 #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
1289 
1290 // #included from: catch_evaluate.hpp
1291 #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
1292 
1293 #ifdef _MSC_VER
1294 #pragma warning(push)
1295 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
1296 #pragma warning(disable:4018) // more "signed/unsigned mismatch"
1297 #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
1298 #endif
1299 
1300 #include <cstddef>
1301 
1302 namespace Catch {
1303 namespace Internal {
1304 
1305     enum Operator {
1306         IsEqualTo,
1307         IsNotEqualTo,
1308         IsLessThan,
1309         IsGreaterThan,
1310         IsLessThanOrEqualTo,
1311         IsGreaterThanOrEqualTo
1312     };
1313 
getNameCatch::Internal::OperatorTraits1314     template<Operator Op> struct OperatorTraits             { static const char* getName(){ return "*error*"; } };
getNameCatch::Internal::OperatorTraits1315     template<> struct OperatorTraits<IsEqualTo>             { static const char* getName(){ return "=="; } };
getNameCatch::Internal::OperatorTraits1316     template<> struct OperatorTraits<IsNotEqualTo>          { static const char* getName(){ return "!="; } };
getNameCatch::Internal::OperatorTraits1317     template<> struct OperatorTraits<IsLessThan>            { static const char* getName(){ return "<"; } };
getNameCatch::Internal::OperatorTraits1318     template<> struct OperatorTraits<IsGreaterThan>         { static const char* getName(){ return ">"; } };
getNameCatch::Internal::OperatorTraits1319     template<> struct OperatorTraits<IsLessThanOrEqualTo>   { static const char* getName(){ return "<="; } };
getNameCatch::Internal::OperatorTraits1320     template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
1321 
1322     template<typename T>
opCast(T const & t)1323     T& opCast(T const& t) { return const_cast<T&>(t); }
1324 
1325 // nullptr_t support based on pull request #154 from Konstantin Baumann
1326 #ifdef CATCH_CONFIG_CPP11_NULLPTR
opCast(std::nullptr_t)1327     inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
1328 #endif // CATCH_CONFIG_CPP11_NULLPTR
1329 
1330     // So the compare overloads can be operator agnostic we convey the operator as a template
1331     // enum, which is used to specialise an Evaluator for doing the comparison.
1332     template<typename T1, typename T2, Operator Op>
1333     struct Evaluator{};
1334 
1335     template<typename T1, typename T2>
1336     struct Evaluator<T1, T2, IsEqualTo> {
evaluateCatch::Internal::Evaluator1337         static bool evaluate( T1 const& lhs, T2 const& rhs) {
1338             return bool( opCast( lhs ) ==  opCast( rhs ) );
1339         }
1340     };
1341     template<typename T1, typename T2>
1342     struct Evaluator<T1, T2, IsNotEqualTo> {
evaluateCatch::Internal::Evaluator1343         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1344             return bool( opCast( lhs ) != opCast( rhs ) );
1345         }
1346     };
1347     template<typename T1, typename T2>
1348     struct Evaluator<T1, T2, IsLessThan> {
evaluateCatch::Internal::Evaluator1349         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1350             return bool( opCast( lhs ) < opCast( rhs ) );
1351         }
1352     };
1353     template<typename T1, typename T2>
1354     struct Evaluator<T1, T2, IsGreaterThan> {
evaluateCatch::Internal::Evaluator1355         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1356             return bool( opCast( lhs ) > opCast( rhs ) );
1357         }
1358     };
1359     template<typename T1, typename T2>
1360     struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
evaluateCatch::Internal::Evaluator1361         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1362             return bool( opCast( lhs ) >= opCast( rhs ) );
1363         }
1364     };
1365     template<typename T1, typename T2>
1366     struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
evaluateCatch::Internal::Evaluator1367         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1368             return bool( opCast( lhs ) <= opCast( rhs ) );
1369         }
1370     };
1371 
1372     template<Operator Op, typename T1, typename T2>
applyEvaluator(T1 const & lhs,T2 const & rhs)1373     bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
1374         return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1375     }
1376 
1377     // This level of indirection allows us to specialise for integer types
1378     // to avoid signed/ unsigned warnings
1379 
1380     // "base" overload
1381     template<Operator Op, typename T1, typename T2>
compare(T1 const & lhs,T2 const & rhs)1382     bool compare( T1 const& lhs, T2 const& rhs ) {
1383         return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1384     }
1385 
1386     // unsigned X to int
compare(unsigned int lhs,int rhs)1387     template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
1388         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1389     }
compare(unsigned long lhs,int rhs)1390     template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
1391         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1392     }
compare(unsigned char lhs,int rhs)1393     template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
1394         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1395     }
1396 
1397     // unsigned X to long
compare(unsigned int lhs,long rhs)1398     template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
1399         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1400     }
compare(unsigned long lhs,long rhs)1401     template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
1402         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1403     }
compare(unsigned char lhs,long rhs)1404     template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
1405         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1406     }
1407 
1408     // int to unsigned X
compare(int lhs,unsigned int rhs)1409     template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
1410         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1411     }
compare(int lhs,unsigned long rhs)1412     template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
1413         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1414     }
compare(int lhs,unsigned char rhs)1415     template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
1416         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1417     }
1418 
1419     // long to unsigned X
compare(long lhs,unsigned int rhs)1420     template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
1421         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1422     }
compare(long lhs,unsigned long rhs)1423     template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
1424         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1425     }
compare(long lhs,unsigned char rhs)1426     template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
1427         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1428     }
1429 
1430     // pointer to long (when comparing against NULL)
compare(long lhs,T * rhs)1431     template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
1432         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1433     }
compare(T * lhs,long rhs)1434     template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
1435         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1436     }
1437 
1438     // pointer to int (when comparing against NULL)
compare(int lhs,T * rhs)1439     template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
1440         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1441     }
compare(T * lhs,int rhs)1442     template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
1443         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1444     }
1445 
1446 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
1447     // long long to unsigned X
compare(long long lhs,unsigned int rhs)1448     template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
1449         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1450     }
compare(long long lhs,unsigned long rhs)1451     template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
1452         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1453     }
compare(long long lhs,unsigned long long rhs)1454     template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
1455         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1456     }
compare(long long lhs,unsigned char rhs)1457     template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
1458         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1459     }
1460 
1461     // unsigned long long to X
compare(unsigned long long lhs,int rhs)1462     template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
1463         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1464     }
compare(unsigned long long lhs,long rhs)1465     template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
1466         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1467     }
compare(unsigned long long lhs,long long rhs)1468     template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
1469         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1470     }
compare(unsigned long long lhs,char rhs)1471     template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
1472         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1473     }
1474 
1475     // pointer to long long (when comparing against NULL)
compare(long long lhs,T * rhs)1476     template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
1477         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1478     }
compare(T * lhs,long long rhs)1479     template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
1480         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1481     }
1482 #endif // CATCH_CONFIG_CPP11_LONG_LONG
1483 
1484 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1485     // pointer to nullptr_t (when comparing against nullptr)
compare(std::nullptr_t,T * rhs)1486     template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
1487         return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
1488     }
compare(T * lhs,std::nullptr_t)1489     template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
1490         return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
1491     }
1492 #endif // CATCH_CONFIG_CPP11_NULLPTR
1493 
1494 } // end of namespace Internal
1495 } // end of namespace Catch
1496 
1497 #ifdef _MSC_VER
1498 #pragma warning(pop)
1499 #endif
1500 
1501 // #included from: catch_tostring.h
1502 #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
1503 
1504 #include <sstream>
1505 #include <iomanip>
1506 #include <limits>
1507 #include <vector>
1508 #include <cstddef>
1509 
1510 #ifdef __OBJC__
1511 // #included from: catch_objc_arc.hpp
1512 #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
1513 
1514 #import <Foundation/Foundation.h>
1515 
1516 #ifdef __has_feature
1517 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1518 #else
1519 #define CATCH_ARC_ENABLED 0
1520 #endif
1521 
1522 void arcSafeRelease( NSObject* obj );
1523 id performOptionalSelector( id obj, SEL sel );
1524 
1525 #if !CATCH_ARC_ENABLED
arcSafeRelease(NSObject * obj)1526 inline void arcSafeRelease( NSObject* obj ) {
1527     [obj release];
1528 }
performOptionalSelector(id obj,SEL sel)1529 inline id performOptionalSelector( id obj, SEL sel ) {
1530     if( [obj respondsToSelector: sel] )
1531         return [obj performSelector: sel];
1532     return nil;
1533 }
1534 #define CATCH_UNSAFE_UNRETAINED
1535 #define CATCH_ARC_STRONG
1536 #else
arcSafeRelease(NSObject *)1537 inline void arcSafeRelease( NSObject* ){}
performOptionalSelector(id obj,SEL sel)1538 inline id performOptionalSelector( id obj, SEL sel ) {
1539 #ifdef __clang__
1540 #pragma clang diagnostic push
1541 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1542 #endif
1543     if( [obj respondsToSelector: sel] )
1544         return [obj performSelector: sel];
1545 #ifdef __clang__
1546 #pragma clang diagnostic pop
1547 #endif
1548     return nil;
1549 }
1550 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1551 #define CATCH_ARC_STRONG __strong
1552 #endif
1553 
1554 #endif
1555 
1556 #ifdef CATCH_CONFIG_CPP11_TUPLE
1557 #include <tuple>
1558 #endif
1559 
1560 #ifdef CATCH_CONFIG_CPP11_IS_ENUM
1561 #include <type_traits>
1562 #endif
1563 
1564 namespace Catch {
1565 
1566 // Why we're here.
1567 template<typename T>
1568 std::string toString( T const& value );
1569 
1570 // Built in overloads
1571 
1572 std::string toString( std::string const& value );
1573 std::string toString( std::wstring const& value );
1574 std::string toString( const char* const value );
1575 std::string toString( char* const value );
1576 std::string toString( const wchar_t* const value );
1577 std::string toString( wchar_t* const value );
1578 std::string toString( int value );
1579 std::string toString( unsigned long value );
1580 std::string toString( unsigned int value );
1581 std::string toString( const double value );
1582 std::string toString( const float value );
1583 std::string toString( bool value );
1584 std::string toString( char value );
1585 std::string toString( signed char value );
1586 std::string toString( unsigned char value );
1587 
1588 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
1589 std::string toString( long long value );
1590 std::string toString( unsigned long long value );
1591 #endif
1592 
1593 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1594 std::string toString( std::nullptr_t );
1595 #endif
1596 
1597 #ifdef __OBJC__
1598     std::string toString( NSString const * const& nsstring );
1599     std::string toString( NSString * CATCH_ARC_STRONG & nsstring );
1600     std::string toString( NSObject* const& nsObject );
1601 #endif
1602 
1603 namespace Detail {
1604 
1605     extern const std::string unprintableString;
1606 
1607  #if !defined(CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK)
1608     struct BorgType {
1609         template<typename T> BorgType( T const& );
1610     };
1611 
1612     struct TrueType { char sizer[1]; };
1613     struct FalseType { char sizer[2]; };
1614 
1615     TrueType& testStreamable( std::ostream& );
1616     FalseType testStreamable( FalseType );
1617 
1618     FalseType operator<<( std::ostream const&, BorgType const& );
1619 
1620     template<typename T>
1621     struct IsStreamInsertable {
1622         static std::ostream &s;
1623         static T  const&t;
1624         enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
1625     };
1626 #else
1627     template<typename T>
1628     class IsStreamInsertable {
1629         template<typename SS, typename TT>
1630         static auto test(int)
1631         -> decltype( std::declval<SS&>() << std::declval<TT>(), std::true_type() );
1632 
1633         template<typename, typename>
1634         static auto test(...) -> std::false_type;
1635 
1636     public:
1637         static const bool value = decltype(test<std::ostream,const T&>(0))::value;
1638     };
1639 #endif
1640 
1641 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1642     template<typename T,
1643              bool IsEnum = std::is_enum<T>::value
1644              >
1645     struct EnumStringMaker
1646     {
convertCatch::Detail::EnumStringMaker1647         static std::string convert( T const& ) { return unprintableString; }
1648     };
1649 
1650     template<typename T>
1651     struct EnumStringMaker<T,true>
1652     {
convertCatch::Detail::EnumStringMaker1653         static std::string convert( T const& v )
1654         {
1655             return ::Catch::toString(
1656                 static_cast<typename std::underlying_type<T>::type>(v)
1657                 );
1658         }
1659     };
1660 #endif
1661     template<bool C>
1662     struct StringMakerBase {
1663 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1664         template<typename T>
convertCatch::Detail::StringMakerBase1665         static std::string convert( T const& v )
1666         {
1667             return EnumStringMaker<T>::convert( v );
1668         }
1669 #else
1670         template<typename T>
1671         static std::string convert( T const& ) { return unprintableString; }
1672 #endif
1673     };
1674 
1675     template<>
1676     struct StringMakerBase<true> {
1677         template<typename T>
convertCatch::Detail::StringMakerBase1678         static std::string convert( T const& _value ) {
1679             std::ostringstream oss;
1680             oss << _value;
1681             return oss.str();
1682         }
1683     };
1684 
1685     std::string rawMemoryToString( const void *object, std::size_t size );
1686 
1687     template<typename T>
rawMemoryToString(const T & object)1688     std::string rawMemoryToString( const T& object ) {
1689       return rawMemoryToString( &object, sizeof(object) );
1690     }
1691 
1692 } // end namespace Detail
1693 
1694 template<typename T>
1695 struct StringMaker :
1696     Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
1697 
1698 template<typename T>
1699 struct StringMaker<T*> {
1700     template<typename U>
convertCatch::StringMaker1701     static std::string convert( U* p ) {
1702         if( !p )
1703             return "NULL";
1704         else
1705             return Detail::rawMemoryToString( p );
1706     }
1707 };
1708 
1709 template<typename R, typename C>
1710 struct StringMaker<R C::*> {
convertCatch::StringMaker1711     static std::string convert( R C::* p ) {
1712         if( !p )
1713             return "NULL";
1714         else
1715             return Detail::rawMemoryToString( p );
1716     }
1717 };
1718 
1719 namespace Detail {
1720     template<typename InputIterator>
1721     std::string rangeToString( InputIterator first, InputIterator last );
1722 }
1723 
1724 //template<typename T, typename Allocator>
1725 //struct StringMaker<std::vector<T, Allocator> > {
1726 //    static std::string convert( std::vector<T,Allocator> const& v ) {
1727 //        return Detail::rangeToString( v.begin(), v.end() );
1728 //    }
1729 //};
1730 
1731 template<typename T, typename Allocator>
toString(std::vector<T,Allocator> const & v)1732 std::string toString( std::vector<T,Allocator> const& v ) {
1733     return Detail::rangeToString( v.begin(), v.end() );
1734 }
1735 
1736 #ifdef CATCH_CONFIG_CPP11_TUPLE
1737 
1738 // toString for tuples
1739 namespace TupleDetail {
1740   template<
1741       typename Tuple,
1742       std::size_t N = 0,
1743       bool = (N < std::tuple_size<Tuple>::value)
1744       >
1745   struct ElementPrinter {
printCatch::TupleDetail::ElementPrinter1746       static void print( const Tuple& tuple, std::ostream& os )
1747       {
1748           os << ( N ? ", " : " " )
1749              << Catch::toString(std::get<N>(tuple));
1750           ElementPrinter<Tuple,N+1>::print(tuple,os);
1751       }
1752   };
1753 
1754   template<
1755       typename Tuple,
1756       std::size_t N
1757       >
1758   struct ElementPrinter<Tuple,N,false> {
printCatch::TupleDetail::ElementPrinter1759       static void print( const Tuple&, std::ostream& ) {}
1760   };
1761 
1762 }
1763 
1764 template<typename ...Types>
1765 struct StringMaker<std::tuple<Types...>> {
1766 
convertCatch::StringMaker1767     static std::string convert( const std::tuple<Types...>& tuple )
1768     {
1769         std::ostringstream os;
1770         os << '{';
1771         TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
1772         os << " }";
1773         return os.str();
1774     }
1775 };
1776 #endif // CATCH_CONFIG_CPP11_TUPLE
1777 
1778 namespace Detail {
1779     template<typename T>
makeString(T const & value)1780     std::string makeString( T const& value ) {
1781         return StringMaker<T>::convert( value );
1782     }
1783 } // end namespace Detail
1784 
1785 /// \brief converts any type to a string
1786 ///
1787 /// The default template forwards on to ostringstream - except when an
1788 /// ostringstream overload does not exist - in which case it attempts to detect
1789 /// that and writes {?}.
1790 /// Overload (not specialise) this template for custom typs that you don't want
1791 /// to provide an ostream overload for.
1792 template<typename T>
toString(T const & value)1793 std::string toString( T const& value ) {
1794     return StringMaker<T>::convert( value );
1795 }
1796 
1797     namespace Detail {
1798     template<typename InputIterator>
rangeToString(InputIterator first,InputIterator last)1799     std::string rangeToString( InputIterator first, InputIterator last ) {
1800         std::ostringstream oss;
1801         oss << "{ ";
1802         if( first != last ) {
1803             oss << Catch::toString( *first );
1804             for( ++first ; first != last ; ++first )
1805                 oss << ", " << Catch::toString( *first );
1806         }
1807         oss << " }";
1808         return oss.str();
1809     }
1810 }
1811 
1812 } // end namespace Catch
1813 
1814 namespace Catch {
1815 
1816 template<typename LhsT, Internal::Operator Op, typename RhsT>
1817 class BinaryExpression;
1818 
1819 template<typename ArgT, typename MatcherT>
1820 class MatchExpression;
1821 
1822 // Wraps the LHS of an expression and overloads comparison operators
1823 // for also capturing those and RHS (if any)
1824 template<typename T>
1825 class ExpressionLhs : public DecomposedExpression {
1826 public:
ExpressionLhs(ResultBuilder & rb,T lhs)1827     ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {}
1828 
1829     ExpressionLhs& operator = ( const ExpressionLhs& );
1830 
1831     template<typename RhsT>
1832     BinaryExpression<T, Internal::IsEqualTo, RhsT const&>
operator ==(RhsT const & rhs)1833     operator == ( RhsT const& rhs ) {
1834         return captureExpression<Internal::IsEqualTo>( rhs );
1835     }
1836 
1837     template<typename RhsT>
1838     BinaryExpression<T, Internal::IsNotEqualTo, RhsT const&>
operator !=(RhsT const & rhs)1839     operator != ( RhsT const& rhs ) {
1840         return captureExpression<Internal::IsNotEqualTo>( rhs );
1841     }
1842 
1843     template<typename RhsT>
1844     BinaryExpression<T, Internal::IsLessThan, RhsT const&>
operator <(RhsT const & rhs)1845     operator < ( RhsT const& rhs ) {
1846         return captureExpression<Internal::IsLessThan>( rhs );
1847     }
1848 
1849     template<typename RhsT>
1850     BinaryExpression<T, Internal::IsGreaterThan, RhsT const&>
operator >(RhsT const & rhs)1851     operator > ( RhsT const& rhs ) {
1852         return captureExpression<Internal::IsGreaterThan>( rhs );
1853     }
1854 
1855     template<typename RhsT>
1856     BinaryExpression<T, Internal::IsLessThanOrEqualTo, RhsT const&>
operator <=(RhsT const & rhs)1857     operator <= ( RhsT const& rhs ) {
1858         return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
1859     }
1860 
1861     template<typename RhsT>
1862     BinaryExpression<T, Internal::IsGreaterThanOrEqualTo, RhsT const&>
operator >=(RhsT const & rhs)1863     operator >= ( RhsT const& rhs ) {
1864         return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
1865     }
1866 
operator ==(bool rhs)1867     BinaryExpression<T, Internal::IsEqualTo, bool> operator == ( bool rhs ) {
1868         return captureExpression<Internal::IsEqualTo>( rhs );
1869     }
1870 
operator !=(bool rhs)1871     BinaryExpression<T, Internal::IsNotEqualTo, bool> operator != ( bool rhs ) {
1872         return captureExpression<Internal::IsNotEqualTo>( rhs );
1873     }
1874 
endExpression()1875     void endExpression() {
1876         m_truthy = m_lhs ? true : false;
1877         m_rb
1878             .setResultType( m_truthy )
1879             .endExpression( *this );
1880     }
1881 
reconstructExpression(std::string & dest) const1882     virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
1883         dest = Catch::toString( m_lhs );
1884     }
1885 
1886 private:
1887     template<Internal::Operator Op, typename RhsT>
captureExpression(RhsT & rhs) const1888     BinaryExpression<T, Op, RhsT&> captureExpression( RhsT& rhs ) const {
1889         return BinaryExpression<T, Op, RhsT&>( m_rb, m_lhs, rhs );
1890     }
1891 
1892     template<Internal::Operator Op>
captureExpression(bool rhs) const1893     BinaryExpression<T, Op, bool> captureExpression( bool rhs ) const {
1894         return BinaryExpression<T, Op, bool>( m_rb, m_lhs, rhs );
1895     }
1896 
1897 private:
1898     ResultBuilder& m_rb;
1899     T m_lhs;
1900     bool m_truthy;
1901 };
1902 
1903 template<typename LhsT, Internal::Operator Op, typename RhsT>
1904 class BinaryExpression : public DecomposedExpression {
1905 public:
BinaryExpression(ResultBuilder & rb,LhsT lhs,RhsT rhs)1906     BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs )
1907         : m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {}
1908 
1909     BinaryExpression& operator = ( BinaryExpression& );
1910 
endExpression() const1911     void endExpression() const {
1912         m_rb
1913             .setResultType( Internal::compare<Op>( m_lhs, m_rhs ) )
1914             .endExpression( *this );
1915     }
1916 
isBinaryExpression() const1917     virtual bool isBinaryExpression() const CATCH_OVERRIDE {
1918         return true;
1919     }
1920 
reconstructExpression(std::string & dest) const1921     virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
1922         std::string lhs = Catch::toString( m_lhs );
1923         std::string rhs = Catch::toString( m_rhs );
1924         char delim = lhs.size() + rhs.size() < 40 &&
1925                      lhs.find('\n') == std::string::npos &&
1926                      rhs.find('\n') == std::string::npos ? ' ' : '\n';
1927         dest.reserve( 7 + lhs.size() + rhs.size() );
1928                    // 2 for spaces around operator
1929                    // 2 for operator
1930                    // 2 for parentheses (conditionally added later)
1931                    // 1 for negation (conditionally added later)
1932         dest = lhs;
1933         dest += delim;
1934         dest += Internal::OperatorTraits<Op>::getName();
1935         dest += delim;
1936         dest += rhs;
1937     }
1938 
1939 private:
1940     ResultBuilder& m_rb;
1941     LhsT m_lhs;
1942     RhsT m_rhs;
1943 };
1944 
1945 template<typename ArgT, typename MatcherT>
1946 class MatchExpression : public DecomposedExpression {
1947 public:
MatchExpression(ArgT arg,MatcherT matcher,char const * matcherString)1948     MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString )
1949         : m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {}
1950 
isBinaryExpression() const1951     virtual bool isBinaryExpression() const CATCH_OVERRIDE {
1952         return true;
1953     }
1954 
reconstructExpression(std::string & dest) const1955     virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
1956         std::string matcherAsString = m_matcher.toString();
1957         dest = Catch::toString( m_arg );
1958         dest += ' ';
1959         if( matcherAsString == Detail::unprintableString )
1960             dest += m_matcherString;
1961         else
1962             dest += matcherAsString;
1963     }
1964 
1965 private:
1966     ArgT m_arg;
1967     MatcherT m_matcher;
1968     char const* m_matcherString;
1969 };
1970 
1971 } // end namespace Catch
1972 
1973 
1974 namespace Catch {
1975 
1976     template<typename T>
operator <=(T const & operand)1977     ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
1978         return ExpressionLhs<T const&>( *this, operand );
1979     }
1980 
operator <=(bool value)1981     inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
1982         return ExpressionLhs<bool>( *this, value );
1983     }
1984 
1985     template<typename ArgT, typename MatcherT>
captureMatch(ArgT const & arg,MatcherT const & matcher,char const * matcherString)1986     void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher,
1987                                              char const* matcherString ) {
1988         MatchExpression<ArgT const&, MatcherT const&> expr( arg, matcher, matcherString );
1989         setResultType( matcher.match( arg ) );
1990         endExpression( expr );
1991     }
1992 
1993 } // namespace Catch
1994 
1995 // #included from: catch_message.h
1996 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
1997 
1998 #include <string>
1999 
2000 namespace Catch {
2001 
2002     struct MessageInfo {
2003         MessageInfo(    std::string const& _macroName,
2004                         SourceLineInfo const& _lineInfo,
2005                         ResultWas::OfType _type );
2006 
2007         std::string macroName;
2008         SourceLineInfo lineInfo;
2009         ResultWas::OfType type;
2010         std::string message;
2011         unsigned int sequence;
2012 
operator ==Catch::MessageInfo2013         bool operator == ( MessageInfo const& other ) const {
2014             return sequence == other.sequence;
2015         }
operator <Catch::MessageInfo2016         bool operator < ( MessageInfo const& other ) const {
2017             return sequence < other.sequence;
2018         }
2019     private:
2020         static unsigned int globalCount;
2021     };
2022 
2023     struct MessageBuilder {
MessageBuilderCatch::MessageBuilder2024         MessageBuilder( std::string const& macroName,
2025                         SourceLineInfo const& lineInfo,
2026                         ResultWas::OfType type )
2027         : m_info( macroName, lineInfo, type )
2028         {}
2029 
2030         template<typename T>
operator <<Catch::MessageBuilder2031         MessageBuilder& operator << ( T const& value ) {
2032             m_stream << value;
2033             return *this;
2034         }
2035 
2036         MessageInfo m_info;
2037         std::ostringstream m_stream;
2038     };
2039 
2040     class ScopedMessage {
2041     public:
2042         ScopedMessage( MessageBuilder const& builder );
2043         ScopedMessage( ScopedMessage const& other );
2044         ~ScopedMessage();
2045 
2046         MessageInfo m_info;
2047     };
2048 
2049 } // end namespace Catch
2050 
2051 // #included from: catch_interfaces_capture.h
2052 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
2053 
2054 #include <string>
2055 
2056 namespace Catch {
2057 
2058     class TestCase;
2059     class AssertionResult;
2060     struct AssertionInfo;
2061     struct SectionInfo;
2062     struct SectionEndInfo;
2063     struct MessageInfo;
2064     class ScopedMessageBuilder;
2065     struct Counts;
2066 
2067     struct IResultCapture {
2068 
2069         virtual ~IResultCapture();
2070 
2071         virtual void assertionEnded( AssertionResult const& result ) = 0;
2072         virtual bool sectionStarted(    SectionInfo const& sectionInfo,
2073                                         Counts& assertions ) = 0;
2074         virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
2075         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
2076         virtual void pushScopedMessage( MessageInfo const& message ) = 0;
2077         virtual void popScopedMessage( MessageInfo const& message ) = 0;
2078 
2079         virtual std::string getCurrentTestName() const = 0;
2080         virtual const AssertionResult* getLastResult() const = 0;
2081 
2082         virtual void exceptionEarlyReported() = 0;
2083 
2084         virtual void handleFatalErrorCondition( std::string const& message ) = 0;
2085 
2086         virtual bool lastAssertionPassed() = 0;
2087         virtual void assertionPassed() = 0;
2088         virtual void assertionRun() = 0;
2089     };
2090 
2091     IResultCapture& getResultCapture();
2092 }
2093 
2094 // #included from: catch_debugger.h
2095 #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
2096 
2097 // #included from: catch_platform.h
2098 #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
2099 
2100 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
2101 #  define CATCH_PLATFORM_MAC
2102 #elif  defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
2103 #  define CATCH_PLATFORM_IPHONE
2104 #elif defined(linux) || defined(__linux) || defined(__linux__)
2105 #  define CATCH_PLATFORM_LINUX
2106 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
2107 #  define CATCH_PLATFORM_WINDOWS
2108 #  if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
2109 #    define CATCH_DEFINES_NOMINMAX
2110 #  endif
2111 #  if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
2112 #    define CATCH_DEFINES_WIN32_LEAN_AND_MEAN
2113 #  endif
2114 #endif
2115 
2116 #include <string>
2117 
2118 namespace Catch{
2119 
2120     bool isDebuggerActive();
2121     void writeToDebugConsole( std::string const& text );
2122 }
2123 
2124 #ifdef CATCH_PLATFORM_MAC
2125 
2126     // The following code snippet based on:
2127     // http://cocoawithlove.com/2008/03/break-into-debugger.html
2128     #if defined(__ppc64__) || defined(__ppc__)
2129         #define CATCH_TRAP() \
2130                 __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
2131                 : : : "memory","r0","r3","r4" ) /* NOLINT */
2132     #else
2133         #define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ )
2134     #endif
2135 
2136 #elif defined(CATCH_PLATFORM_LINUX)
2137     // If we can use inline assembler, do it because this allows us to break
2138     // directly at the location of the failing check instead of breaking inside
2139     // raise() called from it, i.e. one stack frame below.
2140     #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
2141         #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
2142     #else // Fall back to the generic way.
2143         #include <signal.h>
2144 
2145         #define CATCH_TRAP() raise(SIGTRAP)
2146     #endif
2147 #elif defined(_MSC_VER)
2148     #define CATCH_TRAP() __debugbreak()
2149 #elif defined(__MINGW32__)
2150     extern "C" __declspec(dllimport) void __stdcall DebugBreak();
2151     #define CATCH_TRAP() DebugBreak()
2152 #endif
2153 
2154 #ifdef CATCH_TRAP
2155     #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
2156 #else
2157     #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
2158 #endif
2159 
2160 // #included from: catch_interfaces_runner.h
2161 #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
2162 
2163 namespace Catch {
2164     class TestCase;
2165 
2166     struct IRunner {
2167         virtual ~IRunner();
2168         virtual bool aborting() const = 0;
2169     };
2170 }
2171 
2172 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
2173 # define CATCH_INTERNAL_STRINGIFY(expr) #expr
2174 #else
2175 # define CATCH_INTERNAL_STRINGIFY(expr) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
2176 #endif
2177 
2178 #if defined(CATCH_CONFIG_FAST_COMPILE)
2179 ///////////////////////////////////////////////////////////////////////////////
2180 // We can speedup compilation significantly by breaking into debugger lower in
2181 // the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER
2182 // macro in each assertion
2183 #define INTERNAL_CATCH_REACT( resultBuilder ) \
2184     resultBuilder.react();
2185 
2186 ///////////////////////////////////////////////////////////////////////////////
2187 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
2188 // macros.
2189 // This can potentially cause false negative, if the test code catches
2190 // the exception before it propagates back up to the runner.
2191 #define INTERNAL_CATCH_TEST_NO_TRY( macroName, resultDisposition, expr ) \
2192     do { \
2193         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
2194         __catchResult.setExceptionGuard(); \
2195         CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2196         ( __catchResult <= expr ).endExpression(); \
2197         CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
2198         __catchResult.unsetExceptionGuard(); \
2199         INTERNAL_CATCH_REACT( __catchResult ) \
2200     } while( Catch::isTrue( false && static_cast<bool>( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
2201 // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
2202 
2203 #define INTERNAL_CHECK_THAT_NO_TRY( macroName, matcher, resultDisposition, arg ) \
2204     do { \
2205         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2206         __catchResult.setExceptionGuard(); \
2207         __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \
2208         __catchResult.unsetExceptionGuard(); \
2209         INTERNAL_CATCH_REACT( __catchResult ) \
2210     } while( Catch::alwaysFalse() )
2211 
2212 #else
2213 ///////////////////////////////////////////////////////////////////////////////
2214 // In the event of a failure works out if the debugger needs to be invoked
2215 // and/or an exception thrown and takes appropriate action.
2216 // This needs to be done as a macro so the debugger will stop in the user
2217 // source code rather than in Catch library code
2218 #define INTERNAL_CATCH_REACT( resultBuilder ) \
2219     if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
2220     resultBuilder.react();
2221 #endif
2222 
2223 ///////////////////////////////////////////////////////////////////////////////
2224 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ) \
2225     do { \
2226         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
2227         try { \
2228             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2229             ( __catchResult <= expr ).endExpression(); \
2230             CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
2231         } \
2232         catch( ... ) { \
2233             __catchResult.useActiveException( resultDisposition ); \
2234         } \
2235         INTERNAL_CATCH_REACT( __catchResult ) \
2236     } while( Catch::isTrue( false && static_cast<bool>( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
2237     // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
2238 
2239 ///////////////////////////////////////////////////////////////////////////////
2240 #define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \
2241     INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
2242     if( Catch::getResultCapture().lastAssertionPassed() )
2243 
2244 ///////////////////////////////////////////////////////////////////////////////
2245 #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \
2246     INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
2247     if( !Catch::getResultCapture().lastAssertionPassed() )
2248 
2249 ///////////////////////////////////////////////////////////////////////////////
2250 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \
2251     do { \
2252         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
2253         try { \
2254             static_cast<void>(expr); \
2255             __catchResult.captureResult( Catch::ResultWas::Ok ); \
2256         } \
2257         catch( ... ) { \
2258             __catchResult.useActiveException( resultDisposition ); \
2259         } \
2260         INTERNAL_CATCH_REACT( __catchResult ) \
2261     } while( Catch::alwaysFalse() )
2262 
2263 ///////////////////////////////////////////////////////////////////////////////
2264 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, matcher, expr ) \
2265     do { \
2266         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition, CATCH_INTERNAL_STRINGIFY(matcher) ); \
2267         if( __catchResult.allowThrows() ) \
2268             try { \
2269                 static_cast<void>(expr); \
2270                 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
2271             } \
2272             catch( ... ) { \
2273                 __catchResult.captureExpectedException( matcher ); \
2274             } \
2275         else \
2276             __catchResult.captureResult( Catch::ResultWas::Ok ); \
2277         INTERNAL_CATCH_REACT( __catchResult ) \
2278     } while( Catch::alwaysFalse() )
2279 
2280 ///////////////////////////////////////////////////////////////////////////////
2281 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
2282     do { \
2283         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
2284         if( __catchResult.allowThrows() ) \
2285             try { \
2286                 static_cast<void>(expr); \
2287                 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
2288             } \
2289             catch( exceptionType ) { \
2290                 __catchResult.captureResult( Catch::ResultWas::Ok ); \
2291             } \
2292             catch( ... ) { \
2293                 __catchResult.useActiveException( resultDisposition ); \
2294             } \
2295         else \
2296             __catchResult.captureResult( Catch::ResultWas::Ok ); \
2297         INTERNAL_CATCH_REACT( __catchResult ) \
2298     } while( Catch::alwaysFalse() )
2299 
2300 ///////////////////////////////////////////////////////////////////////////////
2301 #ifdef CATCH_CONFIG_VARIADIC_MACROS
2302     #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
2303         do { \
2304             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
2305             __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
2306             __catchResult.captureResult( messageType ); \
2307             INTERNAL_CATCH_REACT( __catchResult ) \
2308         } while( Catch::alwaysFalse() )
2309 #else
2310     #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \
2311         do { \
2312             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
2313             __catchResult << log + ::Catch::StreamEndStop(); \
2314             __catchResult.captureResult( messageType ); \
2315             INTERNAL_CATCH_REACT( __catchResult ) \
2316         } while( Catch::alwaysFalse() )
2317 #endif
2318 
2319 ///////////////////////////////////////////////////////////////////////////////
2320 #define INTERNAL_CATCH_INFO( macroName, log ) \
2321     Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
2322 
2323 ///////////////////////////////////////////////////////////////////////////////
2324 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
2325     do { \
2326         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2327         try { \
2328             __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \
2329         } catch( ... ) { \
2330             __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
2331         } \
2332         INTERNAL_CATCH_REACT( __catchResult ) \
2333     } while( Catch::alwaysFalse() )
2334 
2335 // #included from: internal/catch_section.h
2336 #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
2337 
2338 // #included from: catch_section_info.h
2339 #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
2340 
2341 // #included from: catch_totals.hpp
2342 #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
2343 
2344 #include <cstddef>
2345 
2346 namespace Catch {
2347 
2348     struct Counts {
CountsCatch::Counts2349         Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
2350 
operator -Catch::Counts2351         Counts operator - ( Counts const& other ) const {
2352             Counts diff;
2353             diff.passed = passed - other.passed;
2354             diff.failed = failed - other.failed;
2355             diff.failedButOk = failedButOk - other.failedButOk;
2356             return diff;
2357         }
operator +=Catch::Counts2358         Counts& operator += ( Counts const& other ) {
2359             passed += other.passed;
2360             failed += other.failed;
2361             failedButOk += other.failedButOk;
2362             return *this;
2363         }
2364 
totalCatch::Counts2365         std::size_t total() const {
2366             return passed + failed + failedButOk;
2367         }
allPassedCatch::Counts2368         bool allPassed() const {
2369             return failed == 0 && failedButOk == 0;
2370         }
allOkCatch::Counts2371         bool allOk() const {
2372             return failed == 0;
2373         }
2374 
2375         std::size_t passed;
2376         std::size_t failed;
2377         std::size_t failedButOk;
2378     };
2379 
2380     struct Totals {
2381 
operator -Catch::Totals2382         Totals operator - ( Totals const& other ) const {
2383             Totals diff;
2384             diff.assertions = assertions - other.assertions;
2385             diff.testCases = testCases - other.testCases;
2386             return diff;
2387         }
2388 
deltaCatch::Totals2389         Totals delta( Totals const& prevTotals ) const {
2390             Totals diff = *this - prevTotals;
2391             if( diff.assertions.failed > 0 )
2392                 ++diff.testCases.failed;
2393             else if( diff.assertions.failedButOk > 0 )
2394                 ++diff.testCases.failedButOk;
2395             else
2396                 ++diff.testCases.passed;
2397             return diff;
2398         }
2399 
operator +=Catch::Totals2400         Totals& operator += ( Totals const& other ) {
2401             assertions += other.assertions;
2402             testCases += other.testCases;
2403             return *this;
2404         }
2405 
2406         Counts assertions;
2407         Counts testCases;
2408     };
2409 }
2410 
2411 #include <string>
2412 
2413 namespace Catch {
2414 
2415     struct SectionInfo {
2416         SectionInfo
2417             (   SourceLineInfo const& _lineInfo,
2418                 std::string const& _name,
2419                 std::string const& _description = std::string() );
2420 
2421         std::string name;
2422         std::string description;
2423         SourceLineInfo lineInfo;
2424     };
2425 
2426     struct SectionEndInfo {
SectionEndInfoCatch::SectionEndInfo2427         SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
2428         : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
2429         {}
2430 
2431         SectionInfo sectionInfo;
2432         Counts prevAssertions;
2433         double durationInSeconds;
2434     };
2435 
2436 } // end namespace Catch
2437 
2438 // #included from: catch_timer.h
2439 #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
2440 
2441 #ifdef _MSC_VER
2442 
2443 namespace Catch {
2444     typedef unsigned long long UInt64;
2445 }
2446 #else
2447 #include <stdint.h>
2448 namespace Catch {
2449     typedef uint64_t UInt64;
2450 }
2451 #endif
2452 
2453 namespace Catch {
2454     class Timer {
2455     public:
Timer()2456         Timer() : m_ticks( 0 ) {}
2457         void start();
2458         unsigned int getElapsedMicroseconds() const;
2459         unsigned int getElapsedMilliseconds() const;
2460         double getElapsedSeconds() const;
2461 
2462     private:
2463         UInt64 m_ticks;
2464     };
2465 
2466 } // namespace Catch
2467 
2468 #include <string>
2469 
2470 namespace Catch {
2471 
2472     class Section : NonCopyable {
2473     public:
2474         Section( SectionInfo const& info );
2475         ~Section();
2476 
2477         // This indicates whether the section should be executed or not
2478         operator bool() const;
2479 
2480     private:
2481         SectionInfo m_info;
2482 
2483         std::string m_name;
2484         Counts m_assertions;
2485         bool m_sectionIncluded;
2486         Timer m_timer;
2487     };
2488 
2489 } // end namespace Catch
2490 
2491 #ifdef CATCH_CONFIG_VARIADIC_MACROS
2492     #define INTERNAL_CATCH_SECTION( ... ) \
2493         if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
2494 #else
2495     #define INTERNAL_CATCH_SECTION( name, desc ) \
2496         if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
2497 #endif
2498 
2499 // #included from: internal/catch_generators.hpp
2500 #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
2501 
2502 #include <vector>
2503 #include <string>
2504 #include <stdlib.h>
2505 
2506 namespace Catch {
2507 
2508 template<typename T>
2509 struct IGenerator {
~IGeneratorCatch::IGenerator2510     virtual ~IGenerator() {}
2511     virtual T getValue( std::size_t index ) const = 0;
2512     virtual std::size_t size () const = 0;
2513 };
2514 
2515 template<typename T>
2516 class BetweenGenerator : public IGenerator<T> {
2517 public:
BetweenGenerator(T from,T to)2518     BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
2519 
getValue(std::size_t index) const2520     virtual T getValue( std::size_t index ) const {
2521         return m_from+static_cast<int>( index );
2522     }
2523 
size() const2524     virtual std::size_t size() const {
2525         return static_cast<std::size_t>( 1+m_to-m_from );
2526     }
2527 
2528 private:
2529 
2530     T m_from;
2531     T m_to;
2532 };
2533 
2534 template<typename T>
2535 class ValuesGenerator : public IGenerator<T> {
2536 public:
ValuesGenerator()2537     ValuesGenerator(){}
2538 
add(T value)2539     void add( T value ) {
2540         m_values.push_back( value );
2541     }
2542 
getValue(std::size_t index) const2543     virtual T getValue( std::size_t index ) const {
2544         return m_values[index];
2545     }
2546 
size() const2547     virtual std::size_t size() const {
2548         return m_values.size();
2549     }
2550 
2551 private:
2552     std::vector<T> m_values;
2553 };
2554 
2555 template<typename T>
2556 class CompositeGenerator {
2557 public:
CompositeGenerator()2558     CompositeGenerator() : m_totalSize( 0 ) {}
2559 
2560     // *** Move semantics, similar to auto_ptr ***
CompositeGenerator(CompositeGenerator & other)2561     CompositeGenerator( CompositeGenerator& other )
2562     :   m_fileInfo( other.m_fileInfo ),
2563         m_totalSize( 0 )
2564     {
2565         move( other );
2566     }
2567 
setFileInfo(const char * fileInfo)2568     CompositeGenerator& setFileInfo( const char* fileInfo ) {
2569         m_fileInfo = fileInfo;
2570         return *this;
2571     }
2572 
~CompositeGenerator()2573     ~CompositeGenerator() {
2574         deleteAll( m_composed );
2575     }
2576 
operator T() const2577     operator T () const {
2578         size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
2579 
2580         typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
2581         typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
2582         for( size_t index = 0; it != itEnd; ++it )
2583         {
2584             const IGenerator<T>* generator = *it;
2585             if( overallIndex >= index && overallIndex < index + generator->size() )
2586             {
2587                 return generator->getValue( overallIndex-index );
2588             }
2589             index += generator->size();
2590         }
2591         CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
2592         return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
2593     }
2594 
add(const IGenerator<T> * generator)2595     void add( const IGenerator<T>* generator ) {
2596         m_totalSize += generator->size();
2597         m_composed.push_back( generator );
2598     }
2599 
then(CompositeGenerator & other)2600     CompositeGenerator& then( CompositeGenerator& other ) {
2601         move( other );
2602         return *this;
2603     }
2604 
then(T value)2605     CompositeGenerator& then( T value ) {
2606         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2607         valuesGen->add( value );
2608         add( valuesGen );
2609         return *this;
2610     }
2611 
2612 private:
2613 
move(CompositeGenerator & other)2614     void move( CompositeGenerator& other ) {
2615         m_composed.insert( m_composed.end(), other.m_composed.begin(), other.m_composed.end() );
2616         m_totalSize += other.m_totalSize;
2617         other.m_composed.clear();
2618     }
2619 
2620     std::vector<const IGenerator<T>*> m_composed;
2621     std::string m_fileInfo;
2622     size_t m_totalSize;
2623 };
2624 
2625 namespace Generators
2626 {
2627     template<typename T>
between(T from,T to)2628     CompositeGenerator<T> between( T from, T to ) {
2629         CompositeGenerator<T> generators;
2630         generators.add( new BetweenGenerator<T>( from, to ) );
2631         return generators;
2632     }
2633 
2634     template<typename T>
values(T val1,T val2)2635     CompositeGenerator<T> values( T val1, T val2 ) {
2636         CompositeGenerator<T> generators;
2637         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2638         valuesGen->add( val1 );
2639         valuesGen->add( val2 );
2640         generators.add( valuesGen );
2641         return generators;
2642     }
2643 
2644     template<typename T>
values(T val1,T val2,T val3)2645     CompositeGenerator<T> values( T val1, T val2, T val3 ){
2646         CompositeGenerator<T> generators;
2647         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2648         valuesGen->add( val1 );
2649         valuesGen->add( val2 );
2650         valuesGen->add( val3 );
2651         generators.add( valuesGen );
2652         return generators;
2653     }
2654 
2655     template<typename T>
values(T val1,T val2,T val3,T val4)2656     CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
2657         CompositeGenerator<T> generators;
2658         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2659         valuesGen->add( val1 );
2660         valuesGen->add( val2 );
2661         valuesGen->add( val3 );
2662         valuesGen->add( val4 );
2663         generators.add( valuesGen );
2664         return generators;
2665     }
2666 
2667 } // end namespace Generators
2668 
2669 using namespace Generators;
2670 
2671 } // end namespace Catch
2672 
2673 #define INTERNAL_CATCH_LINESTR2( line ) #line
2674 #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
2675 
2676 #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
2677 
2678 // #included from: internal/catch_interfaces_exception.h
2679 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
2680 
2681 #include <string>
2682 #include <vector>
2683 
2684 // #included from: catch_interfaces_registry_hub.h
2685 #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
2686 
2687 #include <string>
2688 
2689 namespace Catch {
2690 
2691     class TestCase;
2692     struct ITestCaseRegistry;
2693     struct IExceptionTranslatorRegistry;
2694     struct IExceptionTranslator;
2695     struct IReporterRegistry;
2696     struct IReporterFactory;
2697     struct ITagAliasRegistry;
2698 
2699     struct IRegistryHub {
2700         virtual ~IRegistryHub();
2701 
2702         virtual IReporterRegistry const& getReporterRegistry() const = 0;
2703         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2704         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
2705 
2706         virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
2707     };
2708 
2709     struct IMutableRegistryHub {
2710         virtual ~IMutableRegistryHub();
2711         virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
2712         virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
2713         virtual void registerTest( TestCase const& testInfo ) = 0;
2714         virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2715         virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
2716     };
2717 
2718     IRegistryHub& getRegistryHub();
2719     IMutableRegistryHub& getMutableRegistryHub();
2720     void cleanUp();
2721     std::string translateActiveException();
2722 
2723 }
2724 
2725 namespace Catch {
2726 
2727     typedef std::string(*exceptionTranslateFunction)();
2728 
2729     struct IExceptionTranslator;
2730     typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
2731 
2732     struct IExceptionTranslator {
2733         virtual ~IExceptionTranslator();
2734         virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
2735     };
2736 
2737     struct IExceptionTranslatorRegistry {
2738         virtual ~IExceptionTranslatorRegistry();
2739 
2740         virtual std::string translateActiveException() const = 0;
2741     };
2742 
2743     class ExceptionTranslatorRegistrar {
2744         template<typename T>
2745         class ExceptionTranslator : public IExceptionTranslator {
2746         public:
2747 
ExceptionTranslator(std::string (* translateFunction)(T &))2748             ExceptionTranslator( std::string(*translateFunction)( T& ) )
2749             : m_translateFunction( translateFunction )
2750             {}
2751 
translate(ExceptionTranslators::const_iterator it,ExceptionTranslators::const_iterator itEnd) const2752             virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
2753                 try {
2754                     if( it == itEnd )
2755                         throw;
2756                     else
2757                         return (*it)->translate( it+1, itEnd );
2758                 }
2759                 catch( T& ex ) {
2760                     return m_translateFunction( ex );
2761                 }
2762             }
2763 
2764         protected:
2765             std::string(*m_translateFunction)( T& );
2766         };
2767 
2768     public:
2769         template<typename T>
ExceptionTranslatorRegistrar(std::string (* translateFunction)(T &))2770         ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
2771             getMutableRegistryHub().registerTranslator
2772                 ( new ExceptionTranslator<T>( translateFunction ) );
2773         }
2774     };
2775 }
2776 
2777 ///////////////////////////////////////////////////////////////////////////////
2778 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
2779     static std::string translatorName( signature ); \
2780     namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
2781     static std::string translatorName( signature )
2782 
2783 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
2784 
2785 // #included from: internal/catch_approx.hpp
2786 #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
2787 
2788 #include <cmath>
2789 #include <limits>
2790 
2791 #if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
2792 #include <type_traits>
2793 #endif
2794 
2795 namespace Catch {
2796 namespace Detail {
2797 
2798     class Approx {
2799     public:
Approx(double value)2800         explicit Approx ( double value )
2801         :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
2802             m_margin( 0.0 ),
2803             m_scale( 1.0 ),
2804             m_value( value )
2805         {}
2806 
custom()2807         static Approx custom() {
2808             return Approx( 0 );
2809         }
2810 
2811 #if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
2812 
2813         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator ()(T value)2814         Approx operator()( T value ) {
2815             Approx approx( static_cast<double>(value) );
2816             approx.epsilon( m_epsilon );
2817             approx.margin( m_margin );
2818             approx.scale( m_scale );
2819             return approx;
2820         }
2821 
2822         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
Approx(T value)2823         explicit Approx( T value ): Approx(static_cast<double>(value))
2824         {}
2825 
2826         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator ==(const T & lhs,Approx const & rhs)2827         friend bool operator == ( const T& lhs, Approx const& rhs ) {
2828             // Thanks to Richard Harris for his help refining this formula
2829             auto lhs_v = double(lhs);
2830             bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (std::max)(std::fabs(lhs_v), std::fabs(rhs.m_value)));
2831             if (relativeOK) {
2832                 return true;
2833             }
2834 
2835             return std::fabs(lhs_v - rhs.m_value) <= rhs.m_margin;
2836         }
2837 
2838         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator ==(Approx const & lhs,const T & rhs)2839         friend bool operator == ( Approx const& lhs, const T& rhs ) {
2840             return operator==( rhs, lhs );
2841         }
2842 
2843         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator !=(T lhs,Approx const & rhs)2844         friend bool operator != ( T lhs, Approx const& rhs ) {
2845             return !operator==( lhs, rhs );
2846         }
2847 
2848         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator !=(Approx const & lhs,T rhs)2849         friend bool operator != ( Approx const& lhs, T rhs ) {
2850             return !operator==( rhs, lhs );
2851         }
2852 
2853         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator <=(T lhs,Approx const & rhs)2854         friend bool operator <= ( T lhs, Approx const& rhs ) {
2855             return double(lhs) < rhs.m_value || lhs == rhs;
2856         }
2857 
2858         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator <=(Approx const & lhs,T rhs)2859         friend bool operator <= ( Approx const& lhs, T rhs ) {
2860             return lhs.m_value < double(rhs) || lhs == rhs;
2861         }
2862 
2863         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator >=(T lhs,Approx const & rhs)2864         friend bool operator >= ( T lhs, Approx const& rhs ) {
2865             return double(lhs) > rhs.m_value || lhs == rhs;
2866         }
2867 
2868         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
operator >=(Approx const & lhs,T rhs)2869         friend bool operator >= ( Approx const& lhs, T rhs ) {
2870             return lhs.m_value > double(rhs) || lhs == rhs;
2871         }
2872 
2873         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
epsilon(T newEpsilon)2874         Approx& epsilon( T newEpsilon ) {
2875             m_epsilon = double(newEpsilon);
2876             return *this;
2877         }
2878 
2879         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
margin(T newMargin)2880         Approx& margin( T newMargin ) {
2881             m_margin = double(newMargin);
2882             return *this;
2883         }
2884 
2885         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
scale(T newScale)2886         Approx& scale( T newScale ) {
2887             m_scale = double(newScale);
2888             return *this;
2889         }
2890 
2891 #else
2892 
operator ()(double value)2893         Approx operator()( double value ) {
2894             Approx approx( value );
2895             approx.epsilon( m_epsilon );
2896             approx.margin( m_margin );
2897             approx.scale( m_scale );
2898             return approx;
2899         }
2900 
operator ==(double lhs,Approx const & rhs)2901         friend bool operator == ( double lhs, Approx const& rhs ) {
2902             // Thanks to Richard Harris for his help refining this formula
2903             bool relativeOK = std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) );
2904             if (relativeOK) {
2905                 return true;
2906             }
2907             return std::fabs(lhs - rhs.m_value) <= rhs.m_margin;
2908         }
2909 
operator ==(Approx const & lhs,double rhs)2910         friend bool operator == ( Approx const& lhs, double rhs ) {
2911             return operator==( rhs, lhs );
2912         }
2913 
operator !=(double lhs,Approx const & rhs)2914         friend bool operator != ( double lhs, Approx const& rhs ) {
2915             return !operator==( lhs, rhs );
2916         }
2917 
operator !=(Approx const & lhs,double rhs)2918         friend bool operator != ( Approx const& lhs, double rhs ) {
2919             return !operator==( rhs, lhs );
2920         }
2921 
operator <=(double lhs,Approx const & rhs)2922         friend bool operator <= ( double lhs, Approx const& rhs ) {
2923             return lhs < rhs.m_value || lhs == rhs;
2924         }
2925 
operator <=(Approx const & lhs,double rhs)2926         friend bool operator <= ( Approx const& lhs, double rhs ) {
2927             return lhs.m_value < rhs || lhs == rhs;
2928         }
2929 
operator >=(double lhs,Approx const & rhs)2930         friend bool operator >= ( double lhs, Approx const& rhs ) {
2931             return lhs > rhs.m_value || lhs == rhs;
2932         }
2933 
operator >=(Approx const & lhs,double rhs)2934         friend bool operator >= ( Approx const& lhs, double rhs ) {
2935             return lhs.m_value > rhs || lhs == rhs;
2936         }
2937 
epsilon(double newEpsilon)2938         Approx& epsilon( double newEpsilon ) {
2939             m_epsilon = newEpsilon;
2940             return *this;
2941         }
2942 
margin(double newMargin)2943         Approx& margin( double newMargin ) {
2944             m_margin = newMargin;
2945             return *this;
2946         }
2947 
scale(double newScale)2948         Approx& scale( double newScale ) {
2949             m_scale = newScale;
2950             return *this;
2951         }
2952 #endif
2953 
toString() const2954         std::string toString() const {
2955             std::ostringstream oss;
2956             oss << "Approx( " << Catch::toString( m_value ) << " )";
2957             return oss.str();
2958         }
2959 
2960     private:
2961         double m_epsilon;
2962         double m_margin;
2963         double m_scale;
2964         double m_value;
2965     };
2966 }
2967 
2968 template<>
toString(Detail::Approx const & value)2969 inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
2970     return value.toString();
2971 }
2972 
2973 } // end namespace Catch
2974 
2975 // #included from: internal/catch_matchers_string.h
2976 #define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
2977 
2978 namespace Catch {
2979 namespace Matchers {
2980 
2981     namespace StdString {
2982 
2983         struct CasedString
2984         {
2985             CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
2986             std::string adjustString( std::string const& str ) const;
2987             std::string caseSensitivitySuffix() const;
2988 
2989             CaseSensitive::Choice m_caseSensitivity;
2990             std::string m_str;
2991         };
2992 
2993         struct StringMatcherBase : MatcherBase<std::string> {
2994             StringMatcherBase( std::string const& operation, CasedString const& comparator );
2995             virtual std::string describe() const CATCH_OVERRIDE;
2996 
2997             CasedString m_comparator;
2998             std::string m_operation;
2999         };
3000 
3001         struct EqualsMatcher : StringMatcherBase {
3002             EqualsMatcher( CasedString const& comparator );
3003             virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
3004         };
3005         struct ContainsMatcher : StringMatcherBase {
3006             ContainsMatcher( CasedString const& comparator );
3007             virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
3008         };
3009         struct StartsWithMatcher : StringMatcherBase {
3010             StartsWithMatcher( CasedString const& comparator );
3011             virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
3012         };
3013         struct EndsWithMatcher : StringMatcherBase {
3014             EndsWithMatcher( CasedString const& comparator );
3015             virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
3016         };
3017 
3018     } // namespace StdString
3019 
3020     // The following functions create the actual matcher objects.
3021     // This allows the types to be inferred
3022 
3023     StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3024     StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3025     StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3026     StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3027 
3028 } // namespace Matchers
3029 } // namespace Catch
3030 
3031 // #included from: internal/catch_matchers_vector.h
3032 #define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
3033 
3034 namespace Catch {
3035 namespace Matchers {
3036 
3037     namespace Vector {
3038 
3039         template<typename T>
3040         struct ContainsElementMatcher : MatcherBase<std::vector<T>, T> {
3041 
ContainsElementMatcherCatch::Matchers::Vector::ContainsElementMatcher3042             ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
3043 
matchCatch::Matchers::Vector::ContainsElementMatcher3044             bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
3045                 return std::find(v.begin(), v.end(), m_comparator) != v.end();
3046             }
3047 
describeCatch::Matchers::Vector::ContainsElementMatcher3048             virtual std::string describe() const CATCH_OVERRIDE {
3049                 return "Contains: " + Catch::toString( m_comparator );
3050             }
3051 
3052             T const& m_comparator;
3053         };
3054 
3055         template<typename T>
3056         struct ContainsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
3057 
ContainsMatcherCatch::Matchers::Vector::ContainsMatcher3058             ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
3059 
matchCatch::Matchers::Vector::ContainsMatcher3060             bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
3061                 // !TBD: see note in EqualsMatcher
3062                 if (m_comparator.size() > v.size())
3063                     return false;
3064                 for (size_t i = 0; i < m_comparator.size(); ++i)
3065                     if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end())
3066                         return false;
3067                 return true;
3068             }
describeCatch::Matchers::Vector::ContainsMatcher3069             virtual std::string describe() const CATCH_OVERRIDE {
3070                 return "Contains: " + Catch::toString( m_comparator );
3071             }
3072 
3073             std::vector<T> const& m_comparator;
3074         };
3075 
3076         template<typename T>
3077         struct EqualsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
3078 
EqualsMatcherCatch::Matchers::Vector::EqualsMatcher3079             EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
3080 
matchCatch::Matchers::Vector::EqualsMatcher3081             bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
3082                 // !TBD: This currently works if all elements can be compared using !=
3083                 // - a more general approach would be via a compare template that defaults
3084                 // to using !=. but could be specialised for, e.g. std::vector<T> etc
3085                 // - then just call that directly
3086                 if (m_comparator.size() != v.size())
3087                     return false;
3088                 for (size_t i = 0; i < v.size(); ++i)
3089                     if (m_comparator[i] != v[i])
3090                         return false;
3091                 return true;
3092             }
describeCatch::Matchers::Vector::EqualsMatcher3093             virtual std::string describe() const CATCH_OVERRIDE {
3094                 return "Equals: " + Catch::toString( m_comparator );
3095             }
3096             std::vector<T> const& m_comparator;
3097         };
3098 
3099     } // namespace Vector
3100 
3101     // The following functions create the actual matcher objects.
3102     // This allows the types to be inferred
3103 
3104     template<typename T>
Contains(std::vector<T> const & comparator)3105     Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
3106         return Vector::ContainsMatcher<T>( comparator );
3107     }
3108 
3109     template<typename T>
VectorContains(T const & comparator)3110     Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
3111         return Vector::ContainsElementMatcher<T>( comparator );
3112     }
3113 
3114     template<typename T>
Equals(std::vector<T> const & comparator)3115     Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
3116         return Vector::EqualsMatcher<T>( comparator );
3117     }
3118 
3119 } // namespace Matchers
3120 } // namespace Catch
3121 
3122 // #included from: internal/catch_interfaces_tag_alias_registry.h
3123 #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
3124 
3125 // #included from: catch_tag_alias.h
3126 #define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
3127 
3128 #include <string>
3129 
3130 namespace Catch {
3131 
3132     struct TagAlias {
TagAliasCatch::TagAlias3133         TagAlias( std::string const& _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
3134 
3135         std::string tag;
3136         SourceLineInfo lineInfo;
3137     };
3138 
3139     struct RegistrarForTagAliases {
3140         RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
3141     };
3142 
3143 } // end namespace Catch
3144 
3145 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
3146 // #included from: catch_option.hpp
3147 #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
3148 
3149 namespace Catch {
3150 
3151     // An optional type
3152     template<typename T>
3153     class Option {
3154     public:
Option()3155         Option() : nullableValue( CATCH_NULL ) {}
Option(T const & _value)3156         Option( T const& _value )
3157         : nullableValue( new( storage ) T( _value ) )
3158         {}
Option(Option const & _other)3159         Option( Option const& _other )
3160         : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
3161         {}
3162 
~Option()3163         ~Option() {
3164             reset();
3165         }
3166 
operator =(Option const & _other)3167         Option& operator= ( Option const& _other ) {
3168             if( &_other != this ) {
3169                 reset();
3170                 if( _other )
3171                     nullableValue = new( storage ) T( *_other );
3172             }
3173             return *this;
3174         }
operator =(T const & _value)3175         Option& operator = ( T const& _value ) {
3176             reset();
3177             nullableValue = new( storage ) T( _value );
3178             return *this;
3179         }
3180 
reset()3181         void reset() {
3182             if( nullableValue )
3183                 nullableValue->~T();
3184             nullableValue = CATCH_NULL;
3185         }
3186 
operator *()3187         T& operator*() { return *nullableValue; }
operator *() const3188         T const& operator*() const { return *nullableValue; }
operator ->()3189         T* operator->() { return nullableValue; }
operator ->() const3190         const T* operator->() const { return nullableValue; }
3191 
valueOr(T const & defaultValue) const3192         T valueOr( T const& defaultValue ) const {
3193             return nullableValue ? *nullableValue : defaultValue;
3194         }
3195 
some() const3196         bool some() const { return nullableValue != CATCH_NULL; }
none() const3197         bool none() const { return nullableValue == CATCH_NULL; }
3198 
operator !() const3199         bool operator !() const { return nullableValue == CATCH_NULL; }
operator SafeBool::type() const3200         operator SafeBool::type() const {
3201             return SafeBool::makeSafe( some() );
3202         }
3203 
3204     private:
3205         T *nullableValue;
3206         union {
3207             char storage[sizeof(T)];
3208 
3209             // These are here to force alignment for the storage
3210             long double dummy1;
3211             void (*dummy2)();
3212             long double dummy3;
3213 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
3214             long long dummy4;
3215 #endif
3216         };
3217     };
3218 
3219 } // end namespace Catch
3220 
3221 namespace Catch {
3222 
3223     struct ITagAliasRegistry {
3224         virtual ~ITagAliasRegistry();
3225         virtual Option<TagAlias> find( std::string const& alias ) const = 0;
3226         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
3227 
3228         static ITagAliasRegistry const& get();
3229     };
3230 
3231 } // end namespace Catch
3232 
3233 // These files are included here so the single_include script doesn't put them
3234 // in the conditionally compiled sections
3235 // #included from: internal/catch_test_case_info.h
3236 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
3237 
3238 #include <string>
3239 #include <set>
3240 
3241 #ifdef __clang__
3242 #pragma clang diagnostic push
3243 #pragma clang diagnostic ignored "-Wpadded"
3244 #endif
3245 
3246 namespace Catch {
3247 
3248     struct ITestCase;
3249 
3250     struct TestCaseInfo {
3251         enum SpecialProperties{
3252             None = 0,
3253             IsHidden = 1 << 1,
3254             ShouldFail = 1 << 2,
3255             MayFail = 1 << 3,
3256             Throws = 1 << 4,
3257             NonPortable = 1 << 5
3258         };
3259 
3260         TestCaseInfo(   std::string const& _name,
3261                         std::string const& _className,
3262                         std::string const& _description,
3263                         std::set<std::string> const& _tags,
3264                         SourceLineInfo const& _lineInfo );
3265 
3266         TestCaseInfo( TestCaseInfo const& other );
3267 
3268         friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
3269 
3270         bool isHidden() const;
3271         bool throws() const;
3272         bool okToFail() const;
3273         bool expectedToFail() const;
3274 
3275         std::string name;
3276         std::string className;
3277         std::string description;
3278         std::set<std::string> tags;
3279         std::set<std::string> lcaseTags;
3280         std::string tagsAsString;
3281         SourceLineInfo lineInfo;
3282         SpecialProperties properties;
3283     };
3284 
3285     class TestCase : public TestCaseInfo {
3286     public:
3287 
3288         TestCase( ITestCase* testCase, TestCaseInfo const& info );
3289         TestCase( TestCase const& other );
3290 
3291         TestCase withName( std::string const& _newName ) const;
3292 
3293         void invoke() const;
3294 
3295         TestCaseInfo const& getTestCaseInfo() const;
3296 
3297         void swap( TestCase& other );
3298         bool operator == ( TestCase const& other ) const;
3299         bool operator < ( TestCase const& other ) const;
3300         TestCase& operator = ( TestCase const& other );
3301 
3302     private:
3303         Ptr<ITestCase> test;
3304     };
3305 
3306     TestCase makeTestCase(  ITestCase* testCase,
3307                             std::string const& className,
3308                             std::string const& name,
3309                             std::string const& description,
3310                             SourceLineInfo const& lineInfo );
3311 }
3312 
3313 #ifdef __clang__
3314 #pragma clang diagnostic pop
3315 #endif
3316 
3317 
3318 #ifdef __OBJC__
3319 // #included from: internal/catch_objc.hpp
3320 #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
3321 
3322 #import <objc/runtime.h>
3323 
3324 #include <string>
3325 
3326 // NB. Any general catch headers included here must be included
3327 // in catch.hpp first to make sure they are included by the single
3328 // header for non obj-usage
3329 
3330 ///////////////////////////////////////////////////////////////////////////////
3331 // This protocol is really only here for (self) documenting purposes, since
3332 // all its methods are optional.
3333 @protocol OcFixture
3334 
3335 @optional
3336 
3337 -(void) setUp;
3338 -(void) tearDown;
3339 
3340 @end
3341 
3342 namespace Catch {
3343 
3344     class OcMethod : public SharedImpl<ITestCase> {
3345 
3346     public:
OcMethod(Class cls,SEL sel)3347         OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
3348 
invoke() const3349         virtual void invoke() const {
3350             id obj = [[m_cls alloc] init];
3351 
3352             performOptionalSelector( obj, @selector(setUp)  );
3353             performOptionalSelector( obj, m_sel );
3354             performOptionalSelector( obj, @selector(tearDown)  );
3355 
3356             arcSafeRelease( obj );
3357         }
3358     private:
~OcMethod()3359         virtual ~OcMethod() {}
3360 
3361         Class m_cls;
3362         SEL m_sel;
3363     };
3364 
3365     namespace Detail{
3366 
getAnnotation(Class cls,std::string const & annotationName,std::string const & testCaseName)3367         inline std::string getAnnotation(   Class cls,
3368                                             std::string const& annotationName,
3369                                             std::string const& testCaseName ) {
3370             NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
3371             SEL sel = NSSelectorFromString( selStr );
3372             arcSafeRelease( selStr );
3373             id value = performOptionalSelector( cls, sel );
3374             if( value )
3375                 return [(NSString*)value UTF8String];
3376             return "";
3377         }
3378     }
3379 
registerTestMethods()3380     inline size_t registerTestMethods() {
3381         size_t noTestMethods = 0;
3382         int noClasses = objc_getClassList( CATCH_NULL, 0 );
3383 
3384         Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
3385         objc_getClassList( classes, noClasses );
3386 
3387         for( int c = 0; c < noClasses; c++ ) {
3388             Class cls = classes[c];
3389             {
3390                 u_int count;
3391                 Method* methods = class_copyMethodList( cls, &count );
3392                 for( u_int m = 0; m < count ; m++ ) {
3393                     SEL selector = method_getName(methods[m]);
3394                     std::string methodName = sel_getName(selector);
3395                     if( startsWith( methodName, "Catch_TestCase_" ) ) {
3396                         std::string testCaseName = methodName.substr( 15 );
3397                         std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
3398                         std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
3399                         const char* className = class_getName( cls );
3400 
3401                         getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
3402                         noTestMethods++;
3403                     }
3404                 }
3405                 free(methods);
3406             }
3407         }
3408         return noTestMethods;
3409     }
3410 
3411     namespace Matchers {
3412         namespace Impl {
3413         namespace NSStringMatchers {
3414 
3415             struct StringHolder : MatcherBase<NSString*>{
StringHolderCatch::Matchers::Impl::NSStringMatchers::StringHolder3416                 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
StringHolderCatch::Matchers::Impl::NSStringMatchers::StringHolder3417                 StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
StringHolderCatch::Matchers::Impl::NSStringMatchers::StringHolder3418                 StringHolder() {
3419                     arcSafeRelease( m_substr );
3420                 }
3421 
matchCatch::Matchers::Impl::NSStringMatchers::StringHolder3422                 virtual bool match( NSString* arg ) const CATCH_OVERRIDE {
3423                     return false;
3424                 }
3425 
3426                 NSString* m_substr;
3427             };
3428 
3429             struct Equals : StringHolder {
EqualsCatch::Matchers::Impl::NSStringMatchers::Equals3430                 Equals( NSString* substr ) : StringHolder( substr ){}
3431 
matchCatch::Matchers::Impl::NSStringMatchers::Equals3432                 virtual bool match( NSString* str ) const CATCH_OVERRIDE {
3433                     return  (str != nil || m_substr == nil ) &&
3434                             [str isEqualToString:m_substr];
3435                 }
3436 
describeCatch::Matchers::Impl::NSStringMatchers::Equals3437                 virtual std::string describe() const CATCH_OVERRIDE {
3438                     return "equals string: " + Catch::toString( m_substr );
3439                 }
3440             };
3441 
3442             struct Contains : StringHolder {
ContainsCatch::Matchers::Impl::NSStringMatchers::Contains3443                 Contains( NSString* substr ) : StringHolder( substr ){}
3444 
matchCatch::Matchers::Impl::NSStringMatchers::Contains3445                 virtual bool match( NSString* str ) const {
3446                     return  (str != nil || m_substr == nil ) &&
3447                             [str rangeOfString:m_substr].location != NSNotFound;
3448                 }
3449 
describeCatch::Matchers::Impl::NSStringMatchers::Contains3450                 virtual std::string describe() const CATCH_OVERRIDE {
3451                     return "contains string: " + Catch::toString( m_substr );
3452                 }
3453             };
3454 
3455             struct StartsWith : StringHolder {
StartsWithCatch::Matchers::Impl::NSStringMatchers::StartsWith3456                 StartsWith( NSString* substr ) : StringHolder( substr ){}
3457 
matchCatch::Matchers::Impl::NSStringMatchers::StartsWith3458                 virtual bool match( NSString* str ) const {
3459                     return  (str != nil || m_substr == nil ) &&
3460                             [str rangeOfString:m_substr].location == 0;
3461                 }
3462 
describeCatch::Matchers::Impl::NSStringMatchers::StartsWith3463                 virtual std::string describe() const CATCH_OVERRIDE {
3464                     return "starts with: " + Catch::toString( m_substr );
3465                 }
3466             };
3467             struct EndsWith : StringHolder {
EndsWithCatch::Matchers::Impl::NSStringMatchers::EndsWith3468                 EndsWith( NSString* substr ) : StringHolder( substr ){}
3469 
matchCatch::Matchers::Impl::NSStringMatchers::EndsWith3470                 virtual bool match( NSString* str ) const {
3471                     return  (str != nil || m_substr == nil ) &&
3472                             [str rangeOfString:m_substr].location == [str length] - [m_substr length];
3473                 }
3474 
describeCatch::Matchers::Impl::NSStringMatchers::EndsWith3475                 virtual std::string describe() const CATCH_OVERRIDE {
3476                     return "ends with: " + Catch::toString( m_substr );
3477                 }
3478             };
3479 
3480         } // namespace NSStringMatchers
3481         } // namespace Impl
3482 
3483         inline Impl::NSStringMatchers::Equals
Equals(NSString * substr)3484             Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
3485 
3486         inline Impl::NSStringMatchers::Contains
Contains(NSString * substr)3487             Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
3488 
3489         inline Impl::NSStringMatchers::StartsWith
StartsWith(NSString * substr)3490             StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
3491 
3492         inline Impl::NSStringMatchers::EndsWith
EndsWith(NSString * substr)3493             EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
3494 
3495     } // namespace Matchers
3496 
3497     using namespace Matchers;
3498 
3499 } // namespace Catch
3500 
3501 ///////////////////////////////////////////////////////////////////////////////
3502 #define OC_TEST_CASE( name, desc )\
3503 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
3504 {\
3505 return @ name; \
3506 }\
3507 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
3508 { \
3509 return @ desc; \
3510 } \
3511 -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
3512 
3513 #endif
3514 
3515 #ifdef CATCH_IMPL
3516 
3517 // !TBD: Move the leak detector code into a separate header
3518 #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
3519 #include <crtdbg.h>
3520 class LeakDetector {
3521 public:
LeakDetector()3522     LeakDetector() {
3523         int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
3524         flag |= _CRTDBG_LEAK_CHECK_DF;
3525         flag |= _CRTDBG_ALLOC_MEM_DF;
3526         _CrtSetDbgFlag(flag);
3527         _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
3528         _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
3529         // Change this to leaking allocation's number to break there
3530         _CrtSetBreakAlloc(-1);
3531     }
3532 };
3533 #else
3534 class LeakDetector {};
3535 #endif
3536 
3537 LeakDetector leakDetector;
3538 
3539 // #included from: internal/catch_impl.hpp
3540 #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
3541 
3542 // Collect all the implementation files together here
3543 // These are the equivalent of what would usually be cpp files
3544 
3545 #ifdef __clang__
3546 #pragma clang diagnostic push
3547 #pragma clang diagnostic ignored "-Wweak-vtables"
3548 #endif
3549 
3550 // #included from: ../catch_session.hpp
3551 #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
3552 
3553 // #included from: internal/catch_commandline.hpp
3554 #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
3555 
3556 // #included from: catch_config.hpp
3557 #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
3558 
3559 // #included from: catch_test_spec_parser.hpp
3560 #define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
3561 
3562 #ifdef __clang__
3563 #pragma clang diagnostic push
3564 #pragma clang diagnostic ignored "-Wpadded"
3565 #endif
3566 
3567 // #included from: catch_test_spec.hpp
3568 #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
3569 
3570 #ifdef __clang__
3571 #pragma clang diagnostic push
3572 #pragma clang diagnostic ignored "-Wpadded"
3573 #endif
3574 
3575 // #included from: catch_wildcard_pattern.hpp
3576 #define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3577 
3578 #include <stdexcept>
3579 
3580 namespace Catch
3581 {
3582     class WildcardPattern {
3583         enum WildcardPosition {
3584             NoWildcard = 0,
3585             WildcardAtStart = 1,
3586             WildcardAtEnd = 2,
3587             WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
3588         };
3589 
3590     public:
3591 
WildcardPattern(std::string const & pattern,CaseSensitive::Choice caseSensitivity)3592         WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
3593         :   m_caseSensitivity( caseSensitivity ),
3594             m_wildcard( NoWildcard ),
3595             m_pattern( adjustCase( pattern ) )
3596         {
3597             if( startsWith( m_pattern, '*' ) ) {
3598                 m_pattern = m_pattern.substr( 1 );
3599                 m_wildcard = WildcardAtStart;
3600             }
3601             if( endsWith( m_pattern, '*' ) ) {
3602                 m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
3603                 m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
3604             }
3605         }
3606         virtual ~WildcardPattern();
matches(std::string const & str) const3607         virtual bool matches( std::string const& str ) const {
3608             switch( m_wildcard ) {
3609                 case NoWildcard:
3610                     return m_pattern == adjustCase( str );
3611                 case WildcardAtStart:
3612                     return endsWith( adjustCase( str ), m_pattern );
3613                 case WildcardAtEnd:
3614                     return startsWith( adjustCase( str ), m_pattern );
3615                 case WildcardAtBothEnds:
3616                     return contains( adjustCase( str ), m_pattern );
3617             }
3618 
3619 #ifdef __clang__
3620 #pragma clang diagnostic push
3621 #pragma clang diagnostic ignored "-Wunreachable-code"
3622 #endif
3623             throw std::logic_error( "Unknown enum" );
3624 #ifdef __clang__
3625 #pragma clang diagnostic pop
3626 #endif
3627         }
3628     private:
adjustCase(std::string const & str) const3629         std::string adjustCase( std::string const& str ) const {
3630             return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
3631         }
3632         CaseSensitive::Choice m_caseSensitivity;
3633         WildcardPosition m_wildcard;
3634         std::string m_pattern;
3635     };
3636 }
3637 
3638 #include <string>
3639 #include <vector>
3640 
3641 namespace Catch {
3642 
3643     class TestSpec {
3644         struct Pattern : SharedImpl<> {
3645             virtual ~Pattern();
3646             virtual bool matches( TestCaseInfo const& testCase ) const = 0;
3647         };
3648         class NamePattern : public Pattern {
3649         public:
NamePattern(std::string const & name)3650             NamePattern( std::string const& name )
3651             : m_wildcardPattern( toLower( name ), CaseSensitive::No )
3652             {}
3653             virtual ~NamePattern();
matches(TestCaseInfo const & testCase) const3654             virtual bool matches( TestCaseInfo const& testCase ) const {
3655                 return m_wildcardPattern.matches( toLower( testCase.name ) );
3656             }
3657         private:
3658             WildcardPattern m_wildcardPattern;
3659         };
3660 
3661         class TagPattern : public Pattern {
3662         public:
TagPattern(std::string const & tag)3663             TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
3664             virtual ~TagPattern();
matches(TestCaseInfo const & testCase) const3665             virtual bool matches( TestCaseInfo const& testCase ) const {
3666                 return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
3667             }
3668         private:
3669             std::string m_tag;
3670         };
3671 
3672         class ExcludedPattern : public Pattern {
3673         public:
ExcludedPattern(Ptr<Pattern> const & underlyingPattern)3674             ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
3675             virtual ~ExcludedPattern();
matches(TestCaseInfo const & testCase) const3676             virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
3677         private:
3678             Ptr<Pattern> m_underlyingPattern;
3679         };
3680 
3681         struct Filter {
3682             std::vector<Ptr<Pattern> > m_patterns;
3683 
matchesCatch::TestSpec::Filter3684             bool matches( TestCaseInfo const& testCase ) const {
3685                 // All patterns in a filter must match for the filter to be a match
3686                 for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) {
3687                     if( !(*it)->matches( testCase ) )
3688                         return false;
3689                 }
3690                 return true;
3691             }
3692         };
3693 
3694     public:
hasFilters() const3695         bool hasFilters() const {
3696             return !m_filters.empty();
3697         }
matches(TestCaseInfo const & testCase) const3698         bool matches( TestCaseInfo const& testCase ) const {
3699             // A TestSpec matches if any filter matches
3700             for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
3701                 if( it->matches( testCase ) )
3702                     return true;
3703             return false;
3704         }
3705 
3706     private:
3707         std::vector<Filter> m_filters;
3708 
3709         friend class TestSpecParser;
3710     };
3711 }
3712 
3713 #ifdef __clang__
3714 #pragma clang diagnostic pop
3715 #endif
3716 
3717 namespace Catch {
3718 
3719     class TestSpecParser {
3720         enum Mode{ None, Name, QuotedName, Tag, EscapedName };
3721         Mode m_mode;
3722         bool m_exclusion;
3723         std::size_t m_start, m_pos;
3724         std::string m_arg;
3725         std::vector<std::size_t> m_escapeChars;
3726         TestSpec::Filter m_currentFilter;
3727         TestSpec m_testSpec;
3728         ITagAliasRegistry const* m_tagAliases;
3729 
3730     public:
TestSpecParser(ITagAliasRegistry const & tagAliases)3731         TestSpecParser( ITagAliasRegistry const& tagAliases ) :m_mode(None), m_exclusion(false), m_start(0), m_pos(0), m_tagAliases( &tagAliases ) {}
3732 
parse(std::string const & arg)3733         TestSpecParser& parse( std::string const& arg ) {
3734             m_mode = None;
3735             m_exclusion = false;
3736             m_start = std::string::npos;
3737             m_arg = m_tagAliases->expandAliases( arg );
3738             m_escapeChars.clear();
3739             for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
3740                 visitChar( m_arg[m_pos] );
3741             if( m_mode == Name )
3742                 addPattern<TestSpec::NamePattern>();
3743             return *this;
3744         }
testSpec()3745         TestSpec testSpec() {
3746             addFilter();
3747             return m_testSpec;
3748         }
3749     private:
visitChar(char c)3750         void visitChar( char c ) {
3751             if( m_mode == None ) {
3752                 switch( c ) {
3753                 case ' ': return;
3754                 case '~': m_exclusion = true; return;
3755                 case '[': return startNewMode( Tag, ++m_pos );
3756                 case '"': return startNewMode( QuotedName, ++m_pos );
3757                 case '\\': return escape();
3758                 default: startNewMode( Name, m_pos ); break;
3759                 }
3760             }
3761             if( m_mode == Name ) {
3762                 if( c == ',' ) {
3763                     addPattern<TestSpec::NamePattern>();
3764                     addFilter();
3765                 }
3766                 else if( c == '[' ) {
3767                     if( subString() == "exclude:" )
3768                         m_exclusion = true;
3769                     else
3770                         addPattern<TestSpec::NamePattern>();
3771                     startNewMode( Tag, ++m_pos );
3772                 }
3773                 else if( c == '\\' )
3774                     escape();
3775             }
3776             else if( m_mode == EscapedName )
3777                 m_mode = Name;
3778             else if( m_mode == QuotedName && c == '"' )
3779                 addPattern<TestSpec::NamePattern>();
3780             else if( m_mode == Tag && c == ']' )
3781                 addPattern<TestSpec::TagPattern>();
3782         }
startNewMode(Mode mode,std::size_t start)3783         void startNewMode( Mode mode, std::size_t start ) {
3784             m_mode = mode;
3785             m_start = start;
3786         }
escape()3787         void escape() {
3788             if( m_mode == None )
3789                 m_start = m_pos;
3790             m_mode = EscapedName;
3791             m_escapeChars.push_back( m_pos );
3792         }
subString() const3793         std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
3794         template<typename T>
addPattern()3795         void addPattern() {
3796             std::string token = subString();
3797             for( size_t i = 0; i < m_escapeChars.size(); ++i )
3798                 token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
3799             m_escapeChars.clear();
3800             if( startsWith( token, "exclude:" ) ) {
3801                 m_exclusion = true;
3802                 token = token.substr( 8 );
3803             }
3804             if( !token.empty() ) {
3805                 Ptr<TestSpec::Pattern> pattern = new T( token );
3806                 if( m_exclusion )
3807                     pattern = new TestSpec::ExcludedPattern( pattern );
3808                 m_currentFilter.m_patterns.push_back( pattern );
3809             }
3810             m_exclusion = false;
3811             m_mode = None;
3812         }
addFilter()3813         void addFilter() {
3814             if( !m_currentFilter.m_patterns.empty() ) {
3815                 m_testSpec.m_filters.push_back( m_currentFilter );
3816                 m_currentFilter = TestSpec::Filter();
3817             }
3818         }
3819     };
parseTestSpec(std::string const & arg)3820     inline TestSpec parseTestSpec( std::string const& arg ) {
3821         return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
3822     }
3823 
3824 } // namespace Catch
3825 
3826 #ifdef __clang__
3827 #pragma clang diagnostic pop
3828 #endif
3829 
3830 // #included from: catch_interfaces_config.h
3831 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
3832 
3833 #include <iosfwd>
3834 #include <string>
3835 #include <vector>
3836 
3837 namespace Catch {
3838 
3839     struct Verbosity { enum Level {
3840         NoOutput = 0,
3841         Quiet,
3842         Normal
3843     }; };
3844 
3845     struct WarnAbout { enum What {
3846         Nothing = 0x00,
3847         NoAssertions = 0x01
3848     }; };
3849 
3850     struct ShowDurations { enum OrNot {
3851         DefaultForReporter,
3852         Always,
3853         Never
3854     }; };
3855     struct RunTests { enum InWhatOrder {
3856         InDeclarationOrder,
3857         InLexicographicalOrder,
3858         InRandomOrder
3859     }; };
3860     struct UseColour { enum YesOrNo {
3861         Auto,
3862         Yes,
3863         No
3864     }; };
3865     struct WaitForKeypress { enum When {
3866         Never,
3867         BeforeStart = 1,
3868         BeforeExit = 2,
3869         BeforeStartAndExit = BeforeStart | BeforeExit
3870     }; };
3871 
3872     class TestSpec;
3873 
3874     struct IConfig : IShared {
3875 
3876         virtual ~IConfig();
3877 
3878         virtual bool allowThrows() const = 0;
3879         virtual std::ostream& stream() const = 0;
3880         virtual std::string name() const = 0;
3881         virtual bool includeSuccessfulResults() const = 0;
3882         virtual bool shouldDebugBreak() const = 0;
3883         virtual bool warnAboutMissingAssertions() const = 0;
3884         virtual int abortAfter() const = 0;
3885         virtual bool showInvisibles() const = 0;
3886         virtual ShowDurations::OrNot showDurations() const = 0;
3887         virtual TestSpec const& testSpec() const = 0;
3888         virtual RunTests::InWhatOrder runOrder() const = 0;
3889         virtual unsigned int rngSeed() const = 0;
3890         virtual UseColour::YesOrNo useColour() const = 0;
3891         virtual std::vector<std::string> const& getSectionsToRun() const = 0;
3892 
3893     };
3894 }
3895 
3896 // #included from: catch_stream.h
3897 #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
3898 
3899 // #included from: catch_streambuf.h
3900 #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
3901 
3902 #include <streambuf>
3903 
3904 namespace Catch {
3905 
3906     class StreamBufBase : public std::streambuf {
3907     public:
3908         virtual ~StreamBufBase() CATCH_NOEXCEPT;
3909     };
3910 }
3911 
3912 #include <streambuf>
3913 #include <ostream>
3914 #include <fstream>
3915 #include <memory>
3916 
3917 namespace Catch {
3918 
3919     std::ostream& cout();
3920     std::ostream& cerr();
3921     std::ostream& clog();
3922 
3923     struct IStream {
3924         virtual ~IStream() CATCH_NOEXCEPT;
3925         virtual std::ostream& stream() const = 0;
3926     };
3927 
3928     class FileStream : public IStream {
3929         mutable std::ofstream m_ofs;
3930     public:
3931         FileStream( std::string const& filename );
3932         virtual ~FileStream() CATCH_NOEXCEPT;
3933     public: // IStream
3934         virtual std::ostream& stream() const CATCH_OVERRIDE;
3935     };
3936 
3937     class CoutStream : public IStream {
3938         mutable std::ostream m_os;
3939     public:
3940         CoutStream();
3941         virtual ~CoutStream() CATCH_NOEXCEPT;
3942 
3943     public: // IStream
3944         virtual std::ostream& stream() const CATCH_OVERRIDE;
3945     };
3946 
3947     class DebugOutStream : public IStream {
3948         CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf;
3949         mutable std::ostream m_os;
3950     public:
3951         DebugOutStream();
3952         virtual ~DebugOutStream() CATCH_NOEXCEPT;
3953 
3954     public: // IStream
3955         virtual std::ostream& stream() const CATCH_OVERRIDE;
3956     };
3957 }
3958 
3959 #include <memory>
3960 #include <vector>
3961 #include <string>
3962 #include <stdexcept>
3963 
3964 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
3965 #define CATCH_CONFIG_CONSOLE_WIDTH 80
3966 #endif
3967 
3968 namespace Catch {
3969 
3970     struct ConfigData {
3971 
ConfigDataCatch::ConfigData3972         ConfigData()
3973         :   listTests( false ),
3974             listTags( false ),
3975             listReporters( false ),
3976             listTestNamesOnly( false ),
3977             listExtraInfo( false ),
3978             showSuccessfulTests( false ),
3979             shouldDebugBreak( false ),
3980             noThrow( false ),
3981             showHelp( false ),
3982             showInvisibles( false ),
3983             filenamesAsTags( false ),
3984             libIdentify( false ),
3985             abortAfter( -1 ),
3986             rngSeed( 0 ),
3987             verbosity( Verbosity::Normal ),
3988             warnings( WarnAbout::Nothing ),
3989             showDurations( ShowDurations::DefaultForReporter ),
3990             runOrder( RunTests::InDeclarationOrder ),
3991             useColour( UseColour::Auto ),
3992             waitForKeypress( WaitForKeypress::Never )
3993         {}
3994 
3995         bool listTests;
3996         bool listTags;
3997         bool listReporters;
3998         bool listTestNamesOnly;
3999         bool listExtraInfo;
4000 
4001         bool showSuccessfulTests;
4002         bool shouldDebugBreak;
4003         bool noThrow;
4004         bool showHelp;
4005         bool showInvisibles;
4006         bool filenamesAsTags;
4007         bool libIdentify;
4008 
4009         int abortAfter;
4010         unsigned int rngSeed;
4011 
4012         Verbosity::Level verbosity;
4013         WarnAbout::What warnings;
4014         ShowDurations::OrNot showDurations;
4015         RunTests::InWhatOrder runOrder;
4016         UseColour::YesOrNo useColour;
4017         WaitForKeypress::When waitForKeypress;
4018 
4019         std::string outputFilename;
4020         std::string name;
4021         std::string processName;
4022 
4023         std::vector<std::string> reporterNames;
4024         std::vector<std::string> testsOrTags;
4025         std::vector<std::string> sectionsToRun;
4026     };
4027 
4028     class Config : public SharedImpl<IConfig> {
4029     private:
4030         Config( Config const& other );
4031         Config& operator = ( Config const& other );
4032         virtual void dummy();
4033     public:
4034 
Config()4035         Config()
4036         {}
4037 
Config(ConfigData const & data)4038         Config( ConfigData const& data )
4039         :   m_data( data ),
4040             m_stream( openStream() )
4041         {
4042             if( !data.testsOrTags.empty() ) {
4043                 TestSpecParser parser( ITagAliasRegistry::get() );
4044                 for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
4045                     parser.parse( data.testsOrTags[i] );
4046                 m_testSpec = parser.testSpec();
4047             }
4048         }
4049 
~Config()4050         virtual ~Config() {}
4051 
getFilename() const4052         std::string const& getFilename() const {
4053             return m_data.outputFilename ;
4054         }
4055 
listTests() const4056         bool listTests() const { return m_data.listTests; }
listTestNamesOnly() const4057         bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
listTags() const4058         bool listTags() const { return m_data.listTags; }
listReporters() const4059         bool listReporters() const { return m_data.listReporters; }
listExtraInfo() const4060         bool listExtraInfo() const { return m_data.listExtraInfo; }
4061 
getProcessName() const4062         std::string getProcessName() const { return m_data.processName; }
4063 
getReporterNames() const4064         std::vector<std::string> const& getReporterNames() const { return m_data.reporterNames; }
getSectionsToRun() const4065         std::vector<std::string> const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; }
4066 
testSpec() const4067         virtual TestSpec const& testSpec() const CATCH_OVERRIDE { return m_testSpec; }
4068 
showHelp() const4069         bool showHelp() const { return m_data.showHelp; }
4070 
4071         // IConfig interface
allowThrows() const4072         virtual bool allowThrows() const CATCH_OVERRIDE                 { return !m_data.noThrow; }
stream() const4073         virtual std::ostream& stream() const CATCH_OVERRIDE             { return m_stream->stream(); }
name() const4074         virtual std::string name() const CATCH_OVERRIDE                 { return m_data.name.empty() ? m_data.processName : m_data.name; }
includeSuccessfulResults() const4075         virtual bool includeSuccessfulResults() const CATCH_OVERRIDE    { return m_data.showSuccessfulTests; }
warnAboutMissingAssertions() const4076         virtual bool warnAboutMissingAssertions() const CATCH_OVERRIDE  { return m_data.warnings & WarnAbout::NoAssertions; }
showDurations() const4077         virtual ShowDurations::OrNot showDurations() const CATCH_OVERRIDE { return m_data.showDurations; }
runOrder() const4078         virtual RunTests::InWhatOrder runOrder() const CATCH_OVERRIDE   { return m_data.runOrder; }
rngSeed() const4079         virtual unsigned int rngSeed() const CATCH_OVERRIDE             { return m_data.rngSeed; }
useColour() const4080         virtual UseColour::YesOrNo useColour() const CATCH_OVERRIDE     { return m_data.useColour; }
shouldDebugBreak() const4081         virtual bool shouldDebugBreak() const CATCH_OVERRIDE { return m_data.shouldDebugBreak; }
abortAfter() const4082         virtual int abortAfter() const CATCH_OVERRIDE { return m_data.abortAfter; }
showInvisibles() const4083         virtual bool showInvisibles() const CATCH_OVERRIDE { return m_data.showInvisibles; }
4084 
4085     private:
4086 
openStream()4087         IStream const* openStream() {
4088             if( m_data.outputFilename.empty() )
4089                 return new CoutStream();
4090             else if( m_data.outputFilename[0] == '%' ) {
4091                 if( m_data.outputFilename == "%debug" )
4092                     return new DebugOutStream();
4093                 else
4094                     throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
4095             }
4096             else
4097                 return new FileStream( m_data.outputFilename );
4098         }
4099         ConfigData m_data;
4100 
4101         CATCH_AUTO_PTR( IStream const ) m_stream;
4102         TestSpec m_testSpec;
4103     };
4104 
4105 } // end namespace Catch
4106 
4107 // #included from: catch_clara.h
4108 #define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
4109 
4110 // Use Catch's value for console width (store Clara's off to the side, if present)
4111 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
4112 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
4113 #undef CLARA_CONFIG_CONSOLE_WIDTH
4114 #endif
4115 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
4116 
4117 // Declare Clara inside the Catch namespace
4118 #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
4119 // #included from: ../external/clara.h
4120 
4121 // Version 0.0.2.4
4122 
4123 // Only use header guard if we are not using an outer namespace
4124 #if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
4125 
4126 #ifndef STITCH_CLARA_OPEN_NAMESPACE
4127 #define TWOBLUECUBES_CLARA_H_INCLUDED
4128 #define STITCH_CLARA_OPEN_NAMESPACE
4129 #define STITCH_CLARA_CLOSE_NAMESPACE
4130 #else
4131 #define STITCH_CLARA_CLOSE_NAMESPACE }
4132 #endif
4133 
4134 #define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
4135 
4136 // ----------- #included from tbc_text_format.h -----------
4137 
4138 // Only use header guard if we are not using an outer namespace
4139 #if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
4140 #ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4141 #define TBC_TEXT_FORMAT_H_INCLUDED
4142 #endif
4143 
4144 #include <string>
4145 #include <vector>
4146 #include <sstream>
4147 #include <algorithm>
4148 #include <cctype>
4149 
4150 // Use optional outer namespace
4151 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4152 namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
4153 #endif
4154 
4155 namespace Tbc {
4156 
4157 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
4158     const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
4159 #else
4160     const unsigned int consoleWidth = 80;
4161 #endif
4162 
4163     struct TextAttributes {
TextAttributesSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4164         TextAttributes()
4165         :   initialIndent( std::string::npos ),
4166             indent( 0 ),
4167             width( consoleWidth-1 ),
4168             tabChar( '\t' )
4169         {}
4170 
setInitialIndentSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4171         TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
setIndentSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4172         TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
setWidthSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4173         TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
setTabCharSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4174         TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }
4175 
4176         std::size_t initialIndent;  // indent of first line, or npos
4177         std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
4178         std::size_t width;          // maximum width of text, including indent. Longer text will wrap
4179         char tabChar;               // If this char is seen the indent is changed to current pos
4180     };
4181 
4182     class Text {
4183     public:
Text(std::string const & _str,TextAttributes const & _attr=TextAttributes ())4184         Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
4185         : attr( _attr )
4186         {
4187             std::string wrappableChars = " [({.,/|\\-";
4188             std::size_t indent = _attr.initialIndent != std::string::npos
4189                 ? _attr.initialIndent
4190                 : _attr.indent;
4191             std::string remainder = _str;
4192 
4193             while( !remainder.empty() ) {
4194                 if( lines.size() >= 1000 ) {
4195                     lines.push_back( "... message truncated due to excessive size" );
4196                     return;
4197                 }
4198                 std::size_t tabPos = std::string::npos;
4199                 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
4200                 std::size_t pos = remainder.find_first_of( '\n' );
4201                 if( pos <= width ) {
4202                     width = pos;
4203                 }
4204                 pos = remainder.find_last_of( _attr.tabChar, width );
4205                 if( pos != std::string::npos ) {
4206                     tabPos = pos;
4207                     if( remainder[width] == '\n' )
4208                         width--;
4209                     remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
4210                 }
4211 
4212                 if( width == remainder.size() ) {
4213                     spliceLine( indent, remainder, width );
4214                 }
4215                 else if( remainder[width] == '\n' ) {
4216                     spliceLine( indent, remainder, width );
4217                     if( width <= 1 || remainder.size() != 1 )
4218                         remainder = remainder.substr( 1 );
4219                     indent = _attr.indent;
4220                 }
4221                 else {
4222                     pos = remainder.find_last_of( wrappableChars, width );
4223                     if( pos != std::string::npos && pos > 0 ) {
4224                         spliceLine( indent, remainder, pos );
4225                         if( remainder[0] == ' ' )
4226                             remainder = remainder.substr( 1 );
4227                     }
4228                     else {
4229                         spliceLine( indent, remainder, width-1 );
4230                         lines.back() += "-";
4231                     }
4232                     if( lines.size() == 1 )
4233                         indent = _attr.indent;
4234                     if( tabPos != std::string::npos )
4235                         indent += tabPos;
4236                 }
4237             }
4238         }
4239 
spliceLine(std::size_t _indent,std::string & _remainder,std::size_t _pos)4240         void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
4241             lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
4242             _remainder = _remainder.substr( _pos );
4243         }
4244 
4245         typedef std::vector<std::string>::const_iterator const_iterator;
4246 
begin() const4247         const_iterator begin() const { return lines.begin(); }
end() const4248         const_iterator end() const { return lines.end(); }
last() const4249         std::string const& last() const { return lines.back(); }
size() const4250         std::size_t size() const { return lines.size(); }
operator [](std::size_t _index) const4251         std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
toString() const4252         std::string toString() const {
4253             std::ostringstream oss;
4254             oss << *this;
4255             return oss.str();
4256         }
4257 
operator <<(std::ostream & _stream,Text const & _text)4258         friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
4259             for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
4260                 it != itEnd; ++it ) {
4261                 if( it != _text.begin() )
4262                     _stream << "\n";
4263                 _stream << *it;
4264             }
4265             return _stream;
4266         }
4267 
4268     private:
4269         std::string str;
4270         TextAttributes attr;
4271         std::vector<std::string> lines;
4272     };
4273 
4274 } // end namespace Tbc
4275 
4276 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4277 } // end outer namespace
4278 #endif
4279 
4280 #endif // TBC_TEXT_FORMAT_H_INCLUDED
4281 
4282 // ----------- end of #include from tbc_text_format.h -----------
4283 // ........... back in clara.h
4284 
4285 #undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
4286 
4287 // ----------- #included from clara_compilers.h -----------
4288 
4289 #ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
4290 #define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
4291 
4292 // Detect a number of compiler features - mostly C++11/14 conformance - by compiler
4293 // The following features are defined:
4294 //
4295 // CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported?
4296 // CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
4297 // CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
4298 // CLARA_CONFIG_CPP11_OVERRIDE : is override supported?
4299 // CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
4300 
4301 // CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
4302 
4303 // CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported?
4304 
4305 // In general each macro has a _NO_<feature name> form
4306 // (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
4307 // Many features, at point of detection, define an _INTERNAL_ macro, so they
4308 // can be combined, en-mass, with the _NO_ forms later.
4309 
4310 // All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11
4311 
4312 #ifdef __clang__
4313 
4314 #if __has_feature(cxx_nullptr)
4315 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
4316 #endif
4317 
4318 #if __has_feature(cxx_noexcept)
4319 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
4320 #endif
4321 
4322 #endif // __clang__
4323 
4324 ////////////////////////////////////////////////////////////////////////////////
4325 // GCC
4326 #ifdef __GNUC__
4327 
4328 #if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
4329 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
4330 #endif
4331 
4332 // - otherwise more recent versions define __cplusplus >= 201103L
4333 // and will get picked up below
4334 
4335 #endif // __GNUC__
4336 
4337 ////////////////////////////////////////////////////////////////////////////////
4338 // Visual C++
4339 #ifdef _MSC_VER
4340 
4341 #if (_MSC_VER >= 1600)
4342 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
4343 #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
4344 #endif
4345 
4346 #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
4347 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
4348 #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
4349 #endif
4350 
4351 #endif // _MSC_VER
4352 
4353 ////////////////////////////////////////////////////////////////////////////////
4354 // C++ language feature support
4355 
4356 // catch all support for C++11
4357 #if defined(__cplusplus) && __cplusplus >= 201103L
4358 
4359 #define CLARA_CPP11_OR_GREATER
4360 
4361 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)
4362 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
4363 #endif
4364 
4365 #ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
4366 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
4367 #endif
4368 
4369 #ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
4370 #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
4371 #endif
4372 
4373 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)
4374 #define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE
4375 #endif
4376 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
4377 #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
4378 #endif
4379 
4380 #endif // __cplusplus >= 201103L
4381 
4382 // Now set the actual defines based on the above + anything the user has configured
4383 #if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)
4384 #define CLARA_CONFIG_CPP11_NULLPTR
4385 #endif
4386 #if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)
4387 #define CLARA_CONFIG_CPP11_NOEXCEPT
4388 #endif
4389 #if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)
4390 #define CLARA_CONFIG_CPP11_GENERATED_METHODS
4391 #endif
4392 #if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)
4393 #define CLARA_CONFIG_CPP11_OVERRIDE
4394 #endif
4395 #if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)
4396 #define CLARA_CONFIG_CPP11_UNIQUE_PTR
4397 #endif
4398 
4399 // noexcept support:
4400 #if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)
4401 #define CLARA_NOEXCEPT noexcept
4402 #  define CLARA_NOEXCEPT_IS(x) noexcept(x)
4403 #else
4404 #define CLARA_NOEXCEPT throw()
4405 #  define CLARA_NOEXCEPT_IS(x)
4406 #endif
4407 
4408 // nullptr support
4409 #ifdef CLARA_CONFIG_CPP11_NULLPTR
4410 #define CLARA_NULL nullptr
4411 #else
4412 #define CLARA_NULL NULL
4413 #endif
4414 
4415 // override support
4416 #ifdef CLARA_CONFIG_CPP11_OVERRIDE
4417 #define CLARA_OVERRIDE override
4418 #else
4419 #define CLARA_OVERRIDE
4420 #endif
4421 
4422 // unique_ptr support
4423 #ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR
4424 #   define CLARA_AUTO_PTR( T ) std::unique_ptr<T>
4425 #else
4426 #   define CLARA_AUTO_PTR( T ) std::auto_ptr<T>
4427 #endif
4428 
4429 #endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
4430 
4431 // ----------- end of #include from clara_compilers.h -----------
4432 // ........... back in clara.h
4433 
4434 #include <map>
4435 #include <stdexcept>
4436 #include <memory>
4437 
4438 #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
4439 #define CLARA_PLATFORM_WINDOWS
4440 #endif
4441 
4442 // Use optional outer namespace
4443 #ifdef STITCH_CLARA_OPEN_NAMESPACE
4444 STITCH_CLARA_OPEN_NAMESPACE
4445 #endif
4446 
4447 namespace Clara {
4448 
4449     struct UnpositionalTag {};
4450 
4451     extern UnpositionalTag _;
4452 
4453 #ifdef CLARA_CONFIG_MAIN
4454     UnpositionalTag _;
4455 #endif
4456 
4457     namespace Detail {
4458 
4459 #ifdef CLARA_CONSOLE_WIDTH
4460     const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
4461 #else
4462     const unsigned int consoleWidth = 80;
4463 #endif
4464 
4465         using namespace Tbc;
4466 
startsWith(std::string const & str,std::string const & prefix)4467         inline bool startsWith( std::string const& str, std::string const& prefix ) {
4468             return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
4469         }
4470 
4471         template<typename T> struct RemoveConstRef{ typedef T type; };
4472         template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
4473         template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
4474         template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
4475 
4476         template<typename T>    struct IsBool       { static const bool value = false; };
4477         template<>              struct IsBool<bool> { static const bool value = true; };
4478 
4479         template<typename T>
convertInto(std::string const & _source,T & _dest)4480         void convertInto( std::string const& _source, T& _dest ) {
4481             std::stringstream ss;
4482             ss << _source;
4483             ss >> _dest;
4484             if( ss.fail() )
4485                 throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
4486         }
convertInto(std::string const & _source,std::string & _dest)4487         inline void convertInto( std::string const& _source, std::string& _dest ) {
4488             _dest = _source;
4489         }
toLowerCh(char c)4490         char toLowerCh(char c) {
4491             return static_cast<char>( std::tolower( c ) );
4492         }
convertInto(std::string const & _source,bool & _dest)4493         inline void convertInto( std::string const& _source, bool& _dest ) {
4494             std::string sourceLC = _source;
4495             std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh );
4496             if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
4497                 _dest = true;
4498             else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
4499                 _dest = false;
4500             else
4501                 throw std::runtime_error( "Expected a boolean value but did not recognise:\n  '" + _source + "'" );
4502         }
4503 
4504         template<typename ConfigT>
4505         struct IArgFunction {
~IArgFunctionClara::Detail::IArgFunction4506             virtual ~IArgFunction() {}
4507 #ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS
4508             IArgFunction()                      = default;
4509             IArgFunction( IArgFunction const& ) = default;
4510 #endif
4511             virtual void set( ConfigT& config, std::string const& value ) const = 0;
4512             virtual bool takesArg() const = 0;
4513             virtual IArgFunction* clone() const = 0;
4514         };
4515 
4516         template<typename ConfigT>
4517         class BoundArgFunction {
4518         public:
BoundArgFunction()4519             BoundArgFunction() : functionObj( CLARA_NULL ) {}
BoundArgFunction(IArgFunction<ConfigT> * _functionObj)4520             BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
BoundArgFunction(BoundArgFunction const & other)4521             BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
operator =(BoundArgFunction const & other)4522             BoundArgFunction& operator = ( BoundArgFunction const& other ) {
4523                 IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
4524                 delete functionObj;
4525                 functionObj = newFunctionObj;
4526                 return *this;
4527             }
~BoundArgFunction()4528             ~BoundArgFunction() { delete functionObj; }
4529 
set(ConfigT & config,std::string const & value) const4530             void set( ConfigT& config, std::string const& value ) const {
4531                 functionObj->set( config, value );
4532             }
takesArg() const4533             bool takesArg() const { return functionObj->takesArg(); }
4534 
isSet() const4535             bool isSet() const {
4536                 return functionObj != CLARA_NULL;
4537             }
4538         private:
4539             IArgFunction<ConfigT>* functionObj;
4540         };
4541 
4542         template<typename C>
4543         struct NullBinder : IArgFunction<C>{
setClara::Detail::NullBinder4544             virtual void set( C&, std::string const& ) const {}
takesArgClara::Detail::NullBinder4545             virtual bool takesArg() const { return true; }
cloneClara::Detail::NullBinder4546             virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
4547         };
4548 
4549         template<typename C, typename M>
4550         struct BoundDataMember : IArgFunction<C>{
BoundDataMemberClara::Detail::BoundDataMember4551             BoundDataMember( M C::* _member ) : member( _member ) {}
setClara::Detail::BoundDataMember4552             virtual void set( C& p, std::string const& stringValue ) const {
4553                 convertInto( stringValue, p.*member );
4554             }
takesArgClara::Detail::BoundDataMember4555             virtual bool takesArg() const { return !IsBool<M>::value; }
cloneClara::Detail::BoundDataMember4556             virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
4557             M C::* member;
4558         };
4559         template<typename C, typename M>
4560         struct BoundUnaryMethod : IArgFunction<C>{
BoundUnaryMethodClara::Detail::BoundUnaryMethod4561             BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
setClara::Detail::BoundUnaryMethod4562             virtual void set( C& p, std::string const& stringValue ) const {
4563                 typename RemoveConstRef<M>::type value;
4564                 convertInto( stringValue, value );
4565                 (p.*member)( value );
4566             }
takesArgClara::Detail::BoundUnaryMethod4567             virtual bool takesArg() const { return !IsBool<M>::value; }
cloneClara::Detail::BoundUnaryMethod4568             virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
4569             void (C::*member)( M );
4570         };
4571         template<typename C>
4572         struct BoundNullaryMethod : IArgFunction<C>{
BoundNullaryMethodClara::Detail::BoundNullaryMethod4573             BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
setClara::Detail::BoundNullaryMethod4574             virtual void set( C& p, std::string const& stringValue ) const {
4575                 bool value;
4576                 convertInto( stringValue, value );
4577                 if( value )
4578                     (p.*member)();
4579             }
takesArgClara::Detail::BoundNullaryMethod4580             virtual bool takesArg() const { return false; }
cloneClara::Detail::BoundNullaryMethod4581             virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
4582             void (C::*member)();
4583         };
4584 
4585         template<typename C>
4586         struct BoundUnaryFunction : IArgFunction<C>{
BoundUnaryFunctionClara::Detail::BoundUnaryFunction4587             BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
setClara::Detail::BoundUnaryFunction4588             virtual void set( C& obj, std::string const& stringValue ) const {
4589                 bool value;
4590                 convertInto( stringValue, value );
4591                 if( value )
4592                     function( obj );
4593             }
takesArgClara::Detail::BoundUnaryFunction4594             virtual bool takesArg() const { return false; }
cloneClara::Detail::BoundUnaryFunction4595             virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
4596             void (*function)( C& );
4597         };
4598 
4599         template<typename C, typename T>
4600         struct BoundBinaryFunction : IArgFunction<C>{
BoundBinaryFunctionClara::Detail::BoundBinaryFunction4601             BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
setClara::Detail::BoundBinaryFunction4602             virtual void set( C& obj, std::string const& stringValue ) const {
4603                 typename RemoveConstRef<T>::type value;
4604                 convertInto( stringValue, value );
4605                 function( obj, value );
4606             }
takesArgClara::Detail::BoundBinaryFunction4607             virtual bool takesArg() const { return !IsBool<T>::value; }
cloneClara::Detail::BoundBinaryFunction4608             virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
4609             void (*function)( C&, T );
4610         };
4611 
4612     } // namespace Detail
4613 
argsToVector(int argc,char const * const * const argv)4614     inline std::vector<std::string> argsToVector( int argc, char const* const* const argv ) {
4615         std::vector<std::string> args( static_cast<std::size_t>( argc ) );
4616         for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )
4617             args[i] = argv[i];
4618 
4619         return args;
4620     }
4621 
4622     class Parser {
4623         enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };
4624         Mode mode;
4625         std::size_t from;
4626         bool inQuotes;
4627     public:
4628 
4629         struct Token {
4630             enum Type { Positional, ShortOpt, LongOpt };
TokenClara::Parser::Token4631             Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
4632             Type type;
4633             std::string data;
4634         };
4635 
Parser()4636         Parser() : mode( None ), from( 0 ), inQuotes( false ){}
4637 
parseIntoTokens(std::vector<std::string> const & args,std::vector<Token> & tokens)4638         void parseIntoTokens( std::vector<std::string> const& args, std::vector<Token>& tokens ) {
4639             const std::string doubleDash = "--";
4640             for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )
4641                 parseIntoTokens( args[i], tokens);
4642         }
4643 
parseIntoTokens(std::string const & arg,std::vector<Token> & tokens)4644         void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {
4645             for( std::size_t i = 0; i < arg.size(); ++i ) {
4646                 char c = arg[i];
4647                 if( c == '"' )
4648                     inQuotes = !inQuotes;
4649                 mode = handleMode( i, c, arg, tokens );
4650             }
4651             mode = handleMode( arg.size(), '\0', arg, tokens );
4652         }
handleMode(std::size_t i,char c,std::string const & arg,std::vector<Token> & tokens)4653         Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
4654             switch( mode ) {
4655                 case None: return handleNone( i, c );
4656                 case MaybeShortOpt: return handleMaybeShortOpt( i, c );
4657                 case ShortOpt:
4658                 case LongOpt:
4659                 case SlashOpt: return handleOpt( i, c, arg, tokens );
4660                 case Positional: return handlePositional( i, c, arg, tokens );
4661                 default: throw std::logic_error( "Unknown mode" );
4662             }
4663         }
4664 
handleNone(std::size_t i,char c)4665         Mode handleNone( std::size_t i, char c ) {
4666             if( inQuotes ) {
4667                 from = i;
4668                 return Positional;
4669             }
4670             switch( c ) {
4671                 case '-': return MaybeShortOpt;
4672 #ifdef CLARA_PLATFORM_WINDOWS
4673                 case '/': from = i+1; return SlashOpt;
4674 #endif
4675                 default: from = i; return Positional;
4676             }
4677         }
handleMaybeShortOpt(std::size_t i,char c)4678         Mode handleMaybeShortOpt( std::size_t i, char c ) {
4679             switch( c ) {
4680                 case '-': from = i+1; return LongOpt;
4681                 default: from = i; return ShortOpt;
4682             }
4683         }
4684 
handleOpt(std::size_t i,char c,std::string const & arg,std::vector<Token> & tokens)4685         Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
4686             if( std::string( ":=\0", 3 ).find( c ) == std::string::npos )
4687                 return mode;
4688 
4689             std::string optName = arg.substr( from, i-from );
4690             if( mode == ShortOpt )
4691                 for( std::size_t j = 0; j < optName.size(); ++j )
4692                     tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) );
4693             else if( mode == SlashOpt && optName.size() == 1 )
4694                 tokens.push_back( Token( Token::ShortOpt, optName ) );
4695             else
4696                 tokens.push_back( Token( Token::LongOpt, optName ) );
4697             return None;
4698         }
handlePositional(std::size_t i,char c,std::string const & arg,std::vector<Token> & tokens)4699         Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
4700             if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos )
4701                 return mode;
4702 
4703             std::string data = arg.substr( from, i-from );
4704             tokens.push_back( Token( Token::Positional, data ) );
4705             return None;
4706         }
4707     };
4708 
4709     template<typename ConfigT>
4710     struct CommonArgProperties {
CommonArgPropertiesClara::CommonArgProperties4711         CommonArgProperties() {}
CommonArgPropertiesClara::CommonArgProperties4712         CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
4713 
4714         Detail::BoundArgFunction<ConfigT> boundField;
4715         std::string description;
4716         std::string detail;
4717         std::string placeholder; // Only value if boundField takes an arg
4718 
takesArgClara::CommonArgProperties4719         bool takesArg() const {
4720             return !placeholder.empty();
4721         }
validateClara::CommonArgProperties4722         void validate() const {
4723             if( !boundField.isSet() )
4724                 throw std::logic_error( "option not bound" );
4725         }
4726     };
4727     struct OptionArgProperties {
4728         std::vector<std::string> shortNames;
4729         std::string longName;
4730 
hasShortNameClara::OptionArgProperties4731         bool hasShortName( std::string const& shortName ) const {
4732             return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
4733         }
hasLongNameClara::OptionArgProperties4734         bool hasLongName( std::string const& _longName ) const {
4735             return _longName == longName;
4736         }
4737     };
4738     struct PositionalArgProperties {
PositionalArgPropertiesClara::PositionalArgProperties4739         PositionalArgProperties() : position( -1 ) {}
4740         int position; // -1 means non-positional (floating)
4741 
isFixedPositionalClara::PositionalArgProperties4742         bool isFixedPositional() const {
4743             return position != -1;
4744         }
4745     };
4746 
4747     template<typename ConfigT>
4748     class CommandLine {
4749 
4750         struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
ArgClara::CommandLine::Arg4751             Arg() {}
ArgClara::CommandLine::Arg4752             Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
4753 
4754             using CommonArgProperties<ConfigT>::placeholder; // !TBD
4755 
dbgNameClara::CommandLine::Arg4756             std::string dbgName() const {
4757                 if( !longName.empty() )
4758                     return "--" + longName;
4759                 if( !shortNames.empty() )
4760                     return "-" + shortNames[0];
4761                 return "positional args";
4762             }
commandsClara::CommandLine::Arg4763             std::string commands() const {
4764                 std::ostringstream oss;
4765                 bool first = true;
4766                 std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
4767                 for(; it != itEnd; ++it ) {
4768                     if( first )
4769                         first = false;
4770                     else
4771                         oss << ", ";
4772                     oss << "-" << *it;
4773                 }
4774                 if( !longName.empty() ) {
4775                     if( !first )
4776                         oss << ", ";
4777                     oss << "--" << longName;
4778                 }
4779                 if( !placeholder.empty() )
4780                     oss << " <" << placeholder << ">";
4781                 return oss.str();
4782             }
4783         };
4784 
4785         typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
4786 
addOptName(Arg & arg,std::string const & optName)4787         friend void addOptName( Arg& arg, std::string const& optName )
4788         {
4789             if( optName.empty() )
4790                 return;
4791             if( Detail::startsWith( optName, "--" ) ) {
4792                 if( !arg.longName.empty() )
4793                     throw std::logic_error( "Only one long opt may be specified. '"
4794                         + arg.longName
4795                         + "' already specified, now attempting to add '"
4796                         + optName + "'" );
4797                 arg.longName = optName.substr( 2 );
4798             }
4799             else if( Detail::startsWith( optName, "-" ) )
4800                 arg.shortNames.push_back( optName.substr( 1 ) );
4801             else
4802                 throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
4803         }
setPositionalArg(Arg & arg,int position)4804         friend void setPositionalArg( Arg& arg, int position )
4805         {
4806             arg.position = position;
4807         }
4808 
4809         class ArgBuilder {
4810         public:
ArgBuilder(Arg * arg)4811             ArgBuilder( Arg* arg ) : m_arg( arg ) {}
4812 
4813             // Bind a non-boolean data member (requires placeholder string)
4814             template<typename C, typename M>
bind(M C::* field,std::string const & placeholder)4815             void bind( M C::* field, std::string const& placeholder ) {
4816                 m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
4817                 m_arg->placeholder = placeholder;
4818             }
4819             // Bind a boolean data member (no placeholder required)
4820             template<typename C>
bind(bool C::* field)4821             void bind( bool C::* field ) {
4822                 m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
4823             }
4824 
4825             // Bind a method taking a single, non-boolean argument (requires a placeholder string)
4826             template<typename C, typename M>
bind(void (C::* unaryMethod)(M),std::string const & placeholder)4827             void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
4828                 m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
4829                 m_arg->placeholder = placeholder;
4830             }
4831 
4832             // Bind a method taking a single, boolean argument (no placeholder string required)
4833             template<typename C>
bind(void (C::* unaryMethod)(bool))4834             void bind( void (C::* unaryMethod)( bool ) ) {
4835                 m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
4836             }
4837 
4838             // Bind a method that takes no arguments (will be called if opt is present)
4839             template<typename C>
bind(void (C::* nullaryMethod)())4840             void bind( void (C::* nullaryMethod)() ) {
4841                 m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
4842             }
4843 
4844             // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
4845             template<typename C>
bind(void (* unaryFunction)(C &))4846             void bind( void (* unaryFunction)( C& ) ) {
4847                 m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
4848             }
4849 
4850             // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
4851             template<typename C, typename T>
bind(void (* binaryFunction)(C &,T),std::string const & placeholder)4852             void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
4853                 m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
4854                 m_arg->placeholder = placeholder;
4855             }
4856 
describe(std::string const & description)4857             ArgBuilder& describe( std::string const& description ) {
4858                 m_arg->description = description;
4859                 return *this;
4860             }
detail(std::string const & detail)4861             ArgBuilder& detail( std::string const& detail ) {
4862                 m_arg->detail = detail;
4863                 return *this;
4864             }
4865 
4866         protected:
4867             Arg* m_arg;
4868         };
4869 
4870         class OptBuilder : public ArgBuilder {
4871         public:
OptBuilder(Arg * arg)4872             OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
OptBuilder(OptBuilder & other)4873             OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
4874 
operator [](std::string const & optName)4875             OptBuilder& operator[]( std::string const& optName ) {
4876                 addOptName( *ArgBuilder::m_arg, optName );
4877                 return *this;
4878             }
4879         };
4880 
4881     public:
4882 
CommandLine()4883         CommandLine()
4884         :   m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
4885             m_highestSpecifiedArgPosition( 0 ),
4886             m_throwOnUnrecognisedTokens( false )
4887         {}
CommandLine(CommandLine const & other)4888         CommandLine( CommandLine const& other )
4889         :   m_boundProcessName( other.m_boundProcessName ),
4890             m_options ( other.m_options ),
4891             m_positionalArgs( other.m_positionalArgs ),
4892             m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
4893             m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
4894         {
4895             if( other.m_floatingArg.get() )
4896                 m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
4897         }
4898 
setThrowOnUnrecognisedTokens(bool shouldThrow=true)4899         CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
4900             m_throwOnUnrecognisedTokens = shouldThrow;
4901             return *this;
4902         }
4903 
operator [](std::string const & optName)4904         OptBuilder operator[]( std::string const& optName ) {
4905             m_options.push_back( Arg() );
4906             addOptName( m_options.back(), optName );
4907             OptBuilder builder( &m_options.back() );
4908             return builder;
4909         }
4910 
operator [](int position)4911         ArgBuilder operator[]( int position ) {
4912             m_positionalArgs.insert( std::make_pair( position, Arg() ) );
4913             if( position > m_highestSpecifiedArgPosition )
4914                 m_highestSpecifiedArgPosition = position;
4915             setPositionalArg( m_positionalArgs[position], position );
4916             ArgBuilder builder( &m_positionalArgs[position] );
4917             return builder;
4918         }
4919 
4920         // Invoke this with the _ instance
operator [](UnpositionalTag)4921         ArgBuilder operator[]( UnpositionalTag ) {
4922             if( m_floatingArg.get() )
4923                 throw std::logic_error( "Only one unpositional argument can be added" );
4924             m_floatingArg.reset( new Arg() );
4925             ArgBuilder builder( m_floatingArg.get() );
4926             return builder;
4927         }
4928 
4929         template<typename C, typename M>
bindProcessName(M C::* field)4930         void bindProcessName( M C::* field ) {
4931             m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
4932         }
4933         template<typename C, typename M>
bindProcessName(void (C::* _unaryMethod)(M))4934         void bindProcessName( void (C::*_unaryMethod)( M ) ) {
4935             m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
4936         }
4937 
optUsage(std::ostream & os,std::size_t indent=0,std::size_t width=Detail::consoleWidth) const4938         void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
4939             typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
4940             std::size_t maxWidth = 0;
4941             for( it = itBegin; it != itEnd; ++it )
4942                 maxWidth = (std::max)( maxWidth, it->commands().size() );
4943 
4944             for( it = itBegin; it != itEnd; ++it ) {
4945                 Detail::Text usage( it->commands(), Detail::TextAttributes()
4946                                                         .setWidth( maxWidth+indent )
4947                                                         .setIndent( indent ) );
4948                 Detail::Text desc( it->description, Detail::TextAttributes()
4949                                                         .setWidth( width - maxWidth - 3 ) );
4950 
4951                 for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
4952                     std::string usageCol = i < usage.size() ? usage[i] : "";
4953                     os << usageCol;
4954 
4955                     if( i < desc.size() && !desc[i].empty() )
4956                         os  << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
4957                             << desc[i];
4958                     os << "\n";
4959                 }
4960             }
4961         }
optUsage() const4962         std::string optUsage() const {
4963             std::ostringstream oss;
4964             optUsage( oss );
4965             return oss.str();
4966         }
4967 
argSynopsis(std::ostream & os) const4968         void argSynopsis( std::ostream& os ) const {
4969             for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
4970                 if( i > 1 )
4971                     os << " ";
4972                 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
4973                 if( it != m_positionalArgs.end() )
4974                     os << "<" << it->second.placeholder << ">";
4975                 else if( m_floatingArg.get() )
4976                     os << "<" << m_floatingArg->placeholder << ">";
4977                 else
4978                     throw std::logic_error( "non consecutive positional arguments with no floating args" );
4979             }
4980             // !TBD No indication of mandatory args
4981             if( m_floatingArg.get() ) {
4982                 if( m_highestSpecifiedArgPosition > 1 )
4983                     os << " ";
4984                 os << "[<" << m_floatingArg->placeholder << "> ...]";
4985             }
4986         }
argSynopsis() const4987         std::string argSynopsis() const {
4988             std::ostringstream oss;
4989             argSynopsis( oss );
4990             return oss.str();
4991         }
4992 
usage(std::ostream & os,std::string const & procName) const4993         void usage( std::ostream& os, std::string const& procName ) const {
4994             validate();
4995             os << "usage:\n  " << procName << " ";
4996             argSynopsis( os );
4997             if( !m_options.empty() ) {
4998                 os << " [options]\n\nwhere options are: \n";
4999                 optUsage( os, 2 );
5000             }
5001             os << "\n";
5002         }
usage(std::string const & procName) const5003         std::string usage( std::string const& procName ) const {
5004             std::ostringstream oss;
5005             usage( oss, procName );
5006             return oss.str();
5007         }
5008 
parse(std::vector<std::string> const & args) const5009         ConfigT parse( std::vector<std::string> const& args ) const {
5010             ConfigT config;
5011             parseInto( args, config );
5012             return config;
5013         }
5014 
parseInto(std::vector<std::string> const & args,ConfigT & config) const5015         std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {
5016             std::string processName = args.empty() ? std::string() : args[0];
5017             std::size_t lastSlash = processName.find_last_of( "/\\" );
5018             if( lastSlash != std::string::npos )
5019                 processName = processName.substr( lastSlash+1 );
5020             m_boundProcessName.set( config, processName );
5021             std::vector<Parser::Token> tokens;
5022             Parser parser;
5023             parser.parseIntoTokens( args, tokens );
5024             return populate( tokens, config );
5025         }
5026 
populate(std::vector<Parser::Token> const & tokens,ConfigT & config) const5027         std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
5028             validate();
5029             std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
5030             unusedTokens = populateFixedArgs( unusedTokens, config );
5031             unusedTokens = populateFloatingArgs( unusedTokens, config );
5032             return unusedTokens;
5033         }
5034 
populateOptions(std::vector<Parser::Token> const & tokens,ConfigT & config) const5035         std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
5036             std::vector<Parser::Token> unusedTokens;
5037             std::vector<std::string> errors;
5038             for( std::size_t i = 0; i < tokens.size(); ++i ) {
5039                 Parser::Token const& token = tokens[i];
5040                 typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
5041                 for(; it != itEnd; ++it ) {
5042                     Arg const& arg = *it;
5043 
5044                     try {
5045                         if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
5046                             ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
5047                             if( arg.takesArg() ) {
5048                                 if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
5049                                     errors.push_back( "Expected argument to option: " + token.data );
5050                                 else
5051                                     arg.boundField.set( config, tokens[++i].data );
5052                             }
5053                             else {
5054                                 arg.boundField.set( config, "true" );
5055                             }
5056                             break;
5057                         }
5058                     }
5059                     catch( std::exception& ex ) {
5060                         errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
5061                     }
5062                 }
5063                 if( it == itEnd ) {
5064                     if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
5065                         unusedTokens.push_back( token );
5066                     else if( errors.empty() && m_throwOnUnrecognisedTokens )
5067                         errors.push_back( "unrecognised option: " + token.data );
5068                 }
5069             }
5070             if( !errors.empty() ) {
5071                 std::ostringstream oss;
5072                 for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
5073                         it != itEnd;
5074                         ++it ) {
5075                     if( it != errors.begin() )
5076                         oss << "\n";
5077                     oss << *it;
5078                 }
5079                 throw std::runtime_error( oss.str() );
5080             }
5081             return unusedTokens;
5082         }
populateFixedArgs(std::vector<Parser::Token> const & tokens,ConfigT & config) const5083         std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
5084             std::vector<Parser::Token> unusedTokens;
5085             int position = 1;
5086             for( std::size_t i = 0; i < tokens.size(); ++i ) {
5087                 Parser::Token const& token = tokens[i];
5088                 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
5089                 if( it != m_positionalArgs.end() )
5090                     it->second.boundField.set( config, token.data );
5091                 else
5092                     unusedTokens.push_back( token );
5093                 if( token.type == Parser::Token::Positional )
5094                     position++;
5095             }
5096             return unusedTokens;
5097         }
populateFloatingArgs(std::vector<Parser::Token> const & tokens,ConfigT & config) const5098         std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
5099             if( !m_floatingArg.get() )
5100                 return tokens;
5101             std::vector<Parser::Token> unusedTokens;
5102             for( std::size_t i = 0; i < tokens.size(); ++i ) {
5103                 Parser::Token const& token = tokens[i];
5104                 if( token.type == Parser::Token::Positional )
5105                     m_floatingArg->boundField.set( config, token.data );
5106                 else
5107                     unusedTokens.push_back( token );
5108             }
5109             return unusedTokens;
5110         }
5111 
validate() const5112         void validate() const
5113         {
5114             if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
5115                 throw std::logic_error( "No options or arguments specified" );
5116 
5117             for( typename std::vector<Arg>::const_iterator  it = m_options.begin(),
5118                                                             itEnd = m_options.end();
5119                     it != itEnd; ++it )
5120                 it->validate();
5121         }
5122 
5123     private:
5124         Detail::BoundArgFunction<ConfigT> m_boundProcessName;
5125         std::vector<Arg> m_options;
5126         std::map<int, Arg> m_positionalArgs;
5127         ArgAutoPtr m_floatingArg;
5128         int m_highestSpecifiedArgPosition;
5129         bool m_throwOnUnrecognisedTokens;
5130     };
5131 
5132 } // end namespace Clara
5133 
5134 STITCH_CLARA_CLOSE_NAMESPACE
5135 #undef STITCH_CLARA_OPEN_NAMESPACE
5136 #undef STITCH_CLARA_CLOSE_NAMESPACE
5137 
5138 #endif // TWOBLUECUBES_CLARA_H_INCLUDED
5139 #undef STITCH_CLARA_OPEN_NAMESPACE
5140 
5141 // Restore Clara's value for console width, if present
5142 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
5143 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
5144 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
5145 #endif
5146 
5147 #include <fstream>
5148 #include <ctime>
5149 
5150 namespace Catch {
5151 
abortAfterFirst(ConfigData & config)5152     inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
abortAfterX(ConfigData & config,int x)5153     inline void abortAfterX( ConfigData& config, int x ) {
5154         if( x < 1 )
5155             throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
5156         config.abortAfter = x;
5157     }
addTestOrTags(ConfigData & config,std::string const & _testSpec)5158     inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
addSectionToRun(ConfigData & config,std::string const & sectionName)5159     inline void addSectionToRun( ConfigData& config, std::string const& sectionName ) { config.sectionsToRun.push_back( sectionName ); }
addReporterName(ConfigData & config,std::string const & _reporterName)5160     inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
5161 
addWarning(ConfigData & config,std::string const & _warning)5162     inline void addWarning( ConfigData& config, std::string const& _warning ) {
5163         if( _warning == "NoAssertions" )
5164             config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
5165         else
5166             throw std::runtime_error( "Unrecognised warning: '" + _warning + '\'' );
5167     }
setOrder(ConfigData & config,std::string const & order)5168     inline void setOrder( ConfigData& config, std::string const& order ) {
5169         if( startsWith( "declared", order ) )
5170             config.runOrder = RunTests::InDeclarationOrder;
5171         else if( startsWith( "lexical", order ) )
5172             config.runOrder = RunTests::InLexicographicalOrder;
5173         else if( startsWith( "random", order ) )
5174             config.runOrder = RunTests::InRandomOrder;
5175         else
5176             throw std::runtime_error( "Unrecognised ordering: '" + order + '\'' );
5177     }
setRngSeed(ConfigData & config,std::string const & seed)5178     inline void setRngSeed( ConfigData& config, std::string const& seed ) {
5179         if( seed == "time" ) {
5180             config.rngSeed = static_cast<unsigned int>( std::time(0) );
5181         }
5182         else {
5183             std::stringstream ss;
5184             ss << seed;
5185             ss >> config.rngSeed;
5186             if( ss.fail() )
5187                 throw std::runtime_error( "Argument to --rng-seed should be the word 'time' or a number" );
5188         }
5189     }
setVerbosity(ConfigData & config,int level)5190     inline void setVerbosity( ConfigData& config, int level ) {
5191         // !TBD: accept strings?
5192         config.verbosity = static_cast<Verbosity::Level>( level );
5193     }
setShowDurations(ConfigData & config,bool _showDurations)5194     inline void setShowDurations( ConfigData& config, bool _showDurations ) {
5195         config.showDurations = _showDurations
5196             ? ShowDurations::Always
5197             : ShowDurations::Never;
5198     }
setUseColour(ConfigData & config,std::string const & value)5199     inline void setUseColour( ConfigData& config, std::string const& value ) {
5200         std::string mode = toLower( value );
5201 
5202         if( mode == "yes" )
5203             config.useColour = UseColour::Yes;
5204         else if( mode == "no" )
5205             config.useColour = UseColour::No;
5206         else if( mode == "auto" )
5207             config.useColour = UseColour::Auto;
5208         else
5209             throw std::runtime_error( "colour mode must be one of: auto, yes or no" );
5210     }
setWaitForKeypress(ConfigData & config,std::string const & keypress)5211     inline void setWaitForKeypress( ConfigData& config, std::string const& keypress ) {
5212         std::string keypressLc = toLower( keypress );
5213         if( keypressLc == "start" )
5214             config.waitForKeypress = WaitForKeypress::BeforeStart;
5215         else if( keypressLc == "exit" )
5216             config.waitForKeypress = WaitForKeypress::BeforeExit;
5217         else if( keypressLc == "both" )
5218             config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
5219         else
5220             throw std::runtime_error( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
5221     };
5222 
forceColour(ConfigData & config)5223     inline void forceColour( ConfigData& config ) {
5224         config.useColour = UseColour::Yes;
5225     }
loadTestNamesFromFile(ConfigData & config,std::string const & _filename)5226     inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
5227         std::ifstream f( _filename.c_str() );
5228         if( !f.is_open() )
5229             throw std::domain_error( "Unable to load input file: " + _filename );
5230 
5231         std::string line;
5232         while( std::getline( f, line ) ) {
5233             line = trim(line);
5234             if( !line.empty() && !startsWith( line, '#' ) ) {
5235                 if( !startsWith( line, '"' ) )
5236                     line = '"' + line + '"';
5237                 addTestOrTags( config, line + ',' );
5238             }
5239         }
5240     }
5241 
makeCommandLineParser()5242     inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
5243 
5244         using namespace Clara;
5245         CommandLine<ConfigData> cli;
5246 
5247         cli.bindProcessName( &ConfigData::processName );
5248 
5249         cli["-?"]["-h"]["--help"]
5250             .describe( "display usage information" )
5251             .bind( &ConfigData::showHelp );
5252 
5253         cli["-l"]["--list-tests"]
5254             .describe( "list all/matching test cases" )
5255             .bind( &ConfigData::listTests );
5256 
5257         cli["-t"]["--list-tags"]
5258             .describe( "list all/matching tags" )
5259             .bind( &ConfigData::listTags );
5260 
5261         cli["-s"]["--success"]
5262             .describe( "include successful tests in output" )
5263             .bind( &ConfigData::showSuccessfulTests );
5264 
5265         cli["-b"]["--break"]
5266             .describe( "break into debugger on failure" )
5267             .bind( &ConfigData::shouldDebugBreak );
5268 
5269         cli["-e"]["--nothrow"]
5270             .describe( "skip exception tests" )
5271             .bind( &ConfigData::noThrow );
5272 
5273         cli["-i"]["--invisibles"]
5274             .describe( "show invisibles (tabs, newlines)" )
5275             .bind( &ConfigData::showInvisibles );
5276 
5277         cli["-o"]["--out"]
5278             .describe( "output filename" )
5279             .bind( &ConfigData::outputFilename, "filename" );
5280 
5281         cli["-r"]["--reporter"]
5282 //            .placeholder( "name[:filename]" )
5283             .describe( "reporter to use (defaults to console)" )
5284             .bind( &addReporterName, "name" );
5285 
5286         cli["-n"]["--name"]
5287             .describe( "suite name" )
5288             .bind( &ConfigData::name, "name" );
5289 
5290         cli["-a"]["--abort"]
5291             .describe( "abort at first failure" )
5292             .bind( &abortAfterFirst );
5293 
5294         cli["-x"]["--abortx"]
5295             .describe( "abort after x failures" )
5296             .bind( &abortAfterX, "no. failures" );
5297 
5298         cli["-w"]["--warn"]
5299             .describe( "enable warnings" )
5300             .bind( &addWarning, "warning name" );
5301 
5302 // - needs updating if reinstated
5303 //        cli.into( &setVerbosity )
5304 //            .describe( "level of verbosity (0=no output)" )
5305 //            .shortOpt( "v")
5306 //            .longOpt( "verbosity" )
5307 //            .placeholder( "level" );
5308 
5309         cli[_]
5310             .describe( "which test or tests to use" )
5311             .bind( &addTestOrTags, "test name, pattern or tags" );
5312 
5313         cli["-d"]["--durations"]
5314             .describe( "show test durations" )
5315             .bind( &setShowDurations, "yes|no" );
5316 
5317         cli["-f"]["--input-file"]
5318             .describe( "load test names to run from a file" )
5319             .bind( &loadTestNamesFromFile, "filename" );
5320 
5321         cli["-#"]["--filenames-as-tags"]
5322             .describe( "adds a tag for the filename" )
5323             .bind( &ConfigData::filenamesAsTags );
5324 
5325         cli["-c"]["--section"]
5326                 .describe( "specify section to run" )
5327                 .bind( &addSectionToRun, "section name" );
5328 
5329         // Less common commands which don't have a short form
5330         cli["--list-test-names-only"]
5331             .describe( "list all/matching test cases names only" )
5332             .bind( &ConfigData::listTestNamesOnly );
5333 
5334         cli["--list-extra-info"]
5335             .describe( "list all/matching test cases with more info" )
5336             .bind( &ConfigData::listExtraInfo );
5337 
5338         cli["--list-reporters"]
5339             .describe( "list all reporters" )
5340             .bind( &ConfigData::listReporters );
5341 
5342         cli["--order"]
5343             .describe( "test case order (defaults to decl)" )
5344             .bind( &setOrder, "decl|lex|rand" );
5345 
5346         cli["--rng-seed"]
5347             .describe( "set a specific seed for random numbers" )
5348             .bind( &setRngSeed, "'time'|number" );
5349 
5350         cli["--force-colour"]
5351             .describe( "force colourised output (deprecated)" )
5352             .bind( &forceColour );
5353 
5354         cli["--use-colour"]
5355             .describe( "should output be colourised" )
5356             .bind( &setUseColour, "yes|no" );
5357 
5358         cli["--libidentify"]
5359             .describe( "report name and version according to libidentify standard" )
5360             .bind( &ConfigData::libIdentify );
5361 
5362         cli["--wait-for-keypress"]
5363                 .describe( "waits for a keypress before exiting" )
5364                 .bind( &setWaitForKeypress, "start|exit|both" );
5365 
5366         return cli;
5367     }
5368 
5369 } // end namespace Catch
5370 
5371 // #included from: internal/catch_list.hpp
5372 #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
5373 
5374 // #included from: catch_text.h
5375 #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
5376 
5377 #define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
5378 
5379 #define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
5380 // #included from: ../external/tbc_text_format.h
5381 // Only use header guard if we are not using an outer namespace
5382 #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
5383 # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
5384 #  ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
5385 #   define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
5386 #  endif
5387 # else
5388 #  define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
5389 # endif
5390 #endif
5391 #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
5392 #include <string>
5393 #include <vector>
5394 #include <sstream>
5395 
5396 // Use optional outer namespace
5397 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
5398 namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
5399 #endif
5400 
5401 namespace Tbc {
5402 
5403 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
5404     const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
5405 #else
5406     const unsigned int consoleWidth = 80;
5407 #endif
5408 
5409     struct TextAttributes {
TextAttributesCLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes5410         TextAttributes()
5411         :   initialIndent( std::string::npos ),
5412             indent( 0 ),
5413             width( consoleWidth-1 )
5414         {}
5415 
setInitialIndentCLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes5416         TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
setIndentCLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes5417         TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
setWidthCLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes5418         TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
5419 
5420         std::size_t initialIndent;  // indent of first line, or npos
5421         std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
5422         std::size_t width;          // maximum width of text, including indent. Longer text will wrap
5423     };
5424 
5425     class Text {
5426     public:
Text(std::string const & _str,TextAttributes const & _attr=TextAttributes ())5427         Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
5428         : attr( _attr )
5429         {
5430             const std::string wrappableBeforeChars = "[({<\t";
5431             const std::string wrappableAfterChars = "])}>-,./|\\";
5432             const std::string wrappableInsteadOfChars = " \n\r";
5433             std::string indent = _attr.initialIndent != std::string::npos
5434                 ? std::string( _attr.initialIndent, ' ' )
5435                 : std::string( _attr.indent, ' ' );
5436 
5437             typedef std::string::const_iterator iterator;
5438             iterator it = _str.begin();
5439             const iterator strEnd = _str.end();
5440 
5441             while( it != strEnd ) {
5442 
5443                 if( lines.size() >= 1000 ) {
5444                     lines.push_back( "... message truncated due to excessive size" );
5445                     return;
5446                 }
5447 
5448                 std::string suffix;
5449                 std::size_t width = (std::min)( static_cast<size_t>( strEnd-it ), _attr.width-static_cast<size_t>( indent.size() ) );
5450                 iterator itEnd = it+width;
5451                 iterator itNext = _str.end();
5452 
5453                 iterator itNewLine = std::find( it, itEnd, '\n' );
5454                 if( itNewLine != itEnd )
5455                     itEnd = itNewLine;
5456 
5457                 if( itEnd != strEnd  ) {
5458                     bool foundWrapPoint = false;
5459                     iterator findIt = itEnd;
5460                     do {
5461                         if( wrappableAfterChars.find( *findIt ) != std::string::npos && findIt != itEnd ) {
5462                             itEnd = findIt+1;
5463                             itNext = findIt+1;
5464                             foundWrapPoint = true;
5465                         }
5466                         else if( findIt > it && wrappableBeforeChars.find( *findIt ) != std::string::npos ) {
5467                             itEnd = findIt;
5468                             itNext = findIt;
5469                             foundWrapPoint = true;
5470                         }
5471                         else if( wrappableInsteadOfChars.find( *findIt ) != std::string::npos ) {
5472                             itNext = findIt+1;
5473                             itEnd = findIt;
5474                             foundWrapPoint = true;
5475                         }
5476                         if( findIt == it )
5477                             break;
5478                         else
5479                             --findIt;
5480                     }
5481                     while( !foundWrapPoint );
5482 
5483                     if( !foundWrapPoint ) {
5484                         // No good wrap char, so we'll break mid word and add a hyphen
5485                         --itEnd;
5486                         itNext = itEnd;
5487                         suffix = "-";
5488                     }
5489                     else {
5490                         while( itEnd > it && wrappableInsteadOfChars.find( *(itEnd-1) ) != std::string::npos )
5491                             --itEnd;
5492                     }
5493                 }
5494                 lines.push_back( indent + std::string( it, itEnd ) + suffix );
5495 
5496                 if( indent.size() != _attr.indent )
5497                     indent = std::string( _attr.indent, ' ' );
5498                 it = itNext;
5499             }
5500         }
5501 
5502         typedef std::vector<std::string>::const_iterator const_iterator;
5503 
begin() const5504         const_iterator begin() const { return lines.begin(); }
end() const5505         const_iterator end() const { return lines.end(); }
last() const5506         std::string const& last() const { return lines.back(); }
size() const5507         std::size_t size() const { return lines.size(); }
operator [](std::size_t _index) const5508         std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
toString() const5509         std::string toString() const {
5510             std::ostringstream oss;
5511             oss << *this;
5512             return oss.str();
5513         }
5514 
operator <<(std::ostream & _stream,Text const & _text)5515         inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
5516             for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
5517                 it != itEnd; ++it ) {
5518                 if( it != _text.begin() )
5519                     _stream << "\n";
5520                 _stream << *it;
5521             }
5522             return _stream;
5523         }
5524 
5525     private:
5526         std::string str;
5527         TextAttributes attr;
5528         std::vector<std::string> lines;
5529     };
5530 
5531 } // end namespace Tbc
5532 
5533 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
5534 } // end outer namespace
5535 #endif
5536 
5537 #endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
5538 #undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
5539 
5540 namespace Catch {
5541     using Tbc::Text;
5542     using Tbc::TextAttributes;
5543 }
5544 
5545 // #included from: catch_console_colour.hpp
5546 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
5547 
5548 namespace Catch {
5549 
5550     struct Colour {
5551         enum Code {
5552             None = 0,
5553 
5554             White,
5555             Red,
5556             Green,
5557             Blue,
5558             Cyan,
5559             Yellow,
5560             Grey,
5561 
5562             Bright = 0x10,
5563 
5564             BrightRed = Bright | Red,
5565             BrightGreen = Bright | Green,
5566             LightGrey = Bright | Grey,
5567             BrightWhite = Bright | White,
5568 
5569             // By intention
5570             FileName = LightGrey,
5571             Warning = Yellow,
5572             ResultError = BrightRed,
5573             ResultSuccess = BrightGreen,
5574             ResultExpectedFailure = Warning,
5575 
5576             Error = BrightRed,
5577             Success = Green,
5578 
5579             OriginalExpression = Cyan,
5580             ReconstructedExpression = Yellow,
5581 
5582             SecondaryText = LightGrey,
5583             Headers = White
5584         };
5585 
5586         // Use constructed object for RAII guard
5587         Colour( Code _colourCode );
5588         Colour( Colour const& other );
5589         ~Colour();
5590 
5591         // Use static method for one-shot changes
5592         static void use( Code _colourCode );
5593 
5594     private:
5595         bool m_moved;
5596     };
5597 
operator <<(std::ostream & os,Colour const &)5598     inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
5599 
5600 } // end namespace Catch
5601 
5602 // #included from: catch_interfaces_reporter.h
5603 #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
5604 
5605 #include <string>
5606 #include <ostream>
5607 #include <map>
5608 
5609 namespace Catch
5610 {
5611     struct ReporterConfig {
ReporterConfigCatch::ReporterConfig5612         explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
5613         :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
5614 
ReporterConfigCatch::ReporterConfig5615         ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
5616         :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
5617 
streamCatch::ReporterConfig5618         std::ostream& stream() const    { return *m_stream; }
fullConfigCatch::ReporterConfig5619         Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
5620 
5621     private:
5622         std::ostream* m_stream;
5623         Ptr<IConfig const> m_fullConfig;
5624     };
5625 
5626     struct ReporterPreferences {
ReporterPreferencesCatch::ReporterPreferences5627         ReporterPreferences()
5628         : shouldRedirectStdOut( false )
5629         {}
5630 
5631         bool shouldRedirectStdOut;
5632     };
5633 
5634     template<typename T>
5635     struct LazyStat : Option<T> {
LazyStatCatch::LazyStat5636         LazyStat() : used( false ) {}
operator =Catch::LazyStat5637         LazyStat& operator=( T const& _value ) {
5638             Option<T>::operator=( _value );
5639             used = false;
5640             return *this;
5641         }
resetCatch::LazyStat5642         void reset() {
5643             Option<T>::reset();
5644             used = false;
5645         }
5646         bool used;
5647     };
5648 
5649     struct TestRunInfo {
TestRunInfoCatch::TestRunInfo5650         TestRunInfo( std::string const& _name ) : name( _name ) {}
5651         std::string name;
5652     };
5653     struct GroupInfo {
GroupInfoCatch::GroupInfo5654         GroupInfo(  std::string const& _name,
5655                     std::size_t _groupIndex,
5656                     std::size_t _groupsCount )
5657         :   name( _name ),
5658             groupIndex( _groupIndex ),
5659             groupsCounts( _groupsCount )
5660         {}
5661 
5662         std::string name;
5663         std::size_t groupIndex;
5664         std::size_t groupsCounts;
5665     };
5666 
5667     struct AssertionStats {
AssertionStatsCatch::AssertionStats5668         AssertionStats( AssertionResult const& _assertionResult,
5669                         std::vector<MessageInfo> const& _infoMessages,
5670                         Totals const& _totals )
5671         :   assertionResult( _assertionResult ),
5672             infoMessages( _infoMessages ),
5673             totals( _totals )
5674         {
5675             if( assertionResult.hasMessage() ) {
5676                 // Copy message into messages list.
5677                 // !TBD This should have been done earlier, somewhere
5678                 MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
5679                 builder << assertionResult.getMessage();
5680                 builder.m_info.message = builder.m_stream.str();
5681 
5682                 infoMessages.push_back( builder.m_info );
5683             }
5684         }
5685         virtual ~AssertionStats();
5686 
5687 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5688         AssertionStats( AssertionStats const& )              = default;
5689         AssertionStats( AssertionStats && )                  = default;
5690         AssertionStats& operator = ( AssertionStats const& ) = default;
5691         AssertionStats& operator = ( AssertionStats && )     = default;
5692 #  endif
5693 
5694         AssertionResult assertionResult;
5695         std::vector<MessageInfo> infoMessages;
5696         Totals totals;
5697     };
5698 
5699     struct SectionStats {
SectionStatsCatch::SectionStats5700         SectionStats(   SectionInfo const& _sectionInfo,
5701                         Counts const& _assertions,
5702                         double _durationInSeconds,
5703                         bool _missingAssertions )
5704         :   sectionInfo( _sectionInfo ),
5705             assertions( _assertions ),
5706             durationInSeconds( _durationInSeconds ),
5707             missingAssertions( _missingAssertions )
5708         {}
5709         virtual ~SectionStats();
5710 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5711         SectionStats( SectionStats const& )              = default;
5712         SectionStats( SectionStats && )                  = default;
5713         SectionStats& operator = ( SectionStats const& ) = default;
5714         SectionStats& operator = ( SectionStats && )     = default;
5715 #  endif
5716 
5717         SectionInfo sectionInfo;
5718         Counts assertions;
5719         double durationInSeconds;
5720         bool missingAssertions;
5721     };
5722 
5723     struct TestCaseStats {
TestCaseStatsCatch::TestCaseStats5724         TestCaseStats(  TestCaseInfo const& _testInfo,
5725                         Totals const& _totals,
5726                         std::string const& _stdOut,
5727                         std::string const& _stdErr,
5728                         bool _aborting )
5729         : testInfo( _testInfo ),
5730             totals( _totals ),
5731             stdOut( _stdOut ),
5732             stdErr( _stdErr ),
5733             aborting( _aborting )
5734         {}
5735         virtual ~TestCaseStats();
5736 
5737 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5738         TestCaseStats( TestCaseStats const& )              = default;
5739         TestCaseStats( TestCaseStats && )                  = default;
5740         TestCaseStats& operator = ( TestCaseStats const& ) = default;
5741         TestCaseStats& operator = ( TestCaseStats && )     = default;
5742 #  endif
5743 
5744         TestCaseInfo testInfo;
5745         Totals totals;
5746         std::string stdOut;
5747         std::string stdErr;
5748         bool aborting;
5749     };
5750 
5751     struct TestGroupStats {
TestGroupStatsCatch::TestGroupStats5752         TestGroupStats( GroupInfo const& _groupInfo,
5753                         Totals const& _totals,
5754                         bool _aborting )
5755         :   groupInfo( _groupInfo ),
5756             totals( _totals ),
5757             aborting( _aborting )
5758         {}
TestGroupStatsCatch::TestGroupStats5759         TestGroupStats( GroupInfo const& _groupInfo )
5760         :   groupInfo( _groupInfo ),
5761             aborting( false )
5762         {}
5763         virtual ~TestGroupStats();
5764 
5765 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5766         TestGroupStats( TestGroupStats const& )              = default;
5767         TestGroupStats( TestGroupStats && )                  = default;
5768         TestGroupStats& operator = ( TestGroupStats const& ) = default;
5769         TestGroupStats& operator = ( TestGroupStats && )     = default;
5770 #  endif
5771 
5772         GroupInfo groupInfo;
5773         Totals totals;
5774         bool aborting;
5775     };
5776 
5777     struct TestRunStats {
TestRunStatsCatch::TestRunStats5778         TestRunStats(   TestRunInfo const& _runInfo,
5779                         Totals const& _totals,
5780                         bool _aborting )
5781         :   runInfo( _runInfo ),
5782             totals( _totals ),
5783             aborting( _aborting )
5784         {}
5785         virtual ~TestRunStats();
5786 
5787 #  ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
TestRunStatsCatch::TestRunStats5788         TestRunStats( TestRunStats const& _other )
5789         :   runInfo( _other.runInfo ),
5790             totals( _other.totals ),
5791             aborting( _other.aborting )
5792         {}
5793 #  else
5794         TestRunStats( TestRunStats const& )              = default;
5795         TestRunStats( TestRunStats && )                  = default;
5796         TestRunStats& operator = ( TestRunStats const& ) = default;
5797         TestRunStats& operator = ( TestRunStats && )     = default;
5798 #  endif
5799 
5800         TestRunInfo runInfo;
5801         Totals totals;
5802         bool aborting;
5803     };
5804 
5805     class MultipleReporters;
5806 
5807     struct IStreamingReporter : IShared {
5808         virtual ~IStreamingReporter();
5809 
5810         // Implementing class must also provide the following static method:
5811         // static std::string getDescription();
5812 
5813         virtual ReporterPreferences getPreferences() const = 0;
5814 
5815         virtual void noMatchingTestCases( std::string const& spec ) = 0;
5816 
5817         virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
5818         virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
5819 
5820         virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
5821         virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
5822 
5823         virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
5824 
5825         // The return value indicates if the messages buffer should be cleared:
5826         virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
5827 
5828         virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
5829         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
5830         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
5831         virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
5832 
5833         virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
5834 
tryAsMultiCatch::IStreamingReporter5835         virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }
5836     };
5837 
5838     struct IReporterFactory : IShared {
5839         virtual ~IReporterFactory();
5840         virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
5841         virtual std::string getDescription() const = 0;
5842     };
5843 
5844     struct IReporterRegistry {
5845         typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
5846         typedef std::vector<Ptr<IReporterFactory> > Listeners;
5847 
5848         virtual ~IReporterRegistry();
5849         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
5850         virtual FactoryMap const& getFactories() const = 0;
5851         virtual Listeners const& getListeners() const = 0;
5852     };
5853 
5854     Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
5855 
5856 }
5857 
5858 #include <limits>
5859 #include <algorithm>
5860 
5861 namespace Catch {
5862 
listTests(Config const & config)5863     inline std::size_t listTests( Config const& config ) {
5864 
5865         TestSpec testSpec = config.testSpec();
5866         if( config.testSpec().hasFilters() )
5867             Catch::cout() << "Matching test cases:\n";
5868         else {
5869             Catch::cout() << "All available test cases:\n";
5870             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5871         }
5872 
5873         std::size_t matchedTests = 0;
5874         TextAttributes nameAttr, descAttr, tagsAttr;
5875         nameAttr.setInitialIndent( 2 ).setIndent( 4 );
5876         descAttr.setIndent( 4 );
5877         tagsAttr.setIndent( 6 );
5878 
5879         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5880         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5881                 it != itEnd;
5882                 ++it ) {
5883             matchedTests++;
5884             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
5885             Colour::Code colour = testCaseInfo.isHidden()
5886                 ? Colour::SecondaryText
5887                 : Colour::None;
5888             Colour colourGuard( colour );
5889 
5890             Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
5891             if( config.listExtraInfo() ) {
5892                 Catch::cout() << "    " << testCaseInfo.lineInfo << std::endl;
5893                 std::string description = testCaseInfo.description;
5894                 if( description.empty() )
5895                     description = "(NO DESCRIPTION)";
5896                 Catch::cout() << Text( description, descAttr ) << std::endl;
5897             }
5898             if( !testCaseInfo.tags.empty() )
5899                 Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
5900         }
5901 
5902         if( !config.testSpec().hasFilters() )
5903             Catch::cout() << pluralise( matchedTests, "test case" ) << '\n' << std::endl;
5904         else
5905             Catch::cout() << pluralise( matchedTests, "matching test case" ) << '\n' << std::endl;
5906         return matchedTests;
5907     }
5908 
listTestsNamesOnly(Config const & config)5909     inline std::size_t listTestsNamesOnly( Config const& config ) {
5910         TestSpec testSpec = config.testSpec();
5911         if( !config.testSpec().hasFilters() )
5912             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5913         std::size_t matchedTests = 0;
5914         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5915         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5916                 it != itEnd;
5917                 ++it ) {
5918             matchedTests++;
5919             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
5920             if( startsWith( testCaseInfo.name, '#' ) )
5921                Catch::cout() << '"' << testCaseInfo.name << '"';
5922             else
5923                Catch::cout() << testCaseInfo.name;
5924             if ( config.listExtraInfo() )
5925                 Catch::cout() << "\t@" << testCaseInfo.lineInfo;
5926             Catch::cout() << std::endl;
5927         }
5928         return matchedTests;
5929     }
5930 
5931     struct TagInfo {
TagInfoCatch::TagInfo5932         TagInfo() : count ( 0 ) {}
addCatch::TagInfo5933         void add( std::string const& spelling ) {
5934             ++count;
5935             spellings.insert( spelling );
5936         }
allCatch::TagInfo5937         std::string all() const {
5938             std::string out;
5939             for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
5940                         it != itEnd;
5941                         ++it )
5942                 out += "[" + *it + "]";
5943             return out;
5944         }
5945         std::set<std::string> spellings;
5946         std::size_t count;
5947     };
5948 
listTags(Config const & config)5949     inline std::size_t listTags( Config const& config ) {
5950         TestSpec testSpec = config.testSpec();
5951         if( config.testSpec().hasFilters() )
5952             Catch::cout() << "Tags for matching test cases:\n";
5953         else {
5954             Catch::cout() << "All available tags:\n";
5955             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5956         }
5957 
5958         std::map<std::string, TagInfo> tagCounts;
5959 
5960         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5961         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5962                 it != itEnd;
5963                 ++it ) {
5964             for( std::set<std::string>::const_iterator  tagIt = it->getTestCaseInfo().tags.begin(),
5965                                                         tagItEnd = it->getTestCaseInfo().tags.end();
5966                     tagIt != tagItEnd;
5967                     ++tagIt ) {
5968                 std::string tagName = *tagIt;
5969                 std::string lcaseTagName = toLower( tagName );
5970                 std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
5971                 if( countIt == tagCounts.end() )
5972                     countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
5973                 countIt->second.add( tagName );
5974             }
5975         }
5976 
5977         for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
5978                                                             countItEnd = tagCounts.end();
5979                 countIt != countItEnd;
5980                 ++countIt ) {
5981             std::ostringstream oss;
5982             oss << "  " << std::setw(2) << countIt->second.count << "  ";
5983             Text wrapper( countIt->second.all(), TextAttributes()
5984                                                     .setInitialIndent( 0 )
5985                                                     .setIndent( oss.str().size() )
5986                                                     .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
5987             Catch::cout() << oss.str() << wrapper << '\n';
5988         }
5989         Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
5990         return tagCounts.size();
5991     }
5992 
listReporters(Config const &)5993     inline std::size_t listReporters( Config const& /*config*/ ) {
5994         Catch::cout() << "Available reporters:\n";
5995         IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
5996         IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
5997         std::size_t maxNameLen = 0;
5998         for(it = itBegin; it != itEnd; ++it )
5999             maxNameLen = (std::max)( maxNameLen, it->first.size() );
6000 
6001         for(it = itBegin; it != itEnd; ++it ) {
6002             Text wrapper( it->second->getDescription(), TextAttributes()
6003                                                         .setInitialIndent( 0 )
6004                                                         .setIndent( 7+maxNameLen )
6005                                                         .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
6006             Catch::cout() << "  "
6007                     << it->first
6008                     << ':'
6009                     << std::string( maxNameLen - it->first.size() + 2, ' ' )
6010                     << wrapper << '\n';
6011         }
6012         Catch::cout() << std::endl;
6013         return factories.size();
6014     }
6015 
list(Config const & config)6016     inline Option<std::size_t> list( Config const& config ) {
6017         Option<std::size_t> listedCount;
6018         if( config.listTests() || ( config.listExtraInfo() && !config.listTestNamesOnly() ) )
6019             listedCount = listedCount.valueOr(0) + listTests( config );
6020         if( config.listTestNamesOnly() )
6021             listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
6022         if( config.listTags() )
6023             listedCount = listedCount.valueOr(0) + listTags( config );
6024         if( config.listReporters() )
6025             listedCount = listedCount.valueOr(0) + listReporters( config );
6026         return listedCount;
6027     }
6028 
6029 } // end namespace Catch
6030 
6031 // #included from: internal/catch_run_context.hpp
6032 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
6033 
6034 // #included from: catch_test_case_tracker.hpp
6035 #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
6036 
6037 #include <algorithm>
6038 #include <string>
6039 #include <assert.h>
6040 #include <vector>
6041 #include <stdexcept>
6042 
6043 CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS
6044 
6045 namespace Catch {
6046 namespace TestCaseTracking {
6047 
6048     struct NameAndLocation {
6049         std::string name;
6050         SourceLineInfo location;
6051 
NameAndLocationCatch::TestCaseTracking::NameAndLocation6052         NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
6053         :   name( _name ),
6054             location( _location )
6055         {}
6056     };
6057 
6058     struct ITracker : SharedImpl<> {
6059         virtual ~ITracker();
6060 
6061         // static queries
6062         virtual NameAndLocation const& nameAndLocation() const = 0;
6063 
6064         // dynamic queries
6065         virtual bool isComplete() const = 0; // Successfully completed or failed
6066         virtual bool isSuccessfullyCompleted() const = 0;
6067         virtual bool isOpen() const = 0; // Started but not complete
6068         virtual bool hasChildren() const = 0;
6069 
6070         virtual ITracker& parent() = 0;
6071 
6072         // actions
6073         virtual void close() = 0; // Successfully complete
6074         virtual void fail() = 0;
6075         virtual void markAsNeedingAnotherRun() = 0;
6076 
6077         virtual void addChild( Ptr<ITracker> const& child ) = 0;
6078         virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0;
6079         virtual void openChild() = 0;
6080 
6081         // Debug/ checking
6082         virtual bool isSectionTracker() const = 0;
6083         virtual bool isIndexTracker() const = 0;
6084     };
6085 
6086     class  TrackerContext {
6087 
6088         enum RunState {
6089             NotStarted,
6090             Executing,
6091             CompletedCycle
6092         };
6093 
6094         Ptr<ITracker> m_rootTracker;
6095         ITracker* m_currentTracker;
6096         RunState m_runState;
6097 
6098     public:
6099 
instance()6100         static TrackerContext& instance() {
6101             static TrackerContext s_instance;
6102             return s_instance;
6103         }
6104 
TrackerContext()6105         TrackerContext()
6106         :   m_currentTracker( CATCH_NULL ),
6107             m_runState( NotStarted )
6108         {}
6109 
6110         ITracker& startRun();
6111 
endRun()6112         void endRun() {
6113             m_rootTracker.reset();
6114             m_currentTracker = CATCH_NULL;
6115             m_runState = NotStarted;
6116         }
6117 
startCycle()6118         void startCycle() {
6119             m_currentTracker = m_rootTracker.get();
6120             m_runState = Executing;
6121         }
completeCycle()6122         void completeCycle() {
6123             m_runState = CompletedCycle;
6124         }
6125 
completedCycle() const6126         bool completedCycle() const {
6127             return m_runState == CompletedCycle;
6128         }
currentTracker()6129         ITracker& currentTracker() {
6130             return *m_currentTracker;
6131         }
setCurrentTracker(ITracker * tracker)6132         void setCurrentTracker( ITracker* tracker ) {
6133             m_currentTracker = tracker;
6134         }
6135     };
6136 
6137     class TrackerBase : public ITracker {
6138     protected:
6139         enum CycleState {
6140             NotStarted,
6141             Executing,
6142             ExecutingChildren,
6143             NeedsAnotherRun,
6144             CompletedSuccessfully,
6145             Failed
6146         };
6147         class TrackerHasName {
6148             NameAndLocation m_nameAndLocation;
6149         public:
TrackerHasName(NameAndLocation const & nameAndLocation)6150             TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
operator ()(Ptr<ITracker> const & tracker)6151             bool operator ()( Ptr<ITracker> const& tracker ) {
6152                 return
6153                     tracker->nameAndLocation().name == m_nameAndLocation.name &&
6154                     tracker->nameAndLocation().location == m_nameAndLocation.location;
6155             }
6156         };
6157         typedef std::vector<Ptr<ITracker> > Children;
6158         NameAndLocation m_nameAndLocation;
6159         TrackerContext& m_ctx;
6160         ITracker* m_parent;
6161         Children m_children;
6162         CycleState m_runState;
6163     public:
TrackerBase(NameAndLocation const & nameAndLocation,TrackerContext & ctx,ITracker * parent)6164         TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
6165         :   m_nameAndLocation( nameAndLocation ),
6166             m_ctx( ctx ),
6167             m_parent( parent ),
6168             m_runState( NotStarted )
6169         {}
6170         virtual ~TrackerBase();
6171 
nameAndLocation() const6172         virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE {
6173             return m_nameAndLocation;
6174         }
isComplete() const6175         virtual bool isComplete() const CATCH_OVERRIDE {
6176             return m_runState == CompletedSuccessfully || m_runState == Failed;
6177         }
isSuccessfullyCompleted() const6178         virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {
6179             return m_runState == CompletedSuccessfully;
6180         }
isOpen() const6181         virtual bool isOpen() const CATCH_OVERRIDE {
6182             return m_runState != NotStarted && !isComplete();
6183         }
hasChildren() const6184         virtual bool hasChildren() const CATCH_OVERRIDE {
6185             return !m_children.empty();
6186         }
6187 
addChild(Ptr<ITracker> const & child)6188         virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
6189             m_children.push_back( child );
6190         }
6191 
findChild(NameAndLocation const & nameAndLocation)6192         virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE {
6193             Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
6194             return( it != m_children.end() )
6195                 ? it->get()
6196                 : CATCH_NULL;
6197         }
parent()6198         virtual ITracker& parent() CATCH_OVERRIDE {
6199             assert( m_parent ); // Should always be non-null except for root
6200             return *m_parent;
6201         }
6202 
openChild()6203         virtual void openChild() CATCH_OVERRIDE {
6204             if( m_runState != ExecutingChildren ) {
6205                 m_runState = ExecutingChildren;
6206                 if( m_parent )
6207                     m_parent->openChild();
6208             }
6209         }
6210 
isSectionTracker() const6211         virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }
isIndexTracker() const6212         virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }
6213 
open()6214         void open() {
6215             m_runState = Executing;
6216             moveToThis();
6217             if( m_parent )
6218                 m_parent->openChild();
6219         }
6220 
close()6221         virtual void close() CATCH_OVERRIDE {
6222 
6223             // Close any still open children (e.g. generators)
6224             while( &m_ctx.currentTracker() != this )
6225                 m_ctx.currentTracker().close();
6226 
6227             switch( m_runState ) {
6228                 case NotStarted:
6229                 case CompletedSuccessfully:
6230                 case Failed:
6231                     throw std::logic_error( "Illogical state" );
6232 
6233                 case NeedsAnotherRun:
6234                     break;;
6235 
6236                 case Executing:
6237                     m_runState = CompletedSuccessfully;
6238                     break;
6239                 case ExecutingChildren:
6240                     if( m_children.empty() || m_children.back()->isComplete() )
6241                         m_runState = CompletedSuccessfully;
6242                     break;
6243 
6244                 default:
6245                     throw std::logic_error( "Unexpected state" );
6246             }
6247             moveToParent();
6248             m_ctx.completeCycle();
6249         }
fail()6250         virtual void fail() CATCH_OVERRIDE {
6251             m_runState = Failed;
6252             if( m_parent )
6253                 m_parent->markAsNeedingAnotherRun();
6254             moveToParent();
6255             m_ctx.completeCycle();
6256         }
markAsNeedingAnotherRun()6257         virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
6258             m_runState = NeedsAnotherRun;
6259         }
6260     private:
moveToParent()6261         void moveToParent() {
6262             assert( m_parent );
6263             m_ctx.setCurrentTracker( m_parent );
6264         }
moveToThis()6265         void moveToThis() {
6266             m_ctx.setCurrentTracker( this );
6267         }
6268     };
6269 
6270     class SectionTracker : public TrackerBase {
6271         std::vector<std::string> m_filters;
6272     public:
SectionTracker(NameAndLocation const & nameAndLocation,TrackerContext & ctx,ITracker * parent)6273         SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
6274         :   TrackerBase( nameAndLocation, ctx, parent )
6275         {
6276             if( parent ) {
6277                 while( !parent->isSectionTracker() )
6278                     parent = &parent->parent();
6279 
6280                 SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
6281                 addNextFilters( parentSection.m_filters );
6282             }
6283         }
6284         virtual ~SectionTracker();
6285 
isSectionTracker() const6286         virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
6287 
acquire(TrackerContext & ctx,NameAndLocation const & nameAndLocation)6288         static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
6289             SectionTracker* section = CATCH_NULL;
6290 
6291             ITracker& currentTracker = ctx.currentTracker();
6292             if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
6293                 assert( childTracker );
6294                 assert( childTracker->isSectionTracker() );
6295                 section = static_cast<SectionTracker*>( childTracker );
6296             }
6297             else {
6298                 section = new SectionTracker( nameAndLocation, ctx, &currentTracker );
6299                 currentTracker.addChild( section );
6300             }
6301             if( !ctx.completedCycle() )
6302                 section->tryOpen();
6303             return *section;
6304         }
6305 
tryOpen()6306         void tryOpen() {
6307             if( !isComplete() && (m_filters.empty() || m_filters[0].empty() ||  m_filters[0] == m_nameAndLocation.name ) )
6308                 open();
6309         }
6310 
addInitialFilters(std::vector<std::string> const & filters)6311         void addInitialFilters( std::vector<std::string> const& filters ) {
6312             if( !filters.empty() ) {
6313                 m_filters.push_back(""); // Root - should never be consulted
6314                 m_filters.push_back(""); // Test Case - not a section filter
6315                 m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
6316             }
6317         }
addNextFilters(std::vector<std::string> const & filters)6318         void addNextFilters( std::vector<std::string> const& filters ) {
6319             if( filters.size() > 1 )
6320                 m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
6321         }
6322     };
6323 
6324     class IndexTracker : public TrackerBase {
6325         int m_size;
6326         int m_index;
6327     public:
IndexTracker(NameAndLocation const & nameAndLocation,TrackerContext & ctx,ITracker * parent,int size)6328         IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size )
6329         :   TrackerBase( nameAndLocation, ctx, parent ),
6330             m_size( size ),
6331             m_index( -1 )
6332         {}
6333         virtual ~IndexTracker();
6334 
isIndexTracker() const6335         virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
6336 
acquire(TrackerContext & ctx,NameAndLocation const & nameAndLocation,int size)6337         static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) {
6338             IndexTracker* tracker = CATCH_NULL;
6339 
6340             ITracker& currentTracker = ctx.currentTracker();
6341             if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
6342                 assert( childTracker );
6343                 assert( childTracker->isIndexTracker() );
6344                 tracker = static_cast<IndexTracker*>( childTracker );
6345             }
6346             else {
6347                 tracker = new IndexTracker( nameAndLocation, ctx, &currentTracker, size );
6348                 currentTracker.addChild( tracker );
6349             }
6350 
6351             if( !ctx.completedCycle() && !tracker->isComplete() ) {
6352                 if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
6353                     tracker->moveNext();
6354                 tracker->open();
6355             }
6356 
6357             return *tracker;
6358         }
6359 
index() const6360         int index() const { return m_index; }
6361 
moveNext()6362         void moveNext() {
6363             m_index++;
6364             m_children.clear();
6365         }
6366 
close()6367         virtual void close() CATCH_OVERRIDE {
6368             TrackerBase::close();
6369             if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
6370                 m_runState = Executing;
6371         }
6372     };
6373 
startRun()6374     inline ITracker& TrackerContext::startRun() {
6375         m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL );
6376         m_currentTracker = CATCH_NULL;
6377         m_runState = Executing;
6378         return *m_rootTracker;
6379     }
6380 
6381 } // namespace TestCaseTracking
6382 
6383 using TestCaseTracking::ITracker;
6384 using TestCaseTracking::TrackerContext;
6385 using TestCaseTracking::SectionTracker;
6386 using TestCaseTracking::IndexTracker;
6387 
6388 } // namespace Catch
6389 
6390 CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
6391 
6392 // #included from: catch_fatal_condition.hpp
6393 #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
6394 
6395 namespace Catch {
6396 
6397     // Report the error condition
reportFatal(std::string const & message)6398     inline void reportFatal( std::string const& message ) {
6399         IContext& context = Catch::getCurrentContext();
6400         IResultCapture* resultCapture = context.getResultCapture();
6401         resultCapture->handleFatalErrorCondition( message );
6402     }
6403 
6404 } // namespace Catch
6405 
6406 #if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
6407 // #included from: catch_windows_h_proxy.h
6408 
6409 #define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED
6410 
6411 #ifdef CATCH_DEFINES_NOMINMAX
6412 #  define NOMINMAX
6413 #endif
6414 #ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
6415 #  define WIN32_LEAN_AND_MEAN
6416 #endif
6417 
6418 #ifdef __AFXDLL
6419 #include <AfxWin.h>
6420 #else
6421 #include <windows.h>
6422 #endif
6423 
6424 #ifdef CATCH_DEFINES_NOMINMAX
6425 #  undef NOMINMAX
6426 #endif
6427 #ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
6428 #  undef WIN32_LEAN_AND_MEAN
6429 #endif
6430 
6431 
6432 #  if !defined ( CATCH_CONFIG_WINDOWS_SEH )
6433 
6434 namespace Catch {
6435     struct FatalConditionHandler {
resetCatch::FatalConditionHandler6436         void reset() {}
6437     };
6438 }
6439 
6440 #  else // CATCH_CONFIG_WINDOWS_SEH is defined
6441 
6442 namespace Catch {
6443 
6444     struct SignalDefs { DWORD id; const char* name; };
6445     extern SignalDefs signalDefs[];
6446     // There is no 1-1 mapping between signals and windows exceptions.
6447     // Windows can easily distinguish between SO and SigSegV,
6448     // but SigInt, SigTerm, etc are handled differently.
6449     SignalDefs signalDefs[] = {
6450         { EXCEPTION_ILLEGAL_INSTRUCTION,  "SIGILL - Illegal instruction signal" },
6451         { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
6452         { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
6453         { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
6454     };
6455 
6456     struct FatalConditionHandler {
6457 
handleVectoredExceptionCatch::FatalConditionHandler6458         static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
6459             for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
6460                 if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
6461                     reportFatal(signalDefs[i].name);
6462                 }
6463             }
6464             // If its not an exception we care about, pass it along.
6465             // This stops us from eating debugger breaks etc.
6466             return EXCEPTION_CONTINUE_SEARCH;
6467         }
6468 
FatalConditionHandlerCatch::FatalConditionHandler6469         FatalConditionHandler() {
6470             isSet = true;
6471             // 32k seems enough for Catch to handle stack overflow,
6472             // but the value was found experimentally, so there is no strong guarantee
6473             guaranteeSize = 32 * 1024;
6474             exceptionHandlerHandle = CATCH_NULL;
6475             // Register as first handler in current chain
6476             exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
6477             // Pass in guarantee size to be filled
6478             SetThreadStackGuarantee(&guaranteeSize);
6479         }
6480 
resetCatch::FatalConditionHandler6481         static void reset() {
6482             if (isSet) {
6483                 // Unregister handler and restore the old guarantee
6484                 RemoveVectoredExceptionHandler(exceptionHandlerHandle);
6485                 SetThreadStackGuarantee(&guaranteeSize);
6486                 exceptionHandlerHandle = CATCH_NULL;
6487                 isSet = false;
6488             }
6489         }
6490 
~FatalConditionHandlerCatch::FatalConditionHandler6491         ~FatalConditionHandler() {
6492             reset();
6493         }
6494     private:
6495         static bool isSet;
6496         static ULONG guaranteeSize;
6497         static PVOID exceptionHandlerHandle;
6498     };
6499 
6500     bool FatalConditionHandler::isSet = false;
6501     ULONG FatalConditionHandler::guaranteeSize = 0;
6502     PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL;
6503 
6504 } // namespace Catch
6505 
6506 #  endif // CATCH_CONFIG_WINDOWS_SEH
6507 
6508 #else // Not Windows - assumed to be POSIX compatible //////////////////////////
6509 
6510 #  if !defined(CATCH_CONFIG_POSIX_SIGNALS)
6511 
6512 namespace Catch {
6513     struct FatalConditionHandler {
resetCatch::FatalConditionHandler6514         void reset() {}
6515     };
6516 }
6517 
6518 #  else // CATCH_CONFIG_POSIX_SIGNALS is defined
6519 
6520 #include <signal.h>
6521 
6522 namespace Catch {
6523 
6524     struct SignalDefs {
6525         int id;
6526         const char* name;
6527     };
6528     extern SignalDefs signalDefs[];
6529     SignalDefs signalDefs[] = {
6530             { SIGINT,  "SIGINT - Terminal interrupt signal" },
6531             { SIGILL,  "SIGILL - Illegal instruction signal" },
6532             { SIGFPE,  "SIGFPE - Floating point error signal" },
6533             { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
6534             { SIGTERM, "SIGTERM - Termination request signal" },
6535             { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
6536     };
6537 
6538     struct FatalConditionHandler {
6539 
6540         static bool isSet;
6541         static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)];
6542         static stack_t oldSigStack;
6543         static char altStackMem[SIGSTKSZ];
6544 
handleSignalCatch::FatalConditionHandler6545         static void handleSignal( int sig ) {
6546             std::string name = "<unknown signal>";
6547             for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
6548                 SignalDefs &def = signalDefs[i];
6549                 if (sig == def.id) {
6550                     name = def.name;
6551                     break;
6552                 }
6553             }
6554             reset();
6555             reportFatal(name);
6556             raise( sig );
6557         }
6558 
FatalConditionHandlerCatch::FatalConditionHandler6559         FatalConditionHandler() {
6560             isSet = true;
6561             stack_t sigStack;
6562             sigStack.ss_sp = altStackMem;
6563             sigStack.ss_size = SIGSTKSZ;
6564             sigStack.ss_flags = 0;
6565             sigaltstack(&sigStack, &oldSigStack);
6566             struct sigaction sa = { 0 };
6567 
6568             sa.sa_handler = handleSignal;
6569             sa.sa_flags = SA_ONSTACK;
6570             for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
6571                 sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
6572             }
6573         }
6574 
~FatalConditionHandlerCatch::FatalConditionHandler6575         ~FatalConditionHandler() {
6576             reset();
6577         }
resetCatch::FatalConditionHandler6578         static void reset() {
6579             if( isSet ) {
6580                 // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
6581                 for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
6582                     sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL);
6583                 }
6584                 // Return the old stack
6585                 sigaltstack(&oldSigStack, CATCH_NULL);
6586                 isSet = false;
6587             }
6588         }
6589     };
6590 
6591     bool FatalConditionHandler::isSet = false;
6592     struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
6593     stack_t FatalConditionHandler::oldSigStack = {};
6594     char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
6595 
6596 } // namespace Catch
6597 
6598 #  endif // CATCH_CONFIG_POSIX_SIGNALS
6599 
6600 #endif // not Windows
6601 
6602 #include <cassert>
6603 #include <set>
6604 #include <string>
6605 
6606 namespace Catch {
6607 
6608     class StreamRedirect {
6609 
6610     public:
StreamRedirect(std::ostream & stream,std::string & targetString)6611         StreamRedirect( std::ostream& stream, std::string& targetString )
6612         :   m_stream( stream ),
6613             m_prevBuf( stream.rdbuf() ),
6614             m_targetString( targetString )
6615         {
6616             stream.rdbuf( m_oss.rdbuf() );
6617         }
6618 
~StreamRedirect()6619         ~StreamRedirect() {
6620             m_targetString += m_oss.str();
6621             m_stream.rdbuf( m_prevBuf );
6622         }
6623 
6624     private:
6625         std::ostream& m_stream;
6626         std::streambuf* m_prevBuf;
6627         std::ostringstream m_oss;
6628         std::string& m_targetString;
6629     };
6630 
6631     // StdErr has two constituent streams in C++, std::cerr and std::clog
6632     // This means that we need to redirect 2 streams into 1 to keep proper
6633     // order of writes and cannot use StreamRedirect on its own
6634     class StdErrRedirect {
6635     public:
StdErrRedirect(std::string & targetString)6636         StdErrRedirect(std::string& targetString)
6637         :m_cerrBuf( cerr().rdbuf() ), m_clogBuf(clog().rdbuf()),
6638         m_targetString(targetString){
6639             cerr().rdbuf(m_oss.rdbuf());
6640             clog().rdbuf(m_oss.rdbuf());
6641         }
~StdErrRedirect()6642         ~StdErrRedirect() {
6643             m_targetString += m_oss.str();
6644             cerr().rdbuf(m_cerrBuf);
6645             clog().rdbuf(m_clogBuf);
6646         }
6647     private:
6648         std::streambuf* m_cerrBuf;
6649         std::streambuf* m_clogBuf;
6650         std::ostringstream m_oss;
6651         std::string& m_targetString;
6652     };
6653 
6654     ///////////////////////////////////////////////////////////////////////////
6655 
6656     class RunContext : public IResultCapture, public IRunner {
6657 
6658         RunContext( RunContext const& );
6659         void operator =( RunContext const& );
6660 
6661     public:
6662 
RunContext(Ptr<IConfig const> const & _config,Ptr<IStreamingReporter> const & reporter)6663         explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )
6664         :   m_runInfo( _config->name() ),
6665             m_context( getCurrentMutableContext() ),
6666             m_activeTestCase( CATCH_NULL ),
6667             m_config( _config ),
6668             m_reporter( reporter ),
6669             m_shouldReportUnexpected ( true )
6670         {
6671             m_context.setRunner( this );
6672             m_context.setConfig( m_config );
6673             m_context.setResultCapture( this );
6674             m_reporter->testRunStarting( m_runInfo );
6675         }
6676 
~RunContext()6677         virtual ~RunContext() {
6678             m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
6679         }
6680 
testGroupStarting(std::string const & testSpec,std::size_t groupIndex,std::size_t groupsCount)6681         void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
6682             m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
6683         }
testGroupEnded(std::string const & testSpec,Totals const & totals,std::size_t groupIndex,std::size_t groupsCount)6684         void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
6685             m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
6686         }
6687 
runTest(TestCase const & testCase)6688         Totals runTest( TestCase const& testCase ) {
6689             Totals prevTotals = m_totals;
6690 
6691             std::string redirectedCout;
6692             std::string redirectedCerr;
6693 
6694             TestCaseInfo testInfo = testCase.getTestCaseInfo();
6695 
6696             m_reporter->testCaseStarting( testInfo );
6697 
6698             m_activeTestCase = &testCase;
6699 
6700             do {
6701                 ITracker& rootTracker = m_trackerContext.startRun();
6702                 assert( rootTracker.isSectionTracker() );
6703                 static_cast<SectionTracker&>( rootTracker ).addInitialFilters( m_config->getSectionsToRun() );
6704                 do {
6705                     m_trackerContext.startCycle();
6706                     m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) );
6707                     runCurrentTest( redirectedCout, redirectedCerr );
6708                 }
6709                 while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
6710             }
6711             // !TBD: deprecated - this will be replaced by indexed trackers
6712             while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
6713 
6714             Totals deltaTotals = m_totals.delta( prevTotals );
6715             if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {
6716                 deltaTotals.assertions.failed++;
6717                 deltaTotals.testCases.passed--;
6718                 deltaTotals.testCases.failed++;
6719             }
6720             m_totals.testCases += deltaTotals.testCases;
6721             m_reporter->testCaseEnded( TestCaseStats(   testInfo,
6722                                                         deltaTotals,
6723                                                         redirectedCout,
6724                                                         redirectedCerr,
6725                                                         aborting() ) );
6726 
6727             m_activeTestCase = CATCH_NULL;
6728             m_testCaseTracker = CATCH_NULL;
6729 
6730             return deltaTotals;
6731         }
6732 
config() const6733         Ptr<IConfig const> config() const {
6734             return m_config;
6735         }
6736 
6737     private: // IResultCapture
6738 
assertionEnded(AssertionResult const & result)6739         virtual void assertionEnded( AssertionResult const& result ) {
6740             if( result.getResultType() == ResultWas::Ok ) {
6741                 m_totals.assertions.passed++;
6742             }
6743             else if( !result.isOk() ) {
6744                 if( m_activeTestCase->getTestCaseInfo().okToFail() )
6745                     m_totals.assertions.failedButOk++;
6746                 else
6747                     m_totals.assertions.failed++;
6748             }
6749 
6750             // We have no use for the return value (whether messages should be cleared), because messages were made scoped
6751             // and should be let to clear themselves out.
6752             static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
6753 
6754             // Reset working state
6755             m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
6756             m_lastResult = result;
6757         }
6758 
lastAssertionPassed()6759         virtual bool lastAssertionPassed()
6760         {
6761             return m_totals.assertions.passed == (m_prevPassed + 1);
6762         }
6763 
assertionPassed()6764         virtual void assertionPassed()
6765         {
6766             m_totals.assertions.passed++;
6767             m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}";
6768             m_lastAssertionInfo.macroName = "";
6769         }
6770 
assertionRun()6771         virtual void assertionRun()
6772         {
6773             m_prevPassed = m_totals.assertions.passed;
6774         }
6775 
sectionStarted(SectionInfo const & sectionInfo,Counts & assertions)6776         virtual bool sectionStarted (
6777             SectionInfo const& sectionInfo,
6778             Counts& assertions
6779         )
6780         {
6781             ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( sectionInfo.name, sectionInfo.lineInfo ) );
6782             if( !sectionTracker.isOpen() )
6783                 return false;
6784             m_activeSections.push_back( &sectionTracker );
6785 
6786             m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
6787 
6788             m_reporter->sectionStarting( sectionInfo );
6789 
6790             assertions = m_totals.assertions;
6791 
6792             return true;
6793         }
testForMissingAssertions(Counts & assertions)6794         bool testForMissingAssertions( Counts& assertions ) {
6795             if( assertions.total() != 0 )
6796                 return false;
6797             if( !m_config->warnAboutMissingAssertions() )
6798                 return false;
6799             if( m_trackerContext.currentTracker().hasChildren() )
6800                 return false;
6801             m_totals.assertions.failed++;
6802             assertions.failed++;
6803             return true;
6804         }
6805 
sectionEnded(SectionEndInfo const & endInfo)6806         virtual void sectionEnded( SectionEndInfo const& endInfo ) {
6807             Counts assertions = m_totals.assertions - endInfo.prevAssertions;
6808             bool missingAssertions = testForMissingAssertions( assertions );
6809 
6810             if( !m_activeSections.empty() ) {
6811                 m_activeSections.back()->close();
6812                 m_activeSections.pop_back();
6813             }
6814 
6815             m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
6816             m_messages.clear();
6817         }
6818 
sectionEndedEarly(SectionEndInfo const & endInfo)6819         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
6820             if( m_unfinishedSections.empty() )
6821                 m_activeSections.back()->fail();
6822             else
6823                 m_activeSections.back()->close();
6824             m_activeSections.pop_back();
6825 
6826             m_unfinishedSections.push_back( endInfo );
6827         }
6828 
pushScopedMessage(MessageInfo const & message)6829         virtual void pushScopedMessage( MessageInfo const& message ) {
6830             m_messages.push_back( message );
6831         }
6832 
popScopedMessage(MessageInfo const & message)6833         virtual void popScopedMessage( MessageInfo const& message ) {
6834             m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
6835         }
6836 
getCurrentTestName() const6837         virtual std::string getCurrentTestName() const {
6838             return m_activeTestCase
6839                 ? m_activeTestCase->getTestCaseInfo().name
6840                 : std::string();
6841         }
6842 
getLastResult() const6843         virtual const AssertionResult* getLastResult() const {
6844             return &m_lastResult;
6845         }
6846 
exceptionEarlyReported()6847         virtual void exceptionEarlyReported() {
6848             m_shouldReportUnexpected = false;
6849         }
6850 
handleFatalErrorCondition(std::string const & message)6851         virtual void handleFatalErrorCondition( std::string const& message ) {
6852             // Don't rebuild the result -- the stringification itself can cause more fatal errors
6853             // Instead, fake a result data.
6854             AssertionResultData tempResult;
6855             tempResult.resultType = ResultWas::FatalErrorCondition;
6856             tempResult.message = message;
6857             AssertionResult result(m_lastAssertionInfo, tempResult);
6858 
6859             getResultCapture().assertionEnded(result);
6860 
6861             handleUnfinishedSections();
6862 
6863             // Recreate section for test case (as we will lose the one that was in scope)
6864             TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
6865             SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
6866 
6867             Counts assertions;
6868             assertions.failed = 1;
6869             SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
6870             m_reporter->sectionEnded( testCaseSectionStats );
6871 
6872             TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
6873 
6874             Totals deltaTotals;
6875             deltaTotals.testCases.failed = 1;
6876             deltaTotals.assertions.failed = 1;
6877             m_reporter->testCaseEnded( TestCaseStats(   testInfo,
6878                                                         deltaTotals,
6879                                                         std::string(),
6880                                                         std::string(),
6881                                                         false ) );
6882             m_totals.testCases.failed++;
6883             testGroupEnded( std::string(), m_totals, 1, 1 );
6884             m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
6885         }
6886 
6887     public:
6888         // !TBD We need to do this another way!
aborting() const6889         bool aborting() const {
6890             return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
6891         }
6892 
6893     private:
6894 
runCurrentTest(std::string & redirectedCout,std::string & redirectedCerr)6895         void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
6896             TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
6897             SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
6898             m_reporter->sectionStarting( testCaseSection );
6899             Counts prevAssertions = m_totals.assertions;
6900             double duration = 0;
6901             m_shouldReportUnexpected = true;
6902             try {
6903                 m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
6904 
6905                 seedRng( *m_config );
6906 
6907                 Timer timer;
6908                 timer.start();
6909                 if( m_reporter->getPreferences().shouldRedirectStdOut ) {
6910                     StreamRedirect coutRedir( Catch::cout(), redirectedCout );
6911                     StdErrRedirect errRedir( redirectedCerr );
6912                     invokeActiveTestCase();
6913                 }
6914                 else {
6915                     invokeActiveTestCase();
6916                 }
6917                 duration = timer.getElapsedSeconds();
6918             }
6919             catch( TestFailureException& ) {
6920                 // This just means the test was aborted due to failure
6921             }
6922             catch(...) {
6923                 // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
6924                 // are reported without translation at the point of origin.
6925                 if (m_shouldReportUnexpected) {
6926                     makeUnexpectedResultBuilder().useActiveException();
6927                 }
6928             }
6929             m_testCaseTracker->close();
6930             handleUnfinishedSections();
6931             m_messages.clear();
6932 
6933             Counts assertions = m_totals.assertions - prevAssertions;
6934             bool missingAssertions = testForMissingAssertions( assertions );
6935 
6936             SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
6937             m_reporter->sectionEnded( testCaseSectionStats );
6938         }
6939 
invokeActiveTestCase()6940         void invokeActiveTestCase() {
6941             FatalConditionHandler fatalConditionHandler; // Handle signals
6942             m_activeTestCase->invoke();
6943             fatalConditionHandler.reset();
6944         }
6945 
6946     private:
6947 
makeUnexpectedResultBuilder() const6948         ResultBuilder makeUnexpectedResultBuilder() const {
6949             return ResultBuilder(   m_lastAssertionInfo.macroName,
6950                                     m_lastAssertionInfo.lineInfo,
6951                                     m_lastAssertionInfo.capturedExpression,
6952                                     m_lastAssertionInfo.resultDisposition );
6953         }
6954 
handleUnfinishedSections()6955         void handleUnfinishedSections() {
6956             // If sections ended prematurely due to an exception we stored their
6957             // infos here so we can tear them down outside the unwind process.
6958             for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
6959                         itEnd = m_unfinishedSections.rend();
6960                     it != itEnd;
6961                     ++it )
6962                 sectionEnded( *it );
6963             m_unfinishedSections.clear();
6964         }
6965 
6966         TestRunInfo m_runInfo;
6967         IMutableContext& m_context;
6968         TestCase const* m_activeTestCase;
6969         ITracker* m_testCaseTracker;
6970         ITracker* m_currentSectionTracker;
6971         AssertionResult m_lastResult;
6972 
6973         Ptr<IConfig const> m_config;
6974         Totals m_totals;
6975         Ptr<IStreamingReporter> m_reporter;
6976         std::vector<MessageInfo> m_messages;
6977         AssertionInfo m_lastAssertionInfo;
6978         std::vector<SectionEndInfo> m_unfinishedSections;
6979         std::vector<ITracker*> m_activeSections;
6980         TrackerContext m_trackerContext;
6981         size_t m_prevPassed;
6982         bool m_shouldReportUnexpected;
6983     };
6984 
getResultCapture()6985     IResultCapture& getResultCapture() {
6986         if( IResultCapture* capture = getCurrentContext().getResultCapture() )
6987             return *capture;
6988         else
6989             throw std::logic_error( "No result capture instance" );
6990     }
6991 
6992 } // end namespace Catch
6993 
6994 // #included from: internal/catch_version.h
6995 #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
6996 
6997 namespace Catch {
6998 
6999     // Versioning information
7000     struct Version {
7001         Version(    unsigned int _majorVersion,
7002                     unsigned int _minorVersion,
7003                     unsigned int _patchNumber,
7004                     char const * const _branchName,
7005                     unsigned int _buildNumber );
7006 
7007         unsigned int const majorVersion;
7008         unsigned int const minorVersion;
7009         unsigned int const patchNumber;
7010 
7011         // buildNumber is only used if branchName is not null
7012         char const * const branchName;
7013         unsigned int const buildNumber;
7014 
7015         friend std::ostream& operator << ( std::ostream& os, Version const& version );
7016 
7017     private:
7018         void operator=( Version const& );
7019     };
7020 
7021     inline Version libraryVersion();
7022 }
7023 
7024 #include <fstream>
7025 #include <stdlib.h>
7026 #include <limits>
7027 
7028 namespace Catch {
7029 
createReporter(std::string const & reporterName,Ptr<Config> const & config)7030     Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
7031         Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
7032         if( !reporter ) {
7033             std::ostringstream oss;
7034             oss << "No reporter registered with name: '" << reporterName << "'";
7035             throw std::domain_error( oss.str() );
7036         }
7037         return reporter;
7038     }
7039 
7040 #if !defined(CATCH_CONFIG_DEFAULT_REPORTER)
7041 #define CATCH_CONFIG_DEFAULT_REPORTER "console"
7042 #endif
7043 
makeReporter(Ptr<Config> const & config)7044     Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
7045         std::vector<std::string> reporters = config->getReporterNames();
7046         if( reporters.empty() )
7047             reporters.push_back( CATCH_CONFIG_DEFAULT_REPORTER );
7048 
7049         Ptr<IStreamingReporter> reporter;
7050         for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
7051                 it != itEnd;
7052                 ++it )
7053             reporter = addReporter( reporter, createReporter( *it, config ) );
7054         return reporter;
7055     }
addListeners(Ptr<IConfig const> const & config,Ptr<IStreamingReporter> reporters)7056     Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
7057         IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
7058         for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
7059                 it != itEnd;
7060                 ++it )
7061             reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
7062         return reporters;
7063     }
7064 
runTests(Ptr<Config> const & config)7065     Totals runTests( Ptr<Config> const& config ) {
7066 
7067         Ptr<IConfig const> iconfig = config.get();
7068 
7069         Ptr<IStreamingReporter> reporter = makeReporter( config );
7070         reporter = addListeners( iconfig, reporter );
7071 
7072         RunContext context( iconfig, reporter );
7073 
7074         Totals totals;
7075 
7076         context.testGroupStarting( config->name(), 1, 1 );
7077 
7078         TestSpec testSpec = config->testSpec();
7079         if( !testSpec.hasFilters() )
7080             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
7081 
7082         std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
7083         for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
7084                 it != itEnd;
7085                 ++it ) {
7086             if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
7087                 totals += context.runTest( *it );
7088             else
7089                 reporter->skipTest( *it );
7090         }
7091 
7092         context.testGroupEnded( iconfig->name(), totals, 1, 1 );
7093         return totals;
7094     }
7095 
applyFilenamesAsTags(IConfig const & config)7096     void applyFilenamesAsTags( IConfig const& config ) {
7097         std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
7098         for(std::size_t i = 0; i < tests.size(); ++i ) {
7099             TestCase& test = const_cast<TestCase&>( tests[i] );
7100             std::set<std::string> tags = test.tags;
7101 
7102             std::string filename = test.lineInfo.file;
7103             std::string::size_type lastSlash = filename.find_last_of( "\\/" );
7104             if( lastSlash != std::string::npos )
7105                 filename = filename.substr( lastSlash+1 );
7106 
7107             std::string::size_type lastDot = filename.find_last_of( '.' );
7108             if( lastDot != std::string::npos )
7109                 filename = filename.substr( 0, lastDot );
7110 
7111             tags.insert( '#' + filename );
7112             setTags( test, tags );
7113         }
7114     }
7115 
7116     class Session : NonCopyable {
7117         static bool alreadyInstantiated;
7118 
7119     public:
7120 
7121         struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
7122 
Session()7123         Session()
7124         : m_cli( makeCommandLineParser() ) {
7125             if( alreadyInstantiated ) {
7126                 std::string msg = "Only one instance of Catch::Session can ever be used";
7127                 Catch::cerr() << msg << std::endl;
7128                 throw std::logic_error( msg );
7129             }
7130             alreadyInstantiated = true;
7131         }
~Session()7132         ~Session() {
7133             Catch::cleanUp();
7134         }
7135 
showHelp(std::string const & processName)7136         void showHelp( std::string const& processName ) {
7137             Catch::cout() << "\nCatch v" << libraryVersion() << "\n";
7138 
7139             m_cli.usage( Catch::cout(), processName );
7140             Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
7141         }
libIdentify()7142         void libIdentify() {
7143             Catch::cout()
7144                     << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
7145                     << std::left << std::setw(16) << "category: " << "testframework\n"
7146                     << std::left << std::setw(16) << "framework: " << "Catch Test\n"
7147                     << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
7148         }
7149 
applyCommandLine(int argc,char const * const * const argv,OnUnusedOptions::DoWhat unusedOptionBehaviour=OnUnusedOptions::Fail)7150         int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
7151             try {
7152                 m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
7153                 m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );
7154                 if( m_configData.showHelp )
7155                     showHelp( m_configData.processName );
7156                 if( m_configData.libIdentify )
7157                     libIdentify();
7158                 m_config.reset();
7159             }
7160             catch( std::exception& ex ) {
7161                 {
7162                     Colour colourGuard( Colour::Red );
7163                     Catch::cerr()
7164                         << "\nError(s) in input:\n"
7165                         << Text( ex.what(), TextAttributes().setIndent(2) )
7166                         << "\n\n";
7167                 }
7168                 m_cli.usage( Catch::cout(), m_configData.processName );
7169                 return (std::numeric_limits<int>::max)();
7170             }
7171             return 0;
7172         }
7173 
useConfigData(ConfigData const & _configData)7174         void useConfigData( ConfigData const& _configData ) {
7175             m_configData = _configData;
7176             m_config.reset();
7177         }
7178 
run(int argc,char const * const * const argv)7179         int run( int argc, char const* const* const argv ) {
7180 
7181             int returnCode = applyCommandLine( argc, argv );
7182             if( returnCode == 0 )
7183                 returnCode = run();
7184             return returnCode;
7185         }
7186 
7187     #if defined(WIN32) && defined(UNICODE)
run(int argc,wchar_t const * const * const argv)7188         int run( int argc, wchar_t const* const* const argv ) {
7189 
7190             char **utf8Argv = new char *[ argc ];
7191 
7192             for ( int i = 0; i < argc; ++i ) {
7193                 int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
7194 
7195                 utf8Argv[ i ] = new char[ bufSize ];
7196 
7197                 WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
7198             }
7199 
7200             int returnCode = applyCommandLine( argc, utf8Argv );
7201             if( returnCode == 0 )
7202                 returnCode = run();
7203 
7204             for ( int i = 0; i < argc; ++i )
7205                 delete [] utf8Argv[ i ];
7206 
7207             delete [] utf8Argv;
7208 
7209             return returnCode;
7210         }
7211     #endif
7212 
run()7213         int run() {
7214             if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
7215                 Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
7216                 static_cast<void>(std::getchar());
7217             }
7218             int exitCode = runInternal();
7219             if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
7220                 Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
7221                 static_cast<void>(std::getchar());
7222             }
7223             return exitCode;
7224         }
7225 
cli() const7226         Clara::CommandLine<ConfigData> const& cli() const {
7227             return m_cli;
7228         }
unusedTokens() const7229         std::vector<Clara::Parser::Token> const& unusedTokens() const {
7230             return m_unusedTokens;
7231         }
configData()7232         ConfigData& configData() {
7233             return m_configData;
7234         }
config()7235         Config& config() {
7236             if( !m_config )
7237                 m_config = new Config( m_configData );
7238             return *m_config;
7239         }
7240     private:
7241 
runInternal()7242         int runInternal() {
7243             if( m_configData.showHelp || m_configData.libIdentify )
7244                 return 0;
7245 
7246             try
7247             {
7248                 config(); // Force config to be constructed
7249 
7250                 seedRng( *m_config );
7251 
7252                 if( m_configData.filenamesAsTags )
7253                     applyFilenamesAsTags( *m_config );
7254 
7255                 // Handle list request
7256                 if( Option<std::size_t> listed = list( config() ) )
7257                     return static_cast<int>( *listed );
7258 
7259                 return static_cast<int>( runTests( m_config ).assertions.failed );
7260             }
7261             catch( std::exception& ex ) {
7262                 Catch::cerr() << ex.what() << std::endl;
7263                 return (std::numeric_limits<int>::max)();
7264             }
7265         }
7266 
7267         Clara::CommandLine<ConfigData> m_cli;
7268         std::vector<Clara::Parser::Token> m_unusedTokens;
7269         ConfigData m_configData;
7270         Ptr<Config> m_config;
7271     };
7272 
7273     bool Session::alreadyInstantiated = false;
7274 
7275 } // end namespace Catch
7276 
7277 // #included from: catch_registry_hub.hpp
7278 #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
7279 
7280 // #included from: catch_test_case_registry_impl.hpp
7281 #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
7282 
7283 #include <vector>
7284 #include <set>
7285 #include <sstream>
7286 #include <algorithm>
7287 
7288 namespace Catch {
7289 
7290     struct RandomNumberGenerator {
7291         typedef unsigned int result_type;
7292 
operator ()Catch::RandomNumberGenerator7293         result_type operator()( result_type n ) const { return std::rand() % n; }
7294 
7295 #ifdef CATCH_CONFIG_CPP11_SHUFFLE
result_typeCatch::RandomNumberGenerator7296         static constexpr result_type (min)() { return 0; }
result_typeCatch::RandomNumberGenerator7297         static constexpr result_type (max)() { return 1000000; }
operator ()Catch::RandomNumberGenerator7298         result_type operator()() const { return std::rand() % (max)(); }
7299 #endif
7300         template<typename V>
shuffleCatch::RandomNumberGenerator7301         static void shuffle( V& vector ) {
7302             RandomNumberGenerator rng;
7303 #ifdef CATCH_CONFIG_CPP11_SHUFFLE
7304             std::shuffle( vector.begin(), vector.end(), rng );
7305 #else
7306             std::random_shuffle( vector.begin(), vector.end(), rng );
7307 #endif
7308         }
7309     };
7310 
sortTests(IConfig const & config,std::vector<TestCase> const & unsortedTestCases)7311     inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
7312 
7313         std::vector<TestCase> sorted = unsortedTestCases;
7314 
7315         switch( config.runOrder() ) {
7316             case RunTests::InLexicographicalOrder:
7317                 std::sort( sorted.begin(), sorted.end() );
7318                 break;
7319             case RunTests::InRandomOrder:
7320                 {
7321                     seedRng( config );
7322                     RandomNumberGenerator::shuffle( sorted );
7323                 }
7324                 break;
7325             case RunTests::InDeclarationOrder:
7326                 // already in declaration order
7327                 break;
7328         }
7329         return sorted;
7330     }
matchTest(TestCase const & testCase,TestSpec const & testSpec,IConfig const & config)7331     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
7332         return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
7333     }
7334 
enforceNoDuplicateTestCases(std::vector<TestCase> const & functions)7335     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
7336         std::set<TestCase> seenFunctions;
7337         for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
7338             it != itEnd;
7339             ++it ) {
7340             std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
7341             if( !prev.second ) {
7342                 std::ostringstream ss;
7343 
7344                 ss  << Colour( Colour::Red )
7345                     << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
7346                     << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << '\n'
7347                     << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
7348 
7349                 throw std::runtime_error(ss.str());
7350             }
7351         }
7352     }
7353 
filterTests(std::vector<TestCase> const & testCases,TestSpec const & testSpec,IConfig const & config)7354     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
7355         std::vector<TestCase> filtered;
7356         filtered.reserve( testCases.size() );
7357         for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
7358                 it != itEnd;
7359                 ++it )
7360             if( matchTest( *it, testSpec, config ) )
7361                 filtered.push_back( *it );
7362         return filtered;
7363     }
getAllTestCasesSorted(IConfig const & config)7364     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
7365         return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
7366     }
7367 
7368     class TestRegistry : public ITestCaseRegistry {
7369     public:
TestRegistry()7370         TestRegistry()
7371         :   m_currentSortOrder( RunTests::InDeclarationOrder ),
7372             m_unnamedCount( 0 )
7373         {}
7374         virtual ~TestRegistry();
7375 
registerTest(TestCase const & testCase)7376         virtual void registerTest( TestCase const& testCase ) {
7377             std::string name = testCase.getTestCaseInfo().name;
7378             if( name.empty() ) {
7379                 std::ostringstream oss;
7380                 oss << "Anonymous test case " << ++m_unnamedCount;
7381                 return registerTest( testCase.withName( oss.str() ) );
7382             }
7383             m_functions.push_back( testCase );
7384         }
7385 
getAllTests() const7386         virtual std::vector<TestCase> const& getAllTests() const {
7387             return m_functions;
7388         }
getAllTestsSorted(IConfig const & config) const7389         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
7390             if( m_sortedFunctions.empty() )
7391                 enforceNoDuplicateTestCases( m_functions );
7392 
7393             if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
7394                 m_sortedFunctions = sortTests( config, m_functions );
7395                 m_currentSortOrder = config.runOrder();
7396             }
7397             return m_sortedFunctions;
7398         }
7399 
7400     private:
7401         std::vector<TestCase> m_functions;
7402         mutable RunTests::InWhatOrder m_currentSortOrder;
7403         mutable std::vector<TestCase> m_sortedFunctions;
7404         size_t m_unnamedCount;
7405         std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
7406     };
7407 
7408     ///////////////////////////////////////////////////////////////////////////
7409 
7410     class FreeFunctionTestCase : public SharedImpl<ITestCase> {
7411     public:
7412 
FreeFunctionTestCase(TestFunction fun)7413         FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
7414 
invoke() const7415         virtual void invoke() const {
7416             m_fun();
7417         }
7418 
7419     private:
7420         virtual ~FreeFunctionTestCase();
7421 
7422         TestFunction m_fun;
7423     };
7424 
extractClassName(std::string const & classOrQualifiedMethodName)7425     inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
7426         std::string className = classOrQualifiedMethodName;
7427         if( startsWith( className, '&' ) )
7428         {
7429             std::size_t lastColons = className.rfind( "::" );
7430             std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
7431             if( penultimateColons == std::string::npos )
7432                 penultimateColons = 1;
7433             className = className.substr( penultimateColons, lastColons-penultimateColons );
7434         }
7435         return className;
7436     }
7437 
registerTestCase(ITestCase * testCase,char const * classOrQualifiedMethodName,NameAndDesc const & nameAndDesc,SourceLineInfo const & lineInfo)7438     void registerTestCase
7439         (   ITestCase* testCase,
7440             char const* classOrQualifiedMethodName,
7441             NameAndDesc const& nameAndDesc,
7442             SourceLineInfo const& lineInfo ) {
7443 
7444         getMutableRegistryHub().registerTest
7445             ( makeTestCase
7446                 (   testCase,
7447                     extractClassName( classOrQualifiedMethodName ),
7448                     nameAndDesc.name,
7449                     nameAndDesc.description,
7450                     lineInfo ) );
7451     }
registerTestCaseFunction(TestFunction function,SourceLineInfo const & lineInfo,NameAndDesc const & nameAndDesc)7452     void registerTestCaseFunction
7453         (   TestFunction function,
7454             SourceLineInfo const& lineInfo,
7455             NameAndDesc const& nameAndDesc ) {
7456         registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
7457     }
7458 
7459     ///////////////////////////////////////////////////////////////////////////
7460 
AutoReg(TestFunction function,SourceLineInfo const & lineInfo,NameAndDesc const & nameAndDesc)7461     AutoReg::AutoReg
7462         (   TestFunction function,
7463             SourceLineInfo const& lineInfo,
7464             NameAndDesc const& nameAndDesc ) {
7465         registerTestCaseFunction( function, lineInfo, nameAndDesc );
7466     }
7467 
~AutoReg()7468     AutoReg::~AutoReg() {}
7469 
7470 } // end namespace Catch
7471 
7472 // #included from: catch_reporter_registry.hpp
7473 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
7474 
7475 #include <map>
7476 
7477 namespace Catch {
7478 
7479     class ReporterRegistry : public IReporterRegistry {
7480 
7481     public:
7482 
~ReporterRegistry()7483         virtual ~ReporterRegistry() CATCH_OVERRIDE {}
7484 
create(std::string const & name,Ptr<IConfig const> const & config) const7485         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
7486             FactoryMap::const_iterator it =  m_factories.find( name );
7487             if( it == m_factories.end() )
7488                 return CATCH_NULL;
7489             return it->second->create( ReporterConfig( config ) );
7490         }
7491 
registerReporter(std::string const & name,Ptr<IReporterFactory> const & factory)7492         void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
7493             m_factories.insert( std::make_pair( name, factory ) );
7494         }
registerListener(Ptr<IReporterFactory> const & factory)7495         void registerListener( Ptr<IReporterFactory> const& factory ) {
7496             m_listeners.push_back( factory );
7497         }
7498 
getFactories() const7499         virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {
7500             return m_factories;
7501         }
getListeners() const7502         virtual Listeners const& getListeners() const CATCH_OVERRIDE {
7503             return m_listeners;
7504         }
7505 
7506     private:
7507         FactoryMap m_factories;
7508         Listeners m_listeners;
7509     };
7510 }
7511 
7512 // #included from: catch_exception_translator_registry.hpp
7513 #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
7514 
7515 #ifdef __OBJC__
7516 #import "Foundation/Foundation.h"
7517 #endif
7518 
7519 namespace Catch {
7520 
7521     class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
7522     public:
~ExceptionTranslatorRegistry()7523         ~ExceptionTranslatorRegistry() {
7524             deleteAll( m_translators );
7525         }
7526 
registerTranslator(const IExceptionTranslator * translator)7527         virtual void registerTranslator( const IExceptionTranslator* translator ) {
7528             m_translators.push_back( translator );
7529         }
7530 
translateActiveException() const7531         virtual std::string translateActiveException() const {
7532             try {
7533 #ifdef __OBJC__
7534                 // In Objective-C try objective-c exceptions first
7535                 @try {
7536                     return tryTranslators();
7537                 }
7538                 @catch (NSException *exception) {
7539                     return Catch::toString( [exception description] );
7540                 }
7541 #else
7542                 return tryTranslators();
7543 #endif
7544             }
7545             catch( TestFailureException& ) {
7546                 throw;
7547             }
7548             catch( std::exception& ex ) {
7549                 return ex.what();
7550             }
7551             catch( std::string& msg ) {
7552                 return msg;
7553             }
7554             catch( const char* msg ) {
7555                 return msg;
7556             }
7557             catch(...) {
7558                 return "Unknown exception";
7559             }
7560         }
7561 
tryTranslators() const7562         std::string tryTranslators() const {
7563             if( m_translators.empty() )
7564                 throw;
7565             else
7566                 return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
7567         }
7568 
7569     private:
7570         std::vector<const IExceptionTranslator*> m_translators;
7571     };
7572 }
7573 
7574 // #included from: catch_tag_alias_registry.h
7575 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
7576 
7577 #include <map>
7578 
7579 namespace Catch {
7580 
7581     class TagAliasRegistry : public ITagAliasRegistry {
7582     public:
7583         virtual ~TagAliasRegistry();
7584         virtual Option<TagAlias> find( std::string const& alias ) const;
7585         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
7586         void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
7587 
7588     private:
7589         std::map<std::string, TagAlias> m_registry;
7590     };
7591 
7592 } // end namespace Catch
7593 
7594 namespace Catch {
7595 
7596     namespace {
7597 
7598         class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
7599 
7600             RegistryHub( RegistryHub const& );
7601             void operator=( RegistryHub const& );
7602 
7603         public: // IRegistryHub
RegistryHub()7604             RegistryHub() {
7605             }
getReporterRegistry() const7606             virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {
7607                 return m_reporterRegistry;
7608             }
getTestCaseRegistry() const7609             virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {
7610                 return m_testCaseRegistry;
7611             }
getExceptionTranslatorRegistry()7612             virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
7613                 return m_exceptionTranslatorRegistry;
7614             }
getTagAliasRegistry() const7615             virtual ITagAliasRegistry const& getTagAliasRegistry() const CATCH_OVERRIDE {
7616                 return m_tagAliasRegistry;
7617             }
7618 
7619         public: // IMutableRegistryHub
registerReporter(std::string const & name,Ptr<IReporterFactory> const & factory)7620             virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
7621                 m_reporterRegistry.registerReporter( name, factory );
7622             }
registerListener(Ptr<IReporterFactory> const & factory)7623             virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
7624                 m_reporterRegistry.registerListener( factory );
7625             }
registerTest(TestCase const & testInfo)7626             virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {
7627                 m_testCaseRegistry.registerTest( testInfo );
7628             }
registerTranslator(const IExceptionTranslator * translator)7629             virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
7630                 m_exceptionTranslatorRegistry.registerTranslator( translator );
7631             }
registerTagAlias(std::string const & alias,std::string const & tag,SourceLineInfo const & lineInfo)7632             virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) CATCH_OVERRIDE {
7633                 m_tagAliasRegistry.add( alias, tag, lineInfo );
7634             }
7635 
7636         private:
7637             TestRegistry m_testCaseRegistry;
7638             ReporterRegistry m_reporterRegistry;
7639             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
7640             TagAliasRegistry m_tagAliasRegistry;
7641         };
7642 
7643         // Single, global, instance
getTheRegistryHub()7644         inline RegistryHub*& getTheRegistryHub() {
7645             static RegistryHub* theRegistryHub = CATCH_NULL;
7646             if( !theRegistryHub )
7647                 theRegistryHub = new RegistryHub();
7648             return theRegistryHub;
7649         }
7650     }
7651 
getRegistryHub()7652     IRegistryHub& getRegistryHub() {
7653         return *getTheRegistryHub();
7654     }
getMutableRegistryHub()7655     IMutableRegistryHub& getMutableRegistryHub() {
7656         return *getTheRegistryHub();
7657     }
cleanUp()7658     void cleanUp() {
7659         delete getTheRegistryHub();
7660         getTheRegistryHub() = CATCH_NULL;
7661         cleanUpContext();
7662     }
translateActiveException()7663     std::string translateActiveException() {
7664         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
7665     }
7666 
7667 } // end namespace Catch
7668 
7669 // #included from: catch_notimplemented_exception.hpp
7670 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
7671 
7672 #include <sstream>
7673 
7674 namespace Catch {
7675 
NotImplementedException(SourceLineInfo const & lineInfo)7676     NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
7677     :   m_lineInfo( lineInfo ) {
7678         std::ostringstream oss;
7679         oss << lineInfo << ": function ";
7680         oss << "not implemented";
7681         m_what = oss.str();
7682     }
7683 
what() const7684     const char* NotImplementedException::what() const CATCH_NOEXCEPT {
7685         return m_what.c_str();
7686     }
7687 
7688 } // end namespace Catch
7689 
7690 // #included from: catch_context_impl.hpp
7691 #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
7692 
7693 // #included from: catch_stream.hpp
7694 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
7695 
7696 #include <stdexcept>
7697 #include <cstdio>
7698 #include <iostream>
7699 
7700 namespace Catch {
7701 
7702     template<typename WriterF, size_t bufferSize=256>
7703     class StreamBufImpl : public StreamBufBase {
7704         char data[bufferSize];
7705         WriterF m_writer;
7706 
7707     public:
StreamBufImpl()7708         StreamBufImpl() {
7709             setp( data, data + sizeof(data) );
7710         }
7711 
~StreamBufImpl()7712         ~StreamBufImpl() CATCH_NOEXCEPT {
7713             sync();
7714         }
7715 
7716     private:
overflow(int c)7717         int overflow( int c ) {
7718             sync();
7719 
7720             if( c != EOF ) {
7721                 if( pbase() == epptr() )
7722                     m_writer( std::string( 1, static_cast<char>( c ) ) );
7723                 else
7724                     sputc( static_cast<char>( c ) );
7725             }
7726             return 0;
7727         }
7728 
sync()7729         int sync() {
7730             if( pbase() != pptr() ) {
7731                 m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
7732                 setp( pbase(), epptr() );
7733             }
7734             return 0;
7735         }
7736     };
7737 
7738     ///////////////////////////////////////////////////////////////////////////
7739 
FileStream(std::string const & filename)7740     FileStream::FileStream( std::string const& filename ) {
7741         m_ofs.open( filename.c_str() );
7742         if( m_ofs.fail() ) {
7743             std::ostringstream oss;
7744             oss << "Unable to open file: '" << filename << '\'';
7745             throw std::domain_error( oss.str() );
7746         }
7747     }
7748 
stream() const7749     std::ostream& FileStream::stream() const {
7750         return m_ofs;
7751     }
7752 
7753     struct OutputDebugWriter {
7754 
operator ()Catch::OutputDebugWriter7755         void operator()( std::string const&str ) {
7756             writeToDebugConsole( str );
7757         }
7758     };
7759 
DebugOutStream()7760     DebugOutStream::DebugOutStream()
7761     :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
7762         m_os( m_streamBuf.get() )
7763     {}
7764 
stream() const7765     std::ostream& DebugOutStream::stream() const {
7766         return m_os;
7767     }
7768 
7769     // Store the streambuf from cout up-front because
7770     // cout may get redirected when running tests
CoutStream()7771     CoutStream::CoutStream()
7772     :   m_os( Catch::cout().rdbuf() )
7773     {}
7774 
stream() const7775     std::ostream& CoutStream::stream() const {
7776         return m_os;
7777     }
7778 
7779 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
cout()7780     std::ostream& cout() {
7781         return std::cout;
7782     }
cerr()7783     std::ostream& cerr() {
7784         return std::cerr;
7785     }
clog()7786     std::ostream& clog() {
7787         return std::clog;
7788     }
7789 #endif
7790 }
7791 
7792 namespace Catch {
7793 
7794     class Context : public IMutableContext {
7795 
Context()7796         Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
7797         Context( Context const& );
7798         void operator=( Context const& );
7799 
7800     public:
~Context()7801         virtual ~Context() {
7802             deleteAllValues( m_generatorsByTestName );
7803         }
7804 
7805     public: // IContext
getResultCapture()7806         virtual IResultCapture* getResultCapture() {
7807             return m_resultCapture;
7808         }
getRunner()7809         virtual IRunner* getRunner() {
7810             return m_runner;
7811         }
getGeneratorIndex(std::string const & fileInfo,size_t totalSize)7812         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
7813             return getGeneratorsForCurrentTest()
7814             .getGeneratorInfo( fileInfo, totalSize )
7815             .getCurrentIndex();
7816         }
advanceGeneratorsForCurrentTest()7817         virtual bool advanceGeneratorsForCurrentTest() {
7818             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
7819             return generators && generators->moveNext();
7820         }
7821 
getConfig() const7822         virtual Ptr<IConfig const> getConfig() const {
7823             return m_config;
7824         }
7825 
7826     public: // IMutableContext
setResultCapture(IResultCapture * resultCapture)7827         virtual void setResultCapture( IResultCapture* resultCapture ) {
7828             m_resultCapture = resultCapture;
7829         }
setRunner(IRunner * runner)7830         virtual void setRunner( IRunner* runner ) {
7831             m_runner = runner;
7832         }
setConfig(Ptr<IConfig const> const & config)7833         virtual void setConfig( Ptr<IConfig const> const& config ) {
7834             m_config = config;
7835         }
7836 
7837         friend IMutableContext& getCurrentMutableContext();
7838 
7839     private:
findGeneratorsForCurrentTest()7840         IGeneratorsForTest* findGeneratorsForCurrentTest() {
7841             std::string testName = getResultCapture()->getCurrentTestName();
7842 
7843             std::map<std::string, IGeneratorsForTest*>::const_iterator it =
7844                 m_generatorsByTestName.find( testName );
7845             return it != m_generatorsByTestName.end()
7846                 ? it->second
7847                 : CATCH_NULL;
7848         }
7849 
getGeneratorsForCurrentTest()7850         IGeneratorsForTest& getGeneratorsForCurrentTest() {
7851             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
7852             if( !generators ) {
7853                 std::string testName = getResultCapture()->getCurrentTestName();
7854                 generators = createGeneratorsForTest();
7855                 m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
7856             }
7857             return *generators;
7858         }
7859 
7860     private:
7861         Ptr<IConfig const> m_config;
7862         IRunner* m_runner;
7863         IResultCapture* m_resultCapture;
7864         std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
7865     };
7866 
7867     namespace {
7868         Context* currentContext = CATCH_NULL;
7869     }
getCurrentMutableContext()7870     IMutableContext& getCurrentMutableContext() {
7871         if( !currentContext )
7872             currentContext = new Context();
7873         return *currentContext;
7874     }
getCurrentContext()7875     IContext& getCurrentContext() {
7876         return getCurrentMutableContext();
7877     }
7878 
cleanUpContext()7879     void cleanUpContext() {
7880         delete currentContext;
7881         currentContext = CATCH_NULL;
7882     }
7883 }
7884 
7885 // #included from: catch_console_colour_impl.hpp
7886 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
7887 
7888 // #included from: catch_errno_guard.hpp
7889 #define TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
7890 
7891 #include <cerrno>
7892 
7893 namespace Catch {
7894 
7895     class ErrnoGuard {
7896     public:
ErrnoGuard()7897         ErrnoGuard():m_oldErrno(errno){}
~ErrnoGuard()7898         ~ErrnoGuard() { errno = m_oldErrno; }
7899     private:
7900         int m_oldErrno;
7901     };
7902 
7903 }
7904 
7905 namespace Catch {
7906     namespace {
7907 
7908         struct IColourImpl {
~IColourImplCatch::__anon8bb782460511::IColourImpl7909             virtual ~IColourImpl() {}
7910             virtual void use( Colour::Code _colourCode ) = 0;
7911         };
7912 
7913         struct NoColourImpl : IColourImpl {
useCatch::__anon8bb782460511::NoColourImpl7914             void use( Colour::Code ) {}
7915 
instanceCatch::__anon8bb782460511::NoColourImpl7916             static IColourImpl* instance() {
7917                 static NoColourImpl s_instance;
7918                 return &s_instance;
7919             }
7920         };
7921 
7922     } // anon namespace
7923 } // namespace Catch
7924 
7925 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
7926 #   ifdef CATCH_PLATFORM_WINDOWS
7927 #       define CATCH_CONFIG_COLOUR_WINDOWS
7928 #   else
7929 #       define CATCH_CONFIG_COLOUR_ANSI
7930 #   endif
7931 #endif
7932 
7933 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
7934 
7935 namespace Catch {
7936 namespace {
7937 
7938     class Win32ColourImpl : public IColourImpl {
7939     public:
Win32ColourImpl()7940         Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
7941         {
7942             CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
7943             GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
7944             originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
7945             originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
7946         }
7947 
use(Colour::Code _colourCode)7948         virtual void use( Colour::Code _colourCode ) {
7949             switch( _colourCode ) {
7950                 case Colour::None:      return setTextAttribute( originalForegroundAttributes );
7951                 case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7952                 case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
7953                 case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
7954                 case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
7955                 case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
7956                 case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
7957                 case Colour::Grey:      return setTextAttribute( 0 );
7958 
7959                 case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
7960                 case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
7961                 case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
7962                 case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7963 
7964                 case Colour::Bright: throw std::logic_error( "not a colour" );
7965             }
7966         }
7967 
7968     private:
setTextAttribute(WORD _textAttribute)7969         void setTextAttribute( WORD _textAttribute ) {
7970             SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
7971         }
7972         HANDLE stdoutHandle;
7973         WORD originalForegroundAttributes;
7974         WORD originalBackgroundAttributes;
7975     };
7976 
platformColourInstance()7977     IColourImpl* platformColourInstance() {
7978         static Win32ColourImpl s_instance;
7979 
7980         Ptr<IConfig const> config = getCurrentContext().getConfig();
7981         UseColour::YesOrNo colourMode = config
7982             ? config->useColour()
7983             : UseColour::Auto;
7984         if( colourMode == UseColour::Auto )
7985             colourMode = !isDebuggerActive()
7986                 ? UseColour::Yes
7987                 : UseColour::No;
7988         return colourMode == UseColour::Yes
7989             ? &s_instance
7990             : NoColourImpl::instance();
7991     }
7992 
7993 } // end anon namespace
7994 } // end namespace Catch
7995 
7996 #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
7997 
7998 #include <unistd.h>
7999 
8000 namespace Catch {
8001 namespace {
8002 
8003     // use POSIX/ ANSI console terminal codes
8004     // Thanks to Adam Strzelecki for original contribution
8005     // (http://github.com/nanoant)
8006     // https://github.com/philsquared/Catch/pull/131
8007     class PosixColourImpl : public IColourImpl {
8008     public:
use(Colour::Code _colourCode)8009         virtual void use( Colour::Code _colourCode ) {
8010             switch( _colourCode ) {
8011                 case Colour::None:
8012                 case Colour::White:     return setColour( "[0m" );
8013                 case Colour::Red:       return setColour( "[0;31m" );
8014                 case Colour::Green:     return setColour( "[0;32m" );
8015                 case Colour::Blue:      return setColour( "[0;34m" );
8016                 case Colour::Cyan:      return setColour( "[0;36m" );
8017                 case Colour::Yellow:    return setColour( "[0;33m" );
8018                 case Colour::Grey:      return setColour( "[1;30m" );
8019 
8020                 case Colour::LightGrey:     return setColour( "[0;37m" );
8021                 case Colour::BrightRed:     return setColour( "[1;31m" );
8022                 case Colour::BrightGreen:   return setColour( "[1;32m" );
8023                 case Colour::BrightWhite:   return setColour( "[1;37m" );
8024 
8025                 case Colour::Bright: throw std::logic_error( "not a colour" );
8026             }
8027         }
instance()8028         static IColourImpl* instance() {
8029             static PosixColourImpl s_instance;
8030             return &s_instance;
8031         }
8032 
8033     private:
setColour(const char * _escapeCode)8034         void setColour( const char* _escapeCode ) {
8035             Catch::cout() << '\033' << _escapeCode;
8036         }
8037     };
8038 
platformColourInstance()8039     IColourImpl* platformColourInstance() {
8040         ErrnoGuard guard;
8041         Ptr<IConfig const> config = getCurrentContext().getConfig();
8042         UseColour::YesOrNo colourMode = config
8043             ? config->useColour()
8044             : UseColour::Auto;
8045         if( colourMode == UseColour::Auto )
8046             colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )
8047                 ? UseColour::Yes
8048                 : UseColour::No;
8049         return colourMode == UseColour::Yes
8050             ? PosixColourImpl::instance()
8051             : NoColourImpl::instance();
8052     }
8053 
8054 } // end anon namespace
8055 } // end namespace Catch
8056 
8057 #else  // not Windows or ANSI ///////////////////////////////////////////////
8058 
8059 namespace Catch {
8060 
platformColourInstance()8061     static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
8062 
8063 } // end namespace Catch
8064 
8065 #endif // Windows/ ANSI/ None
8066 
8067 namespace Catch {
8068 
Colour(Code _colourCode)8069     Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
Colour(Colour const & _other)8070     Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
~Colour()8071     Colour::~Colour(){ if( !m_moved ) use( None ); }
8072 
use(Code _colourCode)8073     void Colour::use( Code _colourCode ) {
8074         static IColourImpl* impl = platformColourInstance();
8075         impl->use( _colourCode );
8076     }
8077 
8078 } // end namespace Catch
8079 
8080 // #included from: catch_generators_impl.hpp
8081 #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
8082 
8083 #include <vector>
8084 #include <string>
8085 #include <map>
8086 
8087 namespace Catch {
8088 
8089     struct GeneratorInfo : IGeneratorInfo {
8090 
GeneratorInfoCatch::GeneratorInfo8091         GeneratorInfo( std::size_t size )
8092         :   m_size( size ),
8093             m_currentIndex( 0 )
8094         {}
8095 
moveNextCatch::GeneratorInfo8096         bool moveNext() {
8097             if( ++m_currentIndex == m_size ) {
8098                 m_currentIndex = 0;
8099                 return false;
8100             }
8101             return true;
8102         }
8103 
getCurrentIndexCatch::GeneratorInfo8104         std::size_t getCurrentIndex() const {
8105             return m_currentIndex;
8106         }
8107 
8108         std::size_t m_size;
8109         std::size_t m_currentIndex;
8110     };
8111 
8112     ///////////////////////////////////////////////////////////////////////////
8113 
8114     class GeneratorsForTest : public IGeneratorsForTest {
8115 
8116     public:
~GeneratorsForTest()8117         ~GeneratorsForTest() {
8118             deleteAll( m_generatorsInOrder );
8119         }
8120 
getGeneratorInfo(std::string const & fileInfo,std::size_t size)8121         IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
8122             std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
8123             if( it == m_generatorsByName.end() ) {
8124                 IGeneratorInfo* info = new GeneratorInfo( size );
8125                 m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
8126                 m_generatorsInOrder.push_back( info );
8127                 return *info;
8128             }
8129             return *it->second;
8130         }
8131 
moveNext()8132         bool moveNext() {
8133             std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
8134             std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
8135             for(; it != itEnd; ++it ) {
8136                 if( (*it)->moveNext() )
8137                     return true;
8138             }
8139             return false;
8140         }
8141 
8142     private:
8143         std::map<std::string, IGeneratorInfo*> m_generatorsByName;
8144         std::vector<IGeneratorInfo*> m_generatorsInOrder;
8145     };
8146 
createGeneratorsForTest()8147     IGeneratorsForTest* createGeneratorsForTest()
8148     {
8149         return new GeneratorsForTest();
8150     }
8151 
8152 } // end namespace Catch
8153 
8154 // #included from: catch_assertionresult.hpp
8155 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
8156 
8157 namespace Catch {
8158 
AssertionInfo()8159     AssertionInfo::AssertionInfo():macroName(""), capturedExpression(""), resultDisposition(ResultDisposition::Normal), secondArg(""){}
8160 
AssertionInfo(char const * _macroName,SourceLineInfo const & _lineInfo,char const * _capturedExpression,ResultDisposition::Flags _resultDisposition,char const * _secondArg)8161     AssertionInfo::AssertionInfo(   char const * _macroName,
8162                                     SourceLineInfo const& _lineInfo,
8163                                     char const * _capturedExpression,
8164                                     ResultDisposition::Flags _resultDisposition,
8165                                     char const * _secondArg)
8166     :   macroName( _macroName ),
8167         lineInfo( _lineInfo ),
8168         capturedExpression( _capturedExpression ),
8169         resultDisposition( _resultDisposition ),
8170         secondArg( _secondArg )
8171     {}
8172 
AssertionResult()8173     AssertionResult::AssertionResult() {}
8174 
AssertionResult(AssertionInfo const & info,AssertionResultData const & data)8175     AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
8176     :   m_info( info ),
8177         m_resultData( data )
8178     {}
8179 
~AssertionResult()8180     AssertionResult::~AssertionResult() {}
8181 
8182     // Result was a success
succeeded() const8183     bool AssertionResult::succeeded() const {
8184         return Catch::isOk( m_resultData.resultType );
8185     }
8186 
8187     // Result was a success, or failure is suppressed
isOk() const8188     bool AssertionResult::isOk() const {
8189         return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
8190     }
8191 
getResultType() const8192     ResultWas::OfType AssertionResult::getResultType() const {
8193         return m_resultData.resultType;
8194     }
8195 
hasExpression() const8196     bool AssertionResult::hasExpression() const {
8197         return m_info.capturedExpression[0] != 0;
8198     }
8199 
hasMessage() const8200     bool AssertionResult::hasMessage() const {
8201         return !m_resultData.message.empty();
8202     }
8203 
capturedExpressionWithSecondArgument(char const * capturedExpression,char const * secondArg)8204     std::string capturedExpressionWithSecondArgument( char const * capturedExpression, char const * secondArg ) {
8205         return (secondArg[0] == 0 || secondArg[0] == '"' && secondArg[1] == '"')
8206             ? capturedExpression
8207             : std::string(capturedExpression) + ", " + secondArg;
8208     }
8209 
getExpression() const8210     std::string AssertionResult::getExpression() const {
8211         if( isFalseTest( m_info.resultDisposition ) )
8212             return "!(" + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + ")";
8213         else
8214             return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg);
8215     }
getExpressionInMacro() const8216     std::string AssertionResult::getExpressionInMacro() const {
8217         if( m_info.macroName[0] == 0 )
8218             return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg);
8219         else
8220             return std::string(m_info.macroName) + "( " + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + " )";
8221     }
8222 
hasExpandedExpression() const8223     bool AssertionResult::hasExpandedExpression() const {
8224         return hasExpression() && getExpandedExpression() != getExpression();
8225     }
8226 
getExpandedExpression() const8227     std::string AssertionResult::getExpandedExpression() const {
8228         return m_resultData.reconstructExpression();
8229     }
8230 
getMessage() const8231     std::string AssertionResult::getMessage() const {
8232         return m_resultData.message;
8233     }
getSourceInfo() const8234     SourceLineInfo AssertionResult::getSourceInfo() const {
8235         return m_info.lineInfo;
8236     }
8237 
getTestMacroName() const8238     std::string AssertionResult::getTestMacroName() const {
8239         return m_info.macroName;
8240     }
8241 
discardDecomposedExpression() const8242     void AssertionResult::discardDecomposedExpression() const {
8243         m_resultData.decomposedExpression = CATCH_NULL;
8244     }
8245 
expandDecomposedExpression() const8246     void AssertionResult::expandDecomposedExpression() const {
8247         m_resultData.reconstructExpression();
8248     }
8249 
8250 } // end namespace Catch
8251 
8252 // #included from: catch_test_case_info.hpp
8253 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
8254 
8255 #include <cctype>
8256 
8257 namespace Catch {
8258 
parseSpecialTag(std::string const & tag)8259     inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
8260         if( startsWith( tag, '.' ) ||
8261             tag == "hide" ||
8262             tag == "!hide" )
8263             return TestCaseInfo::IsHidden;
8264         else if( tag == "!throws" )
8265             return TestCaseInfo::Throws;
8266         else if( tag == "!shouldfail" )
8267             return TestCaseInfo::ShouldFail;
8268         else if( tag == "!mayfail" )
8269             return TestCaseInfo::MayFail;
8270         else if( tag == "!nonportable" )
8271             return TestCaseInfo::NonPortable;
8272         else
8273             return TestCaseInfo::None;
8274     }
isReservedTag(std::string const & tag)8275     inline bool isReservedTag( std::string const& tag ) {
8276         return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] );
8277     }
enforceNotReservedTag(std::string const & tag,SourceLineInfo const & _lineInfo)8278     inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
8279         if( isReservedTag( tag ) ) {
8280             std::ostringstream ss;
8281             ss << Colour(Colour::Red)
8282                << "Tag name [" << tag << "] not allowed.\n"
8283                << "Tag names starting with non alpha-numeric characters are reserved\n"
8284                << Colour(Colour::FileName)
8285                << _lineInfo << '\n';
8286             throw std::runtime_error(ss.str());
8287         }
8288     }
8289 
makeTestCase(ITestCase * _testCase,std::string const & _className,std::string const & _name,std::string const & _descOrTags,SourceLineInfo const & _lineInfo)8290     TestCase makeTestCase(  ITestCase* _testCase,
8291                             std::string const& _className,
8292                             std::string const& _name,
8293                             std::string const& _descOrTags,
8294                             SourceLineInfo const& _lineInfo )
8295     {
8296         bool isHidden( startsWith( _name, "./" ) ); // Legacy support
8297 
8298         // Parse out tags
8299         std::set<std::string> tags;
8300         std::string desc, tag;
8301         bool inTag = false;
8302         for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
8303             char c = _descOrTags[i];
8304             if( !inTag ) {
8305                 if( c == '[' )
8306                     inTag = true;
8307                 else
8308                     desc += c;
8309             }
8310             else {
8311                 if( c == ']' ) {
8312                     TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
8313                     if( prop == TestCaseInfo::IsHidden )
8314                         isHidden = true;
8315                     else if( prop == TestCaseInfo::None )
8316                         enforceNotReservedTag( tag, _lineInfo );
8317 
8318                     tags.insert( tag );
8319                     tag.clear();
8320                     inTag = false;
8321                 }
8322                 else
8323                     tag += c;
8324             }
8325         }
8326         if( isHidden ) {
8327             tags.insert( "hide" );
8328             tags.insert( "." );
8329         }
8330 
8331         TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
8332         return TestCase( _testCase, info );
8333     }
8334 
setTags(TestCaseInfo & testCaseInfo,std::set<std::string> const & tags)8335     void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )
8336     {
8337         testCaseInfo.tags = tags;
8338         testCaseInfo.lcaseTags.clear();
8339 
8340         std::ostringstream oss;
8341         for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
8342             oss << '[' << *it << ']';
8343             std::string lcaseTag = toLower( *it );
8344             testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
8345             testCaseInfo.lcaseTags.insert( lcaseTag );
8346         }
8347         testCaseInfo.tagsAsString = oss.str();
8348     }
8349 
TestCaseInfo(std::string const & _name,std::string const & _className,std::string const & _description,std::set<std::string> const & _tags,SourceLineInfo const & _lineInfo)8350     TestCaseInfo::TestCaseInfo( std::string const& _name,
8351                                 std::string const& _className,
8352                                 std::string const& _description,
8353                                 std::set<std::string> const& _tags,
8354                                 SourceLineInfo const& _lineInfo )
8355     :   name( _name ),
8356         className( _className ),
8357         description( _description ),
8358         lineInfo( _lineInfo ),
8359         properties( None )
8360     {
8361         setTags( *this, _tags );
8362     }
8363 
TestCaseInfo(TestCaseInfo const & other)8364     TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
8365     :   name( other.name ),
8366         className( other.className ),
8367         description( other.description ),
8368         tags( other.tags ),
8369         lcaseTags( other.lcaseTags ),
8370         tagsAsString( other.tagsAsString ),
8371         lineInfo( other.lineInfo ),
8372         properties( other.properties )
8373     {}
8374 
isHidden() const8375     bool TestCaseInfo::isHidden() const {
8376         return ( properties & IsHidden ) != 0;
8377     }
throws() const8378     bool TestCaseInfo::throws() const {
8379         return ( properties & Throws ) != 0;
8380     }
okToFail() const8381     bool TestCaseInfo::okToFail() const {
8382         return ( properties & (ShouldFail | MayFail ) ) != 0;
8383     }
expectedToFail() const8384     bool TestCaseInfo::expectedToFail() const {
8385         return ( properties & (ShouldFail ) ) != 0;
8386     }
8387 
TestCase(ITestCase * testCase,TestCaseInfo const & info)8388     TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
8389 
TestCase(TestCase const & other)8390     TestCase::TestCase( TestCase const& other )
8391     :   TestCaseInfo( other ),
8392         test( other.test )
8393     {}
8394 
withName(std::string const & _newName) const8395     TestCase TestCase::withName( std::string const& _newName ) const {
8396         TestCase other( *this );
8397         other.name = _newName;
8398         return other;
8399     }
8400 
swap(TestCase & other)8401     void TestCase::swap( TestCase& other ) {
8402         test.swap( other.test );
8403         name.swap( other.name );
8404         className.swap( other.className );
8405         description.swap( other.description );
8406         tags.swap( other.tags );
8407         lcaseTags.swap( other.lcaseTags );
8408         tagsAsString.swap( other.tagsAsString );
8409         std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
8410         std::swap( lineInfo, other.lineInfo );
8411     }
8412 
invoke() const8413     void TestCase::invoke() const {
8414         test->invoke();
8415     }
8416 
operator ==(TestCase const & other) const8417     bool TestCase::operator == ( TestCase const& other ) const {
8418         return  test.get() == other.test.get() &&
8419                 name == other.name &&
8420                 className == other.className;
8421     }
8422 
operator <(TestCase const & other) const8423     bool TestCase::operator < ( TestCase const& other ) const {
8424         return name < other.name;
8425     }
operator =(TestCase const & other)8426     TestCase& TestCase::operator = ( TestCase const& other ) {
8427         TestCase temp( other );
8428         swap( temp );
8429         return *this;
8430     }
8431 
getTestCaseInfo() const8432     TestCaseInfo const& TestCase::getTestCaseInfo() const
8433     {
8434         return *this;
8435     }
8436 
8437 } // end namespace Catch
8438 
8439 // #included from: catch_version.hpp
8440 #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
8441 
8442 namespace Catch {
8443 
Version(unsigned int _majorVersion,unsigned int _minorVersion,unsigned int _patchNumber,char const * const _branchName,unsigned int _buildNumber)8444     Version::Version
8445         (   unsigned int _majorVersion,
8446             unsigned int _minorVersion,
8447             unsigned int _patchNumber,
8448             char const * const _branchName,
8449             unsigned int _buildNumber )
8450     :   majorVersion( _majorVersion ),
8451         minorVersion( _minorVersion ),
8452         patchNumber( _patchNumber ),
8453         branchName( _branchName ),
8454         buildNumber( _buildNumber )
8455     {}
8456 
operator <<(std::ostream & os,Version const & version)8457     std::ostream& operator << ( std::ostream& os, Version const& version ) {
8458         os  << version.majorVersion << '.'
8459             << version.minorVersion << '.'
8460             << version.patchNumber;
8461         // branchName is never null -> 0th char is \0 if it is empty
8462         if (version.branchName[0]) {
8463             os << '-' << version.branchName
8464                << '.' << version.buildNumber;
8465         }
8466         return os;
8467     }
8468 
libraryVersion()8469     inline Version libraryVersion() {
8470         static Version version( 1, 12, 2, "", 0 );
8471         return version;
8472     }
8473 
8474 }
8475 
8476 // #included from: catch_message.hpp
8477 #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
8478 
8479 namespace Catch {
8480 
MessageInfo(std::string const & _macroName,SourceLineInfo const & _lineInfo,ResultWas::OfType _type)8481     MessageInfo::MessageInfo(   std::string const& _macroName,
8482                                 SourceLineInfo const& _lineInfo,
8483                                 ResultWas::OfType _type )
8484     :   macroName( _macroName ),
8485         lineInfo( _lineInfo ),
8486         type( _type ),
8487         sequence( ++globalCount )
8488     {}
8489 
8490     // This may need protecting if threading support is added
8491     unsigned int MessageInfo::globalCount = 0;
8492 
8493     ////////////////////////////////////////////////////////////////////////////
8494 
ScopedMessage(MessageBuilder const & builder)8495     ScopedMessage::ScopedMessage( MessageBuilder const& builder )
8496     : m_info( builder.m_info )
8497     {
8498         m_info.message = builder.m_stream.str();
8499         getResultCapture().pushScopedMessage( m_info );
8500     }
ScopedMessage(ScopedMessage const & other)8501     ScopedMessage::ScopedMessage( ScopedMessage const& other )
8502     : m_info( other.m_info )
8503     {}
8504 
8505 #if defined(_MSC_VER)
8506 #pragma warning(push)
8507 #pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
8508 #endif
~ScopedMessage()8509     ScopedMessage::~ScopedMessage() {
8510         if ( !std::uncaught_exception() ){
8511             getResultCapture().popScopedMessage(m_info);
8512         }
8513     }
8514 #if defined(_MSC_VER)
8515 #pragma warning(pop)
8516 #endif
8517 
8518 } // end namespace Catch
8519 
8520 // #included from: catch_legacy_reporter_adapter.hpp
8521 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
8522 
8523 // #included from: catch_legacy_reporter_adapter.h
8524 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
8525 
8526 namespace Catch
8527 {
8528     // Deprecated
8529     struct IReporter : IShared {
8530         virtual ~IReporter();
8531 
8532         virtual bool shouldRedirectStdout() const = 0;
8533 
8534         virtual void StartTesting() = 0;
8535         virtual void EndTesting( Totals const& totals ) = 0;
8536         virtual void StartGroup( std::string const& groupName ) = 0;
8537         virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
8538         virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
8539         virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
8540         virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
8541         virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
8542         virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
8543         virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
8544         virtual void Aborted() = 0;
8545         virtual void Result( AssertionResult const& result ) = 0;
8546     };
8547 
8548     class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
8549     {
8550     public:
8551         LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
8552         virtual ~LegacyReporterAdapter();
8553 
8554         virtual ReporterPreferences getPreferences() const;
8555         virtual void noMatchingTestCases( std::string const& );
8556         virtual void testRunStarting( TestRunInfo const& );
8557         virtual void testGroupStarting( GroupInfo const& groupInfo );
8558         virtual void testCaseStarting( TestCaseInfo const& testInfo );
8559         virtual void sectionStarting( SectionInfo const& sectionInfo );
8560         virtual void assertionStarting( AssertionInfo const& );
8561         virtual bool assertionEnded( AssertionStats const& assertionStats );
8562         virtual void sectionEnded( SectionStats const& sectionStats );
8563         virtual void testCaseEnded( TestCaseStats const& testCaseStats );
8564         virtual void testGroupEnded( TestGroupStats const& testGroupStats );
8565         virtual void testRunEnded( TestRunStats const& testRunStats );
8566         virtual void skipTest( TestCaseInfo const& );
8567 
8568     private:
8569         Ptr<IReporter> m_legacyReporter;
8570     };
8571 }
8572 
8573 namespace Catch
8574 {
LegacyReporterAdapter(Ptr<IReporter> const & legacyReporter)8575     LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
8576     :   m_legacyReporter( legacyReporter )
8577     {}
~LegacyReporterAdapter()8578     LegacyReporterAdapter::~LegacyReporterAdapter() {}
8579 
getPreferences() const8580     ReporterPreferences LegacyReporterAdapter::getPreferences() const {
8581         ReporterPreferences prefs;
8582         prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
8583         return prefs;
8584     }
8585 
noMatchingTestCases(std::string const &)8586     void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
testRunStarting(TestRunInfo const &)8587     void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
8588         m_legacyReporter->StartTesting();
8589     }
testGroupStarting(GroupInfo const & groupInfo)8590     void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
8591         m_legacyReporter->StartGroup( groupInfo.name );
8592     }
testCaseStarting(TestCaseInfo const & testInfo)8593     void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
8594         m_legacyReporter->StartTestCase( testInfo );
8595     }
sectionStarting(SectionInfo const & sectionInfo)8596     void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
8597         m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
8598     }
assertionStarting(AssertionInfo const &)8599     void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
8600         // Not on legacy interface
8601     }
8602 
assertionEnded(AssertionStats const & assertionStats)8603     bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
8604         if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
8605             for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
8606                     it != itEnd;
8607                     ++it ) {
8608                 if( it->type == ResultWas::Info ) {
8609                     ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
8610                     rb << it->message;
8611                     rb.setResultType( ResultWas::Info );
8612                     AssertionResult result = rb.build();
8613                     m_legacyReporter->Result( result );
8614                 }
8615             }
8616         }
8617         m_legacyReporter->Result( assertionStats.assertionResult );
8618         return true;
8619     }
sectionEnded(SectionStats const & sectionStats)8620     void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
8621         if( sectionStats.missingAssertions )
8622             m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
8623         m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
8624     }
testCaseEnded(TestCaseStats const & testCaseStats)8625     void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
8626         m_legacyReporter->EndTestCase
8627             (   testCaseStats.testInfo,
8628                 testCaseStats.totals,
8629                 testCaseStats.stdOut,
8630                 testCaseStats.stdErr );
8631     }
testGroupEnded(TestGroupStats const & testGroupStats)8632     void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
8633         if( testGroupStats.aborting )
8634             m_legacyReporter->Aborted();
8635         m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
8636     }
testRunEnded(TestRunStats const & testRunStats)8637     void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
8638         m_legacyReporter->EndTesting( testRunStats.totals );
8639     }
skipTest(TestCaseInfo const &)8640     void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
8641     }
8642 }
8643 
8644 // #included from: catch_timer.hpp
8645 
8646 #ifdef __clang__
8647 #pragma clang diagnostic push
8648 #pragma clang diagnostic ignored "-Wc++11-long-long"
8649 #endif
8650 
8651 #ifdef CATCH_PLATFORM_WINDOWS
8652 
8653 #else
8654 
8655 #include <sys/time.h>
8656 
8657 #endif
8658 
8659 namespace Catch {
8660 
8661     namespace {
8662 #ifdef CATCH_PLATFORM_WINDOWS
getCurrentTicks()8663         UInt64 getCurrentTicks() {
8664             static UInt64 hz=0, hzo=0;
8665             if (!hz) {
8666                 QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
8667                 QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
8668             }
8669             UInt64 t;
8670             QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
8671             return ((t-hzo)*1000000)/hz;
8672         }
8673 #else
8674         UInt64 getCurrentTicks() {
8675             timeval t;
8676             gettimeofday(&t,CATCH_NULL);
8677             return static_cast<UInt64>( t.tv_sec ) * 1000000ull + static_cast<UInt64>( t.tv_usec );
8678         }
8679 #endif
8680     }
8681 
start()8682     void Timer::start() {
8683         m_ticks = getCurrentTicks();
8684     }
getElapsedMicroseconds() const8685     unsigned int Timer::getElapsedMicroseconds() const {
8686         return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
8687     }
getElapsedMilliseconds() const8688     unsigned int Timer::getElapsedMilliseconds() const {
8689         return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
8690     }
getElapsedSeconds() const8691     double Timer::getElapsedSeconds() const {
8692         return getElapsedMicroseconds()/1000000.0;
8693     }
8694 
8695 } // namespace Catch
8696 
8697 #ifdef __clang__
8698 #pragma clang diagnostic pop
8699 #endif
8700 // #included from: catch_common.hpp
8701 #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
8702 
8703 #include <cstring>
8704 #include <cctype>
8705 
8706 namespace Catch {
8707 
startsWith(std::string const & s,std::string const & prefix)8708     bool startsWith( std::string const& s, std::string const& prefix ) {
8709         return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
8710     }
startsWith(std::string const & s,char prefix)8711     bool startsWith( std::string const& s, char prefix ) {
8712         return !s.empty() && s[0] == prefix;
8713     }
endsWith(std::string const & s,std::string const & suffix)8714     bool endsWith( std::string const& s, std::string const& suffix ) {
8715         return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
8716     }
endsWith(std::string const & s,char suffix)8717     bool endsWith( std::string const& s, char suffix ) {
8718         return !s.empty() && s[s.size()-1] == suffix;
8719     }
contains(std::string const & s,std::string const & infix)8720     bool contains( std::string const& s, std::string const& infix ) {
8721         return s.find( infix ) != std::string::npos;
8722     }
toLowerCh(char c)8723     char toLowerCh(char c) {
8724         return static_cast<char>( std::tolower( c ) );
8725     }
toLowerInPlace(std::string & s)8726     void toLowerInPlace( std::string& s ) {
8727         std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
8728     }
toLower(std::string const & s)8729     std::string toLower( std::string const& s ) {
8730         std::string lc = s;
8731         toLowerInPlace( lc );
8732         return lc;
8733     }
trim(std::string const & str)8734     std::string trim( std::string const& str ) {
8735         static char const* whitespaceChars = "\n\r\t ";
8736         std::string::size_type start = str.find_first_not_of( whitespaceChars );
8737         std::string::size_type end = str.find_last_not_of( whitespaceChars );
8738 
8739         return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
8740     }
8741 
replaceInPlace(std::string & str,std::string const & replaceThis,std::string const & withThis)8742     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
8743         bool replaced = false;
8744         std::size_t i = str.find( replaceThis );
8745         while( i != std::string::npos ) {
8746             replaced = true;
8747             str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
8748             if( i < str.size()-withThis.size() )
8749                 i = str.find( replaceThis, i+withThis.size() );
8750             else
8751                 i = std::string::npos;
8752         }
8753         return replaced;
8754     }
8755 
pluralise(std::size_t count,std::string const & label)8756     pluralise::pluralise( std::size_t count, std::string const& label )
8757     :   m_count( count ),
8758         m_label( label )
8759     {}
8760 
operator <<(std::ostream & os,pluralise const & pluraliser)8761     std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
8762         os << pluraliser.m_count << ' ' << pluraliser.m_label;
8763         if( pluraliser.m_count != 1 )
8764             os << 's';
8765         return os;
8766     }
8767 
SourceLineInfo()8768     SourceLineInfo::SourceLineInfo() : file(""), line( 0 ){}
SourceLineInfo(char const * _file,std::size_t _line)8769     SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
8770     :   file( _file ),
8771         line( _line )
8772     {}
empty() const8773     bool SourceLineInfo::empty() const {
8774         return file[0] == '\0';
8775     }
operator ==(SourceLineInfo const & other) const8776     bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
8777         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
8778     }
operator <(SourceLineInfo const & other) const8779     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
8780         return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0));
8781     }
8782 
seedRng(IConfig const & config)8783     void seedRng( IConfig const& config ) {
8784         if( config.rngSeed() != 0 )
8785             std::srand( config.rngSeed() );
8786     }
rngSeed()8787     unsigned int rngSeed() {
8788         return getCurrentContext().getConfig()->rngSeed();
8789     }
8790 
operator <<(std::ostream & os,SourceLineInfo const & info)8791     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
8792 #ifndef __GNUG__
8793         os << info.file << '(' << info.line << ')';
8794 #else
8795         os << info.file << ':' << info.line;
8796 #endif
8797         return os;
8798     }
8799 
throwLogicError(std::string const & message,SourceLineInfo const & locationInfo)8800     void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
8801         std::ostringstream oss;
8802         oss << locationInfo << ": Internal Catch error: '" << message << '\'';
8803         if( alwaysTrue() )
8804             throw std::logic_error( oss.str() );
8805     }
8806 }
8807 
8808 // #included from: catch_section.hpp
8809 #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
8810 
8811 namespace Catch {
8812 
SectionInfo(SourceLineInfo const & _lineInfo,std::string const & _name,std::string const & _description)8813     SectionInfo::SectionInfo
8814         (   SourceLineInfo const& _lineInfo,
8815             std::string const& _name,
8816             std::string const& _description )
8817     :   name( _name ),
8818         description( _description ),
8819         lineInfo( _lineInfo )
8820     {}
8821 
Section(SectionInfo const & info)8822     Section::Section( SectionInfo const& info )
8823     :   m_info( info ),
8824         m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
8825     {
8826         m_timer.start();
8827     }
8828 
8829 #if defined(_MSC_VER)
8830 #pragma warning(push)
8831 #pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
8832 #endif
~Section()8833     Section::~Section() {
8834         if( m_sectionIncluded ) {
8835             SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
8836             if( std::uncaught_exception() )
8837                 getResultCapture().sectionEndedEarly( endInfo );
8838             else
8839                 getResultCapture().sectionEnded( endInfo );
8840         }
8841     }
8842 #if defined(_MSC_VER)
8843 #pragma warning(pop)
8844 #endif
8845 
8846     // This indicates whether the section should be executed or not
operator bool() const8847     Section::operator bool() const {
8848         return m_sectionIncluded;
8849     }
8850 
8851 } // end namespace Catch
8852 
8853 // #included from: catch_debugger.hpp
8854 #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
8855 
8856 #ifdef CATCH_PLATFORM_MAC
8857 
8858     #include <assert.h>
8859     #include <stdbool.h>
8860     #include <sys/types.h>
8861     #include <unistd.h>
8862     #include <sys/sysctl.h>
8863 
8864     namespace Catch{
8865 
8866         // The following function is taken directly from the following technical note:
8867         // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
8868 
8869         // Returns true if the current process is being debugged (either
8870         // running under the debugger or has a debugger attached post facto).
isDebuggerActive()8871         bool isDebuggerActive(){
8872 
8873             int                 mib[4];
8874             struct kinfo_proc   info;
8875             size_t              size;
8876 
8877             // Initialize the flags so that, if sysctl fails for some bizarre
8878             // reason, we get a predictable result.
8879 
8880             info.kp_proc.p_flag = 0;
8881 
8882             // Initialize mib, which tells sysctl the info we want, in this case
8883             // we're looking for information about a specific process ID.
8884 
8885             mib[0] = CTL_KERN;
8886             mib[1] = KERN_PROC;
8887             mib[2] = KERN_PROC_PID;
8888             mib[3] = getpid();
8889 
8890             // Call sysctl.
8891 
8892             size = sizeof(info);
8893             if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
8894                 Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
8895                 return false;
8896             }
8897 
8898             // We're being debugged if the P_TRACED flag is set.
8899 
8900             return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
8901         }
8902     } // namespace Catch
8903 
8904 #elif defined(CATCH_PLATFORM_LINUX)
8905     #include <fstream>
8906     #include <string>
8907 
8908     namespace Catch{
8909         // The standard POSIX way of detecting a debugger is to attempt to
8910         // ptrace() the process, but this needs to be done from a child and not
8911         // this process itself to still allow attaching to this process later
8912         // if wanted, so is rather heavy. Under Linux we have the PID of the
8913         // "debugger" (which doesn't need to be gdb, of course, it could also
8914         // be strace, for example) in /proc/$PID/status, so just get it from
8915         // there instead.
isDebuggerActive()8916         bool isDebuggerActive(){
8917             // Libstdc++ has a bug, where std::ifstream sets errno to 0
8918             // This way our users can properly assert over errno values
8919             ErrnoGuard guard;
8920             std::ifstream in("/proc/self/status");
8921             for( std::string line; std::getline(in, line); ) {
8922                 static const int PREFIX_LEN = 11;
8923                 if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
8924                     // We're traced if the PID is not 0 and no other PID starts
8925                     // with 0 digit, so it's enough to check for just a single
8926                     // character.
8927                     return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
8928                 }
8929             }
8930 
8931             return false;
8932         }
8933     } // namespace Catch
8934 #elif defined(_MSC_VER)
8935     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
8936     namespace Catch {
isDebuggerActive()8937         bool isDebuggerActive() {
8938             return IsDebuggerPresent() != 0;
8939         }
8940     }
8941 #elif defined(__MINGW32__)
8942     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
8943     namespace Catch {
isDebuggerActive()8944         bool isDebuggerActive() {
8945             return IsDebuggerPresent() != 0;
8946         }
8947     }
8948 #else
8949     namespace Catch {
isDebuggerActive()8950        inline bool isDebuggerActive() { return false; }
8951     }
8952 #endif // Platform
8953 
8954 #ifdef CATCH_PLATFORM_WINDOWS
8955 
8956     namespace Catch {
writeToDebugConsole(std::string const & text)8957         void writeToDebugConsole( std::string const& text ) {
8958             ::OutputDebugStringA( text.c_str() );
8959         }
8960     }
8961 #else
8962     namespace Catch {
writeToDebugConsole(std::string const & text)8963         void writeToDebugConsole( std::string const& text ) {
8964             // !TBD: Need a version for Mac/ XCode and other IDEs
8965             Catch::cout() << text;
8966         }
8967     }
8968 #endif // Platform
8969 
8970 // #included from: catch_tostring.hpp
8971 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
8972 
8973 namespace Catch {
8974 
8975 namespace Detail {
8976 
8977     const std::string unprintableString = "{?}";
8978 
8979     namespace {
8980         const int hexThreshold = 255;
8981 
8982         struct Endianness {
8983             enum Arch { Big, Little };
8984 
whichCatch::Detail::__anon8bb782460911::Endianness8985             static Arch which() {
8986                 union _{
8987                     int asInt;
8988                     char asChar[sizeof (int)];
8989                 } u;
8990 
8991                 u.asInt = 1;
8992                 return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
8993             }
8994         };
8995     }
8996 
rawMemoryToString(const void * object,std::size_t size)8997     std::string rawMemoryToString( const void *object, std::size_t size )
8998     {
8999         // Reverse order for little endian architectures
9000         int i = 0, end = static_cast<int>( size ), inc = 1;
9001         if( Endianness::which() == Endianness::Little ) {
9002             i = end-1;
9003             end = inc = -1;
9004         }
9005 
9006         unsigned char const *bytes = static_cast<unsigned char const *>(object);
9007         std::ostringstream os;
9008         os << "0x" << std::setfill('0') << std::hex;
9009         for( ; i != end; i += inc )
9010              os << std::setw(2) << static_cast<unsigned>(bytes[i]);
9011        return os.str();
9012     }
9013 }
9014 
toString(std::string const & value)9015 std::string toString( std::string const& value ) {
9016     std::string s = value;
9017     if( getCurrentContext().getConfig()->showInvisibles() ) {
9018         for(size_t i = 0; i < s.size(); ++i ) {
9019             std::string subs;
9020             switch( s[i] ) {
9021             case '\n': subs = "\\n"; break;
9022             case '\t': subs = "\\t"; break;
9023             default: break;
9024             }
9025             if( !subs.empty() ) {
9026                 s = s.substr( 0, i ) + subs + s.substr( i+1 );
9027                 ++i;
9028             }
9029         }
9030     }
9031     return '"' + s + '"';
9032 }
toString(std::wstring const & value)9033 std::string toString( std::wstring const& value ) {
9034 
9035     std::string s;
9036     s.reserve( value.size() );
9037     for(size_t i = 0; i < value.size(); ++i )
9038         s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
9039     return Catch::toString( s );
9040 }
9041 
toString(const char * const value)9042 std::string toString( const char* const value ) {
9043     return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
9044 }
9045 
toString(char * const value)9046 std::string toString( char* const value ) {
9047     return Catch::toString( static_cast<const char*>( value ) );
9048 }
9049 
toString(const wchar_t * const value)9050 std::string toString( const wchar_t* const value )
9051 {
9052     return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
9053 }
9054 
toString(wchar_t * const value)9055 std::string toString( wchar_t* const value )
9056 {
9057     return Catch::toString( static_cast<const wchar_t*>( value ) );
9058 }
9059 
toString(int value)9060 std::string toString( int value ) {
9061     std::ostringstream oss;
9062     oss << value;
9063     if( value > Detail::hexThreshold )
9064         oss << " (0x" << std::hex << value << ')';
9065     return oss.str();
9066 }
9067 
toString(unsigned long value)9068 std::string toString( unsigned long value ) {
9069     std::ostringstream oss;
9070     oss << value;
9071     if( value > Detail::hexThreshold )
9072         oss << " (0x" << std::hex << value << ')';
9073     return oss.str();
9074 }
9075 
toString(unsigned int value)9076 std::string toString( unsigned int value ) {
9077     return Catch::toString( static_cast<unsigned long>( value ) );
9078 }
9079 
9080 template<typename T>
fpToString(T value,int precision)9081 std::string fpToString( T value, int precision ) {
9082     std::ostringstream oss;
9083     oss << std::setprecision( precision )
9084         << std::fixed
9085         << value;
9086     std::string d = oss.str();
9087     std::size_t i = d.find_last_not_of( '0' );
9088     if( i != std::string::npos && i != d.size()-1 ) {
9089         if( d[i] == '.' )
9090             i++;
9091         d = d.substr( 0, i+1 );
9092     }
9093     return d;
9094 }
9095 
toString(const double value)9096 std::string toString( const double value ) {
9097     return fpToString( value, 10 );
9098 }
toString(const float value)9099 std::string toString( const float value ) {
9100     return fpToString( value, 5 ) + 'f';
9101 }
9102 
toString(bool value)9103 std::string toString( bool value ) {
9104     return value ? "true" : "false";
9105 }
9106 
toString(char value)9107 std::string toString( char value ) {
9108     if ( value == '\r' )
9109         return "'\\r'";
9110     if ( value == '\f' )
9111         return "'\\f'";
9112     if ( value == '\n' )
9113         return "'\\n'";
9114     if ( value == '\t' )
9115         return "'\\t'";
9116     if ( '\0' <= value && value < ' ' )
9117         return toString( static_cast<unsigned int>( value ) );
9118     char chstr[] = "' '";
9119     chstr[1] = value;
9120     return chstr;
9121 }
9122 
toString(signed char value)9123 std::string toString( signed char value ) {
9124     return toString( static_cast<char>( value ) );
9125 }
9126 
toString(unsigned char value)9127 std::string toString( unsigned char value ) {
9128     return toString( static_cast<char>( value ) );
9129 }
9130 
9131 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
toString(long long value)9132 std::string toString( long long value ) {
9133     std::ostringstream oss;
9134     oss << value;
9135     if( value > Detail::hexThreshold )
9136         oss << " (0x" << std::hex << value << ')';
9137     return oss.str();
9138 }
toString(unsigned long long value)9139 std::string toString( unsigned long long value ) {
9140     std::ostringstream oss;
9141     oss << value;
9142     if( value > Detail::hexThreshold )
9143         oss << " (0x" << std::hex << value << ')';
9144     return oss.str();
9145 }
9146 #endif
9147 
9148 #ifdef CATCH_CONFIG_CPP11_NULLPTR
toString(std::nullptr_t)9149 std::string toString( std::nullptr_t ) {
9150     return "nullptr";
9151 }
9152 #endif
9153 
9154 #ifdef __OBJC__
toString(NSString const * const & nsstring)9155     std::string toString( NSString const * const& nsstring ) {
9156         if( !nsstring )
9157             return "nil";
9158         return "@" + toString([nsstring UTF8String]);
9159     }
toString(NSString * CATCH_ARC_STRONG & nsstring)9160     std::string toString( NSString * CATCH_ARC_STRONG & nsstring ) {
9161         if( !nsstring )
9162             return "nil";
9163         return "@" + toString([nsstring UTF8String]);
9164     }
toString(NSObject * const & nsObject)9165     std::string toString( NSObject* const& nsObject ) {
9166         return toString( [nsObject description] );
9167     }
9168 #endif
9169 
9170 } // end namespace Catch
9171 
9172 // #included from: catch_result_builder.hpp
9173 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
9174 
9175 #include <cassert>
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 <cassert>
10671 #include <cfloat>
10672 #include <cstdio>
10673 
10674 namespace Catch {
10675 
10676     struct ConsoleReporter : StreamingReporterBase {
ConsoleReporterCatch::ConsoleReporter10677         ConsoleReporter( ReporterConfig const& _config )
10678         :   StreamingReporterBase( _config ),
10679             m_headerPrinted( false )
10680         {}
10681 
10682         virtual ~ConsoleReporter() CATCH_OVERRIDE;
getDescriptionCatch::ConsoleReporter10683         static std::string getDescription() {
10684             return "Reports test results as plain lines of text";
10685         }
10686 
noMatchingTestCasesCatch::ConsoleReporter10687         virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
10688             stream << "No test cases matched '" << spec << '\'' << std::endl;
10689         }
10690 
assertionStartingCatch::ConsoleReporter10691         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
10692         }
10693 
assertionEndedCatch::ConsoleReporter10694         virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
10695             AssertionResult const& result = _assertionStats.assertionResult;
10696 
10697             bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
10698 
10699             // Drop out if result was successful but we're not printing them.
10700             if( !includeResults && result.getResultType() != ResultWas::Warning )
10701                 return false;
10702 
10703             lazyPrint();
10704 
10705             AssertionPrinter printer( stream, _assertionStats, includeResults );
10706             printer.print();
10707             stream << std::endl;
10708             return true;
10709         }
10710 
sectionStartingCatch::ConsoleReporter10711         virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
10712             m_headerPrinted = false;
10713             StreamingReporterBase::sectionStarting( _sectionInfo );
10714         }
sectionEndedCatch::ConsoleReporter10715         virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
10716             if( _sectionStats.missingAssertions ) {
10717                 lazyPrint();
10718                 Colour colour( Colour::ResultError );
10719                 if( m_sectionStack.size() > 1 )
10720                     stream << "\nNo assertions in section";
10721                 else
10722                     stream << "\nNo assertions in test case";
10723                 stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
10724             }
10725             if( m_config->showDurations() == ShowDurations::Always ) {
10726                 stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
10727             }
10728             if( m_headerPrinted ) {
10729                 m_headerPrinted = false;
10730             }
10731             StreamingReporterBase::sectionEnded( _sectionStats );
10732         }
10733 
testCaseEndedCatch::ConsoleReporter10734         virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
10735             StreamingReporterBase::testCaseEnded( _testCaseStats );
10736             m_headerPrinted = false;
10737         }
testGroupEndedCatch::ConsoleReporter10738         virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
10739             if( currentGroupInfo.used ) {
10740                 printSummaryDivider();
10741                 stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
10742                 printTotals( _testGroupStats.totals );
10743                 stream << '\n' << std::endl;
10744             }
10745             StreamingReporterBase::testGroupEnded( _testGroupStats );
10746         }
testRunEndedCatch::ConsoleReporter10747         virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
10748             printTotalsDivider( _testRunStats.totals );
10749             printTotals( _testRunStats.totals );
10750             stream << std::endl;
10751             StreamingReporterBase::testRunEnded( _testRunStats );
10752         }
10753 
10754     private:
10755 
10756         class AssertionPrinter {
10757             void operator= ( AssertionPrinter const& );
10758         public:
AssertionPrinter(std::ostream & _stream,AssertionStats const & _stats,bool _printInfoMessages)10759             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
10760             :   stream( _stream ),
10761                 stats( _stats ),
10762                 result( _stats.assertionResult ),
10763                 colour( Colour::None ),
10764                 message( result.getMessage() ),
10765                 messages( _stats.infoMessages ),
10766                 printInfoMessages( _printInfoMessages )
10767             {
10768                 switch( result.getResultType() ) {
10769                     case ResultWas::Ok:
10770                         colour = Colour::Success;
10771                         passOrFail = "PASSED";
10772                         //if( result.hasMessage() )
10773                         if( _stats.infoMessages.size() == 1 )
10774                             messageLabel = "with message";
10775                         if( _stats.infoMessages.size() > 1 )
10776                             messageLabel = "with messages";
10777                         break;
10778                     case ResultWas::ExpressionFailed:
10779                         if( result.isOk() ) {
10780                             colour = Colour::Success;
10781                             passOrFail = "FAILED - but was ok";
10782                         }
10783                         else {
10784                             colour = Colour::Error;
10785                             passOrFail = "FAILED";
10786                         }
10787                         if( _stats.infoMessages.size() == 1 )
10788                             messageLabel = "with message";
10789                         if( _stats.infoMessages.size() > 1 )
10790                             messageLabel = "with messages";
10791                         break;
10792                     case ResultWas::ThrewException:
10793                         colour = Colour::Error;
10794                         passOrFail = "FAILED";
10795                         messageLabel = "due to unexpected exception with ";
10796                         if (_stats.infoMessages.size() == 1)
10797                             messageLabel += "message";
10798                         if (_stats.infoMessages.size() > 1)
10799                             messageLabel += "messages";
10800                         break;
10801                     case ResultWas::FatalErrorCondition:
10802                         colour = Colour::Error;
10803                         passOrFail = "FAILED";
10804                         messageLabel = "due to a fatal error condition";
10805                         break;
10806                     case ResultWas::DidntThrowException:
10807                         colour = Colour::Error;
10808                         passOrFail = "FAILED";
10809                         messageLabel = "because no exception was thrown where one was expected";
10810                         break;
10811                     case ResultWas::Info:
10812                         messageLabel = "info";
10813                         break;
10814                     case ResultWas::Warning:
10815                         messageLabel = "warning";
10816                         break;
10817                     case ResultWas::ExplicitFailure:
10818                         passOrFail = "FAILED";
10819                         colour = Colour::Error;
10820                         if( _stats.infoMessages.size() == 1 )
10821                             messageLabel = "explicitly with message";
10822                         if( _stats.infoMessages.size() > 1 )
10823                             messageLabel = "explicitly with messages";
10824                         break;
10825                     // These cases are here to prevent compiler warnings
10826                     case ResultWas::Unknown:
10827                     case ResultWas::FailureBit:
10828                     case ResultWas::Exception:
10829                         passOrFail = "** internal error **";
10830                         colour = Colour::Error;
10831                         break;
10832                 }
10833             }
10834 
print() const10835             void print() const {
10836                 printSourceInfo();
10837                 if( stats.totals.assertions.total() > 0 ) {
10838                     if( result.isOk() )
10839                         stream << '\n';
10840                     printResultType();
10841                     printOriginalExpression();
10842                     printReconstructedExpression();
10843                 }
10844                 else {
10845                     stream << '\n';
10846                 }
10847                 printMessage();
10848             }
10849 
10850         private:
printResultType() const10851             void printResultType() const {
10852                 if( !passOrFail.empty() ) {
10853                     Colour colourGuard( colour );
10854                     stream << passOrFail << ":\n";
10855                 }
10856             }
printOriginalExpression() const10857             void printOriginalExpression() const {
10858                 if( result.hasExpression() ) {
10859                     Colour colourGuard( Colour::OriginalExpression );
10860                     stream  << "  ";
10861                     stream << result.getExpressionInMacro();
10862                     stream << '\n';
10863                 }
10864             }
printReconstructedExpression() const10865             void printReconstructedExpression() const {
10866                 if( result.hasExpandedExpression() ) {
10867                     stream << "with expansion:\n";
10868                     Colour colourGuard( Colour::ReconstructedExpression );
10869                     stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << '\n';
10870                 }
10871             }
printMessage() const10872             void printMessage() const {
10873                 if( !messageLabel.empty() )
10874                     stream << messageLabel << ':' << '\n';
10875                 for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
10876                         it != itEnd;
10877                         ++it ) {
10878                     // If this assertion is a warning ignore any INFO messages
10879                     if( printInfoMessages || it->type != ResultWas::Info )
10880                         stream << Text( it->message, TextAttributes().setIndent(2) ) << '\n';
10881                 }
10882             }
printSourceInfo() const10883             void printSourceInfo() const {
10884                 Colour colourGuard( Colour::FileName );
10885                 stream << result.getSourceInfo() << ": ";
10886             }
10887 
10888             std::ostream& stream;
10889             AssertionStats const& stats;
10890             AssertionResult const& result;
10891             Colour::Code colour;
10892             std::string passOrFail;
10893             std::string messageLabel;
10894             std::string message;
10895             std::vector<MessageInfo> messages;
10896             bool printInfoMessages;
10897         };
10898 
lazyPrintCatch::ConsoleReporter10899         void lazyPrint() {
10900 
10901             if( !currentTestRunInfo.used )
10902                 lazyPrintRunInfo();
10903             if( !currentGroupInfo.used )
10904                 lazyPrintGroupInfo();
10905 
10906             if( !m_headerPrinted ) {
10907                 printTestCaseAndSectionHeader();
10908                 m_headerPrinted = true;
10909             }
10910         }
lazyPrintRunInfoCatch::ConsoleReporter10911         void lazyPrintRunInfo() {
10912             stream  << '\n' << getLineOfChars<'~'>() << '\n';
10913             Colour colour( Colour::SecondaryText );
10914             stream  << currentTestRunInfo->name
10915                     << " is a Catch v"  << libraryVersion() << " host application.\n"
10916                     << "Run with -? for options\n\n";
10917 
10918             if( m_config->rngSeed() != 0 )
10919                 stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
10920 
10921             currentTestRunInfo.used = true;
10922         }
lazyPrintGroupInfoCatch::ConsoleReporter10923         void lazyPrintGroupInfo() {
10924             if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
10925                 printClosedHeader( "Group: " + currentGroupInfo->name );
10926                 currentGroupInfo.used = true;
10927             }
10928         }
printTestCaseAndSectionHeaderCatch::ConsoleReporter10929         void printTestCaseAndSectionHeader() {
10930             assert( !m_sectionStack.empty() );
10931             printOpenHeader( currentTestCaseInfo->name );
10932 
10933             if( m_sectionStack.size() > 1 ) {
10934                 Colour colourGuard( Colour::Headers );
10935 
10936                 std::vector<SectionInfo>::const_iterator
10937                     it = m_sectionStack.begin()+1, // Skip first section (test case)
10938                     itEnd = m_sectionStack.end();
10939                 for( ; it != itEnd; ++it )
10940                     printHeaderString( it->name, 2 );
10941             }
10942 
10943             SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
10944 
10945             if( !lineInfo.empty() ){
10946                 stream << getLineOfChars<'-'>() << '\n';
10947                 Colour colourGuard( Colour::FileName );
10948                 stream << lineInfo << '\n';
10949             }
10950             stream << getLineOfChars<'.'>() << '\n' << std::endl;
10951         }
10952 
printClosedHeaderCatch::ConsoleReporter10953         void printClosedHeader( std::string const& _name ) {
10954             printOpenHeader( _name );
10955             stream << getLineOfChars<'.'>() << '\n';
10956         }
printOpenHeaderCatch::ConsoleReporter10957         void printOpenHeader( std::string const& _name ) {
10958             stream  << getLineOfChars<'-'>() << '\n';
10959             {
10960                 Colour colourGuard( Colour::Headers );
10961                 printHeaderString( _name );
10962             }
10963         }
10964 
10965         // if string has a : in first line will set indent to follow it on
10966         // subsequent lines
printHeaderStringCatch::ConsoleReporter10967         void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
10968             std::size_t i = _string.find( ": " );
10969             if( i != std::string::npos )
10970                 i+=2;
10971             else
10972                 i = 0;
10973             stream << Text( _string, TextAttributes()
10974                                         .setIndent( indent+i)
10975                                         .setInitialIndent( indent ) ) << '\n';
10976         }
10977 
10978         struct SummaryColumn {
10979 
SummaryColumnCatch::ConsoleReporter::SummaryColumn10980             SummaryColumn( std::string const& _label, Colour::Code _colour )
10981             :   label( _label ),
10982                 colour( _colour )
10983             {}
addRowCatch::ConsoleReporter::SummaryColumn10984             SummaryColumn addRow( std::size_t count ) {
10985                 std::ostringstream oss;
10986                 oss << count;
10987                 std::string row = oss.str();
10988                 for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
10989                     while( it->size() < row.size() )
10990                         *it = ' ' + *it;
10991                     while( it->size() > row.size() )
10992                         row = ' ' + row;
10993                 }
10994                 rows.push_back( row );
10995                 return *this;
10996             }
10997 
10998             std::string label;
10999             Colour::Code colour;
11000             std::vector<std::string> rows;
11001 
11002         };
11003 
printTotalsCatch::ConsoleReporter11004         void printTotals( Totals const& totals ) {
11005             if( totals.testCases.total() == 0 ) {
11006                 stream << Colour( Colour::Warning ) << "No tests ran\n";
11007             }
11008             else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
11009                 stream << Colour( Colour::ResultSuccess ) << "All tests passed";
11010                 stream << " ("
11011                         << pluralise( totals.assertions.passed, "assertion" ) << " in "
11012                         << pluralise( totals.testCases.passed, "test case" ) << ')'
11013                         << '\n';
11014             }
11015             else {
11016 
11017                 std::vector<SummaryColumn> columns;
11018                 columns.push_back( SummaryColumn( "", Colour::None )
11019                                         .addRow( totals.testCases.total() )
11020                                         .addRow( totals.assertions.total() ) );
11021                 columns.push_back( SummaryColumn( "passed", Colour::Success )
11022                                         .addRow( totals.testCases.passed )
11023                                         .addRow( totals.assertions.passed ) );
11024                 columns.push_back( SummaryColumn( "failed", Colour::ResultError )
11025                                         .addRow( totals.testCases.failed )
11026                                         .addRow( totals.assertions.failed ) );
11027                 columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
11028                                         .addRow( totals.testCases.failedButOk )
11029                                         .addRow( totals.assertions.failedButOk ) );
11030 
11031                 printSummaryRow( "test cases", columns, 0 );
11032                 printSummaryRow( "assertions", columns, 1 );
11033             }
11034         }
printSummaryRowCatch::ConsoleReporter11035         void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
11036             for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
11037                 std::string value = it->rows[row];
11038                 if( it->label.empty() ) {
11039                     stream << label << ": ";
11040                     if( value != "0" )
11041                         stream << value;
11042                     else
11043                         stream << Colour( Colour::Warning ) << "- none -";
11044                 }
11045                 else if( value != "0" ) {
11046                     stream  << Colour( Colour::LightGrey ) << " | ";
11047                     stream  << Colour( it->colour )
11048                             << value << ' ' << it->label;
11049                 }
11050             }
11051             stream << '\n';
11052         }
11053 
makeRatioCatch::ConsoleReporter11054         static std::size_t makeRatio( std::size_t number, std::size_t total ) {
11055             std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
11056             return ( ratio == 0 && number > 0 ) ? 1 : ratio;
11057         }
findMaxCatch::ConsoleReporter11058         static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
11059             if( i > j && i > k )
11060                 return i;
11061             else if( j > k )
11062                 return j;
11063             else
11064                 return k;
11065         }
11066 
printTotalsDividerCatch::ConsoleReporter11067         void printTotalsDivider( Totals const& totals ) {
11068             if( totals.testCases.total() > 0 ) {
11069                 std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
11070                 std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
11071                 std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
11072                 while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
11073                     findMax( failedRatio, failedButOkRatio, passedRatio )++;
11074                 while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
11075                     findMax( failedRatio, failedButOkRatio, passedRatio )--;
11076 
11077                 stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
11078                 stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
11079                 if( totals.testCases.allPassed() )
11080                     stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
11081                 else
11082                     stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
11083             }
11084             else {
11085                 stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
11086             }
11087             stream << '\n';
11088         }
printSummaryDividerCatch::ConsoleReporter11089         void printSummaryDivider() {
11090             stream << getLineOfChars<'-'>() << '\n';
11091         }
11092 
11093     private:
11094         bool m_headerPrinted;
11095     };
11096 
11097     INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
11098 
11099 } // end namespace Catch
11100 
11101 // #included from: ../reporters/catch_reporter_compact.hpp
11102 #define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
11103 
11104 namespace Catch {
11105 
11106     struct CompactReporter : StreamingReporterBase {
11107 
CompactReporterCatch::CompactReporter11108         CompactReporter( ReporterConfig const& _config )
11109         : StreamingReporterBase( _config )
11110         {}
11111 
11112         virtual ~CompactReporter();
11113 
getDescriptionCatch::CompactReporter11114         static std::string getDescription() {
11115             return "Reports test results on a single line, suitable for IDEs";
11116         }
11117 
getPreferencesCatch::CompactReporter11118         virtual ReporterPreferences getPreferences() const {
11119             ReporterPreferences prefs;
11120             prefs.shouldRedirectStdOut = false;
11121             return prefs;
11122         }
11123 
noMatchingTestCasesCatch::CompactReporter11124         virtual void noMatchingTestCases( std::string const& spec ) {
11125             stream << "No test cases matched '" << spec << '\'' << std::endl;
11126         }
11127 
assertionStartingCatch::CompactReporter11128         virtual void assertionStarting( AssertionInfo const& ) {}
11129 
assertionEndedCatch::CompactReporter11130         virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
11131             AssertionResult const& result = _assertionStats.assertionResult;
11132 
11133             bool printInfoMessages = true;
11134 
11135             // Drop out if result was successful and we're not printing those
11136             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
11137                 if( result.getResultType() != ResultWas::Warning )
11138                     return false;
11139                 printInfoMessages = false;
11140             }
11141 
11142             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
11143             printer.print();
11144 
11145             stream << std::endl;
11146             return true;
11147         }
11148 
sectionEndedCatch::CompactReporter11149         virtual void sectionEnded(SectionStats const& _sectionStats) CATCH_OVERRIDE {
11150             if (m_config->showDurations() == ShowDurations::Always) {
11151                 stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
11152             }
11153         }
11154 
testRunEndedCatch::CompactReporter11155         virtual void testRunEnded( TestRunStats const& _testRunStats ) {
11156             printTotals( _testRunStats.totals );
11157             stream << '\n' << std::endl;
11158             StreamingReporterBase::testRunEnded( _testRunStats );
11159         }
11160 
11161     private:
11162         class AssertionPrinter {
11163             void operator= ( AssertionPrinter const& );
11164         public:
AssertionPrinter(std::ostream & _stream,AssertionStats const & _stats,bool _printInfoMessages)11165             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
11166             : stream( _stream )
11167             , stats( _stats )
11168             , result( _stats.assertionResult )
11169             , messages( _stats.infoMessages )
11170             , itMessage( _stats.infoMessages.begin() )
11171             , printInfoMessages( _printInfoMessages )
11172             {}
11173 
print()11174             void print() {
11175                 printSourceInfo();
11176 
11177                 itMessage = messages.begin();
11178 
11179                 switch( result.getResultType() ) {
11180                     case ResultWas::Ok:
11181                         printResultType( Colour::ResultSuccess, passedString() );
11182                         printOriginalExpression();
11183                         printReconstructedExpression();
11184                         if ( ! result.hasExpression() )
11185                             printRemainingMessages( Colour::None );
11186                         else
11187                             printRemainingMessages();
11188                         break;
11189                     case ResultWas::ExpressionFailed:
11190                         if( result.isOk() )
11191                             printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
11192                         else
11193                             printResultType( Colour::Error, failedString() );
11194                         printOriginalExpression();
11195                         printReconstructedExpression();
11196                         printRemainingMessages();
11197                         break;
11198                     case ResultWas::ThrewException:
11199                         printResultType( Colour::Error, failedString() );
11200                         printIssue( "unexpected exception with message:" );
11201                         printMessage();
11202                         printExpressionWas();
11203                         printRemainingMessages();
11204                         break;
11205                     case ResultWas::FatalErrorCondition:
11206                         printResultType( Colour::Error, failedString() );
11207                         printIssue( "fatal error condition with message:" );
11208                         printMessage();
11209                         printExpressionWas();
11210                         printRemainingMessages();
11211                         break;
11212                     case ResultWas::DidntThrowException:
11213                         printResultType( Colour::Error, failedString() );
11214                         printIssue( "expected exception, got none" );
11215                         printExpressionWas();
11216                         printRemainingMessages();
11217                         break;
11218                     case ResultWas::Info:
11219                         printResultType( Colour::None, "info" );
11220                         printMessage();
11221                         printRemainingMessages();
11222                         break;
11223                     case ResultWas::Warning:
11224                         printResultType( Colour::None, "warning" );
11225                         printMessage();
11226                         printRemainingMessages();
11227                         break;
11228                     case ResultWas::ExplicitFailure:
11229                         printResultType( Colour::Error, failedString() );
11230                         printIssue( "explicitly" );
11231                         printRemainingMessages( Colour::None );
11232                         break;
11233                     // These cases are here to prevent compiler warnings
11234                     case ResultWas::Unknown:
11235                     case ResultWas::FailureBit:
11236                     case ResultWas::Exception:
11237                         printResultType( Colour::Error, "** internal error **" );
11238                         break;
11239                 }
11240             }
11241 
11242         private:
11243             // Colour::LightGrey
11244 
dimColour()11245             static Colour::Code dimColour() { return Colour::FileName; }
11246 
11247 #ifdef CATCH_PLATFORM_MAC
failedString()11248             static const char* failedString() { return "FAILED"; }
passedString()11249             static const char* passedString() { return "PASSED"; }
11250 #else
failedString()11251             static const char* failedString() { return "failed"; }
passedString()11252             static const char* passedString() { return "passed"; }
11253 #endif
11254 
printSourceInfo() const11255             void printSourceInfo() const {
11256                 Colour colourGuard( Colour::FileName );
11257                 stream << result.getSourceInfo() << ':';
11258             }
11259 
printResultType(Colour::Code colour,std::string const & passOrFail) const11260             void printResultType( Colour::Code colour, std::string const& passOrFail ) const {
11261                 if( !passOrFail.empty() ) {
11262                     {
11263                         Colour colourGuard( colour );
11264                         stream << ' ' << passOrFail;
11265                     }
11266                     stream << ':';
11267                 }
11268             }
11269 
printIssue(std::string const & issue) const11270             void printIssue( std::string const& issue ) const {
11271                 stream << ' ' << issue;
11272             }
11273 
printExpressionWas()11274             void printExpressionWas() {
11275                 if( result.hasExpression() ) {
11276                     stream << ';';
11277                     {
11278                         Colour colour( dimColour() );
11279                         stream << " expression was:";
11280                     }
11281                     printOriginalExpression();
11282                 }
11283             }
11284 
printOriginalExpression() const11285             void printOriginalExpression() const {
11286                 if( result.hasExpression() ) {
11287                     stream << ' ' << result.getExpression();
11288                 }
11289             }
11290 
printReconstructedExpression() const11291             void printReconstructedExpression() const {
11292                 if( result.hasExpandedExpression() ) {
11293                     {
11294                         Colour colour( dimColour() );
11295                         stream << " for: ";
11296                     }
11297                     stream << result.getExpandedExpression();
11298                 }
11299             }
11300 
printMessage()11301             void printMessage() {
11302                 if ( itMessage != messages.end() ) {
11303                     stream << " '" << itMessage->message << '\'';
11304                     ++itMessage;
11305                 }
11306             }
11307 
printRemainingMessages(Colour::Code colour=dimColour ())11308             void printRemainingMessages( Colour::Code colour = dimColour() ) {
11309                 if ( itMessage == messages.end() )
11310                     return;
11311 
11312                 // using messages.end() directly yields compilation error:
11313                 std::vector<MessageInfo>::const_iterator itEnd = messages.end();
11314                 const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
11315 
11316                 {
11317                     Colour colourGuard( colour );
11318                     stream << " with " << pluralise( N, "message" ) << ':';
11319                 }
11320 
11321                 for(; itMessage != itEnd; ) {
11322                     // If this assertion is a warning ignore any INFO messages
11323                     if( printInfoMessages || itMessage->type != ResultWas::Info ) {
11324                         stream << " '" << itMessage->message << '\'';
11325                         if ( ++itMessage != itEnd ) {
11326                             Colour colourGuard( dimColour() );
11327                             stream << " and";
11328                         }
11329                     }
11330                 }
11331             }
11332 
11333         private:
11334             std::ostream& stream;
11335             AssertionStats const& stats;
11336             AssertionResult const& result;
11337             std::vector<MessageInfo> messages;
11338             std::vector<MessageInfo>::const_iterator itMessage;
11339             bool printInfoMessages;
11340         };
11341 
11342         // Colour, message variants:
11343         // - white: No tests ran.
11344         // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
11345         // - white: Passed [both/all] N test cases (no assertions).
11346         // -   red: Failed N tests cases, failed M assertions.
11347         // - green: Passed [both/all] N tests cases with M assertions.
11348 
bothOrAllCatch::CompactReporter11349         std::string bothOrAll( std::size_t count ) const {
11350             return count == 1 ? std::string() : count == 2 ? "both " : "all " ;
11351         }
11352 
printTotalsCatch::CompactReporter11353         void printTotals( const Totals& totals ) const {
11354             if( totals.testCases.total() == 0 ) {
11355                 stream << "No tests ran.";
11356             }
11357             else if( totals.testCases.failed == totals.testCases.total() ) {
11358                 Colour colour( Colour::ResultError );
11359                 const std::string qualify_assertions_failed =
11360                     totals.assertions.failed == totals.assertions.total() ?
11361                         bothOrAll( totals.assertions.failed ) : std::string();
11362                 stream <<
11363                     "Failed " << bothOrAll( totals.testCases.failed )
11364                               << pluralise( totals.testCases.failed, "test case"  ) << ", "
11365                     "failed " << qualify_assertions_failed <<
11366                                  pluralise( totals.assertions.failed, "assertion" ) << '.';
11367             }
11368             else if( totals.assertions.total() == 0 ) {
11369                 stream <<
11370                     "Passed " << bothOrAll( totals.testCases.total() )
11371                               << pluralise( totals.testCases.total(), "test case" )
11372                               << " (no assertions).";
11373             }
11374             else if( totals.assertions.failed ) {
11375                 Colour colour( Colour::ResultError );
11376                 stream <<
11377                     "Failed " << pluralise( totals.testCases.failed, "test case"  ) << ", "
11378                     "failed " << pluralise( totals.assertions.failed, "assertion" ) << '.';
11379             }
11380             else {
11381                 Colour colour( Colour::ResultSuccess );
11382                 stream <<
11383                     "Passed " << bothOrAll( totals.testCases.passed )
11384                               << pluralise( totals.testCases.passed, "test case"  ) <<
11385                     " with "  << pluralise( totals.assertions.passed, "assertion" ) << '.';
11386             }
11387         }
11388     };
11389 
11390     INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
11391 
11392 } // end namespace Catch
11393 
11394 namespace Catch {
11395     // These are all here to avoid warnings about not having any out of line
11396     // virtual methods
~NonCopyable()11397     NonCopyable::~NonCopyable() {}
~IShared()11398     IShared::~IShared() {}
~IStream()11399     IStream::~IStream() CATCH_NOEXCEPT {}
~FileStream()11400     FileStream::~FileStream() CATCH_NOEXCEPT {}
~CoutStream()11401     CoutStream::~CoutStream() CATCH_NOEXCEPT {}
~DebugOutStream()11402     DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
~StreamBufBase()11403     StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
~IContext()11404     IContext::~IContext() {}
~IResultCapture()11405     IResultCapture::~IResultCapture() {}
~ITestCase()11406     ITestCase::~ITestCase() {}
~ITestCaseRegistry()11407     ITestCaseRegistry::~ITestCaseRegistry() {}
~IRegistryHub()11408     IRegistryHub::~IRegistryHub() {}
~IMutableRegistryHub()11409     IMutableRegistryHub::~IMutableRegistryHub() {}
~IExceptionTranslator()11410     IExceptionTranslator::~IExceptionTranslator() {}
~IExceptionTranslatorRegistry()11411     IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
~IReporter()11412     IReporter::~IReporter() {}
~IReporterFactory()11413     IReporterFactory::~IReporterFactory() {}
~IReporterRegistry()11414     IReporterRegistry::~IReporterRegistry() {}
~IStreamingReporter()11415     IStreamingReporter::~IStreamingReporter() {}
~AssertionStats()11416     AssertionStats::~AssertionStats() {}
~SectionStats()11417     SectionStats::~SectionStats() {}
~TestCaseStats()11418     TestCaseStats::~TestCaseStats() {}
~TestGroupStats()11419     TestGroupStats::~TestGroupStats() {}
~TestRunStats()11420     TestRunStats::~TestRunStats() {}
~SectionNode()11421     CumulativeReporterBase::SectionNode::~SectionNode() {}
~CumulativeReporterBase()11422     CumulativeReporterBase::~CumulativeReporterBase() {}
11423 
~StreamingReporterBase()11424     StreamingReporterBase::~StreamingReporterBase() {}
~ConsoleReporter()11425     ConsoleReporter::~ConsoleReporter() {}
~CompactReporter()11426     CompactReporter::~CompactReporter() {}
~IRunner()11427     IRunner::~IRunner() {}
~IMutableContext()11428     IMutableContext::~IMutableContext() {}
~IConfig()11429     IConfig::~IConfig() {}
~XmlReporter()11430     XmlReporter::~XmlReporter() {}
~JunitReporter()11431     JunitReporter::~JunitReporter() {}
~TestRegistry()11432     TestRegistry::~TestRegistry() {}
~FreeFunctionTestCase()11433     FreeFunctionTestCase::~FreeFunctionTestCase() {}
~IGeneratorInfo()11434     IGeneratorInfo::~IGeneratorInfo() {}
~IGeneratorsForTest()11435     IGeneratorsForTest::~IGeneratorsForTest() {}
~WildcardPattern()11436     WildcardPattern::~WildcardPattern() {}
~Pattern()11437     TestSpec::Pattern::~Pattern() {}
~NamePattern()11438     TestSpec::NamePattern::~NamePattern() {}
~TagPattern()11439     TestSpec::TagPattern::~TagPattern() {}
~ExcludedPattern()11440     TestSpec::ExcludedPattern::~ExcludedPattern() {}
~MatcherUntypedBase()11441     Matchers::Impl::MatcherUntypedBase::~MatcherUntypedBase() {}
11442 
dummy()11443     void Config::dummy() {}
11444 
11445     namespace TestCaseTracking {
~ITracker()11446         ITracker::~ITracker() {}
~TrackerBase()11447         TrackerBase::~TrackerBase() {}
~SectionTracker()11448         SectionTracker::~SectionTracker() {}
~IndexTracker()11449         IndexTracker::~IndexTracker() {}
11450     }
11451 }
11452 
11453 #ifdef __clang__
11454 #pragma clang diagnostic pop
11455 #endif
11456 
11457 #endif
11458 
11459 #ifdef CATCH_CONFIG_MAIN
11460 // #included from: internal/catch_default_main.hpp
11461 #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
11462 
11463 #ifndef __OBJC__
11464 
11465 #if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
11466 // Standard C/C++ Win32 Unicode wmain entry point
wmain(int argc,wchar_t * argv[],wchar_t * [])11467 extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
11468 #else
11469 // Standard C/C++ main entry point
11470 int main (int argc, char * argv[]) {
11471 #endif
11472 
11473     int result = Catch::Session().run( argc, argv );
11474     return ( result < 0xff ? result : 0xff );
11475 }
11476 
11477 #else // __OBJC__
11478 
11479 // Objective-C entry point
11480 int main (int argc, char * const argv[]) {
11481 #if !CATCH_ARC_ENABLED
11482     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
11483 #endif
11484 
11485     Catch::registerTestMethods();
11486     int result = Catch::Session().run( argc, (char* const*)argv );
11487 
11488 #if !CATCH_ARC_ENABLED
11489     [pool drain];
11490 #endif
11491 
11492     return ( result < 0xff ? result : 0xff );
11493 }
11494 
11495 #endif // __OBJC__
11496 
11497 #endif
11498 
11499 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
11500 #  undef CLARA_CONFIG_MAIN
11501 #endif
11502 
11503 //////
11504 
11505 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
11506 #ifdef CATCH_CONFIG_PREFIX_ALL
11507 
11508 #if defined(CATCH_CONFIG_FAST_COMPILE)
11509 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr )
11510 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
11511 #else
11512 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr )
11513 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr  )
11514 #endif
11515 
11516 #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr )
11517 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
11518 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
11519 #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr )
11520 
11521 #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, expr )
11522 #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr )
11523 #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr )
11524 #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr )
11525 #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr )
11526 
11527 #define CATCH_CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr )
11528 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
11529 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
11530 #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr )
11531 
11532 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
11533 
11534 #if defined(CATCH_CONFIG_FAST_COMPILE)
11535 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
11536 #else
11537 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
11538 #endif
11539 
11540 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
11541 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
11542 #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
11543 #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) )
11544 #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) )
11545 
11546 #ifdef CATCH_CONFIG_VARIADIC_MACROS
11547     #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
11548     #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
11549     #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
11550     #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
11551     #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
11552     #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
11553     #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
11554     #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
11555 #else
11556     #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
11557     #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
11558     #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
11559     #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
11560     #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
11561     #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg )
11562     #define CATCH_FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg )
11563     #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg )
11564 #endif
11565 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
11566 
11567 #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
11568 #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
11569 
11570 #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
11571 
11572 // "BDD-style" convenience wrappers
11573 #ifdef CATCH_CONFIG_VARIADIC_MACROS
11574 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
11575 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
11576 #else
11577 #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
11578 #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
11579 #endif
11580 #define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc, "" )
11581 #define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc, "" )
11582 #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
11583 #define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc, "" )
11584 #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
11585 
11586 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
11587 #else
11588 
11589 #if defined(CATCH_CONFIG_FAST_COMPILE)
11590 #define REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE", Catch::ResultDisposition::Normal, expr )
11591 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
11592 
11593 #else
11594 #define REQUIRE( expr ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, expr  )
11595 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
11596 #endif
11597 
11598 #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr )
11599 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
11600 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
11601 #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr )
11602 
11603 #define CHECK( expr ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, expr )
11604 #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr )
11605 #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr )
11606 #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr )
11607 #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr )
11608 
11609 #define CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr )
11610 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
11611 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
11612 #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr )
11613 
11614 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
11615 
11616 #if defined(CATCH_CONFIG_FAST_COMPILE)
11617 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
11618 #else
11619 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
11620 #endif
11621 
11622 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
11623 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
11624 #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
11625 #define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) )
11626 #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) )
11627 
11628 #ifdef CATCH_CONFIG_VARIADIC_MACROS
11629 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
11630 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
11631 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
11632 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
11633 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
11634 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
11635 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
11636 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
11637 #else
11638 #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
11639     #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
11640     #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
11641     #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
11642     #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
11643     #define FAIL( msg ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg )
11644     #define FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg )
11645     #define SUCCEED( msg ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg )
11646 #endif
11647 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
11648 
11649 #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
11650 #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
11651 
11652 #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
11653 
11654 #endif
11655 
11656 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
11657 
11658 // "BDD-style" convenience wrappers
11659 #ifdef CATCH_CONFIG_VARIADIC_MACROS
11660 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
11661 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
11662 #else
11663 #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
11664 #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
11665 #endif
11666 #define GIVEN( desc )    SECTION( std::string("   Given: ") + desc, "" )
11667 #define WHEN( desc )     SECTION( std::string("    When: ") + desc, "" )
11668 #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
11669 #define THEN( desc )     SECTION( std::string("    Then: ") + desc, "" )
11670 #define AND_THEN( desc ) SECTION( std::string("     And: ") + desc, "" )
11671 
11672 using Catch::Detail::Approx;
11673 
11674 // #included from: internal/catch_reenable_warnings.h
11675 
11676 #define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
11677 
11678 #ifdef __clang__
11679 #    ifdef __ICC // icpc defines the __clang__ macro
11680 #        pragma warning(pop)
11681 #    else
11682 #        pragma clang diagnostic pop
11683 #    endif
11684 #elif defined __GNUC__
11685 #    pragma GCC diagnostic pop
11686 #endif
11687 
11688 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
11689 
11690