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