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