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