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