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