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