File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/CPP/catch.x/i/catch.hpp
Criterion Covered Total %
statement 38 60 63.3
branch 16 34 47.0
condition n/a
subroutine n/a
pod n/a
total 54 94 57.4


line stmt bran cond sub pod time code
1             /*
2             * Catch v2.4.0
3             * Generated: 2018-09-04 11:55:01.682061
4             * ----------------------------------------------------------
5             * This file has been merged from multiple headers. Please don't edit it directly
6             * Copyright (c) 2018 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             // start catch.hpp
14              
15             #define CATCH_VERSION_MAJOR 2
16             #define CATCH_VERSION_MINOR 4
17             #define CATCH_VERSION_PATCH 0
18              
19             #ifdef __clang__
20             # pragma clang system_header
21             #elif defined __GNUC__
22             # pragma GCC system_header
23             #endif
24              
25             // start catch_suppress_warnings.h
26              
27             #ifdef __clang__
28             # ifdef __ICC // icpc defines the __clang__ macro
29             # pragma warning(push)
30             # pragma warning(disable: 161 1682)
31             # else // __ICC
32             # pragma clang diagnostic push
33             # pragma clang diagnostic ignored "-Wpadded"
34             # pragma clang diagnostic ignored "-Wswitch-enum"
35             # pragma clang diagnostic ignored "-Wcovered-switch-default"
36             # endif
37             #elif defined __GNUC__
38             // GCC likes to warn on REQUIREs, and we cannot suppress them
39             // locally because g++'s support for _Pragma is lacking in older,
40             // still supported, versions
41             # pragma GCC diagnostic ignored "-Wparentheses"
42             # pragma GCC diagnostic push
43             # pragma GCC diagnostic ignored "-Wunused-variable"
44             # pragma GCC diagnostic ignored "-Wpadded"
45             #endif
46             // end catch_suppress_warnings.h
47             #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
48             # define CATCH_IMPL
49             # define CATCH_CONFIG_ALL_PARTS
50             #endif
51              
52             // In the impl file, we want to have access to all parts of the headers
53             // Can also be used to sanely support PCHs
54             #if defined(CATCH_CONFIG_ALL_PARTS)
55             # define CATCH_CONFIG_EXTERNAL_INTERFACES
56             # if defined(CATCH_CONFIG_DISABLE_MATCHERS)
57             # undef CATCH_CONFIG_DISABLE_MATCHERS
58             # endif
59             # if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
60             # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
61             # endif
62             #endif
63              
64             #if !defined(CATCH_CONFIG_IMPL_ONLY)
65             // start catch_platform.h
66              
67             #ifdef __APPLE__
68             # include
69             # if TARGET_OS_OSX == 1
70             # define CATCH_PLATFORM_MAC
71             # elif TARGET_OS_IPHONE == 1
72             # define CATCH_PLATFORM_IPHONE
73             # endif
74              
75             #elif defined(linux) || defined(__linux) || defined(__linux__)
76             # define CATCH_PLATFORM_LINUX
77              
78             #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
79             # define CATCH_PLATFORM_WINDOWS
80             #endif
81              
82             // end catch_platform.h
83              
84             #ifdef CATCH_IMPL
85             # ifndef CLARA_CONFIG_MAIN
86             # define CLARA_CONFIG_MAIN_NOT_DEFINED
87             # define CLARA_CONFIG_MAIN
88             # endif
89             #endif
90              
91             // start catch_user_interfaces.h
92              
93             namespace Catch {
94             unsigned int rngSeed();
95             }
96              
97             // end catch_user_interfaces.h
98             // start catch_tag_alias_autoregistrar.h
99              
100             // start catch_common.h
101              
102             // start catch_compiler_capabilities.h
103              
104             // Detect a number of compiler features - by compiler
105             // The following features are defined:
106             //
107             // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
108             // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
109             // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
110             // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
111             // ****************
112             // Note to maintainers: if new toggles are added please document them
113             // in configuration.md, too
114             // ****************
115              
116             // In general each macro has a _NO_ form
117             // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
118             // Many features, at point of detection, define an _INTERNAL_ macro, so they
119             // can be combined, en-mass, with the _NO_ forms later.
120              
121             #ifdef __cplusplus
122              
123             # if __cplusplus >= 201402L
124             # define CATCH_CPP14_OR_GREATER
125             # endif
126              
127             # if __cplusplus >= 201703L
128             # define CATCH_CPP17_OR_GREATER
129             # endif
130              
131             #endif
132              
133             #if defined(CATCH_CPP17_OR_GREATER)
134             # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
135             #endif
136              
137             #ifdef __clang__
138              
139             # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
140             _Pragma( "clang diagnostic push" ) \
141             _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
142             _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
143             # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
144             _Pragma( "clang diagnostic pop" )
145              
146             # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
147             _Pragma( "clang diagnostic push" ) \
148             _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
149             # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
150             _Pragma( "clang diagnostic pop" )
151              
152             # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
153             _Pragma( "clang diagnostic push" ) \
154             _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
155             # define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
156             _Pragma( "clang diagnostic pop" )
157              
158             #endif // __clang__
159              
160             ////////////////////////////////////////////////////////////////////////////////
161             // Assume that non-Windows platforms support posix signals by default
162             #if !defined(CATCH_PLATFORM_WINDOWS)
163             #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
164             #endif
165              
166             ////////////////////////////////////////////////////////////////////////////////
167             // We know some environments not to support full POSIX signals
168             #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
169             #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
170             #endif
171              
172             #ifdef __OS400__
173             # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
174             # define CATCH_CONFIG_COLOUR_NONE
175             #endif
176              
177             ////////////////////////////////////////////////////////////////////////////////
178             // Android somehow still does not support std::to_string
179             #if defined(__ANDROID__)
180             # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
181             #endif
182              
183             ////////////////////////////////////////////////////////////////////////////////
184             // Not all Windows environments support SEH properly
185             #if defined(__MINGW32__)
186             # define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
187             #endif
188              
189             ////////////////////////////////////////////////////////////////////////////////
190             // PS4
191             #if defined(__ORBIS__)
192             # define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
193             #endif
194              
195             ////////////////////////////////////////////////////////////////////////////////
196             // Cygwin
197             #ifdef __CYGWIN__
198              
199             // Required for some versions of Cygwin to declare gettimeofday
200             // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
201             # define _BSD_SOURCE
202              
203             #endif // __CYGWIN__
204              
205             ////////////////////////////////////////////////////////////////////////////////
206             // Visual C++
207             #ifdef _MSC_VER
208              
209             # if _MSC_VER >= 1900 // Visual Studio 2015 or newer
210             # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
211             # endif
212              
213             // Universal Windows platform does not support SEH
214             // Or console colours (or console at all...)
215             # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
216             # define CATCH_CONFIG_COLOUR_NONE
217             # else
218             # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
219             # endif
220              
221             #endif // _MSC_VER
222              
223             ////////////////////////////////////////////////////////////////////////////////
224             // Check if we are compiled with -fno-exceptions or equivalent
225             #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
226             # define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
227             #endif
228              
229             ////////////////////////////////////////////////////////////////////////////////
230             // DJGPP
231             #ifdef __DJGPP__
232             # define CATCH_INTERNAL_CONFIG_NO_WCHAR
233             #endif // __DJGPP__
234              
235             ////////////////////////////////////////////////////////////////////////////////
236              
237             // Use of __COUNTER__ is suppressed during code analysis in
238             // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
239             // handled by it.
240             // Otherwise all supported compilers support COUNTER macro,
241             // but user still might want to turn it off
242             #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
243             #define CATCH_INTERNAL_CONFIG_COUNTER
244             #endif
245              
246             #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
247             # define CATCH_CONFIG_COUNTER
248             #endif
249             #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
250             # define CATCH_CONFIG_WINDOWS_SEH
251             #endif
252             // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
253             #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
254             # define CATCH_CONFIG_POSIX_SIGNALS
255             #endif
256             // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
257             #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
258             # define CATCH_CONFIG_WCHAR
259             #endif
260              
261             #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
262             # define CATCH_CONFIG_CPP11_TO_STRING
263             #endif
264              
265             #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
266             # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
267             #endif
268              
269             #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
270             # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
271             #endif
272              
273             #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
274             # define CATCH_CONFIG_NEW_CAPTURE
275             #endif
276              
277             #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
278             # define CATCH_CONFIG_DISABLE_EXCEPTIONS
279             #endif
280              
281             #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
282             # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
283             # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
284             #endif
285             #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
286             # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
287             # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
288             #endif
289             #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
290             # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
291             # define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
292             #endif
293              
294             #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
295             #define CATCH_TRY if ((true))
296             #define CATCH_CATCH_ALL if ((false))
297             #define CATCH_CATCH_ANON(type) if ((false))
298             #else
299             #define CATCH_TRY try
300             #define CATCH_CATCH_ALL catch (...)
301             #define CATCH_CATCH_ANON(type) catch (type)
302             #endif
303              
304             // end catch_compiler_capabilities.h
305             #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
306             #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
307             #ifdef CATCH_CONFIG_COUNTER
308             # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
309             #else
310             # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
311             #endif
312              
313             #include
314             #include
315             #include
316              
317             namespace Catch {
318              
319             struct CaseSensitive { enum Choice {
320             Yes,
321             No
322             }; };
323              
324             class NonCopyable {
325             NonCopyable( NonCopyable const& ) = delete;
326             NonCopyable( NonCopyable && ) = delete;
327             NonCopyable& operator = ( NonCopyable const& ) = delete;
328             NonCopyable& operator = ( NonCopyable && ) = delete;
329              
330             protected:
331             NonCopyable();
332             virtual ~NonCopyable();
333             };
334              
335             struct SourceLineInfo {
336              
337             SourceLineInfo() = delete;
338 0           SourceLineInfo( char const* _file, std::size_t _line ) noexcept
339             : file( _file ),
340 0           line( _line )
341 0           {}
342              
343             SourceLineInfo( SourceLineInfo const& other ) = default;
344             SourceLineInfo( SourceLineInfo && ) = default;
345             SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
346             SourceLineInfo& operator = ( SourceLineInfo && ) = default;
347              
348             bool empty() const noexcept;
349             bool operator == ( SourceLineInfo const& other ) const noexcept;
350             bool operator < ( SourceLineInfo const& other ) const noexcept;
351              
352             char const* file;
353             std::size_t line;
354             };
355              
356             std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
357              
358             // Use this in variadic streaming macros to allow
359             // >> +StreamEndStop
360             // as well as
361             // >> stuff +StreamEndStop
362             struct StreamEndStop {
363             std::string operator+() const;
364             };
365             template
366             T const& operator + ( T const& value, StreamEndStop ) {
367             return value;
368             }
369             }
370              
371             #define CATCH_INTERNAL_LINEINFO \
372             ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) )
373              
374             // end catch_common.h
375             namespace Catch {
376              
377             struct RegistrarForTagAliases {
378             RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
379             };
380              
381             } // end namespace Catch
382              
383             #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
384             CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
385             namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
386             CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
387              
388             // end catch_tag_alias_autoregistrar.h
389             // start catch_test_registry.h
390              
391             // start catch_interfaces_testcase.h
392              
393             #include
394             #include
395              
396             namespace Catch {
397              
398             class TestSpec;
399              
400             struct ITestInvoker {
401             virtual void invoke () const = 0;
402             virtual ~ITestInvoker();
403             };
404              
405             using ITestCasePtr = std::shared_ptr;
406              
407             class TestCase;
408             struct IConfig;
409              
410             struct ITestCaseRegistry {
411             virtual ~ITestCaseRegistry();
412             virtual std::vector const& getAllTests() const = 0;
413             virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0;
414             };
415              
416             bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
417             std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config );
418             std::vector const& getAllTestCasesSorted( IConfig const& config );
419              
420             }
421              
422             // end catch_interfaces_testcase.h
423             // start catch_stringref.h
424              
425             #include
426             #include
427             #include
428              
429             namespace Catch {
430              
431             class StringData;
432              
433             /// A non-owning string class (similar to the forthcoming std::string_view)
434             /// Note that, because a StringRef may be a substring of another string,
435             /// it may not be null terminated. c_str() must return a null terminated
436             /// string, however, and so the StringRef will internally take ownership
437             /// (taking a copy), if necessary. In theory this ownership is not externally
438             /// visible - but it does mean (substring) StringRefs should not be shared between
439             /// threads.
440             class StringRef {
441             public:
442             using size_type = std::size_t;
443              
444             private:
445             friend struct StringRefTestAccess;
446              
447             char const* m_start;
448             size_type m_size;
449              
450             char* m_data = nullptr;
451              
452             void takeOwnership();
453              
454             static constexpr char const* const s_empty = "";
455              
456             public: // construction/ assignment
457 0           StringRef() noexcept
458 0           : StringRef( s_empty, 0 )
459 0           {}
460              
461 0           StringRef( StringRef const& other ) noexcept
462 0           : m_start( other.m_start ),
463 0           m_size( other.m_size )
464 0           {}
465              
466             StringRef( StringRef&& other ) noexcept
467             : m_start( other.m_start ),
468             m_size( other.m_size ),
469             m_data( other.m_data )
470             {
471             other.m_data = nullptr;
472             }
473              
474             StringRef( char const* rawChars ) noexcept;
475              
476 0           StringRef( char const* rawChars, size_type size ) noexcept
477             : m_start( rawChars ),
478 0           m_size( size )
479 0           {}
480              
481             StringRef( std::string const& stdString ) noexcept
482             : m_start( stdString.c_str() ),
483             m_size( stdString.size() )
484             {}
485              
486 0           ~StringRef() noexcept {
487 0 0         delete[] m_data;
488 0           }
489              
490             auto operator = ( StringRef const &other ) noexcept -> StringRef& {
491             delete[] m_data;
492             m_data = nullptr;
493             m_start = other.m_start;
494             m_size = other.m_size;
495             return *this;
496             }
497              
498             operator std::string() const;
499              
500             void swap( StringRef& other ) noexcept;
501              
502             public: // operators
503             auto operator == ( StringRef const& other ) const noexcept -> bool;
504             auto operator != ( StringRef const& other ) const noexcept -> bool;
505              
506             auto operator[] ( size_type index ) const noexcept -> char;
507              
508             public: // named queries
509             auto empty() const noexcept -> bool {
510             return m_size == 0;
511             }
512             auto size() const noexcept -> size_type {
513             return m_size;
514             }
515              
516             auto numberOfCharacters() const noexcept -> size_type;
517             auto c_str() const -> char const*;
518              
519             public: // substrings and searches
520             auto substr( size_type start, size_type size ) const noexcept -> StringRef;
521              
522             // Returns the current start pointer.
523             // Note that the pointer can change when if the StringRef is a substring
524             auto currentData() const noexcept -> char const*;
525              
526             private: // ownership queries - may not be consistent between calls
527             auto isOwned() const noexcept -> bool;
528             auto isSubstring() const noexcept -> bool;
529             };
530              
531             auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
532             auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
533             auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
534              
535             auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
536             auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
537              
538             inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
539             return StringRef( rawChars, size );
540             }
541              
542             } // namespace Catch
543              
544 24           inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
545 24           return Catch::StringRef( rawChars, size );
546             }
547              
548             // end catch_stringref.h
549             namespace Catch {
550              
551             template
552             class TestInvokerAsMethod : public ITestInvoker {
553             void (C::*m_testAsMethod)();
554             public:
555             TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
556              
557             void invoke() const override {
558             C obj;
559             (obj.*m_testAsMethod)();
560             }
561             };
562              
563             auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
564              
565             template
566             auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
567             return new(std::nothrow) TestInvokerAsMethod( testAsMethod );
568             }
569              
570 52           struct NameAndTags {
571             NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
572             StringRef name;
573             StringRef tags;
574             };
575              
576             struct AutoReg : NonCopyable {
577             AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
578             ~AutoReg();
579             };
580              
581             } // end namespace Catch
582              
583             #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
584             #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
585             #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
586             #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
587              
588             #if defined(CATCH_CONFIG_DISABLE)
589             #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
590             static void TestName()
591             #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
592             namespace{ \
593             struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
594             void test(); \
595             }; \
596             } \
597             void TestName::test()
598              
599             #endif
600              
601             ///////////////////////////////////////////////////////////////////////////////
602             #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
603             static void TestName(); \
604             CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
605             namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
606             CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
607             static void TestName()
608             #define INTERNAL_CATCH_TESTCASE( ... ) \
609             INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
610              
611             ///////////////////////////////////////////////////////////////////////////////
612             #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
613             CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
614             namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
615             CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
616              
617             ///////////////////////////////////////////////////////////////////////////////
618             #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
619             CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
620             namespace{ \
621             struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
622             void test(); \
623             }; \
624             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
625             } \
626             CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
627             void TestName::test()
628             #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
629             INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
630              
631             ///////////////////////////////////////////////////////////////////////////////
632             #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
633             CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
634             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
635             CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
636              
637             // end catch_test_registry.h
638             // start catch_capture.hpp
639              
640             // start catch_assertionhandler.h
641              
642             // start catch_assertioninfo.h
643              
644             // start catch_result_type.h
645              
646             namespace Catch {
647              
648             // ResultWas::OfType enum
649             struct ResultWas { enum OfType {
650             Unknown = -1,
651             Ok = 0,
652             Info = 1,
653             Warning = 2,
654              
655             FailureBit = 0x10,
656              
657             ExpressionFailed = FailureBit | 1,
658             ExplicitFailure = FailureBit | 2,
659              
660             Exception = 0x100 | FailureBit,
661              
662             ThrewException = Exception | 1,
663             DidntThrowException = Exception | 2,
664              
665             FatalErrorCondition = 0x200 | FailureBit
666              
667             }; };
668              
669             bool isOk( ResultWas::OfType resultType );
670             bool isJustInfo( int flags );
671              
672             // ResultDisposition::Flags enum
673             struct ResultDisposition { enum Flags {
674             Normal = 0x01,
675              
676             ContinueOnFailure = 0x02, // Failures fail test, but execution continues
677             FalseTest = 0x04, // Prefix expression with !
678             SuppressFail = 0x08 // Failures are reported but do not fail the test
679             }; };
680              
681             ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
682              
683             bool shouldContinueOnFailure( int flags );
684             inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
685             bool shouldSuppressFailure( int flags );
686              
687             } // end namespace Catch
688              
689             // end catch_result_type.h
690             namespace Catch {
691              
692 0           struct AssertionInfo
693             {
694             StringRef macroName;
695             SourceLineInfo lineInfo;
696             StringRef capturedExpression;
697             ResultDisposition::Flags resultDisposition;
698              
699             // We want to delete this constructor but a compiler bug in 4.8 means
700             // the struct is then treated as non-aggregate
701             //AssertionInfo() = delete;
702             };
703              
704             } // end namespace Catch
705              
706             // end catch_assertioninfo.h
707             // start catch_decomposer.h
708              
709             // start catch_tostring.h
710              
711             #include
712             #include
713             #include
714             #include
715             // start catch_stream.h
716              
717             #include
718             #include
719             #include
720              
721             namespace Catch {
722              
723             std::ostream& cout();
724             std::ostream& cerr();
725             std::ostream& clog();
726              
727             class StringRef;
728              
729             struct IStream {
730             virtual ~IStream();
731             virtual std::ostream& stream() const = 0;
732             };
733              
734             auto makeStream( StringRef const &filename ) -> IStream const*;
735              
736             class ReusableStringStream {
737             std::size_t m_index;
738             std::ostream* m_oss;
739             public:
740             ReusableStringStream();
741             ~ReusableStringStream();
742              
743             auto str() const -> std::string;
744              
745             template
746             auto operator << ( T const& value ) -> ReusableStringStream& {
747             *m_oss << value;
748             return *this;
749             }
750             auto get() -> std::ostream& { return *m_oss; }
751             };
752             }
753              
754             // end catch_stream.h
755              
756             #ifdef __OBJC__
757             // start catch_objc_arc.hpp
758              
759             #import
760              
761             #ifdef __has_feature
762             #define CATCH_ARC_ENABLED __has_feature(objc_arc)
763             #else
764             #define CATCH_ARC_ENABLED 0
765             #endif
766              
767             void arcSafeRelease( NSObject* obj );
768             id performOptionalSelector( id obj, SEL sel );
769              
770             #if !CATCH_ARC_ENABLED
771             inline void arcSafeRelease( NSObject* obj ) {
772             [obj release];
773             }
774             inline id performOptionalSelector( id obj, SEL sel ) {
775             if( [obj respondsToSelector: sel] )
776             return [obj performSelector: sel];
777             return nil;
778             }
779             #define CATCH_UNSAFE_UNRETAINED
780             #define CATCH_ARC_STRONG
781             #else
782             inline void arcSafeRelease( NSObject* ){}
783             inline id performOptionalSelector( id obj, SEL sel ) {
784             #ifdef __clang__
785             #pragma clang diagnostic push
786             #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
787             #endif
788             if( [obj respondsToSelector: sel] )
789             return [obj performSelector: sel];
790             #ifdef __clang__
791             #pragma clang diagnostic pop
792             #endif
793             return nil;
794             }
795             #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
796             #define CATCH_ARC_STRONG __strong
797             #endif
798              
799             // end catch_objc_arc.hpp
800             #endif
801              
802             #ifdef _MSC_VER
803             #pragma warning(push)
804             #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
805             #endif
806              
807             // We need a dummy global operator<< so we can bring it into Catch namespace later
808             struct Catch_global_namespace_dummy {};
809             std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
810              
811             namespace Catch {
812             // Bring in operator<< from global namespace into Catch namespace
813             using ::operator<<;
814              
815             namespace Detail {
816              
817             extern const std::string unprintableString;
818              
819             std::string rawMemoryToString( const void *object, std::size_t size );
820              
821             template
822             std::string rawMemoryToString( const T& object ) {
823             return rawMemoryToString( &object, sizeof(object) );
824             }
825              
826             template
827             class IsStreamInsertable {
828             template
829             static auto test(int)
830             -> decltype(std::declval() << std::declval(), std::true_type());
831              
832             template
833             static auto test(...)->std::false_type;
834              
835             public:
836             static const bool value = decltype(test(0))::value;
837             };
838              
839             template
840             std::string convertUnknownEnumToString( E e );
841              
842             template
843             typename std::enable_if<
844             !std::is_enum::value && !std::is_base_of::value,
845             std::string>::type convertUnstreamable( T const& ) {
846             return Detail::unprintableString;
847             }
848             template
849             typename std::enable_if<
850             !std::is_enum::value && std::is_base_of::value,
851             std::string>::type convertUnstreamable(T const& ex) {
852             return ex.what();
853             }
854              
855             template
856             typename std::enable_if<
857             std::is_enum::value
858             , std::string>::type convertUnstreamable( T const& value ) {
859             return convertUnknownEnumToString( value );
860             }
861              
862             #if defined(_MANAGED)
863             //! Convert a CLR string to a utf8 std::string
864             template
865             std::string clrReferenceToString( T^ ref ) {
866             if (ref == nullptr)
867             return std::string("null");
868             auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
869             cli::pin_ptr p = &bytes[0];
870             return std::string(reinterpret_cast(p), bytes->Length);
871             }
872             #endif
873              
874             } // namespace Detail
875              
876             // If we decide for C++14, change these to enable_if_ts
877             template
878             struct StringMaker {
879             template
880             static
881             typename std::enable_if<::Catch::Detail::IsStreamInsertable::value, std::string>::type
882             convert(const Fake& value) {
883             ReusableStringStream rss;
884             // NB: call using the function-like syntax to avoid ambiguity with
885             // user-defined templated operator<< under clang.
886             rss.operator<<(value);
887             return rss.str();
888             }
889              
890             template
891             static
892             typename std::enable_if::value, std::string>::type
893             convert( const Fake& value ) {
894             #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
895             return Detail::convertUnstreamable(value);
896             #else
897             return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
898             #endif
899             }
900             };
901              
902             namespace Detail {
903              
904             // This function dispatches all stringification requests inside of Catch.
905             // Should be preferably called fully qualified, like ::Catch::Detail::stringify
906             template
907 47           std::string stringify(const T& e) {
908 47           return ::Catch::StringMaker::type>::type>::convert(e);
909             }
910              
911             template
912             std::string convertUnknownEnumToString( E e ) {
913             return ::Catch::Detail::stringify(static_cast::type>(e));
914             }
915              
916             #if defined(_MANAGED)
917             template
918             std::string stringify( T^ e ) {
919             return ::Catch::StringMaker::convert(e);
920             }
921             #endif
922              
923             } // namespace Detail
924              
925             // Some predefined specializations
926              
927             template<>
928             struct StringMaker {
929             static std::string convert(const std::string& str);
930             };
931             #ifdef CATCH_CONFIG_WCHAR
932             template<>
933             struct StringMaker {
934             static std::string convert(const std::wstring& wstr);
935             };
936             #endif
937              
938             template<>
939             struct StringMaker {
940             static std::string convert(char const * str);
941             };
942             template<>
943             struct StringMaker {
944             static std::string convert(char * str);
945             };
946              
947             #ifdef CATCH_CONFIG_WCHAR
948             template<>
949             struct StringMaker {
950             static std::string convert(wchar_t const * str);
951             };
952             template<>
953             struct StringMaker {
954             static std::string convert(wchar_t * str);
955             };
956             #endif
957              
958             // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
959             // while keeping string semantics?
960             template
961             struct StringMaker {
962             static std::string convert(char const* str) {
963             return ::Catch::Detail::stringify(std::string{ str });
964             }
965             };
966             template
967             struct StringMaker {
968             static std::string convert(signed char const* str) {
969             return ::Catch::Detail::stringify(std::string{ reinterpret_cast(str) });
970             }
971             };
972             template
973             struct StringMaker {
974             static std::string convert(unsigned char const* str) {
975             return ::Catch::Detail::stringify(std::string{ reinterpret_cast(str) });
976             }
977             };
978              
979             template<>
980             struct StringMaker {
981             static std::string convert(int value);
982             };
983             template<>
984             struct StringMaker {
985             static std::string convert(long value);
986             };
987             template<>
988             struct StringMaker {
989             static std::string convert(long long value);
990             };
991             template<>
992             struct StringMaker {
993             static std::string convert(unsigned int value);
994             };
995             template<>
996             struct StringMaker {
997             static std::string convert(unsigned long value);
998             };
999             template<>
1000             struct StringMaker {
1001             static std::string convert(unsigned long long value);
1002             };
1003              
1004             template<>
1005             struct StringMaker {
1006             static std::string convert(bool b);
1007             };
1008              
1009             template<>
1010             struct StringMaker {
1011             static std::string convert(char c);
1012             };
1013             template<>
1014             struct StringMaker {
1015             static std::string convert(signed char c);
1016             };
1017             template<>
1018             struct StringMaker {
1019             static std::string convert(unsigned char c);
1020             };
1021              
1022             template<>
1023             struct StringMaker {
1024             static std::string convert(std::nullptr_t);
1025             };
1026              
1027             template<>
1028             struct StringMaker {
1029             static std::string convert(float value);
1030             };
1031             template<>
1032             struct StringMaker {
1033             static std::string convert(double value);
1034             };
1035              
1036             template
1037             struct StringMaker {
1038             template
1039             static std::string convert(U* p) {
1040             if (p) {
1041             return ::Catch::Detail::rawMemoryToString(p);
1042             } else {
1043             return "nullptr";
1044             }
1045             }
1046             };
1047              
1048             template
1049             struct StringMaker {
1050             static std::string convert(R C::* p) {
1051             if (p) {
1052             return ::Catch::Detail::rawMemoryToString(p);
1053             } else {
1054             return "nullptr";
1055             }
1056             }
1057             };
1058              
1059             #if defined(_MANAGED)
1060             template
1061             struct StringMaker {
1062             static std::string convert( T^ ref ) {
1063             return ::Catch::Detail::clrReferenceToString(ref);
1064             }
1065             };
1066             #endif
1067              
1068             namespace Detail {
1069             template
1070             std::string rangeToString(InputIterator first, InputIterator last) {
1071             ReusableStringStream rss;
1072             rss << "{ ";
1073             if (first != last) {
1074             rss << ::Catch::Detail::stringify(*first);
1075             for (++first; first != last; ++first)
1076             rss << ", " << ::Catch::Detail::stringify(*first);
1077             }
1078             rss << " }";
1079             return rss.str();
1080             }
1081             }
1082              
1083             #ifdef __OBJC__
1084             template<>
1085             struct StringMaker {
1086             static std::string convert(NSString * nsstring) {
1087             if (!nsstring)
1088             return "nil";
1089             return std::string("@") + [nsstring UTF8String];
1090             }
1091             };
1092             template<>
1093             struct StringMaker {
1094             static std::string convert(NSObject* nsObject) {
1095             return ::Catch::Detail::stringify([nsObject description]);
1096             }
1097              
1098             };
1099             namespace Detail {
1100             inline std::string stringify( NSString* nsstring ) {
1101             return StringMaker::convert( nsstring );
1102             }
1103              
1104             } // namespace Detail
1105             #endif // __OBJC__
1106              
1107             } // namespace Catch
1108              
1109             //////////////////////////////////////////////////////
1110             // Separate std-lib types stringification, so it can be selectively enabled
1111             // This means that we do not bring in
1112              
1113             #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
1114             # define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1115             # define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1116             # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
1117             #endif
1118              
1119             // Separate std::pair specialization
1120             #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
1121             #include
1122             namespace Catch {
1123             template
1124             struct StringMaker > {
1125             static std::string convert(const std::pair& pair) {
1126             ReusableStringStream rss;
1127             rss << "{ "
1128             << ::Catch::Detail::stringify(pair.first)
1129             << ", "
1130             << ::Catch::Detail::stringify(pair.second)
1131             << " }";
1132             return rss.str();
1133             }
1134             };
1135             }
1136             #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1137              
1138             // Separate std::tuple specialization
1139             #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
1140             #include
1141             namespace Catch {
1142             namespace Detail {
1143             template<
1144             typename Tuple,
1145             std::size_t N = 0,
1146             bool = (N < std::tuple_size::value)
1147             >
1148             struct TupleElementPrinter {
1149             static void print(const Tuple& tuple, std::ostream& os) {
1150             os << (N ? ", " : " ")
1151             << ::Catch::Detail::stringify(std::get(tuple));
1152             TupleElementPrinter::print(tuple, os);
1153             }
1154             };
1155              
1156             template<
1157             typename Tuple,
1158             std::size_t N
1159             >
1160             struct TupleElementPrinter {
1161             static void print(const Tuple&, std::ostream&) {}
1162             };
1163              
1164             }
1165              
1166             template
1167             struct StringMaker> {
1168             static std::string convert(const std::tuple& tuple) {
1169             ReusableStringStream rss;
1170             rss << '{';
1171             Detail::TupleElementPrinter>::print(tuple, rss.get());
1172             rss << " }";
1173             return rss.str();
1174             }
1175             };
1176             }
1177             #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1178              
1179             namespace Catch {
1180             struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
1181              
1182             // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
1183             using std::begin;
1184             using std::end;
1185              
1186             not_this_one begin( ... );
1187             not_this_one end( ... );
1188              
1189             template
1190             struct is_range {
1191             static const bool value =
1192             !std::is_same())), not_this_one>::value &&
1193             !std::is_same())), not_this_one>::value;
1194             };
1195              
1196             #if defined(_MANAGED) // Managed types are never ranges
1197             template
1198             struct is_range {
1199             static const bool value = false;
1200             };
1201             #endif
1202              
1203             template
1204             std::string rangeToString( Range const& range ) {
1205             return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
1206             }
1207              
1208             // Handle vector specially
1209             template
1210             std::string rangeToString( std::vector const& v ) {
1211             ReusableStringStream rss;
1212             rss << "{ ";
1213             bool first = true;
1214             for( bool b : v ) {
1215             if( first )
1216             first = false;
1217             else
1218             rss << ", ";
1219             rss << ::Catch::Detail::stringify( b );
1220             }
1221             rss << " }";
1222             return rss.str();
1223             }
1224              
1225             template
1226             struct StringMaker::value && !::Catch::Detail::IsStreamInsertable::value>::type> {
1227             static std::string convert( R const& range ) {
1228             return rangeToString( range );
1229             }
1230             };
1231              
1232             template
1233             struct StringMaker {
1234             static std::string convert(T const(&arr)[SZ]) {
1235             return rangeToString(arr);
1236             }
1237             };
1238              
1239             } // namespace Catch
1240              
1241             // Separate std::chrono::duration specialization
1242             #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
1243             #include
1244             #include
1245             #include
1246              
1247             namespace Catch {
1248              
1249             template
1250             struct ratio_string {
1251             static std::string symbol();
1252             };
1253              
1254             template
1255             std::string ratio_string::symbol() {
1256             Catch::ReusableStringStream rss;
1257             rss << '[' << Ratio::num << '/'
1258             << Ratio::den << ']';
1259             return rss.str();
1260             }
1261             template <>
1262             struct ratio_string {
1263             static std::string symbol();
1264             };
1265             template <>
1266             struct ratio_string {
1267             static std::string symbol();
1268             };
1269             template <>
1270             struct ratio_string {
1271             static std::string symbol();
1272             };
1273             template <>
1274             struct ratio_string {
1275             static std::string symbol();
1276             };
1277             template <>
1278             struct ratio_string {
1279             static std::string symbol();
1280             };
1281             template <>
1282             struct ratio_string {
1283             static std::string symbol();
1284             };
1285              
1286             ////////////
1287             // std::chrono::duration specializations
1288             template
1289             struct StringMaker> {
1290             static std::string convert(std::chrono::duration const& duration) {
1291             ReusableStringStream rss;
1292             rss << duration.count() << ' ' << ratio_string::symbol() << 's';
1293             return rss.str();
1294             }
1295             };
1296             template
1297             struct StringMaker>> {
1298             static std::string convert(std::chrono::duration> const& duration) {
1299             ReusableStringStream rss;
1300             rss << duration.count() << " s";
1301             return rss.str();
1302             }
1303             };
1304             template
1305             struct StringMaker>> {
1306             static std::string convert(std::chrono::duration> const& duration) {
1307             ReusableStringStream rss;
1308             rss << duration.count() << " m";
1309             return rss.str();
1310             }
1311             };
1312             template
1313             struct StringMaker>> {
1314             static std::string convert(std::chrono::duration> const& duration) {
1315             ReusableStringStream rss;
1316             rss << duration.count() << " h";
1317             return rss.str();
1318             }
1319             };
1320              
1321             ////////////
1322             // std::chrono::time_point specialization
1323             // Generic time_point cannot be specialized, only std::chrono::time_point
1324             template
1325             struct StringMaker> {
1326             static std::string convert(std::chrono::time_point const& time_point) {
1327             return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
1328             }
1329             };
1330             // std::chrono::time_point specialization
1331             template
1332             struct StringMaker> {
1333             static std::string convert(std::chrono::time_point const& time_point) {
1334             auto converted = std::chrono::system_clock::to_time_t(time_point);
1335              
1336             #ifdef _MSC_VER
1337             std::tm timeInfo = {};
1338             gmtime_s(&timeInfo, &converted);
1339             #else
1340             std::tm* timeInfo = std::gmtime(&converted);
1341             #endif
1342              
1343             auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
1344             char timeStamp[timeStampSize];
1345             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
1346              
1347             #ifdef _MSC_VER
1348             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
1349             #else
1350             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
1351             #endif
1352             return std::string(timeStamp);
1353             }
1354             };
1355             }
1356             #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
1357              
1358             #ifdef _MSC_VER
1359             #pragma warning(pop)
1360             #endif
1361              
1362             // end catch_tostring.h
1363             #include
1364              
1365             #ifdef _MSC_VER
1366             #pragma warning(push)
1367             #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
1368             #pragma warning(disable:4018) // more "signed/unsigned mismatch"
1369             #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
1370             #pragma warning(disable:4180) // qualifier applied to function type has no meaning
1371             #endif
1372              
1373             namespace Catch {
1374              
1375             struct ITransientExpression {
1376             auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
1377             auto getResult() const -> bool { return m_result; }
1378             virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
1379              
1380 0           ITransientExpression( bool isBinaryExpression, bool result )
1381             : m_isBinaryExpression( isBinaryExpression ),
1382 0           m_result( result )
1383 0           {}
1384              
1385             // We don't actually need a virtual destructor, but many static analysers
1386             // complain if it's not here :-(
1387             virtual ~ITransientExpression();
1388              
1389             bool m_isBinaryExpression;
1390             bool m_result;
1391              
1392             };
1393              
1394             void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
1395              
1396             template
1397 46 50         class BinaryExpr : public ITransientExpression {
    50          
    50          
    50          
1398             LhsT m_lhs;
1399             StringRef m_op;
1400             RhsT m_rhs;
1401              
1402 23           void streamReconstructedExpression( std::ostream &os ) const override {
1403 23 50         formatReconstructedExpression
    50          
    50          
    50          
1404 46 50         ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
    50          
    50          
    50          
1405 23           }
1406              
1407             public:
1408 23           BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
1409             : ITransientExpression{ true, comparisonResult },
1410             m_lhs( lhs ),
1411             m_op( op ),
1412 23           m_rhs( rhs )
1413 23           {}
1414             };
1415              
1416             template
1417 2 50         class UnaryExpr : public ITransientExpression {
1418             LhsT m_lhs;
1419              
1420 1           void streamReconstructedExpression( std::ostream &os ) const override {
1421 1 50         os << Catch::Detail::stringify( m_lhs );
1422 1           }
1423              
1424             public:
1425 1           explicit UnaryExpr( LhsT lhs )
1426             : ITransientExpression{ false, lhs ? true : false },
1427 1           m_lhs( lhs )
1428 1           {}
1429             };
1430              
1431             // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
1432             template
1433 38           auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast(lhs == rhs); }
1434             template
1435             auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast( rhs ); }
1436             template
1437             auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast( rhs ); }
1438             template
1439             auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast( lhs ) == rhs; }
1440             template
1441             auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast( lhs ) == rhs; }
1442              
1443             template
1444             auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast(lhs != rhs); }
1445             template
1446             auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast( rhs ); }
1447             template
1448             auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast( rhs ); }
1449             template
1450             auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast( lhs ) != rhs; }
1451             template
1452             auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast( lhs ) != rhs; }
1453              
1454             template
1455             class ExprLhs {
1456             LhsT m_lhs;
1457             public:
1458 24           explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
1459              
1460             template
1461 19           auto operator == ( RhsT const& rhs ) -> BinaryExpr const {
1462 19           return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
1463             }
1464 4           auto operator == ( bool rhs ) -> BinaryExpr const {
1465 4           return { m_lhs == rhs, m_lhs, "==", rhs };
1466             }
1467              
1468             template
1469             auto operator != ( RhsT const& rhs ) -> BinaryExpr const {
1470             return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
1471             }
1472             auto operator != ( bool rhs ) -> BinaryExpr const {
1473             return { m_lhs != rhs, m_lhs, "!=", rhs };
1474             }
1475              
1476             template
1477             auto operator > ( RhsT const& rhs ) -> BinaryExpr const {
1478             return { static_cast(m_lhs > rhs), m_lhs, ">", rhs };
1479             }
1480             template
1481             auto operator < ( RhsT const& rhs ) -> BinaryExpr const {
1482             return { static_cast(m_lhs < rhs), m_lhs, "<", rhs };
1483             }
1484             template
1485             auto operator >= ( RhsT const& rhs ) -> BinaryExpr const {
1486             return { static_cast(m_lhs >= rhs), m_lhs, ">=", rhs };
1487             }
1488             template
1489             auto operator <= ( RhsT const& rhs ) -> BinaryExpr const {
1490             return { static_cast(m_lhs <= rhs), m_lhs, "<=", rhs };
1491             }
1492              
1493 1           auto makeUnaryExpr() const -> UnaryExpr {
1494 1           return UnaryExpr{ m_lhs };
1495             }
1496             };
1497              
1498             void handleExpression( ITransientExpression const& expr );
1499              
1500             template
1501             void handleExpression( ExprLhs const& expr ) {
1502             handleExpression( expr.makeUnaryExpr() );
1503             }
1504              
1505             struct Decomposer {
1506             template
1507 19           auto operator <= ( T const& lhs ) -> ExprLhs {
1508 19           return ExprLhs{ lhs };
1509             }
1510              
1511 5           auto operator <=( bool value ) -> ExprLhs {
1512 5           return ExprLhs{ value };
1513             }
1514             };
1515              
1516             } // end namespace Catch
1517              
1518             #ifdef _MSC_VER
1519             #pragma warning(pop)
1520             #endif
1521              
1522             // end catch_decomposer.h
1523             // start catch_interfaces_capture.h
1524              
1525             #include
1526              
1527             namespace Catch {
1528              
1529             class AssertionResult;
1530             struct AssertionInfo;
1531             struct SectionInfo;
1532             struct SectionEndInfo;
1533             struct MessageInfo;
1534             struct Counts;
1535             struct BenchmarkInfo;
1536             struct BenchmarkStats;
1537             struct AssertionReaction;
1538             struct SourceLineInfo;
1539              
1540             struct ITransientExpression;
1541             struct IGeneratorTracker;
1542              
1543             struct IResultCapture {
1544              
1545             virtual ~IResultCapture();
1546              
1547             virtual bool sectionStarted( SectionInfo const& sectionInfo,
1548             Counts& assertions ) = 0;
1549             virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
1550             virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
1551              
1552             virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
1553              
1554             virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
1555             virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
1556              
1557             virtual void pushScopedMessage( MessageInfo const& message ) = 0;
1558             virtual void popScopedMessage( MessageInfo const& message ) = 0;
1559              
1560             virtual void handleFatalErrorCondition( StringRef message ) = 0;
1561              
1562             virtual void handleExpr
1563             ( AssertionInfo const& info,
1564             ITransientExpression const& expr,
1565             AssertionReaction& reaction ) = 0;
1566             virtual void handleMessage
1567             ( AssertionInfo const& info,
1568             ResultWas::OfType resultType,
1569             StringRef const& message,
1570             AssertionReaction& reaction ) = 0;
1571             virtual void handleUnexpectedExceptionNotThrown
1572             ( AssertionInfo const& info,
1573             AssertionReaction& reaction ) = 0;
1574             virtual void handleUnexpectedInflightException
1575             ( AssertionInfo const& info,
1576             std::string const& message,
1577             AssertionReaction& reaction ) = 0;
1578             virtual void handleIncomplete
1579             ( AssertionInfo const& info ) = 0;
1580             virtual void handleNonExpr
1581             ( AssertionInfo const &info,
1582             ResultWas::OfType resultType,
1583             AssertionReaction &reaction ) = 0;
1584              
1585             virtual bool lastAssertionPassed() = 0;
1586             virtual void assertionPassed() = 0;
1587              
1588             // Deprecated, do not use:
1589             virtual std::string getCurrentTestName() const = 0;
1590             virtual const AssertionResult* getLastResult() const = 0;
1591             virtual void exceptionEarlyReported() = 0;
1592             };
1593              
1594             IResultCapture& getResultCapture();
1595             }
1596              
1597             // end catch_interfaces_capture.h
1598             namespace Catch {
1599              
1600             struct TestFailureException{};
1601             struct AssertionResultData;
1602             struct IResultCapture;
1603             class RunContext;
1604              
1605             class LazyExpression {
1606             friend class AssertionHandler;
1607             friend struct AssertionStats;
1608             friend class RunContext;
1609              
1610             ITransientExpression const* m_transientExpression = nullptr;
1611             bool m_isNegated;
1612             public:
1613             LazyExpression( bool isNegated );
1614             LazyExpression( LazyExpression const& other );
1615             LazyExpression& operator = ( LazyExpression const& ) = delete;
1616              
1617             explicit operator bool() const;
1618              
1619             friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
1620             };
1621              
1622             struct AssertionReaction {
1623             bool shouldDebugBreak = false;
1624             bool shouldThrow = false;
1625             };
1626              
1627             class AssertionHandler {
1628             AssertionInfo m_assertionInfo;
1629             AssertionReaction m_reaction;
1630             bool m_completed = false;
1631             IResultCapture& m_resultCapture;
1632              
1633             public:
1634             AssertionHandler
1635             ( StringRef const& macroName,
1636             SourceLineInfo const& lineInfo,
1637             StringRef capturedExpression,
1638             ResultDisposition::Flags resultDisposition );
1639 48           ~AssertionHandler() {
1640 24 50         if ( !m_completed ) {
1641 0           m_resultCapture.handleIncomplete( m_assertionInfo );
1642             }
1643 24           }
1644              
1645             template
1646 1           void handleExpr( ExprLhs const& expr ) {
1647 1 50         handleExpr( expr.makeUnaryExpr() );
1648 1           }
1649             void handleExpr( ITransientExpression const& expr );
1650              
1651             void handleMessage(ResultWas::OfType resultType, StringRef const& message);
1652              
1653             void handleExceptionThrownAsExpected();
1654             void handleUnexpectedExceptionNotThrown();
1655             void handleExceptionNotThrownAsExpected();
1656             void handleThrowingCallSkipped();
1657             void handleUnexpectedInflightException();
1658              
1659             void complete();
1660             void setCompleted();
1661              
1662             // query
1663             auto allowThrows() const -> bool;
1664             };
1665              
1666             void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
1667              
1668             } // namespace Catch
1669              
1670             // end catch_assertionhandler.h
1671             // start catch_message.h
1672              
1673             #include
1674             #include
1675              
1676             namespace Catch {
1677              
1678             struct MessageInfo {
1679             MessageInfo( StringRef const& _macroName,
1680             SourceLineInfo const& _lineInfo,
1681             ResultWas::OfType _type );
1682              
1683             StringRef macroName;
1684             std::string message;
1685             SourceLineInfo lineInfo;
1686             ResultWas::OfType type;
1687             unsigned int sequence;
1688              
1689             bool operator == ( MessageInfo const& other ) const;
1690             bool operator < ( MessageInfo const& other ) const;
1691             private:
1692             static unsigned int globalCount;
1693             };
1694              
1695             struct MessageStream {
1696              
1697             template
1698             MessageStream& operator << ( T const& value ) {
1699             m_stream << value;
1700             return *this;
1701             }
1702              
1703             ReusableStringStream m_stream;
1704             };
1705              
1706             struct MessageBuilder : MessageStream {
1707             MessageBuilder( StringRef const& macroName,
1708             SourceLineInfo const& lineInfo,
1709             ResultWas::OfType type );
1710              
1711             template
1712             MessageBuilder& operator << ( T const& value ) {
1713             m_stream << value;
1714             return *this;
1715             }
1716              
1717             MessageInfo m_info;
1718             };
1719              
1720             class ScopedMessage {
1721             public:
1722             explicit ScopedMessage( MessageBuilder const& builder );
1723             ~ScopedMessage();
1724              
1725             MessageInfo m_info;
1726             };
1727              
1728             class Capturer {
1729             std::vector m_messages;
1730             IResultCapture& m_resultCapture = getResultCapture();
1731             size_t m_captured = 0;
1732             public:
1733             Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
1734             ~Capturer();
1735              
1736             void captureValue( size_t index, StringRef value );
1737              
1738             template
1739             void captureValues( size_t index, T&& value ) {
1740             captureValue( index, Catch::Detail::stringify( value ) );
1741             }
1742              
1743             template
1744             void captureValues( size_t index, T&& value, Ts&&... values ) {
1745             captureValues( index, value );
1746             captureValues( index+1, values... );
1747             }
1748             };
1749              
1750             } // end namespace Catch
1751              
1752             // end catch_message.h
1753             #if !defined(CATCH_CONFIG_DISABLE)
1754              
1755             #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
1756             #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
1757             #else
1758             #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
1759             #endif
1760              
1761             #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
1762              
1763             ///////////////////////////////////////////////////////////////////////////////
1764             // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
1765             // macros.
1766             #define INTERNAL_CATCH_TRY
1767             #define INTERNAL_CATCH_CATCH( capturer )
1768              
1769             #else // CATCH_CONFIG_FAST_COMPILE
1770              
1771             #define INTERNAL_CATCH_TRY try
1772             #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
1773              
1774             #endif
1775              
1776             #define INTERNAL_CATCH_REACT( handler ) handler.complete();
1777              
1778             ///////////////////////////////////////////////////////////////////////////////
1779             #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
1780             do { \
1781             Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
1782             INTERNAL_CATCH_TRY { \
1783             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
1784             catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
1785             CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
1786             } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
1787             INTERNAL_CATCH_REACT( catchAssertionHandler ) \
1788             } while( (void)0, false && static_cast( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
1789             // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
1790              
1791             ///////////////////////////////////////////////////////////////////////////////
1792             #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
1793             INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
1794             if( Catch::getResultCapture().lastAssertionPassed() )
1795              
1796             ///////////////////////////////////////////////////////////////////////////////
1797             #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
1798             INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
1799             if( !Catch::getResultCapture().lastAssertionPassed() )
1800              
1801             ///////////////////////////////////////////////////////////////////////////////
1802             #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
1803             do { \
1804             Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
1805             try { \
1806             static_cast(__VA_ARGS__); \
1807             catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
1808             } \
1809             catch( ... ) { \
1810             catchAssertionHandler.handleUnexpectedInflightException(); \
1811             } \
1812             INTERNAL_CATCH_REACT( catchAssertionHandler ) \
1813             } while( false )
1814              
1815             ///////////////////////////////////////////////////////////////////////////////
1816             #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
1817             do { \
1818             Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
1819             if( catchAssertionHandler.allowThrows() ) \
1820             try { \
1821             static_cast(__VA_ARGS__); \
1822             catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
1823             } \
1824             catch( ... ) { \
1825             catchAssertionHandler.handleExceptionThrownAsExpected(); \
1826             } \
1827             else \
1828             catchAssertionHandler.handleThrowingCallSkipped(); \
1829             INTERNAL_CATCH_REACT( catchAssertionHandler ) \
1830             } while( false )
1831              
1832             ///////////////////////////////////////////////////////////////////////////////
1833             #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
1834             do { \
1835             Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
1836             if( catchAssertionHandler.allowThrows() ) \
1837             try { \
1838             static_cast(expr); \
1839             catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
1840             } \
1841             catch( exceptionType const& ) { \
1842             catchAssertionHandler.handleExceptionThrownAsExpected(); \
1843             } \
1844             catch( ... ) { \
1845             catchAssertionHandler.handleUnexpectedInflightException(); \
1846             } \
1847             else \
1848             catchAssertionHandler.handleThrowingCallSkipped(); \
1849             INTERNAL_CATCH_REACT( catchAssertionHandler ) \
1850             } while( false )
1851              
1852             ///////////////////////////////////////////////////////////////////////////////
1853             #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
1854             do { \
1855             Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
1856             catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
1857             INTERNAL_CATCH_REACT( catchAssertionHandler ) \
1858             } while( false )
1859              
1860             ///////////////////////////////////////////////////////////////////////////////
1861             #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
1862             auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
1863             varName.captureValues( 0, __VA_ARGS__ )
1864              
1865             ///////////////////////////////////////////////////////////////////////////////
1866             #define INTERNAL_CATCH_INFO( macroName, log ) \
1867             Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
1868              
1869             ///////////////////////////////////////////////////////////////////////////////
1870             // Although this is matcher-based, it can be used with just a string
1871             #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
1872             do { \
1873             Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
1874             if( catchAssertionHandler.allowThrows() ) \
1875             try { \
1876             static_cast(__VA_ARGS__); \
1877             catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
1878             } \
1879             catch( ... ) { \
1880             Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
1881             } \
1882             else \
1883             catchAssertionHandler.handleThrowingCallSkipped(); \
1884             INTERNAL_CATCH_REACT( catchAssertionHandler ) \
1885             } while( false )
1886              
1887             #endif // CATCH_CONFIG_DISABLE
1888              
1889             // end catch_capture.hpp
1890             // start catch_section.h
1891              
1892             // start catch_section_info.h
1893              
1894             // start catch_totals.h
1895              
1896             #include
1897              
1898             namespace Catch {
1899              
1900             struct Counts {
1901             Counts operator - ( Counts const& other ) const;
1902             Counts& operator += ( Counts const& other );
1903              
1904             std::size_t total() const;
1905             bool allPassed() const;
1906             bool allOk() const;
1907              
1908             std::size_t passed = 0;
1909             std::size_t failed = 0;
1910             std::size_t failedButOk = 0;
1911             };
1912              
1913             struct Totals {
1914              
1915             Totals operator - ( Totals const& other ) const;
1916             Totals& operator += ( Totals const& other );
1917              
1918             Totals delta( Totals const& prevTotals ) const;
1919              
1920             int error = 0;
1921             Counts assertions;
1922             Counts testCases;
1923             };
1924             }
1925              
1926             // end catch_totals.h
1927             #include
1928              
1929             namespace Catch {
1930              
1931 0           struct SectionInfo {
1932             SectionInfo
1933             ( SourceLineInfo const& _lineInfo,
1934             std::string const& _name );
1935              
1936             // Deprecated
1937             SectionInfo
1938             ( SourceLineInfo const& _lineInfo,
1939             std::string const& _name,
1940             std::string const& ) : SectionInfo( _lineInfo, _name ) {}
1941              
1942             std::string name;
1943             std::string description; // !Deprecated: this will always be empty
1944             SourceLineInfo lineInfo;
1945             };
1946              
1947             struct SectionEndInfo {
1948             SectionInfo sectionInfo;
1949             Counts prevAssertions;
1950             double durationInSeconds;
1951             };
1952              
1953             } // end namespace Catch
1954              
1955             // end catch_section_info.h
1956             // start catch_timer.h
1957              
1958             #include
1959              
1960             namespace Catch {
1961              
1962             auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
1963             auto getEstimatedClockResolution() -> uint64_t;
1964              
1965             class Timer {
1966             uint64_t m_nanoseconds = 0;
1967             public:
1968             void start();
1969             auto getElapsedNanoseconds() const -> uint64_t;
1970             auto getElapsedMicroseconds() const -> uint64_t;
1971             auto getElapsedMilliseconds() const -> unsigned int;
1972             auto getElapsedSeconds() const -> double;
1973             };
1974              
1975             } // namespace Catch
1976              
1977             // end catch_timer.h
1978             #include
1979              
1980             namespace Catch {
1981              
1982             class Section : NonCopyable {
1983             public:
1984             Section( SectionInfo const& info );
1985             ~Section();
1986              
1987             // This indicates whether the section should be executed or not
1988             explicit operator bool() const;
1989              
1990             private:
1991             SectionInfo m_info;
1992              
1993             std::string m_name;
1994             Counts m_assertions;
1995             bool m_sectionIncluded;
1996             Timer m_timer;
1997             };
1998              
1999             } // end namespace Catch
2000              
2001             #define INTERNAL_CATCH_SECTION( ... ) \
2002             CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2003             if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
2004             CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
2005              
2006             #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
2007             CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2008             if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
2009             CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
2010              
2011             // end catch_section.h
2012             // start catch_benchmark.h
2013              
2014             #include
2015             #include
2016              
2017             namespace Catch {
2018              
2019             class BenchmarkLooper {
2020              
2021             std::string m_name;
2022             std::size_t m_count = 0;
2023             std::size_t m_iterationsToRun = 1;
2024             uint64_t m_resolution;
2025             Timer m_timer;
2026              
2027             static auto getResolution() -> uint64_t;
2028             public:
2029             // Keep most of this inline as it's on the code path that is being timed
2030             BenchmarkLooper( StringRef name )
2031             : m_name( name ),
2032             m_resolution( getResolution() )
2033             {
2034             reportStart();
2035             m_timer.start();
2036             }
2037              
2038             explicit operator bool() {
2039             if( m_count < m_iterationsToRun )
2040             return true;
2041             return needsMoreIterations();
2042             }
2043              
2044             void increment() {
2045             ++m_count;
2046             }
2047              
2048             void reportStart();
2049             auto needsMoreIterations() -> bool;
2050             };
2051              
2052             } // end namespace Catch
2053              
2054             #define BENCHMARK( name ) \
2055             for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() )
2056              
2057             // end catch_benchmark.h
2058             // start catch_interfaces_exception.h
2059              
2060             // start catch_interfaces_registry_hub.h
2061              
2062             #include
2063             #include
2064              
2065             namespace Catch {
2066              
2067             class TestCase;
2068             struct ITestCaseRegistry;
2069             struct IExceptionTranslatorRegistry;
2070             struct IExceptionTranslator;
2071             struct IReporterRegistry;
2072             struct IReporterFactory;
2073             struct ITagAliasRegistry;
2074             class StartupExceptionRegistry;
2075              
2076             using IReporterFactoryPtr = std::shared_ptr;
2077              
2078             struct IRegistryHub {
2079             virtual ~IRegistryHub();
2080              
2081             virtual IReporterRegistry const& getReporterRegistry() const = 0;
2082             virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2083             virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
2084              
2085             virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
2086              
2087             virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
2088             };
2089              
2090             struct IMutableRegistryHub {
2091             virtual ~IMutableRegistryHub();
2092             virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
2093             virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
2094             virtual void registerTest( TestCase const& testInfo ) = 0;
2095             virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2096             virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
2097             virtual void registerStartupException() noexcept = 0;
2098             };
2099              
2100             IRegistryHub const& getRegistryHub();
2101             IMutableRegistryHub& getMutableRegistryHub();
2102             void cleanUp();
2103             std::string translateActiveException();
2104              
2105             }
2106              
2107             // end catch_interfaces_registry_hub.h
2108             #if defined(CATCH_CONFIG_DISABLE)
2109             #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
2110             static std::string translatorName( signature )
2111             #endif
2112              
2113             #include
2114             #include
2115             #include
2116              
2117             namespace Catch {
2118             using exceptionTranslateFunction = std::string(*)();
2119              
2120             struct IExceptionTranslator;
2121             using ExceptionTranslators = std::vector>;
2122              
2123             struct IExceptionTranslator {
2124             virtual ~IExceptionTranslator();
2125             virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
2126             };
2127              
2128             struct IExceptionTranslatorRegistry {
2129             virtual ~IExceptionTranslatorRegistry();
2130              
2131             virtual std::string translateActiveException() const = 0;
2132             };
2133              
2134             class ExceptionTranslatorRegistrar {
2135             template
2136             class ExceptionTranslator : public IExceptionTranslator {
2137             public:
2138              
2139             ExceptionTranslator( std::string(*translateFunction)( T& ) )
2140             : m_translateFunction( translateFunction )
2141             {}
2142              
2143             std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
2144             try {
2145             if( it == itEnd )
2146             std::rethrow_exception(std::current_exception());
2147             else
2148             return (*it)->translate( it+1, itEnd );
2149             }
2150             catch( T& ex ) {
2151             return m_translateFunction( ex );
2152             }
2153             }
2154              
2155             protected:
2156             std::string(*m_translateFunction)( T& );
2157             };
2158              
2159             public:
2160             template
2161             ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
2162             getMutableRegistryHub().registerTranslator
2163             ( new ExceptionTranslator( translateFunction ) );
2164             }
2165             };
2166             }
2167              
2168             ///////////////////////////////////////////////////////////////////////////////
2169             #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
2170             static std::string translatorName( signature ); \
2171             CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
2172             namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
2173             CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
2174             static std::string translatorName( signature )
2175              
2176             #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
2177              
2178             // end catch_interfaces_exception.h
2179             // start catch_approx.h
2180              
2181             #include
2182              
2183             namespace Catch {
2184             namespace Detail {
2185              
2186             class Approx {
2187             private:
2188             bool equalityComparisonImpl(double other) const;
2189             // Validates the new margin (margin >= 0)
2190             // out-of-line to avoid including stdexcept in the header
2191             void setMargin(double margin);
2192             // Validates the new epsilon (0 < epsilon < 1)
2193             // out-of-line to avoid including stdexcept in the header
2194             void setEpsilon(double epsilon);
2195              
2196             public:
2197             explicit Approx ( double value );
2198              
2199             static Approx custom();
2200              
2201             Approx operator-() const;
2202              
2203             template ::value>::type>
2204             Approx operator()( T const& value ) {
2205             Approx approx( static_cast(value) );
2206             approx.m_epsilon = m_epsilon;
2207             approx.m_margin = m_margin;
2208             approx.m_scale = m_scale;
2209             return approx;
2210             }
2211              
2212             template ::value>::type>
2213             explicit Approx( T const& value ): Approx(static_cast(value))
2214             {}
2215              
2216             template ::value>::type>
2217             friend bool operator == ( const T& lhs, Approx const& rhs ) {
2218             auto lhs_v = static_cast(lhs);
2219             return rhs.equalityComparisonImpl(lhs_v);
2220             }
2221              
2222             template ::value>::type>
2223             friend bool operator == ( Approx const& lhs, const T& rhs ) {
2224             return operator==( rhs, lhs );
2225             }
2226              
2227             template ::value>::type>
2228             friend bool operator != ( T const& lhs, Approx const& rhs ) {
2229             return !operator==( lhs, rhs );
2230             }
2231              
2232             template ::value>::type>
2233             friend bool operator != ( Approx const& lhs, T const& rhs ) {
2234             return !operator==( rhs, lhs );
2235             }
2236              
2237             template ::value>::type>
2238             friend bool operator <= ( T const& lhs, Approx const& rhs ) {
2239             return static_cast(lhs) < rhs.m_value || lhs == rhs;
2240             }
2241              
2242             template ::value>::type>
2243             friend bool operator <= ( Approx const& lhs, T const& rhs ) {
2244             return lhs.m_value < static_cast(rhs) || lhs == rhs;
2245             }
2246              
2247             template ::value>::type>
2248             friend bool operator >= ( T const& lhs, Approx const& rhs ) {
2249             return static_cast(lhs) > rhs.m_value || lhs == rhs;
2250             }
2251              
2252             template ::value>::type>
2253             friend bool operator >= ( Approx const& lhs, T const& rhs ) {
2254             return lhs.m_value > static_cast(rhs) || lhs == rhs;
2255             }
2256              
2257             template ::value>::type>
2258             Approx& epsilon( T const& newEpsilon ) {
2259             double epsilonAsDouble = static_cast(newEpsilon);
2260             setEpsilon(epsilonAsDouble);
2261             return *this;
2262             }
2263              
2264             template ::value>::type>
2265             Approx& margin( T const& newMargin ) {
2266             double marginAsDouble = static_cast(newMargin);
2267             setMargin(marginAsDouble);
2268             return *this;
2269             }
2270              
2271             template ::value>::type>
2272             Approx& scale( T const& newScale ) {
2273             m_scale = static_cast(newScale);
2274             return *this;
2275             }
2276              
2277             std::string toString() const;
2278              
2279             private:
2280             double m_epsilon;
2281             double m_margin;
2282             double m_scale;
2283             double m_value;
2284             };
2285             } // end namespace Detail
2286              
2287             namespace literals {
2288             Detail::Approx operator "" _a(long double val);
2289             Detail::Approx operator "" _a(unsigned long long val);
2290             } // end namespace literals
2291              
2292             template<>
2293             struct StringMaker {
2294             static std::string convert(Catch::Detail::Approx const& value);
2295             };
2296              
2297             } // end namespace Catch
2298              
2299             // end catch_approx.h
2300             // start catch_string_manip.h
2301              
2302             #include
2303             #include
2304              
2305             namespace Catch {
2306              
2307             bool startsWith( std::string const& s, std::string const& prefix );
2308             bool startsWith( std::string const& s, char prefix );
2309             bool endsWith( std::string const& s, std::string const& suffix );
2310             bool endsWith( std::string const& s, char suffix );
2311             bool contains( std::string const& s, std::string const& infix );
2312             void toLowerInPlace( std::string& s );
2313             std::string toLower( std::string const& s );
2314             std::string trim( std::string const& str );
2315             bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
2316              
2317             struct pluralise {
2318             pluralise( std::size_t count, std::string const& label );
2319              
2320             friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
2321              
2322             std::size_t m_count;
2323             std::string m_label;
2324             };
2325             }
2326              
2327             // end catch_string_manip.h
2328             #ifndef CATCH_CONFIG_DISABLE_MATCHERS
2329             // start catch_capture_matchers.h
2330              
2331             // start catch_matchers.h
2332              
2333             #include
2334             #include
2335              
2336             namespace Catch {
2337             namespace Matchers {
2338             namespace Impl {
2339              
2340             template struct MatchAllOf;
2341             template struct MatchAnyOf;
2342             template struct MatchNotOf;
2343              
2344             class MatcherUntypedBase {
2345             public:
2346             MatcherUntypedBase() = default;
2347             MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
2348             MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
2349             std::string toString() const;
2350              
2351             protected:
2352             virtual ~MatcherUntypedBase();
2353             virtual std::string describe() const = 0;
2354             mutable std::string m_cachedToString;
2355             };
2356              
2357             #ifdef __clang__
2358             # pragma clang diagnostic push
2359             # pragma clang diagnostic ignored "-Wnon-virtual-dtor"
2360             #endif
2361              
2362             template
2363             struct MatcherMethod {
2364             virtual bool match( ObjectT const& arg ) const = 0;
2365             };
2366             template
2367             struct MatcherMethod {
2368             virtual bool match( PtrT* arg ) const = 0;
2369             };
2370              
2371             #ifdef __clang__
2372             # pragma clang diagnostic pop
2373             #endif
2374              
2375             template
2376             struct MatcherBase : MatcherUntypedBase, MatcherMethod {
2377              
2378             MatchAllOf operator && ( MatcherBase const& other ) const;
2379             MatchAnyOf operator || ( MatcherBase const& other ) const;
2380             MatchNotOf operator ! () const;
2381             };
2382              
2383             template
2384             struct MatchAllOf : MatcherBase {
2385             bool match( ArgT const& arg ) const override {
2386             for( auto matcher : m_matchers ) {
2387             if (!matcher->match(arg))
2388             return false;
2389             }
2390             return true;
2391             }
2392             std::string describe() const override {
2393             std::string description;
2394             description.reserve( 4 + m_matchers.size()*32 );
2395             description += "( ";
2396             bool first = true;
2397             for( auto matcher : m_matchers ) {
2398             if( first )
2399             first = false;
2400             else
2401             description += " and ";
2402             description += matcher->toString();
2403             }
2404             description += " )";
2405             return description;
2406             }
2407              
2408             MatchAllOf& operator && ( MatcherBase const& other ) {
2409             m_matchers.push_back( &other );
2410             return *this;
2411             }
2412              
2413             std::vector const*> m_matchers;
2414             };
2415             template
2416             struct MatchAnyOf : MatcherBase {
2417              
2418             bool match( ArgT const& arg ) const override {
2419             for( auto matcher : m_matchers ) {
2420             if (matcher->match(arg))
2421             return true;
2422             }
2423             return false;
2424             }
2425             std::string describe() const override {
2426             std::string description;
2427             description.reserve( 4 + m_matchers.size()*32 );
2428             description += "( ";
2429             bool first = true;
2430             for( auto matcher : m_matchers ) {
2431             if( first )
2432             first = false;
2433             else
2434             description += " or ";
2435             description += matcher->toString();
2436             }
2437             description += " )";
2438             return description;
2439             }
2440              
2441             MatchAnyOf& operator || ( MatcherBase const& other ) {
2442             m_matchers.push_back( &other );
2443             return *this;
2444             }
2445              
2446             std::vector const*> m_matchers;
2447             };
2448              
2449             template
2450             struct MatchNotOf : MatcherBase {
2451              
2452             MatchNotOf( MatcherBase const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
2453              
2454             bool match( ArgT const& arg ) const override {
2455             return !m_underlyingMatcher.match( arg );
2456             }
2457              
2458             std::string describe() const override {
2459             return "not " + m_underlyingMatcher.toString();
2460             }
2461             MatcherBase const& m_underlyingMatcher;
2462             };
2463              
2464             template
2465             MatchAllOf MatcherBase::operator && ( MatcherBase const& other ) const {
2466             return MatchAllOf() && *this && other;
2467             }
2468             template
2469             MatchAnyOf MatcherBase::operator || ( MatcherBase const& other ) const {
2470             return MatchAnyOf() || *this || other;
2471             }
2472             template
2473             MatchNotOf MatcherBase::operator ! () const {
2474             return MatchNotOf( *this );
2475             }
2476              
2477             } // namespace Impl
2478              
2479             } // namespace Matchers
2480              
2481             using namespace Matchers;
2482             using Matchers::Impl::MatcherBase;
2483              
2484             } // namespace Catch
2485              
2486             // end catch_matchers.h
2487             // start catch_matchers_floating.h
2488              
2489             #include
2490             #include
2491              
2492             namespace Catch {
2493             namespace Matchers {
2494              
2495             namespace Floating {
2496              
2497             enum class FloatingPointKind : uint8_t;
2498              
2499             struct WithinAbsMatcher : MatcherBase {
2500             WithinAbsMatcher(double target, double margin);
2501             bool match(double const& matchee) const override;
2502             std::string describe() const override;
2503             private:
2504             double m_target;
2505             double m_margin;
2506             };
2507              
2508             struct WithinUlpsMatcher : MatcherBase {
2509             WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
2510             bool match(double const& matchee) const override;
2511             std::string describe() const override;
2512             private:
2513             double m_target;
2514             int m_ulps;
2515             FloatingPointKind m_type;
2516             };
2517              
2518             } // namespace Floating
2519              
2520             // The following functions create the actual matcher objects.
2521             // This allows the types to be inferred
2522             Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
2523             Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
2524             Floating::WithinAbsMatcher WithinAbs(double target, double margin);
2525              
2526             } // namespace Matchers
2527             } // namespace Catch
2528              
2529             // end catch_matchers_floating.h
2530             // start catch_matchers_generic.hpp
2531              
2532             #include
2533             #include
2534              
2535             namespace Catch {
2536             namespace Matchers {
2537             namespace Generic {
2538              
2539             namespace Detail {
2540             std::string finalizeDescription(const std::string& desc);
2541             }
2542              
2543             template
2544             class PredicateMatcher : public MatcherBase {
2545             std::function m_predicate;
2546             std::string m_description;
2547             public:
2548              
2549             PredicateMatcher(std::function const& elem, std::string const& descr)
2550             :m_predicate(std::move(elem)),
2551             m_description(Detail::finalizeDescription(descr))
2552             {}
2553              
2554             bool match( T const& item ) const override {
2555             return m_predicate(item);
2556             }
2557              
2558             std::string describe() const override {
2559             return m_description;
2560             }
2561             };
2562              
2563             } // namespace Generic
2564              
2565             // The following functions create the actual matcher objects.
2566             // The user has to explicitly specify type to the function, because
2567             // infering std::function is hard (but possible) and
2568             // requires a lot of TMP.
2569             template
2570             Generic::PredicateMatcher Predicate(std::function const& predicate, std::string const& description = "") {
2571             return Generic::PredicateMatcher(predicate, description);
2572             }
2573              
2574             } // namespace Matchers
2575             } // namespace Catch
2576              
2577             // end catch_matchers_generic.hpp
2578             // start catch_matchers_string.h
2579              
2580             #include
2581              
2582             namespace Catch {
2583             namespace Matchers {
2584              
2585             namespace StdString {
2586              
2587             struct CasedString
2588             {
2589             CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
2590             std::string adjustString( std::string const& str ) const;
2591             std::string caseSensitivitySuffix() const;
2592              
2593             CaseSensitive::Choice m_caseSensitivity;
2594             std::string m_str;
2595             };
2596              
2597             struct StringMatcherBase : MatcherBase {
2598             StringMatcherBase( std::string const& operation, CasedString const& comparator );
2599             std::string describe() const override;
2600              
2601             CasedString m_comparator;
2602             std::string m_operation;
2603             };
2604              
2605             struct EqualsMatcher : StringMatcherBase {
2606             EqualsMatcher( CasedString const& comparator );
2607             bool match( std::string const& source ) const override;
2608             };
2609             struct ContainsMatcher : StringMatcherBase {
2610             ContainsMatcher( CasedString const& comparator );
2611             bool match( std::string const& source ) const override;
2612             };
2613             struct StartsWithMatcher : StringMatcherBase {
2614             StartsWithMatcher( CasedString const& comparator );
2615             bool match( std::string const& source ) const override;
2616             };
2617             struct EndsWithMatcher : StringMatcherBase {
2618             EndsWithMatcher( CasedString const& comparator );
2619             bool match( std::string const& source ) const override;
2620             };
2621              
2622             struct RegexMatcher : MatcherBase {
2623             RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
2624             bool match( std::string const& matchee ) const override;
2625             std::string describe() const override;
2626              
2627             private:
2628             std::string m_regex;
2629             CaseSensitive::Choice m_caseSensitivity;
2630             };
2631              
2632             } // namespace StdString
2633              
2634             // The following functions create the actual matcher objects.
2635             // This allows the types to be inferred
2636              
2637             StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2638             StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2639             StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2640             StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2641             StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2642              
2643             } // namespace Matchers
2644             } // namespace Catch
2645              
2646             // end catch_matchers_string.h
2647             // start catch_matchers_vector.h
2648              
2649             #include
2650              
2651             namespace Catch {
2652             namespace Matchers {
2653              
2654             namespace Vector {
2655             namespace Detail {
2656             template
2657             size_t count(InputIterator first, InputIterator last, T const& item) {
2658             size_t cnt = 0;
2659             for (; first != last; ++first) {
2660             if (*first == item) {
2661             ++cnt;
2662             }
2663             }
2664             return cnt;
2665             }
2666             template
2667             bool contains(InputIterator first, InputIterator last, T const& item) {
2668             for (; first != last; ++first) {
2669             if (*first == item) {
2670             return true;
2671             }
2672             }
2673             return false;
2674             }
2675             }
2676              
2677             template
2678             struct ContainsElementMatcher : MatcherBase> {
2679              
2680             ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
2681              
2682             bool match(std::vector const &v) const override {
2683             for (auto const& el : v) {
2684             if (el == m_comparator) {
2685             return true;
2686             }
2687             }
2688             return false;
2689             }
2690              
2691             std::string describe() const override {
2692             return "Contains: " + ::Catch::Detail::stringify( m_comparator );
2693             }
2694              
2695             T const& m_comparator;
2696             };
2697              
2698             template
2699             struct ContainsMatcher : MatcherBase> {
2700              
2701             ContainsMatcher(std::vector const &comparator) : m_comparator( comparator ) {}
2702              
2703             bool match(std::vector const &v) const override {
2704             // !TBD: see note in EqualsMatcher
2705             if (m_comparator.size() > v.size())
2706             return false;
2707             for (auto const& comparator : m_comparator) {
2708             auto present = false;
2709             for (const auto& el : v) {
2710             if (el == comparator) {
2711             present = true;
2712             break;
2713             }
2714             }
2715             if (!present) {
2716             return false;
2717             }
2718             }
2719             return true;
2720             }
2721             std::string describe() const override {
2722             return "Contains: " + ::Catch::Detail::stringify( m_comparator );
2723             }
2724              
2725             std::vector const& m_comparator;
2726             };
2727              
2728             template
2729             struct EqualsMatcher : MatcherBase> {
2730              
2731             EqualsMatcher(std::vector const &comparator) : m_comparator( comparator ) {}
2732              
2733             bool match(std::vector const &v) const override {
2734             // !TBD: This currently works if all elements can be compared using !=
2735             // - a more general approach would be via a compare template that defaults
2736             // to using !=. but could be specialised for, e.g. std::vector etc
2737             // - then just call that directly
2738             if (m_comparator.size() != v.size())
2739             return false;
2740             for (std::size_t i = 0; i < v.size(); ++i)
2741             if (m_comparator[i] != v[i])
2742             return false;
2743             return true;
2744             }
2745             std::string describe() const override {
2746             return "Equals: " + ::Catch::Detail::stringify( m_comparator );
2747             }
2748             std::vector const& m_comparator;
2749             };
2750              
2751             template
2752             struct UnorderedEqualsMatcher : MatcherBase> {
2753             UnorderedEqualsMatcher(std::vector const& target) : m_target(target) {}
2754             bool match(std::vector const& vec) const override {
2755             // Note: This is a reimplementation of std::is_permutation,
2756             // because I don't want to include inside the common path
2757             if (m_target.size() != vec.size()) {
2758             return false;
2759             }
2760             auto lfirst = m_target.begin(), llast = m_target.end();
2761             auto rfirst = vec.begin(), rlast = vec.end();
2762             // Cut common prefix to optimize checking of permuted parts
2763             while (lfirst != llast && *lfirst != *rfirst) {
2764             ++lfirst; ++rfirst;
2765             }
2766             if (lfirst == llast) {
2767             return true;
2768             }
2769              
2770             for (auto mid = lfirst; mid != llast; ++mid) {
2771             // Skip already counted items
2772             if (Detail::contains(lfirst, mid, *mid)) {
2773             continue;
2774             }
2775             size_t num_vec = Detail::count(rfirst, rlast, *mid);
2776             if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) {
2777             return false;
2778             }
2779             }
2780              
2781             return true;
2782             }
2783              
2784             std::string describe() const override {
2785             return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
2786             }
2787             private:
2788             std::vector const& m_target;
2789             };
2790              
2791             } // namespace Vector
2792              
2793             // The following functions create the actual matcher objects.
2794             // This allows the types to be inferred
2795              
2796             template
2797             Vector::ContainsMatcher Contains( std::vector const& comparator ) {
2798             return Vector::ContainsMatcher( comparator );
2799             }
2800              
2801             template
2802             Vector::ContainsElementMatcher VectorContains( T const& comparator ) {
2803             return Vector::ContainsElementMatcher( comparator );
2804             }
2805              
2806             template
2807             Vector::EqualsMatcher Equals( std::vector const& comparator ) {
2808             return Vector::EqualsMatcher( comparator );
2809             }
2810              
2811             template
2812             Vector::UnorderedEqualsMatcher UnorderedEquals(std::vector const& target) {
2813             return Vector::UnorderedEqualsMatcher(target);
2814             }
2815              
2816             } // namespace Matchers
2817             } // namespace Catch
2818              
2819             // end catch_matchers_vector.h
2820             namespace Catch {
2821              
2822             template
2823             class MatchExpr : public ITransientExpression {
2824             ArgT const& m_arg;
2825             MatcherT m_matcher;
2826             StringRef m_matcherString;
2827             public:
2828             MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
2829             : ITransientExpression{ true, matcher.match( arg ) },
2830             m_arg( arg ),
2831             m_matcher( matcher ),
2832             m_matcherString( matcherString )
2833             {}
2834              
2835             void streamReconstructedExpression( std::ostream &os ) const override {
2836             auto matcherAsString = m_matcher.toString();
2837             os << Catch::Detail::stringify( m_arg ) << ' ';
2838             if( matcherAsString == Detail::unprintableString )
2839             os << m_matcherString;
2840             else
2841             os << matcherAsString;
2842             }
2843             };
2844              
2845             using StringMatcher = Matchers::Impl::MatcherBase;
2846              
2847             void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
2848              
2849             template
2850             auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr {
2851             return MatchExpr( arg, matcher, matcherString );
2852             }
2853              
2854             } // namespace Catch
2855              
2856             ///////////////////////////////////////////////////////////////////////////////
2857             #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
2858             do { \
2859             Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2860             INTERNAL_CATCH_TRY { \
2861             catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
2862             } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
2863             INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2864             } while( false )
2865              
2866             ///////////////////////////////////////////////////////////////////////////////
2867             #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
2868             do { \
2869             Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2870             if( catchAssertionHandler.allowThrows() ) \
2871             try { \
2872             static_cast(__VA_ARGS__ ); \
2873             catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2874             } \
2875             catch( exceptionType const& ex ) { \
2876             catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
2877             } \
2878             catch( ... ) { \
2879             catchAssertionHandler.handleUnexpectedInflightException(); \
2880             } \
2881             else \
2882             catchAssertionHandler.handleThrowingCallSkipped(); \
2883             INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2884             } while( false )
2885              
2886             // end catch_capture_matchers.h
2887             #endif
2888             // start catch_generators.hpp
2889              
2890             // start catch_interfaces_generatortracker.h
2891              
2892              
2893             #include
2894              
2895             namespace Catch {
2896              
2897             namespace Generators {
2898             class GeneratorBase {
2899             protected:
2900             size_t m_size = 0;
2901              
2902             public:
2903             GeneratorBase( size_t size ) : m_size( size ) {}
2904             virtual ~GeneratorBase();
2905             auto size() const -> size_t { return m_size; }
2906             };
2907             using GeneratorBasePtr = std::unique_ptr;
2908              
2909             } // namespace Generators
2910              
2911             struct IGeneratorTracker {
2912             virtual ~IGeneratorTracker();
2913             virtual auto hasGenerator() const -> bool = 0;
2914             virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
2915             virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
2916             virtual auto getIndex() const -> std::size_t = 0;
2917             };
2918              
2919             } // namespace Catch
2920              
2921             // end catch_interfaces_generatortracker.h
2922             // start catch_enforce.h
2923              
2924             #include
2925              
2926             namespace Catch {
2927             #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
2928             template
2929             [[noreturn]]
2930             void throw_exception(Ex const& e) {
2931             throw e;
2932             }
2933             #else // ^^ Exceptions are enabled // Exceptions are disabled vv
2934             [[noreturn]]
2935             void throw_exception(std::exception const& e);
2936             #endif
2937             } // namespace Catch;
2938              
2939             #define CATCH_PREPARE_EXCEPTION( type, msg ) \
2940             type( ( Catch::ReusableStringStream() << msg ).str() )
2941             #define CATCH_INTERNAL_ERROR( msg ) \
2942             Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg))
2943             #define CATCH_ERROR( msg ) \
2944             Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::domain_error, msg ))
2945             #define CATCH_RUNTIME_ERROR( msg ) \
2946             Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::runtime_error, msg ))
2947             #define CATCH_ENFORCE( condition, msg ) \
2948             do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
2949              
2950             // end catch_enforce.h
2951             #include
2952             #include
2953             #include
2954              
2955             #include
2956              
2957             namespace Catch {
2958             namespace Generators {
2959              
2960             // !TBD move this into its own location?
2961             namespace pf{
2962             template
2963             std::unique_ptr make_unique( Args&&... args ) {
2964             return std::unique_ptr(new T(std::forward(args)...));
2965             }
2966             }
2967              
2968             template
2969             struct IGenerator {
2970             virtual ~IGenerator() {}
2971             virtual auto get( size_t index ) const -> T = 0;
2972             };
2973              
2974             template
2975             class SingleValueGenerator : public IGenerator {
2976             T m_value;
2977             public:
2978             SingleValueGenerator( T const& value ) : m_value( value ) {}
2979              
2980             auto get( size_t ) const -> T override {
2981             return m_value;
2982             }
2983             };
2984              
2985             template
2986             class FixedValuesGenerator : public IGenerator {
2987             std::vector m_values;
2988              
2989             public:
2990             FixedValuesGenerator( std::initializer_list values ) : m_values( values ) {}
2991              
2992             auto get( size_t index ) const -> T override {
2993             return m_values[index];
2994             }
2995             };
2996              
2997             template
2998             class RangeGenerator : public IGenerator {
2999             T const m_first;
3000             T const m_last;
3001              
3002             public:
3003             RangeGenerator( T const& first, T const& last ) : m_first( first ), m_last( last ) {
3004             assert( m_last > m_first );
3005             }
3006              
3007             auto get( size_t index ) const -> T override {
3008             // ToDo:: introduce a safe cast to catch potential overflows
3009             return static_cast(m_first+index);
3010             }
3011             };
3012              
3013             template
3014             struct NullGenerator : IGenerator {
3015             auto get( size_t ) const -> T override {
3016             CATCH_INTERNAL_ERROR("A Null Generator is always empty");
3017             }
3018             };
3019              
3020             template
3021             class Generator {
3022             std::unique_ptr> m_generator;
3023             size_t m_size;
3024              
3025             public:
3026             Generator( size_t size, std::unique_ptr> generator )
3027             : m_generator( std::move( generator ) ),
3028             m_size( size )
3029             {}
3030              
3031             auto size() const -> size_t { return m_size; }
3032             auto operator[]( size_t index ) const -> T {
3033             assert( index < m_size );
3034             return m_generator->get( index );
3035             }
3036             };
3037              
3038             std::vector randomiseIndices( size_t selectionSize, size_t sourceSize );
3039              
3040             template
3041             class GeneratorRandomiser : public IGenerator {
3042             Generator m_baseGenerator;
3043              
3044             std::vector m_indices;
3045             public:
3046             GeneratorRandomiser( Generator&& baseGenerator, size_t numberOfItems )
3047             : m_baseGenerator( std::move( baseGenerator ) ),
3048             m_indices( randomiseIndices( numberOfItems, m_baseGenerator.size() ) )
3049             {}
3050              
3051             auto get( size_t index ) const -> T override {
3052             return m_baseGenerator[m_indices[index]];
3053             }
3054             };
3055              
3056             template
3057             struct RequiresASpecialisationFor;
3058              
3059             template
3060             auto all() -> Generator { return RequiresASpecialisationFor(); }
3061              
3062             template<>
3063             auto all() -> Generator;
3064              
3065             template
3066             auto range( T const& first, T const& last ) -> Generator {
3067             return Generator( (last-first), pf::make_unique>( first, last ) );
3068             }
3069              
3070             template
3071             auto random( T const& first, T const& last ) -> Generator {
3072             auto gen = range( first, last );
3073             auto size = gen.size();
3074              
3075             return Generator( size, pf::make_unique>( std::move( gen ), size ) );
3076             }
3077             template
3078             auto random( size_t size ) -> Generator {
3079             return Generator( size, pf::make_unique>( all(), size ) );
3080             }
3081              
3082             template
3083             auto values( std::initializer_list values ) -> Generator {
3084             return Generator( values.size(), pf::make_unique>( values ) );
3085             }
3086             template
3087             auto value( T const& val ) -> Generator {
3088             return Generator( 1, pf::make_unique>( val ) );
3089             }
3090              
3091             template
3092             auto as() -> Generator {
3093             return Generator( 0, pf::make_unique>() );
3094             }
3095              
3096             template
3097             auto table( std::initializer_list>&& tuples ) -> Generator> {
3098             return values>( std::forward>>( tuples ) );
3099             }
3100              
3101             template
3102             struct Generators : GeneratorBase {
3103             std::vector> m_generators;
3104              
3105             using type = T;
3106              
3107             Generators() : GeneratorBase( 0 ) {}
3108              
3109             void populate( T&& val ) {
3110             m_size += 1;
3111             m_generators.emplace_back( value( std::move( val ) ) );
3112             }
3113             template
3114             void populate( U&& val ) {
3115             populate( T( std::move( val ) ) );
3116             }
3117             void populate( Generator&& generator ) {
3118             m_size += generator.size();
3119             m_generators.emplace_back( std::move( generator ) );
3120             }
3121              
3122             template
3123             void populate( U&& valueOrGenerator, Gs... moreGenerators ) {
3124             populate( std::forward( valueOrGenerator ) );
3125             populate( std::forward( moreGenerators )... );
3126             }
3127              
3128             auto operator[]( size_t index ) const -> T {
3129             size_t sizes = 0;
3130             for( auto const& gen : m_generators ) {
3131             auto localIndex = index-sizes;
3132             sizes += gen.size();
3133             if( index < sizes )
3134             return gen[localIndex];
3135             }
3136             CATCH_INTERNAL_ERROR("Index '" << index << "' is out of range (" << sizes << ')');
3137             }
3138             };
3139              
3140             template
3141             auto makeGenerators( Generator&& generator, Gs... moreGenerators ) -> Generators {
3142             Generators generators;
3143             generators.m_generators.reserve( 1+sizeof...(Gs) );
3144             generators.populate( std::move( generator ), std::forward( moreGenerators )... );
3145             return generators;
3146             }
3147             template
3148             auto makeGenerators( Generator&& generator ) -> Generators {
3149             Generators generators;
3150             generators.populate( std::move( generator ) );
3151             return generators;
3152             }
3153             template
3154             auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators {
3155             return makeGenerators( value( std::forward( val ) ), std::forward( moreGenerators )... );
3156             }
3157             template
3158             auto makeGenerators( U&& val, Gs... moreGenerators ) -> Generators {
3159             return makeGenerators( value( T( std::forward( val ) ) ), std::forward( moreGenerators )... );
3160             }
3161              
3162             auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
3163              
3164             template
3165             // Note: The type after -> is weird, because VS2015 cannot parse
3166             // the expression used in the typedef inside, when it is in
3167             // return type. Yeah, ¯\_(ツ)_/¯
3168             auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval()[0]) {
3169             using UnderlyingType = typename decltype(generatorExpression())::type;
3170              
3171             IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
3172             if( !tracker.hasGenerator() )
3173             tracker.setGenerator( pf::make_unique>( generatorExpression() ) );
3174              
3175             auto const& generator = static_cast const&>( *tracker.getGenerator() );
3176             return generator[tracker.getIndex()];
3177             }
3178              
3179             } // namespace Generators
3180             } // namespace Catch
3181              
3182             #define GENERATE( ... ) \
3183             Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
3184              
3185             // end catch_generators.hpp
3186              
3187             // These files are included here so the single_include script doesn't put them
3188             // in the conditionally compiled sections
3189             // start catch_test_case_info.h
3190              
3191             #include
3192             #include
3193             #include
3194              
3195             #ifdef __clang__
3196             #pragma clang diagnostic push
3197             #pragma clang diagnostic ignored "-Wpadded"
3198             #endif
3199              
3200             namespace Catch {
3201              
3202             struct ITestInvoker;
3203              
3204             struct TestCaseInfo {
3205             enum SpecialProperties{
3206             None = 0,
3207             IsHidden = 1 << 1,
3208             ShouldFail = 1 << 2,
3209             MayFail = 1 << 3,
3210             Throws = 1 << 4,
3211             NonPortable = 1 << 5,
3212             Benchmark = 1 << 6
3213             };
3214              
3215             TestCaseInfo( std::string const& _name,
3216             std::string const& _className,
3217             std::string const& _description,
3218             std::vector const& _tags,
3219             SourceLineInfo const& _lineInfo );
3220              
3221             friend void setTags( TestCaseInfo& testCaseInfo, std::vector tags );
3222              
3223             bool isHidden() const;
3224             bool throws() const;
3225             bool okToFail() const;
3226             bool expectedToFail() const;
3227              
3228             std::string tagsAsString() const;
3229              
3230             std::string name;
3231             std::string className;
3232             std::string description;
3233             std::vector tags;
3234             std::vector lcaseTags;
3235             SourceLineInfo lineInfo;
3236             SpecialProperties properties;
3237             };
3238              
3239             class TestCase : public TestCaseInfo {
3240             public:
3241              
3242             TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
3243              
3244             TestCase withName( std::string const& _newName ) const;
3245              
3246             void invoke() const;
3247              
3248             TestCaseInfo const& getTestCaseInfo() const;
3249              
3250             bool operator == ( TestCase const& other ) const;
3251             bool operator < ( TestCase const& other ) const;
3252              
3253             private:
3254             std::shared_ptr test;
3255             };
3256              
3257             TestCase makeTestCase( ITestInvoker* testCase,
3258             std::string const& className,
3259             NameAndTags const& nameAndTags,
3260             SourceLineInfo const& lineInfo );
3261             }
3262              
3263             #ifdef __clang__
3264             #pragma clang diagnostic pop
3265             #endif
3266              
3267             // end catch_test_case_info.h
3268             // start catch_interfaces_runner.h
3269              
3270             namespace Catch {
3271              
3272             struct IRunner {
3273             virtual ~IRunner();
3274             virtual bool aborting() const = 0;
3275             };
3276             }
3277              
3278             // end catch_interfaces_runner.h
3279              
3280             #ifdef __OBJC__
3281             // start catch_objc.hpp
3282              
3283             #import
3284              
3285             #include
3286              
3287             // NB. Any general catch headers included here must be included
3288             // in catch.hpp first to make sure they are included by the single
3289             // header for non obj-usage
3290              
3291             ///////////////////////////////////////////////////////////////////////////////
3292             // This protocol is really only here for (self) documenting purposes, since
3293             // all its methods are optional.
3294             @protocol OcFixture
3295              
3296             @optional
3297              
3298             -(void) setUp;
3299             -(void) tearDown;
3300              
3301             @end
3302              
3303             namespace Catch {
3304              
3305             class OcMethod : public ITestInvoker {
3306              
3307             public:
3308             OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
3309              
3310             virtual void invoke() const {
3311             id obj = [[m_cls alloc] init];
3312              
3313             performOptionalSelector( obj, @selector(setUp) );
3314             performOptionalSelector( obj, m_sel );
3315             performOptionalSelector( obj, @selector(tearDown) );
3316              
3317             arcSafeRelease( obj );
3318             }
3319             private:
3320             virtual ~OcMethod() {}
3321              
3322             Class m_cls;
3323             SEL m_sel;
3324             };
3325              
3326             namespace Detail{
3327              
3328             inline std::string getAnnotation( Class cls,
3329             std::string const& annotationName,
3330             std::string const& testCaseName ) {
3331             NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
3332             SEL sel = NSSelectorFromString( selStr );
3333             arcSafeRelease( selStr );
3334             id value = performOptionalSelector( cls, sel );
3335             if( value )
3336             return [(NSString*)value UTF8String];
3337             return "";
3338             }
3339             }
3340              
3341             inline std::size_t registerTestMethods() {
3342             std::size_t noTestMethods = 0;
3343             int noClasses = objc_getClassList( nullptr, 0 );
3344              
3345             Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
3346             objc_getClassList( classes, noClasses );
3347              
3348             for( int c = 0; c < noClasses; c++ ) {
3349             Class cls = classes[c];
3350             {
3351             u_int count;
3352             Method* methods = class_copyMethodList( cls, &count );
3353             for( u_int m = 0; m < count ; m++ ) {
3354             SEL selector = method_getName(methods[m]);
3355             std::string methodName = sel_getName(selector);
3356             if( startsWith( methodName, "Catch_TestCase_" ) ) {
3357             std::string testCaseName = methodName.substr( 15 );
3358             std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
3359             std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
3360             const char* className = class_getName( cls );
3361              
3362             getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
3363             noTestMethods++;
3364             }
3365             }
3366             free(methods);
3367             }
3368             }
3369             return noTestMethods;
3370             }
3371              
3372             #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
3373              
3374             namespace Matchers {
3375             namespace Impl {
3376             namespace NSStringMatchers {
3377              
3378             struct StringHolder : MatcherBase{
3379             StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
3380             StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
3381             StringHolder() {
3382             arcSafeRelease( m_substr );
3383             }
3384              
3385             bool match( NSString* arg ) const override {
3386             return false;
3387             }
3388              
3389             NSString* CATCH_ARC_STRONG m_substr;
3390             };
3391              
3392             struct Equals : StringHolder {
3393             Equals( NSString* substr ) : StringHolder( substr ){}
3394              
3395             bool match( NSString* str ) const override {
3396             return (str != nil || m_substr == nil ) &&
3397             [str isEqualToString:m_substr];
3398             }
3399              
3400             std::string describe() const override {
3401             return "equals string: " + Catch::Detail::stringify( m_substr );
3402             }
3403             };
3404              
3405             struct Contains : StringHolder {
3406             Contains( NSString* substr ) : StringHolder( substr ){}
3407              
3408             bool match( NSString* str ) const {
3409             return (str != nil || m_substr == nil ) &&
3410             [str rangeOfString:m_substr].location != NSNotFound;
3411             }
3412              
3413             std::string describe() const override {
3414             return "contains string: " + Catch::Detail::stringify( m_substr );
3415             }
3416             };
3417              
3418             struct StartsWith : StringHolder {
3419             StartsWith( NSString* substr ) : StringHolder( substr ){}
3420              
3421             bool match( NSString* str ) const override {
3422             return (str != nil || m_substr == nil ) &&
3423             [str rangeOfString:m_substr].location == 0;
3424             }
3425              
3426             std::string describe() const override {
3427             return "starts with: " + Catch::Detail::stringify( m_substr );
3428             }
3429             };
3430             struct EndsWith : StringHolder {
3431             EndsWith( NSString* substr ) : StringHolder( substr ){}
3432              
3433             bool match( NSString* str ) const override {
3434             return (str != nil || m_substr == nil ) &&
3435             [str rangeOfString:m_substr].location == [str length] - [m_substr length];
3436             }
3437              
3438             std::string describe() const override {
3439             return "ends with: " + Catch::Detail::stringify( m_substr );
3440             }
3441             };
3442              
3443             } // namespace NSStringMatchers
3444             } // namespace Impl
3445              
3446             inline Impl::NSStringMatchers::Equals
3447             Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
3448              
3449             inline Impl::NSStringMatchers::Contains
3450             Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
3451              
3452             inline Impl::NSStringMatchers::StartsWith
3453             StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
3454              
3455             inline Impl::NSStringMatchers::EndsWith
3456             EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
3457              
3458             } // namespace Matchers
3459              
3460             using namespace Matchers;
3461              
3462             #endif // CATCH_CONFIG_DISABLE_MATCHERS
3463              
3464             } // namespace Catch
3465              
3466             ///////////////////////////////////////////////////////////////////////////////
3467             #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
3468             #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
3469             +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
3470             { \
3471             return @ name; \
3472             } \
3473             +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
3474             { \
3475             return @ desc; \
3476             } \
3477             -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
3478              
3479             #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
3480              
3481             // end catch_objc.hpp
3482             #endif
3483              
3484             #ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
3485             // start catch_external_interfaces.h
3486              
3487             // start catch_reporter_bases.hpp
3488              
3489             // start catch_interfaces_reporter.h
3490              
3491             // start catch_config.hpp
3492              
3493             // start catch_test_spec_parser.h
3494              
3495             #ifdef __clang__
3496             #pragma clang diagnostic push
3497             #pragma clang diagnostic ignored "-Wpadded"
3498             #endif
3499              
3500             // start catch_test_spec.h
3501              
3502             #ifdef __clang__
3503             #pragma clang diagnostic push
3504             #pragma clang diagnostic ignored "-Wpadded"
3505             #endif
3506              
3507             // start catch_wildcard_pattern.h
3508              
3509             namespace Catch
3510             {
3511             class WildcardPattern {
3512             enum WildcardPosition {
3513             NoWildcard = 0,
3514             WildcardAtStart = 1,
3515             WildcardAtEnd = 2,
3516             WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
3517             };
3518              
3519             public:
3520              
3521             WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
3522             virtual ~WildcardPattern() = default;
3523             virtual bool matches( std::string const& str ) const;
3524              
3525             private:
3526             std::string adjustCase( std::string const& str ) const;
3527             CaseSensitive::Choice m_caseSensitivity;
3528             WildcardPosition m_wildcard = NoWildcard;
3529             std::string m_pattern;
3530             };
3531             }
3532              
3533             // end catch_wildcard_pattern.h
3534             #include
3535             #include
3536             #include
3537              
3538             namespace Catch {
3539              
3540             class TestSpec {
3541             struct Pattern {
3542             virtual ~Pattern();
3543             virtual bool matches( TestCaseInfo const& testCase ) const = 0;
3544             };
3545             using PatternPtr = std::shared_ptr;
3546              
3547             class NamePattern : public Pattern {
3548             public:
3549             NamePattern( std::string const& name );
3550             virtual ~NamePattern();
3551             virtual bool matches( TestCaseInfo const& testCase ) const override;
3552             private:
3553             WildcardPattern m_wildcardPattern;
3554             };
3555              
3556             class TagPattern : public Pattern {
3557             public:
3558             TagPattern( std::string const& tag );
3559             virtual ~TagPattern();
3560             virtual bool matches( TestCaseInfo const& testCase ) const override;
3561             private:
3562             std::string m_tag;
3563             };
3564              
3565             class ExcludedPattern : public Pattern {
3566             public:
3567             ExcludedPattern( PatternPtr const& underlyingPattern );
3568             virtual ~ExcludedPattern();
3569             virtual bool matches( TestCaseInfo const& testCase ) const override;
3570             private:
3571             PatternPtr m_underlyingPattern;
3572             };
3573              
3574             struct Filter {
3575             std::vector m_patterns;
3576              
3577             bool matches( TestCaseInfo const& testCase ) const;
3578             };
3579              
3580             public:
3581             bool hasFilters() const;
3582             bool matches( TestCaseInfo const& testCase ) const;
3583              
3584             private:
3585             std::vector m_filters;
3586              
3587             friend class TestSpecParser;
3588             };
3589             }
3590              
3591             #ifdef __clang__
3592             #pragma clang diagnostic pop
3593             #endif
3594              
3595             // end catch_test_spec.h
3596             // start catch_interfaces_tag_alias_registry.h
3597              
3598             #include
3599              
3600             namespace Catch {
3601              
3602             struct TagAlias;
3603              
3604             struct ITagAliasRegistry {
3605             virtual ~ITagAliasRegistry();
3606             // Nullptr if not present
3607             virtual TagAlias const* find( std::string const& alias ) const = 0;
3608             virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
3609              
3610             static ITagAliasRegistry const& get();
3611             };
3612              
3613             } // end namespace Catch
3614              
3615             // end catch_interfaces_tag_alias_registry.h
3616             namespace Catch {
3617              
3618             class TestSpecParser {
3619             enum Mode{ None, Name, QuotedName, Tag, EscapedName };
3620             Mode m_mode = None;
3621             bool m_exclusion = false;
3622             std::size_t m_start = std::string::npos, m_pos = 0;
3623             std::string m_arg;
3624             std::vector m_escapeChars;
3625             TestSpec::Filter m_currentFilter;
3626             TestSpec m_testSpec;
3627             ITagAliasRegistry const* m_tagAliases = nullptr;
3628              
3629             public:
3630             TestSpecParser( ITagAliasRegistry const& tagAliases );
3631              
3632             TestSpecParser& parse( std::string const& arg );
3633             TestSpec testSpec();
3634              
3635             private:
3636             void visitChar( char c );
3637             void startNewMode( Mode mode, std::size_t start );
3638             void escape();
3639             std::string subString() const;
3640              
3641             template
3642             void addPattern() {
3643             std::string token = subString();
3644             for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
3645             token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
3646             m_escapeChars.clear();
3647             if( startsWith( token, "exclude:" ) ) {
3648             m_exclusion = true;
3649             token = token.substr( 8 );
3650             }
3651             if( !token.empty() ) {
3652             TestSpec::PatternPtr pattern = std::make_shared( token );
3653             if( m_exclusion )
3654             pattern = std::make_shared( pattern );
3655             m_currentFilter.m_patterns.push_back( pattern );
3656             }
3657             m_exclusion = false;
3658             m_mode = None;
3659             }
3660              
3661             void addFilter();
3662             };
3663             TestSpec parseTestSpec( std::string const& arg );
3664              
3665             } // namespace Catch
3666              
3667             #ifdef __clang__
3668             #pragma clang diagnostic pop
3669             #endif
3670              
3671             // end catch_test_spec_parser.h
3672             // start catch_interfaces_config.h
3673              
3674             #include
3675             #include
3676             #include
3677             #include
3678              
3679             namespace Catch {
3680              
3681             enum class Verbosity {
3682             Quiet = 0,
3683             Normal,
3684             High
3685             };
3686              
3687             struct WarnAbout { enum What {
3688             Nothing = 0x00,
3689             NoAssertions = 0x01,
3690             NoTests = 0x02
3691             }; };
3692              
3693             struct ShowDurations { enum OrNot {
3694             DefaultForReporter,
3695             Always,
3696             Never
3697             }; };
3698             struct RunTests { enum InWhatOrder {
3699             InDeclarationOrder,
3700             InLexicographicalOrder,
3701             InRandomOrder
3702             }; };
3703             struct UseColour { enum YesOrNo {
3704             Auto,
3705             Yes,
3706             No
3707             }; };
3708             struct WaitForKeypress { enum When {
3709             Never,
3710             BeforeStart = 1,
3711             BeforeExit = 2,
3712             BeforeStartAndExit = BeforeStart | BeforeExit
3713             }; };
3714              
3715             class TestSpec;
3716              
3717             struct IConfig : NonCopyable {
3718              
3719             virtual ~IConfig();
3720              
3721             virtual bool allowThrows() const = 0;
3722             virtual std::ostream& stream() const = 0;
3723             virtual std::string name() const = 0;
3724             virtual bool includeSuccessfulResults() const = 0;
3725             virtual bool shouldDebugBreak() const = 0;
3726             virtual bool warnAboutMissingAssertions() const = 0;
3727             virtual bool warnAboutNoTests() const = 0;
3728             virtual int abortAfter() const = 0;
3729             virtual bool showInvisibles() const = 0;
3730             virtual ShowDurations::OrNot showDurations() const = 0;
3731             virtual TestSpec const& testSpec() const = 0;
3732             virtual bool hasTestFilters() const = 0;
3733             virtual RunTests::InWhatOrder runOrder() const = 0;
3734             virtual unsigned int rngSeed() const = 0;
3735             virtual int benchmarkResolutionMultiple() const = 0;
3736             virtual UseColour::YesOrNo useColour() const = 0;
3737             virtual std::vector const& getSectionsToRun() const = 0;
3738             virtual Verbosity verbosity() const = 0;
3739             };
3740              
3741             using IConfigPtr = std::shared_ptr;
3742             }
3743              
3744             // end catch_interfaces_config.h
3745             // Libstdc++ doesn't like incomplete classes for unique_ptr
3746              
3747             #include
3748             #include
3749             #include
3750              
3751             #ifndef CATCH_CONFIG_CONSOLE_WIDTH
3752             #define CATCH_CONFIG_CONSOLE_WIDTH 80
3753             #endif
3754              
3755             namespace Catch {
3756              
3757             struct IStream;
3758              
3759             struct ConfigData {
3760             bool listTests = false;
3761             bool listTags = false;
3762             bool listReporters = false;
3763             bool listTestNamesOnly = false;
3764              
3765             bool showSuccessfulTests = false;
3766             bool shouldDebugBreak = false;
3767             bool noThrow = false;
3768             bool showHelp = false;
3769             bool showInvisibles = false;
3770             bool filenamesAsTags = false;
3771             bool libIdentify = false;
3772              
3773             int abortAfter = -1;
3774             unsigned int rngSeed = 0;
3775             int benchmarkResolutionMultiple = 100;
3776              
3777             Verbosity verbosity = Verbosity::Normal;
3778             WarnAbout::What warnings = WarnAbout::Nothing;
3779             ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
3780             RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
3781             UseColour::YesOrNo useColour = UseColour::Auto;
3782             WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
3783              
3784             std::string outputFilename;
3785             std::string name;
3786             std::string processName;
3787             #ifndef CATCH_CONFIG_DEFAULT_REPORTER
3788             #define CATCH_CONFIG_DEFAULT_REPORTER "console"
3789             #endif
3790             std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
3791             #undef CATCH_CONFIG_DEFAULT_REPORTER
3792              
3793             std::vector testsOrTags;
3794             std::vector sectionsToRun;
3795             };
3796              
3797             class Config : public IConfig {
3798             public:
3799              
3800             Config() = default;
3801             Config( ConfigData const& data );
3802             virtual ~Config() = default;
3803              
3804             std::string const& getFilename() const;
3805              
3806             bool listTests() const;
3807             bool listTestNamesOnly() const;
3808             bool listTags() const;
3809             bool listReporters() const;
3810              
3811             std::string getProcessName() const;
3812             std::string const& getReporterName() const;
3813              
3814             std::vector const& getTestsOrTags() const;
3815             std::vector const& getSectionsToRun() const override;
3816              
3817             virtual TestSpec const& testSpec() const override;
3818             bool hasTestFilters() const override;
3819              
3820             bool showHelp() const;
3821              
3822             // IConfig interface
3823             bool allowThrows() const override;
3824             std::ostream& stream() const override;
3825             std::string name() const override;
3826             bool includeSuccessfulResults() const override;
3827             bool warnAboutMissingAssertions() const override;
3828             bool warnAboutNoTests() const override;
3829             ShowDurations::OrNot showDurations() const override;
3830             RunTests::InWhatOrder runOrder() const override;
3831             unsigned int rngSeed() const override;
3832             int benchmarkResolutionMultiple() const override;
3833             UseColour::YesOrNo useColour() const override;
3834             bool shouldDebugBreak() const override;
3835             int abortAfter() const override;
3836             bool showInvisibles() const override;
3837             Verbosity verbosity() const override;
3838              
3839             private:
3840              
3841             IStream const* openStream();
3842             ConfigData m_data;
3843              
3844             std::unique_ptr m_stream;
3845             TestSpec m_testSpec;
3846             bool m_hasTestFilters = false;
3847             };
3848              
3849             } // end namespace Catch
3850              
3851             // end catch_config.hpp
3852             // start catch_assertionresult.h
3853              
3854             #include
3855              
3856             namespace Catch {
3857              
3858             struct AssertionResultData
3859             {
3860             AssertionResultData() = delete;
3861              
3862             AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
3863              
3864             std::string message;
3865             mutable std::string reconstructedExpression;
3866             LazyExpression lazyExpression;
3867             ResultWas::OfType resultType;
3868              
3869             std::string reconstructExpression() const;
3870             };
3871              
3872             class AssertionResult {
3873             public:
3874             AssertionResult() = delete;
3875             AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
3876              
3877             bool isOk() const;
3878             bool succeeded() const;
3879             ResultWas::OfType getResultType() const;
3880             bool hasExpression() const;
3881             bool hasMessage() const;
3882             std::string getExpression() const;
3883             std::string getExpressionInMacro() const;
3884             bool hasExpandedExpression() const;
3885             std::string getExpandedExpression() const;
3886             std::string getMessage() const;
3887             SourceLineInfo getSourceInfo() const;
3888             StringRef getTestMacroName() const;
3889              
3890             //protected:
3891             AssertionInfo m_info;
3892             AssertionResultData m_resultData;
3893             };
3894              
3895             } // end namespace Catch
3896              
3897             // end catch_assertionresult.h
3898             // start catch_option.hpp
3899              
3900             namespace Catch {
3901              
3902             // An optional type
3903             template
3904             class Option {
3905             public:
3906             Option() : nullableValue( nullptr ) {}
3907             Option( T const& _value )
3908             : nullableValue( new( storage ) T( _value ) )
3909             {}
3910             Option( Option const& _other )
3911             : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
3912             {}
3913              
3914             ~Option() {
3915             reset();
3916             }
3917              
3918             Option& operator= ( Option const& _other ) {
3919             if( &_other != this ) {
3920             reset();
3921             if( _other )
3922             nullableValue = new( storage ) T( *_other );
3923             }
3924             return *this;
3925             }
3926             Option& operator = ( T const& _value ) {
3927             reset();
3928             nullableValue = new( storage ) T( _value );
3929             return *this;
3930             }
3931              
3932             void reset() {
3933             if( nullableValue )
3934             nullableValue->~T();
3935             nullableValue = nullptr;
3936             }
3937              
3938             T& operator*() { return *nullableValue; }
3939             T const& operator*() const { return *nullableValue; }
3940             T* operator->() { return nullableValue; }
3941             const T* operator->() const { return nullableValue; }
3942              
3943             T valueOr( T const& defaultValue ) const {
3944             return nullableValue ? *nullableValue : defaultValue;
3945             }
3946              
3947             bool some() const { return nullableValue != nullptr; }
3948             bool none() const { return nullableValue == nullptr; }
3949              
3950             bool operator !() const { return nullableValue == nullptr; }
3951             explicit operator bool() const {
3952             return some();
3953             }
3954              
3955             private:
3956             T *nullableValue;
3957             alignas(alignof(T)) char storage[sizeof(T)];
3958             };
3959              
3960             } // end namespace Catch
3961              
3962             // end catch_option.hpp
3963             #include
3964             #include
3965             #include
3966             #include
3967             #include
3968              
3969             namespace Catch {
3970              
3971             struct ReporterConfig {
3972             explicit ReporterConfig( IConfigPtr const& _fullConfig );
3973              
3974             ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
3975              
3976             std::ostream& stream() const;
3977             IConfigPtr fullConfig() const;
3978              
3979             private:
3980             std::ostream* m_stream;
3981             IConfigPtr m_fullConfig;
3982             };
3983              
3984             struct ReporterPreferences {
3985             bool shouldRedirectStdOut = false;
3986             bool shouldReportAllAssertions = false;
3987             };
3988              
3989             template
3990             struct LazyStat : Option {
3991             LazyStat& operator=( T const& _value ) {
3992             Option::operator=( _value );
3993             used = false;
3994             return *this;
3995             }
3996             void reset() {
3997             Option::reset();
3998             used = false;
3999             }
4000             bool used = false;
4001             };
4002              
4003             struct TestRunInfo {
4004             TestRunInfo( std::string const& _name );
4005             std::string name;
4006             };
4007             struct GroupInfo {
4008             GroupInfo( std::string const& _name,
4009             std::size_t _groupIndex,
4010             std::size_t _groupsCount );
4011              
4012             std::string name;
4013             std::size_t groupIndex;
4014             std::size_t groupsCounts;
4015             };
4016              
4017             struct AssertionStats {
4018             AssertionStats( AssertionResult const& _assertionResult,
4019             std::vector const& _infoMessages,
4020             Totals const& _totals );
4021              
4022             AssertionStats( AssertionStats const& ) = default;
4023             AssertionStats( AssertionStats && ) = default;
4024             AssertionStats& operator = ( AssertionStats const& ) = default;
4025             AssertionStats& operator = ( AssertionStats && ) = default;
4026             virtual ~AssertionStats();
4027              
4028             AssertionResult assertionResult;
4029             std::vector infoMessages;
4030             Totals totals;
4031             };
4032              
4033             struct SectionStats {
4034             SectionStats( SectionInfo const& _sectionInfo,
4035             Counts const& _assertions,
4036             double _durationInSeconds,
4037             bool _missingAssertions );
4038             SectionStats( SectionStats const& ) = default;
4039             SectionStats( SectionStats && ) = default;
4040             SectionStats& operator = ( SectionStats const& ) = default;
4041             SectionStats& operator = ( SectionStats && ) = default;
4042             virtual ~SectionStats();
4043              
4044             SectionInfo sectionInfo;
4045             Counts assertions;
4046             double durationInSeconds;
4047             bool missingAssertions;
4048             };
4049              
4050             struct TestCaseStats {
4051             TestCaseStats( TestCaseInfo const& _testInfo,
4052             Totals const& _totals,
4053             std::string const& _stdOut,
4054             std::string const& _stdErr,
4055             bool _aborting );
4056              
4057             TestCaseStats( TestCaseStats const& ) = default;
4058             TestCaseStats( TestCaseStats && ) = default;
4059             TestCaseStats& operator = ( TestCaseStats const& ) = default;
4060             TestCaseStats& operator = ( TestCaseStats && ) = default;
4061             virtual ~TestCaseStats();
4062              
4063             TestCaseInfo testInfo;
4064             Totals totals;
4065             std::string stdOut;
4066             std::string stdErr;
4067             bool aborting;
4068             };
4069              
4070             struct TestGroupStats {
4071             TestGroupStats( GroupInfo const& _groupInfo,
4072             Totals const& _totals,
4073             bool _aborting );
4074             TestGroupStats( GroupInfo const& _groupInfo );
4075              
4076             TestGroupStats( TestGroupStats const& ) = default;
4077             TestGroupStats( TestGroupStats && ) = default;
4078             TestGroupStats& operator = ( TestGroupStats const& ) = default;
4079             TestGroupStats& operator = ( TestGroupStats && ) = default;
4080             virtual ~TestGroupStats();
4081              
4082             GroupInfo groupInfo;
4083             Totals totals;
4084             bool aborting;
4085             };
4086              
4087             struct TestRunStats {
4088             TestRunStats( TestRunInfo const& _runInfo,
4089             Totals const& _totals,
4090             bool _aborting );
4091              
4092             TestRunStats( TestRunStats const& ) = default;
4093             TestRunStats( TestRunStats && ) = default;
4094             TestRunStats& operator = ( TestRunStats const& ) = default;
4095             TestRunStats& operator = ( TestRunStats && ) = default;
4096             virtual ~TestRunStats();
4097              
4098             TestRunInfo runInfo;
4099             Totals totals;
4100             bool aborting;
4101             };
4102              
4103             struct BenchmarkInfo {
4104             std::string name;
4105             };
4106             struct BenchmarkStats {
4107             BenchmarkInfo info;
4108             std::size_t iterations;
4109             uint64_t elapsedTimeInNanoseconds;
4110             };
4111              
4112             struct IStreamingReporter {
4113             virtual ~IStreamingReporter() = default;
4114              
4115             // Implementing class must also provide the following static methods:
4116             // static std::string getDescription();
4117             // static std::set getSupportedVerbosities()
4118              
4119             virtual ReporterPreferences getPreferences() const = 0;
4120              
4121             virtual void noMatchingTestCases( std::string const& spec ) = 0;
4122              
4123             virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
4124             virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
4125              
4126             virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
4127             virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
4128              
4129             // *** experimental ***
4130             virtual void benchmarkStarting( BenchmarkInfo const& ) {}
4131              
4132             virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
4133              
4134             // The return value indicates if the messages buffer should be cleared:
4135             virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
4136              
4137             // *** experimental ***
4138             virtual void benchmarkEnded( BenchmarkStats const& ) {}
4139              
4140             virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
4141             virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
4142             virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
4143             virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
4144              
4145             virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
4146              
4147             // Default empty implementation provided
4148             virtual void fatalErrorEncountered( StringRef name );
4149              
4150             virtual bool isMulti() const;
4151             };
4152             using IStreamingReporterPtr = std::unique_ptr;
4153              
4154             struct IReporterFactory {
4155             virtual ~IReporterFactory();
4156             virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
4157             virtual std::string getDescription() const = 0;
4158             };
4159             using IReporterFactoryPtr = std::shared_ptr;
4160              
4161             struct IReporterRegistry {
4162             using FactoryMap = std::map;
4163             using Listeners = std::vector;
4164              
4165             virtual ~IReporterRegistry();
4166             virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
4167             virtual FactoryMap const& getFactories() const = 0;
4168             virtual Listeners const& getListeners() const = 0;
4169             };
4170              
4171             } // end namespace Catch
4172              
4173             // end catch_interfaces_reporter.h
4174             #include
4175             #include
4176             #include
4177             #include
4178             #include
4179             #include
4180             #include
4181              
4182             namespace Catch {
4183             void prepareExpandedExpression(AssertionResult& result);
4184              
4185             // Returns double formatted as %.3f (format expected on output)
4186             std::string getFormattedDuration( double duration );
4187              
4188             template
4189             struct StreamingReporterBase : IStreamingReporter {
4190              
4191             StreamingReporterBase( ReporterConfig const& _config )
4192             : m_config( _config.fullConfig() ),
4193             stream( _config.stream() )
4194             {
4195             m_reporterPrefs.shouldRedirectStdOut = false;
4196             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
4197             CATCH_ERROR( "Verbosity level not supported by this reporter" );
4198             }
4199              
4200             ReporterPreferences getPreferences() const override {
4201             return m_reporterPrefs;
4202             }
4203              
4204             static std::set getSupportedVerbosities() {
4205             return { Verbosity::Normal };
4206             }
4207              
4208             ~StreamingReporterBase() override = default;
4209              
4210             void noMatchingTestCases(std::string const&) override {}
4211              
4212             void testRunStarting(TestRunInfo const& _testRunInfo) override {
4213             currentTestRunInfo = _testRunInfo;
4214             }
4215             void testGroupStarting(GroupInfo const& _groupInfo) override {
4216             currentGroupInfo = _groupInfo;
4217             }
4218              
4219             void testCaseStarting(TestCaseInfo const& _testInfo) override {
4220             currentTestCaseInfo = _testInfo;
4221             }
4222             void sectionStarting(SectionInfo const& _sectionInfo) override {
4223             m_sectionStack.push_back(_sectionInfo);
4224             }
4225              
4226             void sectionEnded(SectionStats const& /* _sectionStats */) override {
4227             m_sectionStack.pop_back();
4228             }
4229             void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
4230             currentTestCaseInfo.reset();
4231             }
4232             void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
4233             currentGroupInfo.reset();
4234             }
4235             void testRunEnded(TestRunStats const& /* _testRunStats */) override {
4236             currentTestCaseInfo.reset();
4237             currentGroupInfo.reset();
4238             currentTestRunInfo.reset();
4239             }
4240              
4241             void skipTest(TestCaseInfo const&) override {
4242             // Don't do anything with this by default.
4243             // It can optionally be overridden in the derived class.
4244             }
4245              
4246             IConfigPtr m_config;
4247             std::ostream& stream;
4248              
4249             LazyStat currentTestRunInfo;
4250             LazyStat currentGroupInfo;
4251             LazyStat currentTestCaseInfo;
4252              
4253             std::vector m_sectionStack;
4254             ReporterPreferences m_reporterPrefs;
4255             };
4256              
4257             template
4258             struct CumulativeReporterBase : IStreamingReporter {
4259             template
4260             struct Node {
4261             explicit Node( T const& _value ) : value( _value ) {}
4262             virtual ~Node() {}
4263              
4264             using ChildNodes = std::vector>;
4265             T value;
4266             ChildNodes children;
4267             };
4268             struct SectionNode {
4269             explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
4270             virtual ~SectionNode() = default;
4271              
4272             bool operator == (SectionNode const& other) const {
4273             return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
4274             }
4275             bool operator == (std::shared_ptr const& other) const {
4276             return operator==(*other);
4277             }
4278              
4279             SectionStats stats;
4280             using ChildSections = std::vector>;
4281             using Assertions = std::vector;
4282             ChildSections childSections;
4283             Assertions assertions;
4284             std::string stdOut;
4285             std::string stdErr;
4286             };
4287              
4288             struct BySectionInfo {
4289             BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
4290             BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
4291             bool operator() (std::shared_ptr const& node) const {
4292             return ((node->stats.sectionInfo.name == m_other.name) &&
4293             (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
4294             }
4295             void operator=(BySectionInfo const&) = delete;
4296              
4297             private:
4298             SectionInfo const& m_other;
4299             };
4300              
4301             using TestCaseNode = Node;
4302             using TestGroupNode = Node;
4303             using TestRunNode = Node;
4304              
4305             CumulativeReporterBase( ReporterConfig const& _config )
4306             : m_config( _config.fullConfig() ),
4307             stream( _config.stream() )
4308             {
4309             m_reporterPrefs.shouldRedirectStdOut = false;
4310             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
4311             CATCH_ERROR( "Verbosity level not supported by this reporter" );
4312             }
4313             ~CumulativeReporterBase() override = default;
4314              
4315             ReporterPreferences getPreferences() const override {
4316             return m_reporterPrefs;
4317             }
4318              
4319             static std::set getSupportedVerbosities() {
4320             return { Verbosity::Normal };
4321             }
4322              
4323             void testRunStarting( TestRunInfo const& ) override {}
4324             void testGroupStarting( GroupInfo const& ) override {}
4325              
4326             void testCaseStarting( TestCaseInfo const& ) override {}
4327              
4328             void sectionStarting( SectionInfo const& sectionInfo ) override {
4329             SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
4330             std::shared_ptr node;
4331             if( m_sectionStack.empty() ) {
4332             if( !m_rootSection )
4333             m_rootSection = std::make_shared( incompleteStats );
4334             node = m_rootSection;
4335             }
4336             else {
4337             SectionNode& parentNode = *m_sectionStack.back();
4338             auto it =
4339             std::find_if( parentNode.childSections.begin(),
4340             parentNode.childSections.end(),
4341             BySectionInfo( sectionInfo ) );
4342             if( it == parentNode.childSections.end() ) {
4343             node = std::make_shared( incompleteStats );
4344             parentNode.childSections.push_back( node );
4345             }
4346             else
4347             node = *it;
4348             }
4349             m_sectionStack.push_back( node );
4350             m_deepestSection = std::move(node);
4351             }
4352              
4353             void assertionStarting(AssertionInfo const&) override {}
4354              
4355             bool assertionEnded(AssertionStats const& assertionStats) override {
4356             assert(!m_sectionStack.empty());
4357             // AssertionResult holds a pointer to a temporary DecomposedExpression,
4358             // which getExpandedExpression() calls to build the expression string.
4359             // Our section stack copy of the assertionResult will likely outlive the
4360             // temporary, so it must be expanded or discarded now to avoid calling
4361             // a destroyed object later.
4362             prepareExpandedExpression(const_cast( assertionStats.assertionResult ) );
4363             SectionNode& sectionNode = *m_sectionStack.back();
4364             sectionNode.assertions.push_back(assertionStats);
4365             return true;
4366             }
4367             void sectionEnded(SectionStats const& sectionStats) override {
4368             assert(!m_sectionStack.empty());
4369             SectionNode& node = *m_sectionStack.back();
4370             node.stats = sectionStats;
4371             m_sectionStack.pop_back();
4372             }
4373             void testCaseEnded(TestCaseStats const& testCaseStats) override {
4374             auto node = std::make_shared(testCaseStats);
4375             assert(m_sectionStack.size() == 0);
4376             node->children.push_back(m_rootSection);
4377             m_testCases.push_back(node);
4378             m_rootSection.reset();
4379              
4380             assert(m_deepestSection);
4381             m_deepestSection->stdOut = testCaseStats.stdOut;
4382             m_deepestSection->stdErr = testCaseStats.stdErr;
4383             }
4384             void testGroupEnded(TestGroupStats const& testGroupStats) override {
4385             auto node = std::make_shared(testGroupStats);
4386             node->children.swap(m_testCases);
4387             m_testGroups.push_back(node);
4388             }
4389             void testRunEnded(TestRunStats const& testRunStats) override {
4390             auto node = std::make_shared(testRunStats);
4391             node->children.swap(m_testGroups);
4392             m_testRuns.push_back(node);
4393             testRunEndedCumulative();
4394             }
4395             virtual void testRunEndedCumulative() = 0;
4396              
4397             void skipTest(TestCaseInfo const&) override {}
4398              
4399             IConfigPtr m_config;
4400             std::ostream& stream;
4401             std::vector m_assertions;
4402             std::vector>> m_sections;
4403             std::vector> m_testCases;
4404             std::vector> m_testGroups;
4405              
4406             std::vector> m_testRuns;
4407              
4408             std::shared_ptr m_rootSection;
4409             std::shared_ptr m_deepestSection;
4410             std::vector> m_sectionStack;
4411             ReporterPreferences m_reporterPrefs;
4412             };
4413              
4414             template
4415             char const* getLineOfChars() {
4416             static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
4417             if( !*line ) {
4418             std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
4419             line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
4420             }
4421             return line;
4422             }
4423              
4424             struct TestEventListenerBase : StreamingReporterBase {
4425             TestEventListenerBase( ReporterConfig const& _config );
4426              
4427             void assertionStarting(AssertionInfo const&) override;
4428             bool assertionEnded(AssertionStats const&) override;
4429             };
4430              
4431             } // end namespace Catch
4432              
4433             // end catch_reporter_bases.hpp
4434             // start catch_console_colour.h
4435              
4436             namespace Catch {
4437              
4438             struct Colour {
4439             enum Code {
4440             None = 0,
4441              
4442             White,
4443             Red,
4444             Green,
4445             Blue,
4446             Cyan,
4447             Yellow,
4448             Grey,
4449              
4450             Bright = 0x10,
4451              
4452             BrightRed = Bright | Red,
4453             BrightGreen = Bright | Green,
4454             LightGrey = Bright | Grey,
4455             BrightWhite = Bright | White,
4456             BrightYellow = Bright | Yellow,
4457              
4458             // By intention
4459             FileName = LightGrey,
4460             Warning = BrightYellow,
4461             ResultError = BrightRed,
4462             ResultSuccess = BrightGreen,
4463             ResultExpectedFailure = Warning,
4464              
4465             Error = BrightRed,
4466             Success = Green,
4467              
4468             OriginalExpression = Cyan,
4469             ReconstructedExpression = BrightYellow,
4470              
4471             SecondaryText = LightGrey,
4472             Headers = White
4473             };
4474              
4475             // Use constructed object for RAII guard
4476             Colour( Code _colourCode );
4477             Colour( Colour&& other ) noexcept;
4478             Colour& operator=( Colour&& other ) noexcept;
4479             ~Colour();
4480              
4481             // Use static method for one-shot changes
4482             static void use( Code _colourCode );
4483              
4484             private:
4485             bool m_moved = false;
4486             };
4487              
4488             std::ostream& operator << ( std::ostream& os, Colour const& );
4489              
4490             } // end namespace Catch
4491              
4492             // end catch_console_colour.h
4493             // start catch_reporter_registrars.hpp
4494              
4495              
4496             namespace Catch {
4497              
4498             template
4499             class ReporterRegistrar {
4500              
4501             class ReporterFactory : public IReporterFactory {
4502              
4503             virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
4504             return std::unique_ptr( new T( config ) );
4505             }
4506              
4507             virtual std::string getDescription() const override {
4508             return T::getDescription();
4509             }
4510             };
4511              
4512             public:
4513              
4514             explicit ReporterRegistrar( std::string const& name ) {
4515             getMutableRegistryHub().registerReporter( name, std::make_shared() );
4516             }
4517             };
4518              
4519             template
4520             class ListenerRegistrar {
4521              
4522             class ListenerFactory : public IReporterFactory {
4523              
4524             virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
4525             return std::unique_ptr( new T( config ) );
4526             }
4527             virtual std::string getDescription() const override {
4528             return std::string();
4529             }
4530             };
4531              
4532             public:
4533              
4534             ListenerRegistrar() {
4535             getMutableRegistryHub().registerListener( std::make_shared() );
4536             }
4537             };
4538             }
4539              
4540             #if !defined(CATCH_CONFIG_DISABLE)
4541              
4542             #define CATCH_REGISTER_REPORTER( name, reporterType ) \
4543             CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
4544             namespace{ Catch::ReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } \
4545             CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
4546              
4547             #define CATCH_REGISTER_LISTENER( listenerType ) \
4548             CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
4549             namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } \
4550             CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
4551             #else // CATCH_CONFIG_DISABLE
4552              
4553             #define CATCH_REGISTER_REPORTER(name, reporterType)
4554             #define CATCH_REGISTER_LISTENER(listenerType)
4555              
4556             #endif // CATCH_CONFIG_DISABLE
4557              
4558             // end catch_reporter_registrars.hpp
4559             // Allow users to base their work off existing reporters
4560             // start catch_reporter_compact.h
4561              
4562             namespace Catch {
4563              
4564             struct CompactReporter : StreamingReporterBase {
4565              
4566             using StreamingReporterBase::StreamingReporterBase;
4567              
4568             ~CompactReporter() override;
4569              
4570             static std::string getDescription();
4571              
4572             ReporterPreferences getPreferences() const override;
4573              
4574             void noMatchingTestCases(std::string const& spec) override;
4575              
4576             void assertionStarting(AssertionInfo const&) override;
4577              
4578             bool assertionEnded(AssertionStats const& _assertionStats) override;
4579              
4580             void sectionEnded(SectionStats const& _sectionStats) override;
4581              
4582             void testRunEnded(TestRunStats const& _testRunStats) override;
4583              
4584             };
4585              
4586             } // end namespace Catch
4587              
4588             // end catch_reporter_compact.h
4589             // start catch_reporter_console.h
4590              
4591             #if defined(_MSC_VER)
4592             #pragma warning(push)
4593             #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
4594             // Note that 4062 (not all labels are handled
4595             // and default is missing) is enabled
4596             #endif
4597              
4598             namespace Catch {
4599             // Fwd decls
4600             struct SummaryColumn;
4601             class TablePrinter;
4602              
4603             struct ConsoleReporter : StreamingReporterBase {
4604             std::unique_ptr m_tablePrinter;
4605              
4606             ConsoleReporter(ReporterConfig const& config);
4607             ~ConsoleReporter() override;
4608             static std::string getDescription();
4609              
4610             void noMatchingTestCases(std::string const& spec) override;
4611              
4612             void assertionStarting(AssertionInfo const&) override;
4613              
4614             bool assertionEnded(AssertionStats const& _assertionStats) override;
4615              
4616             void sectionStarting(SectionInfo const& _sectionInfo) override;
4617             void sectionEnded(SectionStats const& _sectionStats) override;
4618              
4619             void benchmarkStarting(BenchmarkInfo const& info) override;
4620             void benchmarkEnded(BenchmarkStats const& stats) override;
4621              
4622             void testCaseEnded(TestCaseStats const& _testCaseStats) override;
4623             void testGroupEnded(TestGroupStats const& _testGroupStats) override;
4624             void testRunEnded(TestRunStats const& _testRunStats) override;
4625              
4626             private:
4627              
4628             void lazyPrint();
4629              
4630             void lazyPrintWithoutClosingBenchmarkTable();
4631             void lazyPrintRunInfo();
4632             void lazyPrintGroupInfo();
4633             void printTestCaseAndSectionHeader();
4634              
4635             void printClosedHeader(std::string const& _name);
4636             void printOpenHeader(std::string const& _name);
4637              
4638             // if string has a : in first line will set indent to follow it on
4639             // subsequent lines
4640             void printHeaderString(std::string const& _string, std::size_t indent = 0);
4641              
4642             void printTotals(Totals const& totals);
4643             void printSummaryRow(std::string const& label, std::vector const& cols, std::size_t row);
4644              
4645             void printTotalsDivider(Totals const& totals);
4646             void printSummaryDivider();
4647              
4648             private:
4649             bool m_headerPrinted = false;
4650             };
4651              
4652             } // end namespace Catch
4653              
4654             #if defined(_MSC_VER)
4655             #pragma warning(pop)
4656             #endif
4657              
4658             // end catch_reporter_console.h
4659             // start catch_reporter_junit.h
4660              
4661             // start catch_xmlwriter.h
4662              
4663             #include
4664              
4665             namespace Catch {
4666              
4667             class XmlEncode {
4668             public:
4669             enum ForWhat { ForTextNodes, ForAttributes };
4670              
4671             XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
4672              
4673             void encodeTo( std::ostream& os ) const;
4674              
4675             friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
4676              
4677             private:
4678             std::string m_str;
4679             ForWhat m_forWhat;
4680             };
4681              
4682             class XmlWriter {
4683             public:
4684              
4685             class ScopedElement {
4686             public:
4687             ScopedElement( XmlWriter* writer );
4688              
4689             ScopedElement( ScopedElement&& other ) noexcept;
4690             ScopedElement& operator=( ScopedElement&& other ) noexcept;
4691              
4692             ~ScopedElement();
4693              
4694             ScopedElement& writeText( std::string const& text, bool indent = true );
4695              
4696             template
4697             ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
4698             m_writer->writeAttribute( name, attribute );
4699             return *this;
4700             }
4701              
4702             private:
4703             mutable XmlWriter* m_writer = nullptr;
4704             };
4705              
4706             XmlWriter( std::ostream& os = Catch::cout() );
4707             ~XmlWriter();
4708              
4709             XmlWriter( XmlWriter const& ) = delete;
4710             XmlWriter& operator=( XmlWriter const& ) = delete;
4711              
4712             XmlWriter& startElement( std::string const& name );
4713              
4714             ScopedElement scopedElement( std::string const& name );
4715              
4716             XmlWriter& endElement();
4717              
4718             XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
4719              
4720             XmlWriter& writeAttribute( std::string const& name, bool attribute );
4721              
4722             template
4723             XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
4724             ReusableStringStream rss;
4725             rss << attribute;
4726             return writeAttribute( name, rss.str() );
4727             }
4728              
4729             XmlWriter& writeText( std::string const& text, bool indent = true );
4730              
4731             XmlWriter& writeComment( std::string const& text );
4732              
4733             void writeStylesheetRef( std::string const& url );
4734              
4735             XmlWriter& writeBlankLine();
4736              
4737             void ensureTagClosed();
4738              
4739             private:
4740              
4741             void writeDeclaration();
4742              
4743             void newlineIfNecessary();
4744              
4745             bool m_tagIsOpen = false;
4746             bool m_needsNewline = false;
4747             std::vector m_tags;
4748             std::string m_indent;
4749             std::ostream& m_os;
4750             };
4751              
4752             }
4753              
4754             // end catch_xmlwriter.h
4755             namespace Catch {
4756              
4757             class JunitReporter : public CumulativeReporterBase {
4758             public:
4759             JunitReporter(ReporterConfig const& _config);
4760              
4761             ~JunitReporter() override;
4762              
4763             static std::string getDescription();
4764              
4765             void noMatchingTestCases(std::string const& /*spec*/) override;
4766              
4767             void testRunStarting(TestRunInfo const& runInfo) override;
4768              
4769             void testGroupStarting(GroupInfo const& groupInfo) override;
4770              
4771             void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
4772             bool assertionEnded(AssertionStats const& assertionStats) override;
4773              
4774             void testCaseEnded(TestCaseStats const& testCaseStats) override;
4775              
4776             void testGroupEnded(TestGroupStats const& testGroupStats) override;
4777              
4778             void testRunEndedCumulative() override;
4779              
4780             void writeGroup(TestGroupNode const& groupNode, double suiteTime);
4781              
4782             void writeTestCase(TestCaseNode const& testCaseNode);
4783              
4784             void writeSection(std::string const& className,
4785             std::string const& rootName,
4786             SectionNode const& sectionNode);
4787              
4788             void writeAssertions(SectionNode const& sectionNode);
4789             void writeAssertion(AssertionStats const& stats);
4790              
4791             XmlWriter xml;
4792             Timer suiteTimer;
4793             std::string stdOutForSuite;
4794             std::string stdErrForSuite;
4795             unsigned int unexpectedExceptions = 0;
4796             bool m_okToFail = false;
4797             };
4798              
4799             } // end namespace Catch
4800              
4801             // end catch_reporter_junit.h
4802             // start catch_reporter_xml.h
4803              
4804             namespace Catch {
4805             class XmlReporter : public StreamingReporterBase {
4806             public:
4807             XmlReporter(ReporterConfig const& _config);
4808              
4809             ~XmlReporter() override;
4810              
4811             static std::string getDescription();
4812              
4813             virtual std::string getStylesheetRef() const;
4814              
4815             void writeSourceInfo(SourceLineInfo const& sourceInfo);
4816              
4817             public: // StreamingReporterBase
4818              
4819             void noMatchingTestCases(std::string const& s) override;
4820              
4821             void testRunStarting(TestRunInfo const& testInfo) override;
4822              
4823             void testGroupStarting(GroupInfo const& groupInfo) override;
4824              
4825             void testCaseStarting(TestCaseInfo const& testInfo) override;
4826              
4827             void sectionStarting(SectionInfo const& sectionInfo) override;
4828              
4829             void assertionStarting(AssertionInfo const&) override;
4830              
4831             bool assertionEnded(AssertionStats const& assertionStats) override;
4832              
4833             void sectionEnded(SectionStats const& sectionStats) override;
4834              
4835             void testCaseEnded(TestCaseStats const& testCaseStats) override;
4836              
4837             void testGroupEnded(TestGroupStats const& testGroupStats) override;
4838              
4839             void testRunEnded(TestRunStats const& testRunStats) override;
4840              
4841             private:
4842             Timer m_testCaseTimer;
4843             XmlWriter m_xml;
4844             int m_sectionDepth = 0;
4845             };
4846              
4847             } // end namespace Catch
4848              
4849             // end catch_reporter_xml.h
4850              
4851             // end catch_external_interfaces.h
4852             #endif
4853              
4854             #endif // ! CATCH_CONFIG_IMPL_ONLY
4855              
4856             #ifdef CATCH_IMPL
4857             // start catch_impl.hpp
4858              
4859             #ifdef __clang__
4860             #pragma clang diagnostic push
4861             #pragma clang diagnostic ignored "-Wweak-vtables"
4862             #endif
4863              
4864             // Keep these here for external reporters
4865             // start catch_test_case_tracker.h
4866              
4867             #include
4868             #include
4869             #include
4870              
4871             namespace Catch {
4872             namespace TestCaseTracking {
4873              
4874             struct NameAndLocation {
4875             std::string name;
4876             SourceLineInfo location;
4877              
4878             NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
4879             };
4880              
4881             struct ITracker;
4882              
4883             using ITrackerPtr = std::shared_ptr;
4884              
4885             struct ITracker {
4886             virtual ~ITracker();
4887              
4888             // static queries
4889             virtual NameAndLocation const& nameAndLocation() const = 0;
4890              
4891             // dynamic queries
4892             virtual bool isComplete() const = 0; // Successfully completed or failed
4893             virtual bool isSuccessfullyCompleted() const = 0;
4894             virtual bool isOpen() const = 0; // Started but not complete
4895             virtual bool hasChildren() const = 0;
4896              
4897             virtual ITracker& parent() = 0;
4898              
4899             // actions
4900             virtual void close() = 0; // Successfully complete
4901             virtual void fail() = 0;
4902             virtual void markAsNeedingAnotherRun() = 0;
4903              
4904             virtual void addChild( ITrackerPtr const& child ) = 0;
4905             virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
4906             virtual void openChild() = 0;
4907              
4908             // Debug/ checking
4909             virtual bool isSectionTracker() const = 0;
4910             virtual bool isIndexTracker() const = 0;
4911             };
4912              
4913             class TrackerContext {
4914              
4915             enum RunState {
4916             NotStarted,
4917             Executing,
4918             CompletedCycle
4919             };
4920              
4921             ITrackerPtr m_rootTracker;
4922             ITracker* m_currentTracker = nullptr;
4923             RunState m_runState = NotStarted;
4924              
4925             public:
4926              
4927             static TrackerContext& instance();
4928              
4929             ITracker& startRun();
4930             void endRun();
4931              
4932             void startCycle();
4933             void completeCycle();
4934              
4935             bool completedCycle() const;
4936             ITracker& currentTracker();
4937             void setCurrentTracker( ITracker* tracker );
4938             };
4939              
4940             class TrackerBase : public ITracker {
4941             protected:
4942             enum CycleState {
4943             NotStarted,
4944             Executing,
4945             ExecutingChildren,
4946             NeedsAnotherRun,
4947             CompletedSuccessfully,
4948             Failed
4949             };
4950              
4951             using Children = std::vector;
4952             NameAndLocation m_nameAndLocation;
4953             TrackerContext& m_ctx;
4954             ITracker* m_parent;
4955             Children m_children;
4956             CycleState m_runState = NotStarted;
4957              
4958             public:
4959             TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
4960              
4961             NameAndLocation const& nameAndLocation() const override;
4962             bool isComplete() const override;
4963             bool isSuccessfullyCompleted() const override;
4964             bool isOpen() const override;
4965             bool hasChildren() const override;
4966              
4967             void addChild( ITrackerPtr const& child ) override;
4968              
4969             ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
4970             ITracker& parent() override;
4971              
4972             void openChild() override;
4973              
4974             bool isSectionTracker() const override;
4975             bool isIndexTracker() const override;
4976              
4977             void open();
4978              
4979             void close() override;
4980             void fail() override;
4981             void markAsNeedingAnotherRun() override;
4982              
4983             private:
4984             void moveToParent();
4985             void moveToThis();
4986             };
4987              
4988             class SectionTracker : public TrackerBase {
4989             std::vector m_filters;
4990             public:
4991             SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
4992              
4993             bool isSectionTracker() const override;
4994              
4995             static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
4996              
4997             void tryOpen();
4998              
4999             void addInitialFilters( std::vector const& filters );
5000             void addNextFilters( std::vector const& filters );
5001             };
5002              
5003             class IndexTracker : public TrackerBase {
5004             int m_size;
5005             int m_index = -1;
5006             public:
5007             IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size );
5008              
5009             bool isIndexTracker() const override;
5010             void close() override;
5011              
5012             static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size );
5013              
5014             int index() const;
5015              
5016             void moveNext();
5017             };
5018              
5019             } // namespace TestCaseTracking
5020              
5021             using TestCaseTracking::ITracker;
5022             using TestCaseTracking::TrackerContext;
5023             using TestCaseTracking::SectionTracker;
5024             using TestCaseTracking::IndexTracker;
5025              
5026             } // namespace Catch
5027              
5028             // end catch_test_case_tracker.h
5029              
5030             // start catch_leak_detector.h
5031              
5032             namespace Catch {
5033              
5034             struct LeakDetector {
5035             LeakDetector();
5036             };
5037              
5038             }
5039             // end catch_leak_detector.h
5040             // Cpp files will be included in the single-header file here
5041             // start catch_approx.cpp
5042              
5043             #include
5044             #include
5045              
5046             namespace {
5047              
5048             // Performs equivalent check of std::fabs(lhs - rhs) <= margin
5049             // But without the subtraction to allow for INFINITY in comparison
5050             bool marginComparison(double lhs, double rhs, double margin) {
5051             return (lhs + margin >= rhs) && (rhs + margin >= lhs);
5052             }
5053              
5054             }
5055              
5056             namespace Catch {
5057             namespace Detail {
5058              
5059             Approx::Approx ( double value )
5060             : m_epsilon( std::numeric_limits::epsilon()*100 ),
5061             m_margin( 0.0 ),
5062             m_scale( 0.0 ),
5063             m_value( value )
5064             {}
5065              
5066             Approx Approx::custom() {
5067             return Approx( 0 );
5068             }
5069              
5070             Approx Approx::operator-() const {
5071             auto temp(*this);
5072             temp.m_value = -temp.m_value;
5073             return temp;
5074             }
5075              
5076             std::string Approx::toString() const {
5077             ReusableStringStream rss;
5078             rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
5079             return rss.str();
5080             }
5081              
5082             bool Approx::equalityComparisonImpl(const double other) const {
5083             // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
5084             // Thanks to Richard Harris for his help refining the scaled margin value
5085             return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
5086             }
5087              
5088             void Approx::setMargin(double margin) {
5089             CATCH_ENFORCE(margin >= 0,
5090             "Invalid Approx::margin: " << margin << '.'
5091             << " Approx::Margin has to be non-negative.");
5092             m_margin = margin;
5093             }
5094              
5095             void Approx::setEpsilon(double epsilon) {
5096             CATCH_ENFORCE(epsilon >= 0 && epsilon <= 1.0,
5097             "Invalid Approx::epsilon: " << epsilon << '.'
5098             << " Approx::epsilon has to be in [0, 1]");
5099             m_epsilon = epsilon;
5100             }
5101              
5102             } // end namespace Detail
5103              
5104             namespace literals {
5105             Detail::Approx operator "" _a(long double val) {
5106             return Detail::Approx(val);
5107             }
5108             Detail::Approx operator "" _a(unsigned long long val) {
5109             return Detail::Approx(val);
5110             }
5111             } // end namespace literals
5112              
5113             std::string StringMaker::convert(Catch::Detail::Approx const& value) {
5114             return value.toString();
5115             }
5116              
5117             } // end namespace Catch
5118             // end catch_approx.cpp
5119             // start catch_assertionhandler.cpp
5120              
5121             // start catch_context.h
5122              
5123             #include
5124              
5125             namespace Catch {
5126              
5127             struct IResultCapture;
5128             struct IRunner;
5129             struct IConfig;
5130             struct IMutableContext;
5131              
5132             using IConfigPtr = std::shared_ptr;
5133              
5134             struct IContext
5135             {
5136             virtual ~IContext();
5137              
5138             virtual IResultCapture* getResultCapture() = 0;
5139             virtual IRunner* getRunner() = 0;
5140             virtual IConfigPtr const& getConfig() const = 0;
5141             };
5142              
5143             struct IMutableContext : IContext
5144             {
5145             virtual ~IMutableContext();
5146             virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
5147             virtual void setRunner( IRunner* runner ) = 0;
5148             virtual void setConfig( IConfigPtr const& config ) = 0;
5149              
5150             private:
5151             static IMutableContext *currentContext;
5152             friend IMutableContext& getCurrentMutableContext();
5153             friend void cleanUpContext();
5154             static void createContext();
5155             };
5156              
5157             inline IMutableContext& getCurrentMutableContext()
5158             {
5159             if( !IMutableContext::currentContext )
5160             IMutableContext::createContext();
5161             return *IMutableContext::currentContext;
5162             }
5163              
5164             inline IContext& getCurrentContext()
5165             {
5166             return getCurrentMutableContext();
5167             }
5168              
5169             void cleanUpContext();
5170             }
5171              
5172             // end catch_context.h
5173             // start catch_debugger.h
5174              
5175             namespace Catch {
5176             bool isDebuggerActive();
5177             }
5178              
5179             #ifdef CATCH_PLATFORM_MAC
5180              
5181             #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
5182              
5183             #elif defined(CATCH_PLATFORM_LINUX)
5184             // If we can use inline assembler, do it because this allows us to break
5185             // directly at the location of the failing check instead of breaking inside
5186             // raise() called from it, i.e. one stack frame below.
5187             #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
5188             #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
5189             #else // Fall back to the generic way.
5190             #include
5191              
5192             #define CATCH_TRAP() raise(SIGTRAP)
5193             #endif
5194             #elif defined(_MSC_VER)
5195             #define CATCH_TRAP() __debugbreak()
5196             #elif defined(__MINGW32__)
5197             extern "C" __declspec(dllimport) void __stdcall DebugBreak();
5198             #define CATCH_TRAP() DebugBreak()
5199             #endif
5200              
5201             #ifdef CATCH_TRAP
5202             #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
5203             #else
5204             namespace Catch {
5205             inline void doNothing() {}
5206             }
5207             #define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing()
5208             #endif
5209              
5210             // end catch_debugger.h
5211             // start catch_run_context.h
5212              
5213             // start catch_fatal_condition.h
5214              
5215             // start catch_windows_h_proxy.h
5216              
5217              
5218             #if defined(CATCH_PLATFORM_WINDOWS)
5219              
5220             #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
5221             # define CATCH_DEFINED_NOMINMAX
5222             # define NOMINMAX
5223             #endif
5224             #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
5225             # define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
5226             # define WIN32_LEAN_AND_MEAN
5227             #endif
5228              
5229             #ifdef __AFXDLL
5230             #include
5231             #else
5232             #include
5233             #endif
5234              
5235             #ifdef CATCH_DEFINED_NOMINMAX
5236             # undef NOMINMAX
5237             #endif
5238             #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
5239             # undef WIN32_LEAN_AND_MEAN
5240             #endif
5241              
5242             #endif // defined(CATCH_PLATFORM_WINDOWS)
5243              
5244             // end catch_windows_h_proxy.h
5245             #if defined( CATCH_CONFIG_WINDOWS_SEH )
5246              
5247             namespace Catch {
5248              
5249             struct FatalConditionHandler {
5250              
5251             static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
5252             FatalConditionHandler();
5253             static void reset();
5254             ~FatalConditionHandler();
5255              
5256             private:
5257             static bool isSet;
5258             static ULONG guaranteeSize;
5259             static PVOID exceptionHandlerHandle;
5260             };
5261              
5262             } // namespace Catch
5263              
5264             #elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
5265              
5266             #include
5267              
5268             namespace Catch {
5269              
5270             struct FatalConditionHandler {
5271              
5272             static bool isSet;
5273             static struct sigaction oldSigActions[];
5274             static stack_t oldSigStack;
5275             static char altStackMem[];
5276              
5277             static void handleSignal( int sig );
5278              
5279             FatalConditionHandler();
5280             ~FatalConditionHandler();
5281             static void reset();
5282             };
5283              
5284             } // namespace Catch
5285              
5286             #else
5287              
5288             namespace Catch {
5289             struct FatalConditionHandler {
5290             void reset();
5291             };
5292             }
5293              
5294             #endif
5295              
5296             // end catch_fatal_condition.h
5297             #include
5298              
5299             namespace Catch {
5300              
5301             struct IMutableContext;
5302              
5303             ///////////////////////////////////////////////////////////////////////////
5304              
5305             class RunContext : public IResultCapture, public IRunner {
5306              
5307             public:
5308             RunContext( RunContext const& ) = delete;
5309             RunContext& operator =( RunContext const& ) = delete;
5310              
5311             explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
5312              
5313             ~RunContext() override;
5314              
5315             void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
5316             void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
5317              
5318             Totals runTest(TestCase const& testCase);
5319              
5320             IConfigPtr config() const;
5321             IStreamingReporter& reporter() const;
5322              
5323             public: // IResultCapture
5324              
5325             // Assertion handlers
5326             void handleExpr
5327             ( AssertionInfo const& info,
5328             ITransientExpression const& expr,
5329             AssertionReaction& reaction ) override;
5330             void handleMessage
5331             ( AssertionInfo const& info,
5332             ResultWas::OfType resultType,
5333             StringRef const& message,
5334             AssertionReaction& reaction ) override;
5335             void handleUnexpectedExceptionNotThrown
5336             ( AssertionInfo const& info,
5337             AssertionReaction& reaction ) override;
5338             void handleUnexpectedInflightException
5339             ( AssertionInfo const& info,
5340             std::string const& message,
5341             AssertionReaction& reaction ) override;
5342             void handleIncomplete
5343             ( AssertionInfo const& info ) override;
5344             void handleNonExpr
5345             ( AssertionInfo const &info,
5346             ResultWas::OfType resultType,
5347             AssertionReaction &reaction ) override;
5348              
5349             bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
5350              
5351             void sectionEnded( SectionEndInfo const& endInfo ) override;
5352             void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
5353              
5354             auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
5355              
5356             void benchmarkStarting( BenchmarkInfo const& info ) override;
5357             void benchmarkEnded( BenchmarkStats const& stats ) override;
5358              
5359             void pushScopedMessage( MessageInfo const& message ) override;
5360             void popScopedMessage( MessageInfo const& message ) override;
5361              
5362             std::string getCurrentTestName() const override;
5363              
5364             const AssertionResult* getLastResult() const override;
5365              
5366             void exceptionEarlyReported() override;
5367              
5368             void handleFatalErrorCondition( StringRef message ) override;
5369              
5370             bool lastAssertionPassed() override;
5371              
5372             void assertionPassed() override;
5373              
5374             public:
5375             // !TBD We need to do this another way!
5376             bool aborting() const final;
5377              
5378             private:
5379              
5380             void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
5381             void invokeActiveTestCase();
5382              
5383             void resetAssertionInfo();
5384             bool testForMissingAssertions( Counts& assertions );
5385              
5386             void assertionEnded( AssertionResult const& result );
5387             void reportExpr
5388             ( AssertionInfo const &info,
5389             ResultWas::OfType resultType,
5390             ITransientExpression const *expr,
5391             bool negated );
5392              
5393             void populateReaction( AssertionReaction& reaction );
5394              
5395             private:
5396              
5397             void handleUnfinishedSections();
5398              
5399             TestRunInfo m_runInfo;
5400             IMutableContext& m_context;
5401             TestCase const* m_activeTestCase = nullptr;
5402             ITracker* m_testCaseTracker;
5403             Option m_lastResult;
5404              
5405             IConfigPtr m_config;
5406             Totals m_totals;
5407             IStreamingReporterPtr m_reporter;
5408             std::vector m_messages;
5409             AssertionInfo m_lastAssertionInfo;
5410             std::vector m_unfinishedSections;
5411             std::vector m_activeSections;
5412             TrackerContext m_trackerContext;
5413             bool m_lastAssertionPassed = false;
5414             bool m_shouldReportUnexpected = true;
5415             bool m_includeSuccessfulResults;
5416             };
5417              
5418             } // end namespace Catch
5419              
5420             // end catch_run_context.h
5421             namespace Catch {
5422              
5423             namespace {
5424             auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
5425             expr.streamReconstructedExpression( os );
5426             return os;
5427             }
5428             }
5429              
5430             LazyExpression::LazyExpression( bool isNegated )
5431             : m_isNegated( isNegated )
5432             {}
5433              
5434             LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
5435              
5436             LazyExpression::operator bool() const {
5437             return m_transientExpression != nullptr;
5438             }
5439              
5440             auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
5441             if( lazyExpr.m_isNegated )
5442             os << "!";
5443              
5444             if( lazyExpr ) {
5445             if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
5446             os << "(" << *lazyExpr.m_transientExpression << ")";
5447             else
5448             os << *lazyExpr.m_transientExpression;
5449             }
5450             else {
5451             os << "{** error - unchecked empty expression requested **}";
5452             }
5453             return os;
5454             }
5455              
5456             AssertionHandler::AssertionHandler
5457             ( StringRef const& macroName,
5458             SourceLineInfo const& lineInfo,
5459             StringRef capturedExpression,
5460             ResultDisposition::Flags resultDisposition )
5461             : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
5462             m_resultCapture( getResultCapture() )
5463             {}
5464              
5465             void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
5466             m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
5467             }
5468             void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
5469             m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
5470             }
5471              
5472             auto AssertionHandler::allowThrows() const -> bool {
5473             return getCurrentContext().getConfig()->allowThrows();
5474             }
5475              
5476             void AssertionHandler::complete() {
5477             setCompleted();
5478             if( m_reaction.shouldDebugBreak ) {
5479              
5480             // If you find your debugger stopping you here then go one level up on the
5481             // call-stack for the code that caused it (typically a failed assertion)
5482              
5483             // (To go back to the test and change execution, jump over the throw, next)
5484             CATCH_BREAK_INTO_DEBUGGER();
5485             }
5486             if (m_reaction.shouldThrow) {
5487             #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
5488             throw Catch::TestFailureException();
5489             #else
5490             CATCH_ERROR( "Test failure requires aborting test!" );
5491             #endif
5492             }
5493             }
5494             void AssertionHandler::setCompleted() {
5495             m_completed = true;
5496             }
5497              
5498             void AssertionHandler::handleUnexpectedInflightException() {
5499             m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
5500             }
5501              
5502             void AssertionHandler::handleExceptionThrownAsExpected() {
5503             m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
5504             }
5505             void AssertionHandler::handleExceptionNotThrownAsExpected() {
5506             m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
5507             }
5508              
5509             void AssertionHandler::handleUnexpectedExceptionNotThrown() {
5510             m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
5511             }
5512              
5513             void AssertionHandler::handleThrowingCallSkipped() {
5514             m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
5515             }
5516              
5517             // This is the overload that takes a string and infers the Equals matcher from it
5518             // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
5519             void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ) {
5520             handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
5521             }
5522              
5523             } // namespace Catch
5524             // end catch_assertionhandler.cpp
5525             // start catch_assertionresult.cpp
5526              
5527             namespace Catch {
5528             AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
5529             lazyExpression(_lazyExpression),
5530             resultType(_resultType) {}
5531              
5532             std::string AssertionResultData::reconstructExpression() const {
5533              
5534             if( reconstructedExpression.empty() ) {
5535             if( lazyExpression ) {
5536             ReusableStringStream rss;
5537             rss << lazyExpression;
5538             reconstructedExpression = rss.str();
5539             }
5540             }
5541             return reconstructedExpression;
5542             }
5543              
5544             AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
5545             : m_info( info ),
5546             m_resultData( data )
5547             {}
5548              
5549             // Result was a success
5550             bool AssertionResult::succeeded() const {
5551             return Catch::isOk( m_resultData.resultType );
5552             }
5553              
5554             // Result was a success, or failure is suppressed
5555             bool AssertionResult::isOk() const {
5556             return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
5557             }
5558              
5559             ResultWas::OfType AssertionResult::getResultType() const {
5560             return m_resultData.resultType;
5561             }
5562              
5563             bool AssertionResult::hasExpression() const {
5564             return m_info.capturedExpression[0] != 0;
5565             }
5566              
5567             bool AssertionResult::hasMessage() const {
5568             return !m_resultData.message.empty();
5569             }
5570              
5571             std::string AssertionResult::getExpression() const {
5572             if( isFalseTest( m_info.resultDisposition ) )
5573             return "!(" + m_info.capturedExpression + ")";
5574             else
5575             return m_info.capturedExpression;
5576             }
5577              
5578             std::string AssertionResult::getExpressionInMacro() const {
5579             std::string expr;
5580             if( m_info.macroName[0] == 0 )
5581             expr = m_info.capturedExpression;
5582             else {
5583             expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
5584             expr += m_info.macroName;
5585             expr += "( ";
5586             expr += m_info.capturedExpression;
5587             expr += " )";
5588             }
5589             return expr;
5590             }
5591              
5592             bool AssertionResult::hasExpandedExpression() const {
5593             return hasExpression() && getExpandedExpression() != getExpression();
5594             }
5595              
5596             std::string AssertionResult::getExpandedExpression() const {
5597             std::string expr = m_resultData.reconstructExpression();
5598             return expr.empty()
5599             ? getExpression()
5600             : expr;
5601             }
5602              
5603             std::string AssertionResult::getMessage() const {
5604             return m_resultData.message;
5605             }
5606             SourceLineInfo AssertionResult::getSourceInfo() const {
5607             return m_info.lineInfo;
5608             }
5609              
5610             StringRef AssertionResult::getTestMacroName() const {
5611             return m_info.macroName;
5612             }
5613              
5614             } // end namespace Catch
5615             // end catch_assertionresult.cpp
5616             // start catch_benchmark.cpp
5617              
5618             namespace Catch {
5619              
5620             auto BenchmarkLooper::getResolution() -> uint64_t {
5621             return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple();
5622             }
5623              
5624             void BenchmarkLooper::reportStart() {
5625             getResultCapture().benchmarkStarting( { m_name } );
5626             }
5627             auto BenchmarkLooper::needsMoreIterations() -> bool {
5628             auto elapsed = m_timer.getElapsedNanoseconds();
5629              
5630             // Exponentially increasing iterations until we're confident in our timer resolution
5631             if( elapsed < m_resolution ) {
5632             m_iterationsToRun *= 10;
5633             return true;
5634             }
5635              
5636             getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } );
5637             return false;
5638             }
5639              
5640             } // end namespace Catch
5641             // end catch_benchmark.cpp
5642             // start catch_capture_matchers.cpp
5643              
5644             namespace Catch {
5645              
5646             using StringMatcher = Matchers::Impl::MatcherBase;
5647              
5648             // This is the general overload that takes a any string matcher
5649             // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
5650             // the Equals matcher (so the header does not mention matchers)
5651             void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ) {
5652             std::string exceptionMessage = Catch::translateActiveException();
5653             MatchExpr expr( exceptionMessage, matcher, matcherString );
5654             handler.handleExpr( expr );
5655             }
5656              
5657             } // namespace Catch
5658             // end catch_capture_matchers.cpp
5659             // start catch_commandline.cpp
5660              
5661             // start catch_commandline.h
5662              
5663             // start catch_clara.h
5664              
5665             // Use Catch's value for console width (store Clara's off to the side, if present)
5666             #ifdef CLARA_CONFIG_CONSOLE_WIDTH
5667             #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
5668             #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
5669             #endif
5670             #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
5671              
5672             #ifdef __clang__
5673             #pragma clang diagnostic push
5674             #pragma clang diagnostic ignored "-Wweak-vtables"
5675             #pragma clang diagnostic ignored "-Wexit-time-destructors"
5676             #pragma clang diagnostic ignored "-Wshadow"
5677             #endif
5678              
5679             // start clara.hpp
5680             // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
5681             //
5682             // Distributed under the Boost Software License, Version 1.0. (See accompanying
5683             // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5684             //
5685             // See https://github.com/philsquared/Clara for more details
5686              
5687             // Clara v1.1.4
5688              
5689              
5690             #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
5691             #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
5692             #endif
5693              
5694             #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
5695             #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
5696             #endif
5697              
5698             #ifndef CLARA_CONFIG_OPTIONAL_TYPE
5699             #ifdef __has_include
5700             #if __has_include() && __cplusplus >= 201703L
5701             #include
5702             #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
5703             #endif
5704             #endif
5705             #endif
5706              
5707             // ----------- #included from clara_textflow.hpp -----------
5708              
5709             // TextFlowCpp
5710             //
5711             // A single-header library for wrapping and laying out basic text, by Phil Nash
5712             //
5713             // This work is licensed under the BSD 2-Clause license.
5714             // See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause
5715             //
5716             // This project is hosted at https://github.com/philsquared/textflowcpp
5717              
5718              
5719             #include
5720             #include
5721             #include
5722             #include
5723              
5724             #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
5725             #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
5726             #endif
5727              
5728             namespace Catch { namespace clara { namespace TextFlow {
5729              
5730             inline auto isWhitespace( char c ) -> bool {
5731             static std::string chars = " \t\n\r";
5732             return chars.find( c ) != std::string::npos;
5733             }
5734             inline auto isBreakableBefore( char c ) -> bool {
5735             static std::string chars = "[({<|";
5736             return chars.find( c ) != std::string::npos;
5737             }
5738             inline auto isBreakableAfter( char c ) -> bool {
5739             static std::string chars = "])}>.,:;*+-=&/\\";
5740             return chars.find( c ) != std::string::npos;
5741             }
5742              
5743             class Columns;
5744              
5745             class Column {
5746             std::vector m_strings;
5747             size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
5748             size_t m_indent = 0;
5749             size_t m_initialIndent = std::string::npos;
5750              
5751             public:
5752             class iterator {
5753             friend Column;
5754              
5755             Column const& m_column;
5756             size_t m_stringIndex = 0;
5757             size_t m_pos = 0;
5758              
5759             size_t m_len = 0;
5760             size_t m_end = 0;
5761             bool m_suffix = false;
5762              
5763             iterator( Column const& column, size_t stringIndex )
5764             : m_column( column ),
5765             m_stringIndex( stringIndex )
5766             {}
5767              
5768             auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
5769              
5770             auto isBoundary( size_t at ) const -> bool {
5771             assert( at > 0 );
5772             assert( at <= line().size() );
5773              
5774             return at == line().size() ||
5775             ( isWhitespace( line()[at] ) && !isWhitespace( line()[at-1] ) ) ||
5776             isBreakableBefore( line()[at] ) ||
5777             isBreakableAfter( line()[at-1] );
5778             }
5779              
5780             void calcLength() {
5781             assert( m_stringIndex < m_column.m_strings.size() );
5782              
5783             m_suffix = false;
5784             auto width = m_column.m_width-indent();
5785             m_end = m_pos;
5786             while( m_end < line().size() && line()[m_end] != '\n' )
5787             ++m_end;
5788              
5789             if( m_end < m_pos + width ) {
5790             m_len = m_end - m_pos;
5791             }
5792             else {
5793             size_t len = width;
5794             while (len > 0 && !isBoundary(m_pos + len))
5795             --len;
5796             while (len > 0 && isWhitespace( line()[m_pos + len - 1] ))
5797             --len;
5798              
5799             if (len > 0) {
5800             m_len = len;
5801             } else {
5802             m_suffix = true;
5803             m_len = width - 1;
5804             }
5805             }
5806             }
5807              
5808             auto indent() const -> size_t {
5809             auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
5810             return initial == std::string::npos ? m_column.m_indent : initial;
5811             }
5812              
5813             auto addIndentAndSuffix(std::string const &plain) const -> std::string {
5814             return std::string( indent(), ' ' ) + (m_suffix ? plain + "-" : plain);
5815             }
5816              
5817             public:
5818             explicit iterator( Column const& column ) : m_column( column ) {
5819             assert( m_column.m_width > m_column.m_indent );
5820             assert( m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent );
5821             calcLength();
5822             if( m_len == 0 )
5823             m_stringIndex++; // Empty string
5824             }
5825              
5826             auto operator *() const -> std::string {
5827             assert( m_stringIndex < m_column.m_strings.size() );
5828             assert( m_pos <= m_end );
5829             if( m_pos + m_column.m_width < m_end )
5830             return addIndentAndSuffix(line().substr(m_pos, m_len));
5831             else
5832             return addIndentAndSuffix(line().substr(m_pos, m_end - m_pos));
5833             }
5834              
5835             auto operator ++() -> iterator& {
5836             m_pos += m_len;
5837             if( m_pos < line().size() && line()[m_pos] == '\n' )
5838             m_pos += 1;
5839             else
5840             while( m_pos < line().size() && isWhitespace( line()[m_pos] ) )
5841             ++m_pos;
5842              
5843             if( m_pos == line().size() ) {
5844             m_pos = 0;
5845             ++m_stringIndex;
5846             }
5847             if( m_stringIndex < m_column.m_strings.size() )
5848             calcLength();
5849             return *this;
5850             }
5851             auto operator ++(int) -> iterator {
5852             iterator prev( *this );
5853             operator++();
5854             return prev;
5855             }
5856              
5857             auto operator ==( iterator const& other ) const -> bool {
5858             return
5859             m_pos == other.m_pos &&
5860             m_stringIndex == other.m_stringIndex &&
5861             &m_column == &other.m_column;
5862             }
5863             auto operator !=( iterator const& other ) const -> bool {
5864             return !operator==( other );
5865             }
5866             };
5867             using const_iterator = iterator;
5868              
5869             explicit Column( std::string const& text ) { m_strings.push_back( text ); }
5870              
5871             auto width( size_t newWidth ) -> Column& {
5872             assert( newWidth > 0 );
5873             m_width = newWidth;
5874             return *this;
5875             }
5876             auto indent( size_t newIndent ) -> Column& {
5877             m_indent = newIndent;
5878             return *this;
5879             }
5880             auto initialIndent( size_t newIndent ) -> Column& {
5881             m_initialIndent = newIndent;
5882             return *this;
5883             }
5884              
5885             auto width() const -> size_t { return m_width; }
5886             auto begin() const -> iterator { return iterator( *this ); }
5887             auto end() const -> iterator { return { *this, m_strings.size() }; }
5888              
5889             inline friend std::ostream& operator << ( std::ostream& os, Column const& col ) {
5890             bool first = true;
5891             for( auto line : col ) {
5892             if( first )
5893             first = false;
5894             else
5895             os << "\n";
5896             os << line;
5897             }
5898             return os;
5899             }
5900              
5901             auto operator + ( Column const& other ) -> Columns;
5902              
5903             auto toString() const -> std::string {
5904             std::ostringstream oss;
5905             oss << *this;
5906             return oss.str();
5907             }
5908             };
5909              
5910             class Spacer : public Column {
5911              
5912             public:
5913             explicit Spacer( size_t spaceWidth ) : Column( "" ) {
5914             width( spaceWidth );
5915             }
5916             };
5917              
5918             class Columns {
5919             std::vector m_columns;
5920              
5921             public:
5922              
5923             class iterator {
5924             friend Columns;
5925             struct EndTag {};
5926              
5927             std::vector const& m_columns;
5928             std::vector m_iterators;
5929             size_t m_activeIterators;
5930              
5931             iterator( Columns const& columns, EndTag )
5932             : m_columns( columns.m_columns ),
5933             m_activeIterators( 0 )
5934             {
5935             m_iterators.reserve( m_columns.size() );
5936              
5937             for( auto const& col : m_columns )
5938             m_iterators.push_back( col.end() );
5939             }
5940              
5941             public:
5942             explicit iterator( Columns const& columns )
5943             : m_columns( columns.m_columns ),
5944             m_activeIterators( m_columns.size() )
5945             {
5946             m_iterators.reserve( m_columns.size() );
5947              
5948             for( auto const& col : m_columns )
5949             m_iterators.push_back( col.begin() );
5950             }
5951              
5952             auto operator ==( iterator const& other ) const -> bool {
5953             return m_iterators == other.m_iterators;
5954             }
5955             auto operator !=( iterator const& other ) const -> bool {
5956             return m_iterators != other.m_iterators;
5957             }
5958             auto operator *() const -> std::string {
5959             std::string row, padding;
5960              
5961             for( size_t i = 0; i < m_columns.size(); ++i ) {
5962             auto width = m_columns[i].width();
5963             if( m_iterators[i] != m_columns[i].end() ) {
5964             std::string col = *m_iterators[i];
5965             row += padding + col;
5966             if( col.size() < width )
5967             padding = std::string( width - col.size(), ' ' );
5968             else
5969             padding = "";
5970             }
5971             else {
5972             padding += std::string( width, ' ' );
5973             }
5974             }
5975             return row;
5976             }
5977             auto operator ++() -> iterator& {
5978             for( size_t i = 0; i < m_columns.size(); ++i ) {
5979             if (m_iterators[i] != m_columns[i].end())
5980             ++m_iterators[i];
5981             }
5982             return *this;
5983             }
5984             auto operator ++(int) -> iterator {
5985             iterator prev( *this );
5986             operator++();
5987             return prev;
5988             }
5989             };
5990             using const_iterator = iterator;
5991              
5992             auto begin() const -> iterator { return iterator( *this ); }
5993             auto end() const -> iterator { return { *this, iterator::EndTag() }; }
5994              
5995             auto operator += ( Column const& col ) -> Columns& {
5996             m_columns.push_back( col );
5997             return *this;
5998             }
5999             auto operator + ( Column const& col ) -> Columns {
6000             Columns combined = *this;
6001             combined += col;
6002             return combined;
6003             }
6004              
6005             inline friend std::ostream& operator << ( std::ostream& os, Columns const& cols ) {
6006              
6007             bool first = true;
6008             for( auto line : cols ) {
6009             if( first )
6010             first = false;
6011             else
6012             os << "\n";
6013             os << line;
6014             }
6015             return os;
6016             }
6017              
6018             auto toString() const -> std::string {
6019             std::ostringstream oss;
6020             oss << *this;
6021             return oss.str();
6022             }
6023             };
6024              
6025             inline auto Column::operator + ( Column const& other ) -> Columns {
6026             Columns cols;
6027             cols += *this;
6028             cols += other;
6029             return cols;
6030             }
6031             }}} // namespace Catch::clara::TextFlow
6032              
6033             // ----------- end of #include from clara_textflow.hpp -----------
6034             // ........... back in clara.hpp
6035              
6036             #include
6037             #include
6038             #include
6039              
6040             #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
6041             #define CATCH_PLATFORM_WINDOWS
6042             #endif
6043              
6044             namespace Catch { namespace clara {
6045             namespace detail {
6046              
6047             // Traits for extracting arg and return type of lambdas (for single argument lambdas)
6048             template
6049             struct UnaryLambdaTraits : UnaryLambdaTraits {};
6050              
6051             template
6052             struct UnaryLambdaTraits {
6053             static const bool isValid = false;
6054             };
6055              
6056             template
6057             struct UnaryLambdaTraits {
6058             static const bool isValid = true;
6059             using ArgType = typename std::remove_const::type>::type;
6060             using ReturnType = ReturnT;
6061             };
6062              
6063             class TokenStream;
6064              
6065             // Transport for raw args (copied from main args, or supplied via init list for testing)
6066             class Args {
6067             friend TokenStream;
6068             std::string m_exeName;
6069             std::vector m_args;
6070              
6071             public:
6072             Args( int argc, char const* const* argv )
6073             : m_exeName(argv[0]),
6074             m_args(argv + 1, argv + argc) {}
6075              
6076             Args( std::initializer_list args )
6077             : m_exeName( *args.begin() ),
6078             m_args( args.begin()+1, args.end() )
6079             {}
6080              
6081             auto exeName() const -> std::string {
6082             return m_exeName;
6083             }
6084             };
6085              
6086             // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
6087             // may encode an option + its argument if the : or = form is used
6088             enum class TokenType {
6089             Option, Argument
6090             };
6091             struct Token {
6092             TokenType type;
6093             std::string token;
6094             };
6095              
6096             inline auto isOptPrefix( char c ) -> bool {
6097             return c == '-'
6098             #ifdef CATCH_PLATFORM_WINDOWS
6099             || c == '/'
6100             #endif
6101             ;
6102             }
6103              
6104             // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
6105             class TokenStream {
6106             using Iterator = std::vector::const_iterator;
6107             Iterator it;
6108             Iterator itEnd;
6109             std::vector m_tokenBuffer;
6110              
6111             void loadBuffer() {
6112             m_tokenBuffer.resize( 0 );
6113              
6114             // Skip any empty strings
6115             while( it != itEnd && it->empty() )
6116             ++it;
6117              
6118             if( it != itEnd ) {
6119             auto const &next = *it;
6120             if( isOptPrefix( next[0] ) ) {
6121             auto delimiterPos = next.find_first_of( " :=" );
6122             if( delimiterPos != std::string::npos ) {
6123             m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
6124             m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
6125             } else {
6126             if( next[1] != '-' && next.size() > 2 ) {
6127             std::string opt = "- ";
6128             for( size_t i = 1; i < next.size(); ++i ) {
6129             opt[1] = next[i];
6130             m_tokenBuffer.push_back( { TokenType::Option, opt } );
6131             }
6132             } else {
6133             m_tokenBuffer.push_back( { TokenType::Option, next } );
6134             }
6135             }
6136             } else {
6137             m_tokenBuffer.push_back( { TokenType::Argument, next } );
6138             }
6139             }
6140             }
6141              
6142             public:
6143             explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
6144              
6145             TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
6146             loadBuffer();
6147             }
6148              
6149             explicit operator bool() const {
6150             return !m_tokenBuffer.empty() || it != itEnd;
6151             }
6152              
6153             auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
6154              
6155             auto operator*() const -> Token {
6156             assert( !m_tokenBuffer.empty() );
6157             return m_tokenBuffer.front();
6158             }
6159              
6160             auto operator->() const -> Token const * {
6161             assert( !m_tokenBuffer.empty() );
6162             return &m_tokenBuffer.front();
6163             }
6164              
6165             auto operator++() -> TokenStream & {
6166             if( m_tokenBuffer.size() >= 2 ) {
6167             m_tokenBuffer.erase( m_tokenBuffer.begin() );
6168             } else {
6169             if( it != itEnd )
6170             ++it;
6171             loadBuffer();
6172             }
6173             return *this;
6174             }
6175             };
6176              
6177             class ResultBase {
6178             public:
6179             enum Type {
6180             Ok, LogicError, RuntimeError
6181             };
6182              
6183             protected:
6184             ResultBase( Type type ) : m_type( type ) {}
6185             virtual ~ResultBase() = default;
6186              
6187             virtual void enforceOk() const = 0;
6188              
6189             Type m_type;
6190             };
6191              
6192             template
6193             class ResultValueBase : public ResultBase {
6194             public:
6195             auto value() const -> T const & {
6196             enforceOk();
6197             return m_value;
6198             }
6199              
6200             protected:
6201             ResultValueBase( Type type ) : ResultBase( type ) {}
6202              
6203             ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
6204             if( m_type == ResultBase::Ok )
6205             new( &m_value ) T( other.m_value );
6206             }
6207              
6208             ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
6209             new( &m_value ) T( value );
6210             }
6211              
6212             auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
6213             if( m_type == ResultBase::Ok )
6214             m_value.~T();
6215             ResultBase::operator=(other);
6216             if( m_type == ResultBase::Ok )
6217             new( &m_value ) T( other.m_value );
6218             return *this;
6219             }
6220              
6221             ~ResultValueBase() override {
6222             if( m_type == Ok )
6223             m_value.~T();
6224             }
6225              
6226             union {
6227             T m_value;
6228             };
6229             };
6230              
6231             template<>
6232             class ResultValueBase : public ResultBase {
6233             protected:
6234             using ResultBase::ResultBase;
6235             };
6236              
6237             template
6238             class BasicResult : public ResultValueBase {
6239             public:
6240             template
6241             explicit BasicResult( BasicResult const &other )
6242             : ResultValueBase( other.type() ),
6243             m_errorMessage( other.errorMessage() )
6244             {
6245             assert( type() != ResultBase::Ok );
6246             }
6247              
6248             template
6249             static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
6250             static auto ok() -> BasicResult { return { ResultBase::Ok }; }
6251             static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
6252             static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
6253              
6254             explicit operator bool() const { return m_type == ResultBase::Ok; }
6255             auto type() const -> ResultBase::Type { return m_type; }
6256             auto errorMessage() const -> std::string { return m_errorMessage; }
6257              
6258             protected:
6259             void enforceOk() const override {
6260              
6261             // Errors shouldn't reach this point, but if they do
6262             // the actual error message will be in m_errorMessage
6263             assert( m_type != ResultBase::LogicError );
6264             assert( m_type != ResultBase::RuntimeError );
6265             if( m_type != ResultBase::Ok )
6266             std::abort();
6267             }
6268              
6269             std::string m_errorMessage; // Only populated if resultType is an error
6270              
6271             BasicResult( ResultBase::Type type, std::string const &message )
6272             : ResultValueBase(type),
6273             m_errorMessage(message)
6274             {
6275             assert( m_type != ResultBase::Ok );
6276             }
6277              
6278             using ResultValueBase::ResultValueBase;
6279             using ResultBase::m_type;
6280             };
6281              
6282             enum class ParseResultType {
6283             Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
6284             };
6285              
6286             class ParseState {
6287             public:
6288              
6289             ParseState( ParseResultType type, TokenStream const &remainingTokens )
6290             : m_type(type),
6291             m_remainingTokens( remainingTokens )
6292             {}
6293              
6294             auto type() const -> ParseResultType { return m_type; }
6295             auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
6296              
6297             private:
6298             ParseResultType m_type;
6299             TokenStream m_remainingTokens;
6300             };
6301              
6302             using Result = BasicResult;
6303             using ParserResult = BasicResult;
6304             using InternalParseResult = BasicResult;
6305              
6306             struct HelpColumns {
6307             std::string left;
6308             std::string right;
6309             };
6310              
6311             template
6312             inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
6313             std::stringstream ss;
6314             ss << source;
6315             ss >> target;
6316             if( ss.fail() )
6317             return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
6318             else
6319             return ParserResult::ok( ParseResultType::Matched );
6320             }
6321             inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
6322             target = source;
6323             return ParserResult::ok( ParseResultType::Matched );
6324             }
6325             inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
6326             std::string srcLC = source;
6327             std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast( ::tolower(c) ); } );
6328             if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
6329             target = true;
6330             else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
6331             target = false;
6332             else
6333             return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
6334             return ParserResult::ok( ParseResultType::Matched );
6335             }
6336             #ifdef CLARA_CONFIG_OPTIONAL_TYPE
6337             template
6338             inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE& target ) -> ParserResult {
6339             T temp;
6340             auto result = convertInto( source, temp );
6341             if( result )
6342             target = std::move(temp);
6343             return result;
6344             }
6345             #endif // CLARA_CONFIG_OPTIONAL_TYPE
6346              
6347             struct NonCopyable {
6348             NonCopyable() = default;
6349             NonCopyable( NonCopyable const & ) = delete;
6350             NonCopyable( NonCopyable && ) = delete;
6351             NonCopyable &operator=( NonCopyable const & ) = delete;
6352             NonCopyable &operator=( NonCopyable && ) = delete;
6353             };
6354              
6355             struct BoundRef : NonCopyable {
6356             virtual ~BoundRef() = default;
6357             virtual auto isContainer() const -> bool { return false; }
6358             virtual auto isFlag() const -> bool { return false; }
6359             };
6360             struct BoundValueRefBase : BoundRef {
6361             virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
6362             };
6363             struct BoundFlagRefBase : BoundRef {
6364             virtual auto setFlag( bool flag ) -> ParserResult = 0;
6365             virtual auto isFlag() const -> bool { return true; }
6366             };
6367              
6368             template
6369             struct BoundValueRef : BoundValueRefBase {
6370             T &m_ref;
6371              
6372             explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
6373              
6374             auto setValue( std::string const &arg ) -> ParserResult override {
6375             return convertInto( arg, m_ref );
6376             }
6377             };
6378              
6379             template
6380             struct BoundValueRef> : BoundValueRefBase {
6381             std::vector &m_ref;
6382              
6383             explicit BoundValueRef( std::vector &ref ) : m_ref( ref ) {}
6384              
6385             auto isContainer() const -> bool override { return true; }
6386              
6387             auto setValue( std::string const &arg ) -> ParserResult override {
6388             T temp;
6389             auto result = convertInto( arg, temp );
6390             if( result )
6391             m_ref.push_back( temp );
6392             return result;
6393             }
6394             };
6395              
6396             struct BoundFlagRef : BoundFlagRefBase {
6397             bool &m_ref;
6398              
6399             explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
6400              
6401             auto setFlag( bool flag ) -> ParserResult override {
6402             m_ref = flag;
6403             return ParserResult::ok( ParseResultType::Matched );
6404             }
6405             };
6406              
6407             template
6408             struct LambdaInvoker {
6409             static_assert( std::is_same::value, "Lambda must return void or clara::ParserResult" );
6410              
6411             template
6412             static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
6413             return lambda( arg );
6414             }
6415             };
6416              
6417             template<>
6418             struct LambdaInvoker {
6419             template
6420             static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
6421             lambda( arg );
6422             return ParserResult::ok( ParseResultType::Matched );
6423             }
6424             };
6425              
6426             template
6427             inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
6428             ArgType temp{};
6429             auto result = convertInto( arg, temp );
6430             return !result
6431             ? result
6432             : LambdaInvoker::ReturnType>::invoke( lambda, temp );
6433             }
6434              
6435             template
6436             struct BoundLambda : BoundValueRefBase {
6437             L m_lambda;
6438              
6439             static_assert( UnaryLambdaTraits::isValid, "Supplied lambda must take exactly one argument" );
6440             explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
6441              
6442             auto setValue( std::string const &arg ) -> ParserResult override {
6443             return invokeLambda::ArgType>( m_lambda, arg );
6444             }
6445             };
6446              
6447             template
6448             struct BoundFlagLambda : BoundFlagRefBase {
6449             L m_lambda;
6450              
6451             static_assert( UnaryLambdaTraits::isValid, "Supplied lambda must take exactly one argument" );
6452             static_assert( std::is_same::ArgType, bool>::value, "flags must be boolean" );
6453              
6454             explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
6455              
6456             auto setFlag( bool flag ) -> ParserResult override {
6457             return LambdaInvoker::ReturnType>::invoke( m_lambda, flag );
6458             }
6459             };
6460              
6461             enum class Optionality { Optional, Required };
6462              
6463             struct Parser;
6464              
6465             class ParserBase {
6466             public:
6467             virtual ~ParserBase() = default;
6468             virtual auto validate() const -> Result { return Result::ok(); }
6469             virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0;
6470             virtual auto cardinality() const -> size_t { return 1; }
6471              
6472             auto parse( Args const &args ) const -> InternalParseResult {
6473             return parse( args.exeName(), TokenStream( args ) );
6474             }
6475             };
6476              
6477             template
6478             class ComposableParserImpl : public ParserBase {
6479             public:
6480             template
6481             auto operator|( T const &other ) const -> Parser;
6482              
6483             template
6484             auto operator+( T const &other ) const -> Parser;
6485             };
6486              
6487             // Common code and state for Args and Opts
6488             template
6489             class ParserRefImpl : public ComposableParserImpl {
6490             protected:
6491             Optionality m_optionality = Optionality::Optional;
6492             std::shared_ptr m_ref;
6493             std::string m_hint;
6494             std::string m_description;
6495              
6496             explicit ParserRefImpl( std::shared_ptr const &ref ) : m_ref( ref ) {}
6497              
6498             public:
6499             template
6500             ParserRefImpl( T &ref, std::string const &hint )
6501             : m_ref( std::make_shared>( ref ) ),
6502             m_hint( hint )
6503             {}
6504              
6505             template
6506             ParserRefImpl( LambdaT const &ref, std::string const &hint )
6507             : m_ref( std::make_shared>( ref ) ),
6508             m_hint(hint)
6509             {}
6510              
6511             auto operator()( std::string const &description ) -> DerivedT & {
6512             m_description = description;
6513             return static_cast( *this );
6514             }
6515              
6516             auto optional() -> DerivedT & {
6517             m_optionality = Optionality::Optional;
6518             return static_cast( *this );
6519             };
6520              
6521             auto required() -> DerivedT & {
6522             m_optionality = Optionality::Required;
6523             return static_cast( *this );
6524             };
6525              
6526             auto isOptional() const -> bool {
6527             return m_optionality == Optionality::Optional;
6528             }
6529              
6530             auto cardinality() const -> size_t override {
6531             if( m_ref->isContainer() )
6532             return 0;
6533             else
6534             return 1;
6535             }
6536              
6537             auto hint() const -> std::string { return m_hint; }
6538             };
6539              
6540             class ExeName : public ComposableParserImpl {
6541             std::shared_ptr m_name;
6542             std::shared_ptr m_ref;
6543              
6544             template
6545             static auto makeRef(LambdaT const &lambda) -> std::shared_ptr {
6546             return std::make_shared>( lambda) ;
6547             }
6548              
6549             public:
6550             ExeName() : m_name( std::make_shared( "" ) ) {}
6551              
6552             explicit ExeName( std::string &ref ) : ExeName() {
6553             m_ref = std::make_shared>( ref );
6554             }
6555              
6556             template
6557             explicit ExeName( LambdaT const& lambda ) : ExeName() {
6558             m_ref = std::make_shared>( lambda );
6559             }
6560              
6561             // The exe name is not parsed out of the normal tokens, but is handled specially
6562             auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
6563             return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
6564             }
6565              
6566             auto name() const -> std::string { return *m_name; }
6567             auto set( std::string const& newName ) -> ParserResult {
6568              
6569             auto lastSlash = newName.find_last_of( "\\/" );
6570             auto filename = ( lastSlash == std::string::npos )
6571             ? newName
6572             : newName.substr( lastSlash+1 );
6573              
6574             *m_name = filename;
6575             if( m_ref )
6576             return m_ref->setValue( filename );
6577             else
6578             return ParserResult::ok( ParseResultType::Matched );
6579             }
6580             };
6581              
6582             class Arg : public ParserRefImpl {
6583             public:
6584             using ParserRefImpl::ParserRefImpl;
6585              
6586             auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
6587             auto validationResult = validate();
6588             if( !validationResult )
6589             return InternalParseResult( validationResult );
6590              
6591             auto remainingTokens = tokens;
6592             auto const &token = *remainingTokens;
6593             if( token.type != TokenType::Argument )
6594             return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
6595              
6596             assert( !m_ref->isFlag() );
6597             auto valueRef = static_cast( m_ref.get() );
6598              
6599             auto result = valueRef->setValue( remainingTokens->token );
6600             if( !result )
6601             return InternalParseResult( result );
6602             else
6603             return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
6604             }
6605             };
6606              
6607             inline auto normaliseOpt( std::string const &optName ) -> std::string {
6608             #ifdef CATCH_PLATFORM_WINDOWS
6609             if( optName[0] == '/' )
6610             return "-" + optName.substr( 1 );
6611             else
6612             #endif
6613             return optName;
6614             }
6615              
6616             class Opt : public ParserRefImpl {
6617             protected:
6618             std::vector m_optNames;
6619              
6620             public:
6621             template
6622             explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared>( ref ) ) {}
6623              
6624             explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared( ref ) ) {}
6625              
6626             template
6627             Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
6628              
6629             template
6630             Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
6631              
6632             auto operator[]( std::string const &optName ) -> Opt & {
6633             m_optNames.push_back( optName );
6634             return *this;
6635             }
6636              
6637             auto getHelpColumns() const -> std::vector {
6638             std::ostringstream oss;
6639             bool first = true;
6640             for( auto const &opt : m_optNames ) {
6641             if (first)
6642             first = false;
6643             else
6644             oss << ", ";
6645             oss << opt;
6646             }
6647             if( !m_hint.empty() )
6648             oss << " <" << m_hint << ">";
6649             return { { oss.str(), m_description } };
6650             }
6651              
6652             auto isMatch( std::string const &optToken ) const -> bool {
6653             auto normalisedToken = normaliseOpt( optToken );
6654             for( auto const &name : m_optNames ) {
6655             if( normaliseOpt( name ) == normalisedToken )
6656             return true;
6657             }
6658             return false;
6659             }
6660              
6661             using ParserBase::parse;
6662              
6663             auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
6664             auto validationResult = validate();
6665             if( !validationResult )
6666             return InternalParseResult( validationResult );
6667              
6668             auto remainingTokens = tokens;
6669             if( remainingTokens && remainingTokens->type == TokenType::Option ) {
6670             auto const &token = *remainingTokens;
6671             if( isMatch(token.token ) ) {
6672             if( m_ref->isFlag() ) {
6673             auto flagRef = static_cast( m_ref.get() );
6674             auto result = flagRef->setFlag( true );
6675             if( !result )
6676             return InternalParseResult( result );
6677             if( result.value() == ParseResultType::ShortCircuitAll )
6678             return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
6679             } else {
6680             auto valueRef = static_cast( m_ref.get() );
6681             ++remainingTokens;
6682             if( !remainingTokens )
6683             return InternalParseResult::runtimeError( "Expected argument following " + token.token );
6684             auto const &argToken = *remainingTokens;
6685             if( argToken.type != TokenType::Argument )
6686             return InternalParseResult::runtimeError( "Expected argument following " + token.token );
6687             auto result = valueRef->setValue( argToken.token );
6688             if( !result )
6689             return InternalParseResult( result );
6690             if( result.value() == ParseResultType::ShortCircuitAll )
6691             return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
6692             }
6693             return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
6694             }
6695             }
6696             return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
6697             }
6698              
6699             auto validate() const -> Result override {
6700             if( m_optNames.empty() )
6701             return Result::logicError( "No options supplied to Opt" );
6702             for( auto const &name : m_optNames ) {
6703             if( name.empty() )
6704             return Result::logicError( "Option name cannot be empty" );
6705             #ifdef CATCH_PLATFORM_WINDOWS
6706             if( name[0] != '-' && name[0] != '/' )
6707             return Result::logicError( "Option name must begin with '-' or '/'" );
6708             #else
6709             if( name[0] != '-' )
6710             return Result::logicError( "Option name must begin with '-'" );
6711             #endif
6712             }
6713             return ParserRefImpl::validate();
6714             }
6715             };
6716              
6717             struct Help : Opt {
6718             Help( bool &showHelpFlag )
6719             : Opt([&]( bool flag ) {
6720             showHelpFlag = flag;
6721             return ParserResult::ok( ParseResultType::ShortCircuitAll );
6722             })
6723             {
6724             static_cast( *this )
6725             ("display usage information")
6726             ["-?"]["-h"]["--help"]
6727             .optional();
6728             }
6729             };
6730              
6731             struct Parser : ParserBase {
6732              
6733             mutable ExeName m_exeName;
6734             std::vector m_options;
6735             std::vector m_args;
6736              
6737             auto operator|=( ExeName const &exeName ) -> Parser & {
6738             m_exeName = exeName;
6739             return *this;
6740             }
6741              
6742             auto operator|=( Arg const &arg ) -> Parser & {
6743             m_args.push_back(arg);
6744             return *this;
6745             }
6746              
6747             auto operator|=( Opt const &opt ) -> Parser & {
6748             m_options.push_back(opt);
6749             return *this;
6750             }
6751              
6752             auto operator|=( Parser const &other ) -> Parser & {
6753             m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
6754             m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
6755             return *this;
6756             }
6757              
6758             template
6759             auto operator|( T const &other ) const -> Parser {
6760             return Parser( *this ) |= other;
6761             }
6762              
6763             // Forward deprecated interface with '+' instead of '|'
6764             template
6765             auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
6766             template
6767             auto operator+( T const &other ) const -> Parser { return operator|( other ); }
6768              
6769             auto getHelpColumns() const -> std::vector {
6770             std::vector cols;
6771             for (auto const &o : m_options) {
6772             auto childCols = o.getHelpColumns();
6773             cols.insert( cols.end(), childCols.begin(), childCols.end() );
6774             }
6775             return cols;
6776             }
6777              
6778             void writeToStream( std::ostream &os ) const {
6779             if (!m_exeName.name().empty()) {
6780             os << "usage:\n" << " " << m_exeName.name() << " ";
6781             bool required = true, first = true;
6782             for( auto const &arg : m_args ) {
6783             if (first)
6784             first = false;
6785             else
6786             os << " ";
6787             if( arg.isOptional() && required ) {
6788             os << "[";
6789             required = false;
6790             }
6791             os << "<" << arg.hint() << ">";
6792             if( arg.cardinality() == 0 )
6793             os << " ... ";
6794             }
6795             if( !required )
6796             os << "]";
6797             if( !m_options.empty() )
6798             os << " options";
6799             os << "\n\nwhere options are:" << std::endl;
6800             }
6801              
6802             auto rows = getHelpColumns();
6803             size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
6804             size_t optWidth = 0;
6805             for( auto const &cols : rows )
6806             optWidth = (std::max)(optWidth, cols.left.size() + 2);
6807              
6808             optWidth = (std::min)(optWidth, consoleWidth/2);
6809              
6810             for( auto const &cols : rows ) {
6811             auto row =
6812             TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
6813             TextFlow::Spacer(4) +
6814             TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
6815             os << row << std::endl;
6816             }
6817             }
6818              
6819             friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
6820             parser.writeToStream( os );
6821             return os;
6822             }
6823              
6824             auto validate() const -> Result override {
6825             for( auto const &opt : m_options ) {
6826             auto result = opt.validate();
6827             if( !result )
6828             return result;
6829             }
6830             for( auto const &arg : m_args ) {
6831             auto result = arg.validate();
6832             if( !result )
6833             return result;
6834             }
6835             return Result::ok();
6836             }
6837              
6838             using ParserBase::parse;
6839              
6840             auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
6841              
6842             struct ParserInfo {
6843             ParserBase const* parser = nullptr;
6844             size_t count = 0;
6845             };
6846             const size_t totalParsers = m_options.size() + m_args.size();
6847             assert( totalParsers < 512 );
6848             // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
6849             ParserInfo parseInfos[512];
6850              
6851             {
6852             size_t i = 0;
6853             for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
6854             for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
6855             }
6856              
6857             m_exeName.set( exeName );
6858              
6859             auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
6860             while( result.value().remainingTokens() ) {
6861             bool tokenParsed = false;
6862              
6863             for( size_t i = 0; i < totalParsers; ++i ) {
6864             auto& parseInfo = parseInfos[i];
6865             if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
6866             result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
6867             if (!result)
6868             return result;
6869             if (result.value().type() != ParseResultType::NoMatch) {
6870             tokenParsed = true;
6871             ++parseInfo.count;
6872             break;
6873             }
6874             }
6875             }
6876              
6877             if( result.value().type() == ParseResultType::ShortCircuitAll )
6878             return result;
6879             if( !tokenParsed )
6880             return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
6881             }
6882             // !TBD Check missing required options
6883             return result;
6884             }
6885             };
6886              
6887             template
6888             template
6889             auto ComposableParserImpl::operator|( T const &other ) const -> Parser {
6890             return Parser() | static_cast( *this ) | other;
6891             }
6892             } // namespace detail
6893              
6894             // A Combined parser
6895             using detail::Parser;
6896              
6897             // A parser for options
6898             using detail::Opt;
6899              
6900             // A parser for arguments
6901             using detail::Arg;
6902              
6903             // Wrapper for argc, argv from main()
6904             using detail::Args;
6905              
6906             // Specifies the name of the executable
6907             using detail::ExeName;
6908              
6909             // Convenience wrapper for option parser that specifies the help option
6910             using detail::Help;
6911              
6912             // enum of result types from a parse
6913             using detail::ParseResultType;
6914              
6915             // Result type for parser operation
6916             using detail::ParserResult;
6917              
6918             }} // namespace Catch::clara
6919              
6920             // end clara.hpp
6921             #ifdef __clang__
6922             #pragma clang diagnostic pop
6923             #endif
6924              
6925             // Restore Clara's value for console width, if present
6926             #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
6927             #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
6928             #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
6929             #endif
6930              
6931             // end catch_clara.h
6932             namespace Catch {
6933              
6934             clara::Parser makeCommandLineParser( ConfigData& config );
6935              
6936             } // end namespace Catch
6937              
6938             // end catch_commandline.h
6939             #include
6940             #include
6941              
6942             namespace Catch {
6943              
6944             clara::Parser makeCommandLineParser( ConfigData& config ) {
6945              
6946             using namespace clara;
6947              
6948             auto const setWarning = [&]( std::string const& warning ) {
6949             auto warningSet = [&]() {
6950             if( warning == "NoAssertions" )
6951             return WarnAbout::NoAssertions;
6952              
6953             if ( warning == "NoTests" )
6954             return WarnAbout::NoTests;
6955              
6956             return WarnAbout::Nothing;
6957             }();
6958              
6959             if (warningSet == WarnAbout::Nothing)
6960             return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
6961             config.warnings = static_cast( config.warnings | warningSet );
6962             return ParserResult::ok( ParseResultType::Matched );
6963             };
6964             auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
6965             std::ifstream f( filename.c_str() );
6966             if( !f.is_open() )
6967             return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
6968              
6969             std::string line;
6970             while( std::getline( f, line ) ) {
6971             line = trim(line);
6972             if( !line.empty() && !startsWith( line, '#' ) ) {
6973             if( !startsWith( line, '"' ) )
6974             line = '"' + line + '"';
6975             config.testsOrTags.push_back( line + ',' );
6976             }
6977             }
6978             return ParserResult::ok( ParseResultType::Matched );
6979             };
6980             auto const setTestOrder = [&]( std::string const& order ) {
6981             if( startsWith( "declared", order ) )
6982             config.runOrder = RunTests::InDeclarationOrder;
6983             else if( startsWith( "lexical", order ) )
6984             config.runOrder = RunTests::InLexicographicalOrder;
6985             else if( startsWith( "random", order ) )
6986             config.runOrder = RunTests::InRandomOrder;
6987             else
6988             return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
6989             return ParserResult::ok( ParseResultType::Matched );
6990             };
6991             auto const setRngSeed = [&]( std::string const& seed ) {
6992             if( seed != "time" )
6993             return clara::detail::convertInto( seed, config.rngSeed );
6994             config.rngSeed = static_cast( std::time(nullptr) );
6995             return ParserResult::ok( ParseResultType::Matched );
6996             };
6997             auto const setColourUsage = [&]( std::string const& useColour ) {
6998             auto mode = toLower( useColour );
6999              
7000             if( mode == "yes" )
7001             config.useColour = UseColour::Yes;
7002             else if( mode == "no" )
7003             config.useColour = UseColour::No;
7004             else if( mode == "auto" )
7005             config.useColour = UseColour::Auto;
7006             else
7007             return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
7008             return ParserResult::ok( ParseResultType::Matched );
7009             };
7010             auto const setWaitForKeypress = [&]( std::string const& keypress ) {
7011             auto keypressLc = toLower( keypress );
7012             if( keypressLc == "start" )
7013             config.waitForKeypress = WaitForKeypress::BeforeStart;
7014             else if( keypressLc == "exit" )
7015             config.waitForKeypress = WaitForKeypress::BeforeExit;
7016             else if( keypressLc == "both" )
7017             config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
7018             else
7019             return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
7020             return ParserResult::ok( ParseResultType::Matched );
7021             };
7022             auto const setVerbosity = [&]( std::string const& verbosity ) {
7023             auto lcVerbosity = toLower( verbosity );
7024             if( lcVerbosity == "quiet" )
7025             config.verbosity = Verbosity::Quiet;
7026             else if( lcVerbosity == "normal" )
7027             config.verbosity = Verbosity::Normal;
7028             else if( lcVerbosity == "high" )
7029             config.verbosity = Verbosity::High;
7030             else
7031             return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
7032             return ParserResult::ok( ParseResultType::Matched );
7033             };
7034              
7035             auto cli
7036             = ExeName( config.processName )
7037             | Help( config.showHelp )
7038             | Opt( config.listTests )
7039             ["-l"]["--list-tests"]
7040             ( "list all/matching test cases" )
7041             | Opt( config.listTags )
7042             ["-t"]["--list-tags"]
7043             ( "list all/matching tags" )
7044             | Opt( config.showSuccessfulTests )
7045             ["-s"]["--success"]
7046             ( "include successful tests in output" )
7047             | Opt( config.shouldDebugBreak )
7048             ["-b"]["--break"]
7049             ( "break into debugger on failure" )
7050             | Opt( config.noThrow )
7051             ["-e"]["--nothrow"]
7052             ( "skip exception tests" )
7053             | Opt( config.showInvisibles )
7054             ["-i"]["--invisibles"]
7055             ( "show invisibles (tabs, newlines)" )
7056             | Opt( config.outputFilename, "filename" )
7057             ["-o"]["--out"]
7058             ( "output filename" )
7059             | Opt( config.reporterName, "name" )
7060             ["-r"]["--reporter"]
7061             ( "reporter to use (defaults to console)" )
7062             | Opt( config.name, "name" )
7063             ["-n"]["--name"]
7064             ( "suite name" )
7065             | Opt( [&]( bool ){ config.abortAfter = 1; } )
7066             ["-a"]["--abort"]
7067             ( "abort at first failure" )
7068             | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
7069             ["-x"]["--abortx"]
7070             ( "abort after x failures" )
7071             | Opt( setWarning, "warning name" )
7072             ["-w"]["--warn"]
7073             ( "enable warnings" )
7074             | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
7075             ["-d"]["--durations"]
7076             ( "show test durations" )
7077             | Opt( loadTestNamesFromFile, "filename" )
7078             ["-f"]["--input-file"]
7079             ( "load test names to run from a file" )
7080             | Opt( config.filenamesAsTags )
7081             ["-#"]["--filenames-as-tags"]
7082             ( "adds a tag for the filename" )
7083             | Opt( config.sectionsToRun, "section name" )
7084             ["-c"]["--section"]
7085             ( "specify section to run" )
7086             | Opt( setVerbosity, "quiet|normal|high" )
7087             ["-v"]["--verbosity"]
7088             ( "set output verbosity" )
7089             | Opt( config.listTestNamesOnly )
7090             ["--list-test-names-only"]
7091             ( "list all/matching test cases names only" )
7092             | Opt( config.listReporters )
7093             ["--list-reporters"]
7094             ( "list all reporters" )
7095             | Opt( setTestOrder, "decl|lex|rand" )
7096             ["--order"]
7097             ( "test case order (defaults to decl)" )
7098             | Opt( setRngSeed, "'time'|number" )
7099             ["--rng-seed"]
7100             ( "set a specific seed for random numbers" )
7101             | Opt( setColourUsage, "yes|no" )
7102             ["--use-colour"]
7103             ( "should output be colourised" )
7104             | Opt( config.libIdentify )
7105             ["--libidentify"]
7106             ( "report name and version according to libidentify standard" )
7107             | Opt( setWaitForKeypress, "start|exit|both" )
7108             ["--wait-for-keypress"]
7109             ( "waits for a keypress before exiting" )
7110             | Opt( config.benchmarkResolutionMultiple, "multiplier" )
7111             ["--benchmark-resolution-multiple"]
7112             ( "multiple of clock resolution to run benchmarks" )
7113              
7114             | Arg( config.testsOrTags, "test name|pattern|tags" )
7115             ( "which test or tests to use" );
7116              
7117             return cli;
7118             }
7119              
7120             } // end namespace Catch
7121             // end catch_commandline.cpp
7122             // start catch_common.cpp
7123              
7124             #include
7125             #include
7126              
7127             namespace Catch {
7128              
7129             bool SourceLineInfo::empty() const noexcept {
7130             return file[0] == '\0';
7131             }
7132             bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
7133             return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
7134             }
7135             bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
7136             // We can assume that the same file will usually have the same pointer.
7137             // Thus, if the pointers are the same, there is no point in calling the strcmp
7138             return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
7139             }
7140              
7141             std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
7142             #ifndef __GNUG__
7143             os << info.file << '(' << info.line << ')';
7144             #else
7145             os << info.file << ':' << info.line;
7146             #endif
7147             return os;
7148             }
7149              
7150             std::string StreamEndStop::operator+() const {
7151             return std::string();
7152             }
7153              
7154             NonCopyable::NonCopyable() = default;
7155             NonCopyable::~NonCopyable() = default;
7156              
7157             }
7158             // end catch_common.cpp
7159             // start catch_config.cpp
7160              
7161             namespace Catch {
7162              
7163             Config::Config( ConfigData const& data )
7164             : m_data( data ),
7165             m_stream( openStream() )
7166             {
7167             TestSpecParser parser(ITagAliasRegistry::get());
7168             if (data.testsOrTags.empty()) {
7169             parser.parse("~[.]"); // All not hidden tests
7170             }
7171             else {
7172             m_hasTestFilters = true;
7173             for( auto const& testOrTags : data.testsOrTags )
7174             parser.parse( testOrTags );
7175             }
7176             m_testSpec = parser.testSpec();
7177             }
7178              
7179             std::string const& Config::getFilename() const {
7180             return m_data.outputFilename ;
7181             }
7182              
7183             bool Config::listTests() const { return m_data.listTests; }
7184             bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
7185             bool Config::listTags() const { return m_data.listTags; }
7186             bool Config::listReporters() const { return m_data.listReporters; }
7187              
7188             std::string Config::getProcessName() const { return m_data.processName; }
7189             std::string const& Config::getReporterName() const { return m_data.reporterName; }
7190              
7191             std::vector const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
7192             std::vector const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
7193              
7194             TestSpec const& Config::testSpec() const { return m_testSpec; }
7195             bool Config::hasTestFilters() const { return m_hasTestFilters; }
7196              
7197             bool Config::showHelp() const { return m_data.showHelp; }
7198              
7199             // IConfig interface
7200             bool Config::allowThrows() const { return !m_data.noThrow; }
7201             std::ostream& Config::stream() const { return m_stream->stream(); }
7202             std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
7203             bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
7204             bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
7205             bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
7206             ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
7207             RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
7208             unsigned int Config::rngSeed() const { return m_data.rngSeed; }
7209             int Config::benchmarkResolutionMultiple() const { return m_data.benchmarkResolutionMultiple; }
7210             UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
7211             bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
7212             int Config::abortAfter() const { return m_data.abortAfter; }
7213             bool Config::showInvisibles() const { return m_data.showInvisibles; }
7214             Verbosity Config::verbosity() const { return m_data.verbosity; }
7215              
7216             IStream const* Config::openStream() {
7217             return Catch::makeStream(m_data.outputFilename);
7218             }
7219              
7220             } // end namespace Catch
7221             // end catch_config.cpp
7222             // start catch_console_colour.cpp
7223              
7224             #if defined(__clang__)
7225             # pragma clang diagnostic push
7226             # pragma clang diagnostic ignored "-Wexit-time-destructors"
7227             #endif
7228              
7229             // start catch_errno_guard.h
7230              
7231             namespace Catch {
7232              
7233             class ErrnoGuard {
7234             public:
7235             ErrnoGuard();
7236             ~ErrnoGuard();
7237             private:
7238             int m_oldErrno;
7239             };
7240              
7241             }
7242              
7243             // end catch_errno_guard.h
7244             #include
7245              
7246             namespace Catch {
7247             namespace {
7248              
7249             struct IColourImpl {
7250             virtual ~IColourImpl() = default;
7251             virtual void use( Colour::Code _colourCode ) = 0;
7252             };
7253              
7254             struct NoColourImpl : IColourImpl {
7255             void use( Colour::Code ) {}
7256              
7257             static IColourImpl* instance() {
7258             static NoColourImpl s_instance;
7259             return &s_instance;
7260             }
7261             };
7262              
7263             } // anon namespace
7264             } // namespace Catch
7265              
7266             #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
7267             # ifdef CATCH_PLATFORM_WINDOWS
7268             # define CATCH_CONFIG_COLOUR_WINDOWS
7269             # else
7270             # define CATCH_CONFIG_COLOUR_ANSI
7271             # endif
7272             #endif
7273              
7274             #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
7275              
7276             namespace Catch {
7277             namespace {
7278              
7279             class Win32ColourImpl : public IColourImpl {
7280             public:
7281             Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
7282             {
7283             CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
7284             GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
7285             originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
7286             originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
7287             }
7288              
7289             virtual void use( Colour::Code _colourCode ) override {
7290             switch( _colourCode ) {
7291             case Colour::None: return setTextAttribute( originalForegroundAttributes );
7292             case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7293             case Colour::Red: return setTextAttribute( FOREGROUND_RED );
7294             case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
7295             case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
7296             case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
7297             case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
7298             case Colour::Grey: return setTextAttribute( 0 );
7299              
7300             case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
7301             case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
7302             case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
7303             case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7304             case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
7305              
7306             case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
7307              
7308             default:
7309             CATCH_ERROR( "Unknown colour requested" );
7310             }
7311             }
7312              
7313             private:
7314             void setTextAttribute( WORD _textAttribute ) {
7315             SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
7316             }
7317             HANDLE stdoutHandle;
7318             WORD originalForegroundAttributes;
7319             WORD originalBackgroundAttributes;
7320             };
7321              
7322             IColourImpl* platformColourInstance() {
7323             static Win32ColourImpl s_instance;
7324              
7325             IConfigPtr config = getCurrentContext().getConfig();
7326             UseColour::YesOrNo colourMode = config
7327             ? config->useColour()
7328             : UseColour::Auto;
7329             if( colourMode == UseColour::Auto )
7330             colourMode = UseColour::Yes;
7331             return colourMode == UseColour::Yes
7332             ? &s_instance
7333             : NoColourImpl::instance();
7334             }
7335              
7336             } // end anon namespace
7337             } // end namespace Catch
7338              
7339             #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
7340              
7341             #include
7342              
7343             namespace Catch {
7344             namespace {
7345              
7346             // use POSIX/ ANSI console terminal codes
7347             // Thanks to Adam Strzelecki for original contribution
7348             // (http://github.com/nanoant)
7349             // https://github.com/philsquared/Catch/pull/131
7350             class PosixColourImpl : public IColourImpl {
7351             public:
7352             virtual void use( Colour::Code _colourCode ) override {
7353             switch( _colourCode ) {
7354             case Colour::None:
7355             case Colour::White: return setColour( "[0m" );
7356             case Colour::Red: return setColour( "[0;31m" );
7357             case Colour::Green: return setColour( "[0;32m" );
7358             case Colour::Blue: return setColour( "[0;34m" );
7359             case Colour::Cyan: return setColour( "[0;36m" );
7360             case Colour::Yellow: return setColour( "[0;33m" );
7361             case Colour::Grey: return setColour( "[1;30m" );
7362              
7363             case Colour::LightGrey: return setColour( "[0;37m" );
7364             case Colour::BrightRed: return setColour( "[1;31m" );
7365             case Colour::BrightGreen: return setColour( "[1;32m" );
7366             case Colour::BrightWhite: return setColour( "[1;37m" );
7367             case Colour::BrightYellow: return setColour( "[1;33m" );
7368              
7369             case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
7370             default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
7371             }
7372             }
7373             static IColourImpl* instance() {
7374             static PosixColourImpl s_instance;
7375             return &s_instance;
7376             }
7377              
7378             private:
7379             void setColour( const char* _escapeCode ) {
7380             Catch::cout() << '\033' << _escapeCode;
7381             }
7382             };
7383              
7384             bool useColourOnPlatform() {
7385             return
7386             #ifdef CATCH_PLATFORM_MAC
7387             !isDebuggerActive() &&
7388             #endif
7389             #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
7390             isatty(STDOUT_FILENO)
7391             #else
7392             false
7393             #endif
7394             ;
7395             }
7396             IColourImpl* platformColourInstance() {
7397             ErrnoGuard guard;
7398             IConfigPtr config = getCurrentContext().getConfig();
7399             UseColour::YesOrNo colourMode = config
7400             ? config->useColour()
7401             : UseColour::Auto;
7402             if( colourMode == UseColour::Auto )
7403             colourMode = useColourOnPlatform()
7404             ? UseColour::Yes
7405             : UseColour::No;
7406             return colourMode == UseColour::Yes
7407             ? PosixColourImpl::instance()
7408             : NoColourImpl::instance();
7409             }
7410              
7411             } // end anon namespace
7412             } // end namespace Catch
7413              
7414             #else // not Windows or ANSI ///////////////////////////////////////////////
7415              
7416             namespace Catch {
7417              
7418             static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
7419              
7420             } // end namespace Catch
7421              
7422             #endif // Windows/ ANSI/ None
7423              
7424             namespace Catch {
7425              
7426             Colour::Colour( Code _colourCode ) { use( _colourCode ); }
7427             Colour::Colour( Colour&& rhs ) noexcept {
7428             m_moved = rhs.m_moved;
7429             rhs.m_moved = true;
7430             }
7431             Colour& Colour::operator=( Colour&& rhs ) noexcept {
7432             m_moved = rhs.m_moved;
7433             rhs.m_moved = true;
7434             return *this;
7435             }
7436              
7437             Colour::~Colour(){ if( !m_moved ) use( None ); }
7438              
7439             void Colour::use( Code _colourCode ) {
7440             static IColourImpl* impl = platformColourInstance();
7441             impl->use( _colourCode );
7442             }
7443              
7444             std::ostream& operator << ( std::ostream& os, Colour const& ) {
7445             return os;
7446             }
7447              
7448             } // end namespace Catch
7449              
7450             #if defined(__clang__)
7451             # pragma clang diagnostic pop
7452             #endif
7453              
7454             // end catch_console_colour.cpp
7455             // start catch_context.cpp
7456              
7457             namespace Catch {
7458              
7459             class Context : public IMutableContext, NonCopyable {
7460              
7461             public: // IContext
7462             virtual IResultCapture* getResultCapture() override {
7463             return m_resultCapture;
7464             }
7465             virtual IRunner* getRunner() override {
7466             return m_runner;
7467             }
7468              
7469             virtual IConfigPtr const& getConfig() const override {
7470             return m_config;
7471             }
7472              
7473             virtual ~Context() override;
7474              
7475             public: // IMutableContext
7476             virtual void setResultCapture( IResultCapture* resultCapture ) override {
7477             m_resultCapture = resultCapture;
7478             }
7479             virtual void setRunner( IRunner* runner ) override {
7480             m_runner = runner;
7481             }
7482             virtual void setConfig( IConfigPtr const& config ) override {
7483             m_config = config;
7484             }
7485              
7486             friend IMutableContext& getCurrentMutableContext();
7487              
7488             private:
7489             IConfigPtr m_config;
7490             IRunner* m_runner = nullptr;
7491             IResultCapture* m_resultCapture = nullptr;
7492             };
7493              
7494             IMutableContext *IMutableContext::currentContext = nullptr;
7495              
7496             void IMutableContext::createContext()
7497             {
7498             currentContext = new Context();
7499             }
7500              
7501             void cleanUpContext() {
7502             delete IMutableContext::currentContext;
7503             IMutableContext::currentContext = nullptr;
7504             }
7505             IContext::~IContext() = default;
7506             IMutableContext::~IMutableContext() = default;
7507             Context::~Context() = default;
7508             }
7509             // end catch_context.cpp
7510             // start catch_debug_console.cpp
7511              
7512             // start catch_debug_console.h
7513              
7514             #include
7515              
7516             namespace Catch {
7517             void writeToDebugConsole( std::string const& text );
7518             }
7519              
7520             // end catch_debug_console.h
7521             #ifdef CATCH_PLATFORM_WINDOWS
7522              
7523             namespace Catch {
7524             void writeToDebugConsole( std::string const& text ) {
7525             ::OutputDebugStringA( text.c_str() );
7526             }
7527             }
7528              
7529             #else
7530              
7531             namespace Catch {
7532             void writeToDebugConsole( std::string const& text ) {
7533             // !TBD: Need a version for Mac/ XCode and other IDEs
7534             Catch::cout() << text;
7535             }
7536             }
7537              
7538             #endif // Platform
7539             // end catch_debug_console.cpp
7540             // start catch_debugger.cpp
7541              
7542             #ifdef CATCH_PLATFORM_MAC
7543              
7544             # include
7545             # include
7546             # include
7547             # include
7548             # include
7549             # include
7550             # include
7551              
7552             namespace Catch {
7553              
7554             // The following function is taken directly from the following technical note:
7555             // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
7556              
7557             // Returns true if the current process is being debugged (either
7558             // running under the debugger or has a debugger attached post facto).
7559             bool isDebuggerActive(){
7560              
7561             int mib[4];
7562             struct kinfo_proc info;
7563             std::size_t size;
7564              
7565             // Initialize the flags so that, if sysctl fails for some bizarre
7566             // reason, we get a predictable result.
7567              
7568             info.kp_proc.p_flag = 0;
7569              
7570             // Initialize mib, which tells sysctl the info we want, in this case
7571             // we're looking for information about a specific process ID.
7572              
7573             mib[0] = CTL_KERN;
7574             mib[1] = KERN_PROC;
7575             mib[2] = KERN_PROC_PID;
7576             mib[3] = getpid();
7577              
7578             // Call sysctl.
7579              
7580             size = sizeof(info);
7581             if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
7582             Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
7583             return false;
7584             }
7585              
7586             // We're being debugged if the P_TRACED flag is set.
7587              
7588             return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
7589             }
7590             } // namespace Catch
7591              
7592             #elif defined(CATCH_PLATFORM_LINUX)
7593             #include
7594             #include
7595              
7596             namespace Catch{
7597             // The standard POSIX way of detecting a debugger is to attempt to
7598             // ptrace() the process, but this needs to be done from a child and not
7599             // this process itself to still allow attaching to this process later
7600             // if wanted, so is rather heavy. Under Linux we have the PID of the
7601             // "debugger" (which doesn't need to be gdb, of course, it could also
7602             // be strace, for example) in /proc/$PID/status, so just get it from
7603             // there instead.
7604             bool isDebuggerActive(){
7605             // Libstdc++ has a bug, where std::ifstream sets errno to 0
7606             // This way our users can properly assert over errno values
7607             ErrnoGuard guard;
7608             std::ifstream in("/proc/self/status");
7609             for( std::string line; std::getline(in, line); ) {
7610             static const int PREFIX_LEN = 11;
7611             if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
7612             // We're traced if the PID is not 0 and no other PID starts
7613             // with 0 digit, so it's enough to check for just a single
7614             // character.
7615             return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
7616             }
7617             }
7618              
7619             return false;
7620             }
7621             } // namespace Catch
7622             #elif defined(_MSC_VER)
7623             extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7624             namespace Catch {
7625             bool isDebuggerActive() {
7626             return IsDebuggerPresent() != 0;
7627             }
7628             }
7629             #elif defined(__MINGW32__)
7630             extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7631             namespace Catch {
7632             bool isDebuggerActive() {
7633             return IsDebuggerPresent() != 0;
7634             }
7635             }
7636             #else
7637             namespace Catch {
7638             bool isDebuggerActive() { return false; }
7639             }
7640             #endif // Platform
7641             // end catch_debugger.cpp
7642             // start catch_decomposer.cpp
7643              
7644             namespace Catch {
7645              
7646             ITransientExpression::~ITransientExpression() = default;
7647              
7648             void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
7649             if( lhs.size() + rhs.size() < 40 &&
7650             lhs.find('\n') == std::string::npos &&
7651             rhs.find('\n') == std::string::npos )
7652             os << lhs << " " << op << " " << rhs;
7653             else
7654             os << lhs << "\n" << op << "\n" << rhs;
7655             }
7656             }
7657             // end catch_decomposer.cpp
7658             // start catch_enforce.cpp
7659              
7660             namespace Catch {
7661             #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
7662             [[noreturn]]
7663             void throw_exception(std::exception const& e) {
7664             Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
7665             << "The message was: " << e.what() << '\n';
7666             std::terminate();
7667             }
7668             #endif
7669             } // namespace Catch;
7670             // end catch_enforce.cpp
7671             // start catch_errno_guard.cpp
7672              
7673             #include
7674              
7675             namespace Catch {
7676             ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
7677             ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
7678             }
7679             // end catch_errno_guard.cpp
7680             // start catch_exception_translator_registry.cpp
7681              
7682             // start catch_exception_translator_registry.h
7683              
7684             #include
7685             #include
7686             #include
7687              
7688             namespace Catch {
7689              
7690             class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
7691             public:
7692             ~ExceptionTranslatorRegistry();
7693             virtual void registerTranslator( const IExceptionTranslator* translator );
7694             virtual std::string translateActiveException() const override;
7695             std::string tryTranslators() const;
7696              
7697             private:
7698             std::vector> m_translators;
7699             };
7700             }
7701              
7702             // end catch_exception_translator_registry.h
7703             #ifdef __OBJC__
7704             #import "Foundation/Foundation.h"
7705             #endif
7706              
7707             namespace Catch {
7708              
7709             ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
7710             }
7711              
7712             void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
7713             m_translators.push_back( std::unique_ptr( translator ) );
7714             }
7715              
7716             #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
7717             std::string ExceptionTranslatorRegistry::translateActiveException() const {
7718             try {
7719             #ifdef __OBJC__
7720             // In Objective-C try objective-c exceptions first
7721             @try {
7722             return tryTranslators();
7723             }
7724             @catch (NSException *exception) {
7725             return Catch::Detail::stringify( [exception description] );
7726             }
7727             #else
7728             // Compiling a mixed mode project with MSVC means that CLR
7729             // exceptions will be caught in (...) as well. However, these
7730             // do not fill-in std::current_exception and thus lead to crash
7731             // when attempting rethrow.
7732             // /EHa switch also causes structured exceptions to be caught
7733             // here, but they fill-in current_exception properly, so
7734             // at worst the output should be a little weird, instead of
7735             // causing a crash.
7736             if (std::current_exception() == nullptr) {
7737             return "Non C++ exception. Possibly a CLR exception.";
7738             }
7739             return tryTranslators();
7740             #endif
7741             }
7742             catch( TestFailureException& ) {
7743             std::rethrow_exception(std::current_exception());
7744             }
7745             catch( std::exception& ex ) {
7746             return ex.what();
7747             }
7748             catch( std::string& msg ) {
7749             return msg;
7750             }
7751             catch( const char* msg ) {
7752             return msg;
7753             }
7754             catch(...) {
7755             return "Unknown exception";
7756             }
7757             }
7758              
7759             #else // ^^ Exceptions are enabled // Exceptions are disabled vv
7760             std::string ExceptionTranslatorRegistry::translateActiveException() const {
7761             CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
7762             }
7763             #endif
7764              
7765             std::string ExceptionTranslatorRegistry::tryTranslators() const {
7766             if( m_translators.empty() )
7767             std::rethrow_exception(std::current_exception());
7768             else
7769             return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
7770             }
7771             }
7772             // end catch_exception_translator_registry.cpp
7773             // start catch_fatal_condition.cpp
7774              
7775             #if defined(__GNUC__)
7776             # pragma GCC diagnostic push
7777             # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
7778             #endif
7779              
7780             #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
7781              
7782             namespace {
7783             // Report the error condition
7784             void reportFatal( char const * const message ) {
7785             Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
7786             }
7787             }
7788              
7789             #endif // signals/SEH handling
7790              
7791             #if defined( CATCH_CONFIG_WINDOWS_SEH )
7792              
7793             namespace Catch {
7794             struct SignalDefs { DWORD id; const char* name; };
7795              
7796             // There is no 1-1 mapping between signals and windows exceptions.
7797             // Windows can easily distinguish between SO and SigSegV,
7798             // but SigInt, SigTerm, etc are handled differently.
7799             static SignalDefs signalDefs[] = {
7800             { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" },
7801             { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
7802             { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
7803             { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
7804             };
7805              
7806             LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
7807             for (auto const& def : signalDefs) {
7808             if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
7809             reportFatal(def.name);
7810             }
7811             }
7812             // If its not an exception we care about, pass it along.
7813             // This stops us from eating debugger breaks etc.
7814             return EXCEPTION_CONTINUE_SEARCH;
7815             }
7816              
7817             FatalConditionHandler::FatalConditionHandler() {
7818             isSet = true;
7819             // 32k seems enough for Catch to handle stack overflow,
7820             // but the value was found experimentally, so there is no strong guarantee
7821             guaranteeSize = 32 * 1024;
7822             exceptionHandlerHandle = nullptr;
7823             // Register as first handler in current chain
7824             exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
7825             // Pass in guarantee size to be filled
7826             SetThreadStackGuarantee(&guaranteeSize);
7827             }
7828              
7829             void FatalConditionHandler::reset() {
7830             if (isSet) {
7831             RemoveVectoredExceptionHandler(exceptionHandlerHandle);
7832             SetThreadStackGuarantee(&guaranteeSize);
7833             exceptionHandlerHandle = nullptr;
7834             isSet = false;
7835             }
7836             }
7837              
7838             FatalConditionHandler::~FatalConditionHandler() {
7839             reset();
7840             }
7841              
7842             bool FatalConditionHandler::isSet = false;
7843             ULONG FatalConditionHandler::guaranteeSize = 0;
7844             PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
7845              
7846             } // namespace Catch
7847              
7848             #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
7849              
7850             namespace Catch {
7851              
7852             struct SignalDefs {
7853             int id;
7854             const char* name;
7855             };
7856              
7857             // 32kb for the alternate stack seems to be sufficient. However, this value
7858             // is experimentally determined, so that's not guaranteed.
7859             constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
7860              
7861             static SignalDefs signalDefs[] = {
7862             { SIGINT, "SIGINT - Terminal interrupt signal" },
7863             { SIGILL, "SIGILL - Illegal instruction signal" },
7864             { SIGFPE, "SIGFPE - Floating point error signal" },
7865             { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
7866             { SIGTERM, "SIGTERM - Termination request signal" },
7867             { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
7868             };
7869              
7870             void FatalConditionHandler::handleSignal( int sig ) {
7871             char const * name = "";
7872             for (auto const& def : signalDefs) {
7873             if (sig == def.id) {
7874             name = def.name;
7875             break;
7876             }
7877             }
7878             reset();
7879             reportFatal(name);
7880             raise( sig );
7881             }
7882              
7883             FatalConditionHandler::FatalConditionHandler() {
7884             isSet = true;
7885             stack_t sigStack;
7886             sigStack.ss_sp = altStackMem;
7887             sigStack.ss_size = sigStackSize;
7888             sigStack.ss_flags = 0;
7889             sigaltstack(&sigStack, &oldSigStack);
7890             struct sigaction sa = { };
7891              
7892             sa.sa_handler = handleSignal;
7893             sa.sa_flags = SA_ONSTACK;
7894             for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
7895             sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
7896             }
7897             }
7898              
7899             FatalConditionHandler::~FatalConditionHandler() {
7900             reset();
7901             }
7902              
7903             void FatalConditionHandler::reset() {
7904             if( isSet ) {
7905             // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
7906             for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
7907             sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
7908             }
7909             // Return the old stack
7910             sigaltstack(&oldSigStack, nullptr);
7911             isSet = false;
7912             }
7913             }
7914              
7915             bool FatalConditionHandler::isSet = false;
7916             struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
7917             stack_t FatalConditionHandler::oldSigStack = {};
7918             char FatalConditionHandler::altStackMem[sigStackSize] = {};
7919              
7920             } // namespace Catch
7921              
7922             #else
7923              
7924             namespace Catch {
7925             void FatalConditionHandler::reset() {}
7926             }
7927              
7928             #endif // signals/SEH handling
7929              
7930             #if defined(__GNUC__)
7931             # pragma GCC diagnostic pop
7932             #endif
7933             // end catch_fatal_condition.cpp
7934             // start catch_generators.cpp
7935              
7936             // start catch_random_number_generator.h
7937              
7938             #include
7939             #include
7940              
7941             namespace Catch {
7942              
7943             struct IConfig;
7944              
7945             std::mt19937& rng();
7946             void seedRng( IConfig const& config );
7947             unsigned int rngSeed();
7948              
7949             }
7950              
7951             // end catch_random_number_generator.h
7952             #include
7953             #include
7954              
7955             namespace Catch {
7956              
7957             IGeneratorTracker::~IGeneratorTracker() {}
7958              
7959             namespace Generators {
7960              
7961             GeneratorBase::~GeneratorBase() {}
7962              
7963             std::vector randomiseIndices( size_t selectionSize, size_t sourceSize ) {
7964              
7965             assert( selectionSize <= sourceSize );
7966             std::vector indices;
7967             indices.reserve( selectionSize );
7968             std::uniform_int_distribution uid( 0, sourceSize-1 );
7969              
7970             std::set seen;
7971             // !TBD: improve this algorithm
7972             while( indices.size() < selectionSize ) {
7973             auto index = uid( rng() );
7974             if( seen.insert( index ).second )
7975             indices.push_back( index );
7976             }
7977             return indices;
7978             }
7979              
7980             auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
7981             return getResultCapture().acquireGeneratorTracker( lineInfo );
7982             }
7983              
7984             template<>
7985             auto all() -> Generator {
7986             return range( std::numeric_limits::min(), std::numeric_limits::max() );
7987             }
7988              
7989             } // namespace Generators
7990             } // namespace Catch
7991             // end catch_generators.cpp
7992             // start catch_interfaces_capture.cpp
7993              
7994             namespace Catch {
7995             IResultCapture::~IResultCapture() = default;
7996             }
7997             // end catch_interfaces_capture.cpp
7998             // start catch_interfaces_config.cpp
7999              
8000             namespace Catch {
8001             IConfig::~IConfig() = default;
8002             }
8003             // end catch_interfaces_config.cpp
8004             // start catch_interfaces_exception.cpp
8005              
8006             namespace Catch {
8007             IExceptionTranslator::~IExceptionTranslator() = default;
8008             IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
8009             }
8010             // end catch_interfaces_exception.cpp
8011             // start catch_interfaces_registry_hub.cpp
8012              
8013             namespace Catch {
8014             IRegistryHub::~IRegistryHub() = default;
8015             IMutableRegistryHub::~IMutableRegistryHub() = default;
8016             }
8017             // end catch_interfaces_registry_hub.cpp
8018             // start catch_interfaces_reporter.cpp
8019              
8020             // start catch_reporter_listening.h
8021              
8022             namespace Catch {
8023              
8024             class ListeningReporter : public IStreamingReporter {
8025             using Reporters = std::vector;
8026             Reporters m_listeners;
8027             IStreamingReporterPtr m_reporter = nullptr;
8028             ReporterPreferences m_preferences;
8029              
8030             public:
8031             ListeningReporter();
8032              
8033             void addListener( IStreamingReporterPtr&& listener );
8034             void addReporter( IStreamingReporterPtr&& reporter );
8035              
8036             public: // IStreamingReporter
8037              
8038             ReporterPreferences getPreferences() const override;
8039              
8040             void noMatchingTestCases( std::string const& spec ) override;
8041              
8042             static std::set getSupportedVerbosities();
8043              
8044             void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
8045             void benchmarkEnded( BenchmarkStats const& benchmarkStats ) override;
8046              
8047             void testRunStarting( TestRunInfo const& testRunInfo ) override;
8048             void testGroupStarting( GroupInfo const& groupInfo ) override;
8049             void testCaseStarting( TestCaseInfo const& testInfo ) override;
8050             void sectionStarting( SectionInfo const& sectionInfo ) override;
8051             void assertionStarting( AssertionInfo const& assertionInfo ) override;
8052              
8053             // The return value indicates if the messages buffer should be cleared:
8054             bool assertionEnded( AssertionStats const& assertionStats ) override;
8055             void sectionEnded( SectionStats const& sectionStats ) override;
8056             void testCaseEnded( TestCaseStats const& testCaseStats ) override;
8057             void testGroupEnded( TestGroupStats const& testGroupStats ) override;
8058             void testRunEnded( TestRunStats const& testRunStats ) override;
8059              
8060             void skipTest( TestCaseInfo const& testInfo ) override;
8061             bool isMulti() const override;
8062              
8063             };
8064              
8065             } // end namespace Catch
8066              
8067             // end catch_reporter_listening.h
8068             namespace Catch {
8069              
8070             ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
8071             : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
8072              
8073             ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
8074             : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
8075              
8076             std::ostream& ReporterConfig::stream() const { return *m_stream; }
8077             IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
8078              
8079             TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
8080              
8081             GroupInfo::GroupInfo( std::string const& _name,
8082             std::size_t _groupIndex,
8083             std::size_t _groupsCount )
8084             : name( _name ),
8085             groupIndex( _groupIndex ),
8086             groupsCounts( _groupsCount )
8087             {}
8088              
8089             AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
8090             std::vector const& _infoMessages,
8091             Totals const& _totals )
8092             : assertionResult( _assertionResult ),
8093             infoMessages( _infoMessages ),
8094             totals( _totals )
8095             {
8096             assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
8097              
8098             if( assertionResult.hasMessage() ) {
8099             // Copy message into messages list.
8100             // !TBD This should have been done earlier, somewhere
8101             MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
8102             builder << assertionResult.getMessage();
8103             builder.m_info.message = builder.m_stream.str();
8104              
8105             infoMessages.push_back( builder.m_info );
8106             }
8107             }
8108              
8109             AssertionStats::~AssertionStats() = default;
8110              
8111             SectionStats::SectionStats( SectionInfo const& _sectionInfo,
8112             Counts const& _assertions,
8113             double _durationInSeconds,
8114             bool _missingAssertions )
8115             : sectionInfo( _sectionInfo ),
8116             assertions( _assertions ),
8117             durationInSeconds( _durationInSeconds ),
8118             missingAssertions( _missingAssertions )
8119             {}
8120              
8121             SectionStats::~SectionStats() = default;
8122              
8123             TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo,
8124             Totals const& _totals,
8125             std::string const& _stdOut,
8126             std::string const& _stdErr,
8127             bool _aborting )
8128             : testInfo( _testInfo ),
8129             totals( _totals ),
8130             stdOut( _stdOut ),
8131             stdErr( _stdErr ),
8132             aborting( _aborting )
8133             {}
8134              
8135             TestCaseStats::~TestCaseStats() = default;
8136              
8137             TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
8138             Totals const& _totals,
8139             bool _aborting )
8140             : groupInfo( _groupInfo ),
8141             totals( _totals ),
8142             aborting( _aborting )
8143             {}
8144              
8145             TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
8146             : groupInfo( _groupInfo ),
8147             aborting( false )
8148             {}
8149              
8150             TestGroupStats::~TestGroupStats() = default;
8151              
8152             TestRunStats::TestRunStats( TestRunInfo const& _runInfo,
8153             Totals const& _totals,
8154             bool _aborting )
8155             : runInfo( _runInfo ),
8156             totals( _totals ),
8157             aborting( _aborting )
8158             {}
8159              
8160             TestRunStats::~TestRunStats() = default;
8161              
8162             void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
8163             bool IStreamingReporter::isMulti() const { return false; }
8164              
8165             IReporterFactory::~IReporterFactory() = default;
8166             IReporterRegistry::~IReporterRegistry() = default;
8167              
8168             } // end namespace Catch
8169             // end catch_interfaces_reporter.cpp
8170             // start catch_interfaces_runner.cpp
8171              
8172             namespace Catch {
8173             IRunner::~IRunner() = default;
8174             }
8175             // end catch_interfaces_runner.cpp
8176             // start catch_interfaces_testcase.cpp
8177              
8178             namespace Catch {
8179             ITestInvoker::~ITestInvoker() = default;
8180             ITestCaseRegistry::~ITestCaseRegistry() = default;
8181             }
8182             // end catch_interfaces_testcase.cpp
8183             // start catch_leak_detector.cpp
8184              
8185             #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
8186             #include
8187              
8188             namespace Catch {
8189              
8190             LeakDetector::LeakDetector() {
8191             int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
8192             flag |= _CRTDBG_LEAK_CHECK_DF;
8193             flag |= _CRTDBG_ALLOC_MEM_DF;
8194             _CrtSetDbgFlag(flag);
8195             _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
8196             _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
8197             // Change this to leaking allocation's number to break there
8198             _CrtSetBreakAlloc(-1);
8199             }
8200             }
8201              
8202             #else
8203              
8204             Catch::LeakDetector::LeakDetector() {}
8205              
8206             #endif
8207             // end catch_leak_detector.cpp
8208             // start catch_list.cpp
8209              
8210             // start catch_list.h
8211              
8212             #include
8213              
8214             namespace Catch {
8215              
8216             std::size_t listTests( Config const& config );
8217              
8218             std::size_t listTestsNamesOnly( Config const& config );
8219              
8220             struct TagInfo {
8221             void add( std::string const& spelling );
8222             std::string all() const;
8223              
8224             std::set spellings;
8225             std::size_t count = 0;
8226             };
8227              
8228             std::size_t listTags( Config const& config );
8229              
8230             std::size_t listReporters( Config const& /*config*/ );
8231              
8232             Option list( Config const& config );
8233              
8234             } // end namespace Catch
8235              
8236             // end catch_list.h
8237             // start catch_text.h
8238              
8239             namespace Catch {
8240             using namespace clara::TextFlow;
8241             }
8242              
8243             // end catch_text.h
8244             #include
8245             #include
8246             #include
8247              
8248             namespace Catch {
8249              
8250             std::size_t listTests( Config const& config ) {
8251             TestSpec testSpec = config.testSpec();
8252             if( config.hasTestFilters() )
8253             Catch::cout() << "Matching test cases:\n";
8254             else {
8255             Catch::cout() << "All available test cases:\n";
8256             }
8257              
8258             auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
8259             for( auto const& testCaseInfo : matchedTestCases ) {
8260             Colour::Code colour = testCaseInfo.isHidden()
8261             ? Colour::SecondaryText
8262             : Colour::None;
8263             Colour colourGuard( colour );
8264              
8265             Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
8266             if( config.verbosity() >= Verbosity::High ) {
8267             Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
8268             std::string description = testCaseInfo.description;
8269             if( description.empty() )
8270             description = "(NO DESCRIPTION)";
8271             Catch::cout() << Column( description ).indent(4) << std::endl;
8272             }
8273             if( !testCaseInfo.tags.empty() )
8274             Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
8275             }
8276              
8277             if( !config.hasTestFilters() )
8278             Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
8279             else
8280             Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
8281             return matchedTestCases.size();
8282             }
8283              
8284             std::size_t listTestsNamesOnly( Config const& config ) {
8285             TestSpec testSpec = config.testSpec();
8286             std::size_t matchedTests = 0;
8287             std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
8288             for( auto const& testCaseInfo : matchedTestCases ) {
8289             matchedTests++;
8290             if( startsWith( testCaseInfo.name, '#' ) )
8291             Catch::cout() << '"' << testCaseInfo.name << '"';
8292             else
8293             Catch::cout() << testCaseInfo.name;
8294             if ( config.verbosity() >= Verbosity::High )
8295             Catch::cout() << "\t@" << testCaseInfo.lineInfo;
8296             Catch::cout() << std::endl;
8297             }
8298             return matchedTests;
8299             }
8300              
8301             void TagInfo::add( std::string const& spelling ) {
8302             ++count;
8303             spellings.insert( spelling );
8304             }
8305              
8306             std::string TagInfo::all() const {
8307             std::string out;
8308             for( auto const& spelling : spellings )
8309             out += "[" + spelling + "]";
8310             return out;
8311             }
8312              
8313             std::size_t listTags( Config const& config ) {
8314             TestSpec testSpec = config.testSpec();
8315             if( config.hasTestFilters() )
8316             Catch::cout() << "Tags for matching test cases:\n";
8317             else {
8318             Catch::cout() << "All available tags:\n";
8319             }
8320              
8321             std::map tagCounts;
8322              
8323             std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
8324             for( auto const& testCase : matchedTestCases ) {
8325             for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
8326             std::string lcaseTagName = toLower( tagName );
8327             auto countIt = tagCounts.find( lcaseTagName );
8328             if( countIt == tagCounts.end() )
8329             countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
8330             countIt->second.add( tagName );
8331             }
8332             }
8333              
8334             for( auto const& tagCount : tagCounts ) {
8335             ReusableStringStream rss;
8336             rss << " " << std::setw(2) << tagCount.second.count << " ";
8337             auto str = rss.str();
8338             auto wrapper = Column( tagCount.second.all() )
8339             .initialIndent( 0 )
8340             .indent( str.size() )
8341             .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
8342             Catch::cout() << str << wrapper << '\n';
8343             }
8344             Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
8345             return tagCounts.size();
8346             }
8347              
8348             std::size_t listReporters( Config const& /*config*/ ) {
8349             Catch::cout() << "Available reporters:\n";
8350             IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
8351             std::size_t maxNameLen = 0;
8352             for( auto const& factoryKvp : factories )
8353             maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
8354              
8355             for( auto const& factoryKvp : factories ) {
8356             Catch::cout()
8357             << Column( factoryKvp.first + ":" )
8358             .indent(2)
8359             .width( 5+maxNameLen )
8360             + Column( factoryKvp.second->getDescription() )
8361             .initialIndent(0)
8362             .indent(2)
8363             .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
8364             << "\n";
8365             }
8366             Catch::cout() << std::endl;
8367             return factories.size();
8368             }
8369              
8370             Option list( Config const& config ) {
8371             Option listedCount;
8372             if( config.listTests() )
8373             listedCount = listedCount.valueOr(0) + listTests( config );
8374             if( config.listTestNamesOnly() )
8375             listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
8376             if( config.listTags() )
8377             listedCount = listedCount.valueOr(0) + listTags( config );
8378             if( config.listReporters() )
8379             listedCount = listedCount.valueOr(0) + listReporters( config );
8380             return listedCount;
8381             }
8382              
8383             } // end namespace Catch
8384             // end catch_list.cpp
8385             // start catch_matchers.cpp
8386              
8387             namespace Catch {
8388             namespace Matchers {
8389             namespace Impl {
8390              
8391             std::string MatcherUntypedBase::toString() const {
8392             if( m_cachedToString.empty() )
8393             m_cachedToString = describe();
8394             return m_cachedToString;
8395             }
8396              
8397             MatcherUntypedBase::~MatcherUntypedBase() = default;
8398              
8399             } // namespace Impl
8400             } // namespace Matchers
8401              
8402             using namespace Matchers;
8403             using Matchers::Impl::MatcherBase;
8404              
8405             } // namespace Catch
8406             // end catch_matchers.cpp
8407             // start catch_matchers_floating.cpp
8408              
8409             // start catch_to_string.hpp
8410              
8411             #include
8412              
8413             namespace Catch {
8414             template
8415             std::string to_string(T const& t) {
8416             #if defined(CATCH_CONFIG_CPP11_TO_STRING)
8417             return std::to_string(t);
8418             #else
8419             ReusableStringStream rss;
8420             rss << t;
8421             return rss.str();
8422             #endif
8423             }
8424             } // end namespace Catch
8425              
8426             // end catch_to_string.hpp
8427             #include
8428             #include
8429             #include
8430              
8431             namespace Catch {
8432             namespace Matchers {
8433             namespace Floating {
8434             enum class FloatingPointKind : uint8_t {
8435             Float,
8436             Double
8437             };
8438             }
8439             }
8440             }
8441              
8442             namespace {
8443              
8444             template
8445             struct Converter;
8446              
8447             template <>
8448             struct Converter {
8449             static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
8450             Converter(float f) {
8451             std::memcpy(&i, &f, sizeof(f));
8452             }
8453             int32_t i;
8454             };
8455              
8456             template <>
8457             struct Converter {
8458             static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
8459             Converter(double d) {
8460             std::memcpy(&i, &d, sizeof(d));
8461             }
8462             int64_t i;
8463             };
8464              
8465             template
8466             auto convert(T t) -> Converter {
8467             return Converter(t);
8468             }
8469              
8470             template
8471             bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) {
8472             // Comparison with NaN should always be false.
8473             // This way we can rule it out before getting into the ugly details
8474             if (std::isnan(lhs) || std::isnan(rhs)) {
8475             return false;
8476             }
8477              
8478             auto lc = convert(lhs);
8479             auto rc = convert(rhs);
8480              
8481             if ((lc.i < 0) != (rc.i < 0)) {
8482             // Potentially we can have +0 and -0
8483             return lhs == rhs;
8484             }
8485              
8486             auto ulpDiff = std::abs(lc.i - rc.i);
8487             return ulpDiff <= maxUlpDiff;
8488             }
8489              
8490             }
8491              
8492             namespace Catch {
8493             namespace Matchers {
8494             namespace Floating {
8495             WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
8496             :m_target{ target }, m_margin{ margin } {
8497             CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
8498             << " Margin has to be non-negative.");
8499             }
8500              
8501             // Performs equivalent check of std::fabs(lhs - rhs) <= margin
8502             // But without the subtraction to allow for INFINITY in comparison
8503             bool WithinAbsMatcher::match(double const& matchee) const {
8504             return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
8505             }
8506              
8507             std::string WithinAbsMatcher::describe() const {
8508             return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
8509             }
8510              
8511             WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
8512             :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
8513             CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.'
8514             << " ULPs have to be non-negative.");
8515             }
8516              
8517             #if defined(__clang__)
8518             #pragma clang diagnostic push
8519             // Clang <3.5 reports on the default branch in the switch below
8520             #pragma clang diagnostic ignored "-Wunreachable-code"
8521             #endif
8522              
8523             bool WithinUlpsMatcher::match(double const& matchee) const {
8524             switch (m_type) {
8525             case FloatingPointKind::Float:
8526             return almostEqualUlps(static_cast(matchee), static_cast(m_target), m_ulps);
8527             case FloatingPointKind::Double:
8528             return almostEqualUlps(matchee, m_target, m_ulps);
8529             default:
8530             CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
8531             }
8532             }
8533              
8534             #if defined(__clang__)
8535             #pragma clang diagnostic pop
8536             #endif
8537              
8538             std::string WithinUlpsMatcher::describe() const {
8539             return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
8540             }
8541              
8542             }// namespace Floating
8543              
8544             Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) {
8545             return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
8546             }
8547              
8548             Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) {
8549             return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
8550             }
8551              
8552             Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
8553             return Floating::WithinAbsMatcher(target, margin);
8554             }
8555              
8556             } // namespace Matchers
8557             } // namespace Catch
8558              
8559             // end catch_matchers_floating.cpp
8560             // start catch_matchers_generic.cpp
8561              
8562             std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
8563             if (desc.empty()) {
8564             return "matches undescribed predicate";
8565             } else {
8566             return "matches predicate: \"" + desc + '"';
8567             }
8568             }
8569             // end catch_matchers_generic.cpp
8570             // start catch_matchers_string.cpp
8571              
8572             #include
8573              
8574             namespace Catch {
8575             namespace Matchers {
8576              
8577             namespace StdString {
8578              
8579             CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
8580             : m_caseSensitivity( caseSensitivity ),
8581             m_str( adjustString( str ) )
8582             {}
8583             std::string CasedString::adjustString( std::string const& str ) const {
8584             return m_caseSensitivity == CaseSensitive::No
8585             ? toLower( str )
8586             : str;
8587             }
8588             std::string CasedString::caseSensitivitySuffix() const {
8589             return m_caseSensitivity == CaseSensitive::No
8590             ? " (case insensitive)"
8591             : std::string();
8592             }
8593              
8594             StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
8595             : m_comparator( comparator ),
8596             m_operation( operation ) {
8597             }
8598              
8599             std::string StringMatcherBase::describe() const {
8600             std::string description;
8601             description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
8602             m_comparator.caseSensitivitySuffix().size());
8603             description += m_operation;
8604             description += ": \"";
8605             description += m_comparator.m_str;
8606             description += "\"";
8607             description += m_comparator.caseSensitivitySuffix();
8608             return description;
8609             }
8610              
8611             EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
8612              
8613             bool EqualsMatcher::match( std::string const& source ) const {
8614             return m_comparator.adjustString( source ) == m_comparator.m_str;
8615             }
8616              
8617             ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
8618              
8619             bool ContainsMatcher::match( std::string const& source ) const {
8620             return contains( m_comparator.adjustString( source ), m_comparator.m_str );
8621             }
8622              
8623             StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
8624              
8625             bool StartsWithMatcher::match( std::string const& source ) const {
8626             return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
8627             }
8628              
8629             EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
8630              
8631             bool EndsWithMatcher::match( std::string const& source ) const {
8632             return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
8633             }
8634              
8635             RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
8636              
8637             bool RegexMatcher::match(std::string const& matchee) const {
8638             auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
8639             if (m_caseSensitivity == CaseSensitive::Choice::No) {
8640             flags |= std::regex::icase;
8641             }
8642             auto reg = std::regex(m_regex, flags);
8643             return std::regex_match(matchee, reg);
8644             }
8645              
8646             std::string RegexMatcher::describe() const {
8647             return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
8648             }
8649              
8650             } // namespace StdString
8651              
8652             StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
8653             return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
8654             }
8655             StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
8656             return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
8657             }
8658             StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
8659             return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
8660             }
8661             StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
8662             return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
8663             }
8664              
8665             StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
8666             return StdString::RegexMatcher(regex, caseSensitivity);
8667             }
8668              
8669             } // namespace Matchers
8670             } // namespace Catch
8671             // end catch_matchers_string.cpp
8672             // start catch_message.cpp
8673              
8674             // start catch_uncaught_exceptions.h
8675              
8676             namespace Catch {
8677             bool uncaught_exceptions();
8678             } // end namespace Catch
8679              
8680             // end catch_uncaught_exceptions.h
8681             #include
8682              
8683             namespace Catch {
8684              
8685             MessageInfo::MessageInfo( StringRef const& _macroName,
8686             SourceLineInfo const& _lineInfo,
8687             ResultWas::OfType _type )
8688             : macroName( _macroName ),
8689             lineInfo( _lineInfo ),
8690             type( _type ),
8691             sequence( ++globalCount )
8692             {}
8693              
8694             bool MessageInfo::operator==( MessageInfo const& other ) const {
8695             return sequence == other.sequence;
8696             }
8697              
8698             bool MessageInfo::operator<( MessageInfo const& other ) const {
8699             return sequence < other.sequence;
8700             }
8701              
8702             // This may need protecting if threading support is added
8703             unsigned int MessageInfo::globalCount = 0;
8704              
8705             ////////////////////////////////////////////////////////////////////////////
8706              
8707             Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
8708             SourceLineInfo const& lineInfo,
8709             ResultWas::OfType type )
8710             :m_info(macroName, lineInfo, type) {}
8711              
8712             ////////////////////////////////////////////////////////////////////////////
8713              
8714             ScopedMessage::ScopedMessage( MessageBuilder const& builder )
8715             : m_info( builder.m_info )
8716             {
8717             m_info.message = builder.m_stream.str();
8718             getResultCapture().pushScopedMessage( m_info );
8719             }
8720              
8721             ScopedMessage::~ScopedMessage() {
8722             if ( !uncaught_exceptions() ){
8723             getResultCapture().popScopedMessage(m_info);
8724             }
8725             }
8726              
8727             Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
8728             auto start = std::string::npos;
8729             for( size_t pos = 0; pos <= names.size(); ++pos ) {
8730             char c = names[pos];
8731             if( pos == names.size() || c == ' ' || c == '\t' || c == ',' || c == ']' ) {
8732             if( start != std::string::npos ) {
8733             m_messages.push_back( MessageInfo( macroName, lineInfo, resultType ) );
8734             m_messages.back().message = names.substr( start, pos-start) + " := ";
8735             start = std::string::npos;
8736             }
8737             }
8738             else if( c != '[' && c != ']' && start == std::string::npos )
8739             start = pos;
8740             }
8741             }
8742             Capturer::~Capturer() {
8743             if ( !uncaught_exceptions() ){
8744             assert( m_captured == m_messages.size() );
8745             for( size_t i = 0; i < m_captured; ++i )
8746             m_resultCapture.popScopedMessage( m_messages[i] );
8747             }
8748             }
8749              
8750             void Capturer::captureValue( size_t index, StringRef value ) {
8751             assert( index < m_messages.size() );
8752             m_messages[index].message += value;
8753             m_resultCapture.pushScopedMessage( m_messages[index] );
8754             m_captured++;
8755             }
8756              
8757             } // end namespace Catch
8758             // end catch_message.cpp
8759             // start catch_output_redirect.cpp
8760              
8761             // start catch_output_redirect.h
8762             #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
8763             #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
8764              
8765             #include
8766             #include
8767             #include
8768              
8769             namespace Catch {
8770              
8771             class RedirectedStream {
8772             std::ostream& m_originalStream;
8773             std::ostream& m_redirectionStream;
8774             std::streambuf* m_prevBuf;
8775              
8776             public:
8777             RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
8778             ~RedirectedStream();
8779             };
8780              
8781             class RedirectedStdOut {
8782             ReusableStringStream m_rss;
8783             RedirectedStream m_cout;
8784             public:
8785             RedirectedStdOut();
8786             auto str() const -> std::string;
8787             };
8788              
8789             // StdErr has two constituent streams in C++, std::cerr and std::clog
8790             // This means that we need to redirect 2 streams into 1 to keep proper
8791             // order of writes
8792             class RedirectedStdErr {
8793             ReusableStringStream m_rss;
8794             RedirectedStream m_cerr;
8795             RedirectedStream m_clog;
8796             public:
8797             RedirectedStdErr();
8798             auto str() const -> std::string;
8799             };
8800              
8801             #if defined(CATCH_CONFIG_NEW_CAPTURE)
8802              
8803             // Windows's implementation of std::tmpfile is terrible (it tries
8804             // to create a file inside system folder, thus requiring elevated
8805             // privileges for the binary), so we have to use tmpnam(_s) and
8806             // create the file ourselves there.
8807             class TempFile {
8808             public:
8809             TempFile(TempFile const&) = delete;
8810             TempFile& operator=(TempFile const&) = delete;
8811             TempFile(TempFile&&) = delete;
8812             TempFile& operator=(TempFile&&) = delete;
8813              
8814             TempFile();
8815             ~TempFile();
8816              
8817             std::FILE* getFile();
8818             std::string getContents();
8819              
8820             private:
8821             std::FILE* m_file = nullptr;
8822             #if defined(_MSC_VER)
8823             char m_buffer[L_tmpnam] = { 0 };
8824             #endif
8825             };
8826              
8827             class OutputRedirect {
8828             public:
8829             OutputRedirect(OutputRedirect const&) = delete;
8830             OutputRedirect& operator=(OutputRedirect const&) = delete;
8831             OutputRedirect(OutputRedirect&&) = delete;
8832             OutputRedirect& operator=(OutputRedirect&&) = delete;
8833              
8834             OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
8835             ~OutputRedirect();
8836              
8837             private:
8838             int m_originalStdout = -1;
8839             int m_originalStderr = -1;
8840             TempFile m_stdoutFile;
8841             TempFile m_stderrFile;
8842             std::string& m_stdoutDest;
8843             std::string& m_stderrDest;
8844             };
8845              
8846             #endif
8847              
8848             } // end namespace Catch
8849              
8850             #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
8851             // end catch_output_redirect.h
8852             #include
8853             #include
8854             #include
8855             #include
8856             #include
8857              
8858             #if defined(CATCH_CONFIG_NEW_CAPTURE)
8859             #if defined(_MSC_VER)
8860             #include //_dup and _dup2
8861             #define dup _dup
8862             #define dup2 _dup2
8863             #define fileno _fileno
8864             #else
8865             #include // dup and dup2
8866             #endif
8867             #endif
8868              
8869             namespace Catch {
8870              
8871             RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
8872             : m_originalStream( originalStream ),
8873             m_redirectionStream( redirectionStream ),
8874             m_prevBuf( m_originalStream.rdbuf() )
8875             {
8876             m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
8877             }
8878              
8879             RedirectedStream::~RedirectedStream() {
8880             m_originalStream.rdbuf( m_prevBuf );
8881             }
8882              
8883             RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
8884             auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
8885              
8886             RedirectedStdErr::RedirectedStdErr()
8887             : m_cerr( Catch::cerr(), m_rss.get() ),
8888             m_clog( Catch::clog(), m_rss.get() )
8889             {}
8890             auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
8891              
8892             #if defined(CATCH_CONFIG_NEW_CAPTURE)
8893              
8894             #if defined(_MSC_VER)
8895             TempFile::TempFile() {
8896             if (tmpnam_s(m_buffer)) {
8897             CATCH_RUNTIME_ERROR("Could not get a temp filename");
8898             }
8899             if (fopen_s(&m_file, m_buffer, "w")) {
8900             char buffer[100];
8901             if (strerror_s(buffer, errno)) {
8902             CATCH_RUNTIME_ERROR("Could not translate errno to a string");
8903             }
8904             CATCH_RUNTIME_ERROR("Coul dnot open the temp file: '" << m_buffer << "' because: " << buffer);
8905             }
8906             }
8907             #else
8908             TempFile::TempFile() {
8909             m_file = std::tmpfile();
8910             if (!m_file) {
8911             CATCH_RUNTIME_ERROR("Could not create a temp file.");
8912             }
8913             }
8914              
8915             #endif
8916              
8917             TempFile::~TempFile() {
8918             // TBD: What to do about errors here?
8919             std::fclose(m_file);
8920             // We manually create the file on Windows only, on Linux
8921             // it will be autodeleted
8922             #if defined(_MSC_VER)
8923             std::remove(m_buffer);
8924             #endif
8925             }
8926              
8927             FILE* TempFile::getFile() {
8928             return m_file;
8929             }
8930              
8931             std::string TempFile::getContents() {
8932             std::stringstream sstr;
8933             char buffer[100] = {};
8934             std::rewind(m_file);
8935             while (std::fgets(buffer, sizeof(buffer), m_file)) {
8936             sstr << buffer;
8937             }
8938             return sstr.str();
8939             }
8940              
8941             OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
8942             m_originalStdout(dup(1)),
8943             m_originalStderr(dup(2)),
8944             m_stdoutDest(stdout_dest),
8945             m_stderrDest(stderr_dest) {
8946             dup2(fileno(m_stdoutFile.getFile()), 1);
8947             dup2(fileno(m_stderrFile.getFile()), 2);
8948             }
8949              
8950             OutputRedirect::~OutputRedirect() {
8951             Catch::cout() << std::flush;
8952             fflush(stdout);
8953             // Since we support overriding these streams, we flush cerr
8954             // even though std::cerr is unbuffered
8955             Catch::cerr() << std::flush;
8956             Catch::clog() << std::flush;
8957             fflush(stderr);
8958              
8959             dup2(m_originalStdout, 1);
8960             dup2(m_originalStderr, 2);
8961              
8962             m_stdoutDest += m_stdoutFile.getContents();
8963             m_stderrDest += m_stderrFile.getContents();
8964             }
8965              
8966             #endif // CATCH_CONFIG_NEW_CAPTURE
8967              
8968             } // namespace Catch
8969              
8970             #if defined(CATCH_CONFIG_NEW_CAPTURE)
8971             #if defined(_MSC_VER)
8972             #undef dup
8973             #undef dup2
8974             #undef fileno
8975             #endif
8976             #endif
8977             // end catch_output_redirect.cpp
8978             // start catch_random_number_generator.cpp
8979              
8980             namespace Catch {
8981              
8982             std::mt19937& rng() {
8983             static std::mt19937 s_rng;
8984             return s_rng;
8985             }
8986              
8987             void seedRng( IConfig const& config ) {
8988             if( config.rngSeed() != 0 ) {
8989             std::srand( config.rngSeed() );
8990             rng().seed( config.rngSeed() );
8991             }
8992             }
8993              
8994             unsigned int rngSeed() {
8995             return getCurrentContext().getConfig()->rngSeed();
8996             }
8997             }
8998             // end catch_random_number_generator.cpp
8999             // start catch_registry_hub.cpp
9000              
9001             // start catch_test_case_registry_impl.h
9002              
9003             #include
9004             #include
9005             #include
9006             #include
9007              
9008             namespace Catch {
9009              
9010             class TestCase;
9011             struct IConfig;
9012              
9013             std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases );
9014             bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
9015              
9016             void enforceNoDuplicateTestCases( std::vector const& functions );
9017              
9018             std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config );
9019             std::vector const& getAllTestCasesSorted( IConfig const& config );
9020              
9021             class TestRegistry : public ITestCaseRegistry {
9022             public:
9023             virtual ~TestRegistry() = default;
9024              
9025             virtual void registerTest( TestCase const& testCase );
9026              
9027             std::vector const& getAllTests() const override;
9028             std::vector const& getAllTestsSorted( IConfig const& config ) const override;
9029              
9030             private:
9031             std::vector m_functions;
9032             mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
9033             mutable std::vector m_sortedFunctions;
9034             std::size_t m_unnamedCount = 0;
9035             std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
9036             };
9037              
9038             ///////////////////////////////////////////////////////////////////////////
9039              
9040             class TestInvokerAsFunction : public ITestInvoker {
9041             void(*m_testAsFunction)();
9042             public:
9043             TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
9044              
9045             void invoke() const override;
9046             };
9047              
9048             std::string extractClassName( StringRef const& classOrQualifiedMethodName );
9049              
9050             ///////////////////////////////////////////////////////////////////////////
9051              
9052             } // end namespace Catch
9053              
9054             // end catch_test_case_registry_impl.h
9055             // start catch_reporter_registry.h
9056              
9057             #include
9058              
9059             namespace Catch {
9060              
9061             class ReporterRegistry : public IReporterRegistry {
9062              
9063             public:
9064              
9065             ~ReporterRegistry() override;
9066              
9067             IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
9068              
9069             void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
9070             void registerListener( IReporterFactoryPtr const& factory );
9071              
9072             FactoryMap const& getFactories() const override;
9073             Listeners const& getListeners() const override;
9074              
9075             private:
9076             FactoryMap m_factories;
9077             Listeners m_listeners;
9078             };
9079             }
9080              
9081             // end catch_reporter_registry.h
9082             // start catch_tag_alias_registry.h
9083              
9084             // start catch_tag_alias.h
9085              
9086             #include
9087              
9088             namespace Catch {
9089              
9090             struct TagAlias {
9091             TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
9092              
9093             std::string tag;
9094             SourceLineInfo lineInfo;
9095             };
9096              
9097             } // end namespace Catch
9098              
9099             // end catch_tag_alias.h
9100             #include
9101              
9102             namespace Catch {
9103              
9104             class TagAliasRegistry : public ITagAliasRegistry {
9105             public:
9106             ~TagAliasRegistry() override;
9107             TagAlias const* find( std::string const& alias ) const override;
9108             std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
9109             void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
9110              
9111             private:
9112             std::map m_registry;
9113             };
9114              
9115             } // end namespace Catch
9116              
9117             // end catch_tag_alias_registry.h
9118             // start catch_startup_exception_registry.h
9119              
9120             #include
9121             #include
9122              
9123             namespace Catch {
9124              
9125             class StartupExceptionRegistry {
9126             public:
9127             void add(std::exception_ptr const& exception) noexcept;
9128             std::vector const& getExceptions() const noexcept;
9129             private:
9130             std::vector m_exceptions;
9131             };
9132              
9133             } // end namespace Catch
9134              
9135             // end catch_startup_exception_registry.h
9136             // start catch_singletons.hpp
9137              
9138             namespace Catch {
9139              
9140             struct ISingleton {
9141             virtual ~ISingleton();
9142             };
9143              
9144             void addSingleton( ISingleton* singleton );
9145             void cleanupSingletons();
9146              
9147             template
9148             class Singleton : SingletonImplT, public ISingleton {
9149              
9150             static auto getInternal() -> Singleton* {
9151             static Singleton* s_instance = nullptr;
9152             if( !s_instance ) {
9153             s_instance = new Singleton;
9154             addSingleton( s_instance );
9155             }
9156             return s_instance;
9157             }
9158              
9159             public:
9160             static auto get() -> InterfaceT const& {
9161             return *getInternal();
9162             }
9163             static auto getMutable() -> MutableInterfaceT& {
9164             return *getInternal();
9165             }
9166             };
9167              
9168             } // namespace Catch
9169              
9170             // end catch_singletons.hpp
9171             namespace Catch {
9172              
9173             namespace {
9174              
9175             class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
9176             private NonCopyable {
9177              
9178             public: // IRegistryHub
9179             RegistryHub() = default;
9180             IReporterRegistry const& getReporterRegistry() const override {
9181             return m_reporterRegistry;
9182             }
9183             ITestCaseRegistry const& getTestCaseRegistry() const override {
9184             return m_testCaseRegistry;
9185             }
9186             IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
9187             return m_exceptionTranslatorRegistry;
9188             }
9189             ITagAliasRegistry const& getTagAliasRegistry() const override {
9190             return m_tagAliasRegistry;
9191             }
9192             StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
9193             return m_exceptionRegistry;
9194             }
9195              
9196             public: // IMutableRegistryHub
9197             void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
9198             m_reporterRegistry.registerReporter( name, factory );
9199             }
9200             void registerListener( IReporterFactoryPtr const& factory ) override {
9201             m_reporterRegistry.registerListener( factory );
9202             }
9203             void registerTest( TestCase const& testInfo ) override {
9204             m_testCaseRegistry.registerTest( testInfo );
9205             }
9206             void registerTranslator( const IExceptionTranslator* translator ) override {
9207             m_exceptionTranslatorRegistry.registerTranslator( translator );
9208             }
9209             void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
9210             m_tagAliasRegistry.add( alias, tag, lineInfo );
9211             }
9212             void registerStartupException() noexcept override {
9213             m_exceptionRegistry.add(std::current_exception());
9214             }
9215              
9216             private:
9217             TestRegistry m_testCaseRegistry;
9218             ReporterRegistry m_reporterRegistry;
9219             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
9220             TagAliasRegistry m_tagAliasRegistry;
9221             StartupExceptionRegistry m_exceptionRegistry;
9222             };
9223             }
9224              
9225             using RegistryHubSingleton = Singleton;
9226              
9227             IRegistryHub const& getRegistryHub() {
9228             return RegistryHubSingleton::get();
9229             }
9230             IMutableRegistryHub& getMutableRegistryHub() {
9231             return RegistryHubSingleton::getMutable();
9232             }
9233             void cleanUp() {
9234             cleanupSingletons();
9235             cleanUpContext();
9236             }
9237             std::string translateActiveException() {
9238             return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
9239             }
9240              
9241             } // end namespace Catch
9242             // end catch_registry_hub.cpp
9243             // start catch_reporter_registry.cpp
9244              
9245             namespace Catch {
9246              
9247             ReporterRegistry::~ReporterRegistry() = default;
9248              
9249             IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
9250             auto it = m_factories.find( name );
9251             if( it == m_factories.end() )
9252             return nullptr;
9253             return it->second->create( ReporterConfig( config ) );
9254             }
9255              
9256             void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
9257             m_factories.emplace(name, factory);
9258             }
9259             void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
9260             m_listeners.push_back( factory );
9261             }
9262              
9263             IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
9264             return m_factories;
9265             }
9266             IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
9267             return m_listeners;
9268             }
9269              
9270             }
9271             // end catch_reporter_registry.cpp
9272             // start catch_result_type.cpp
9273              
9274             namespace Catch {
9275              
9276             bool isOk( ResultWas::OfType resultType ) {
9277             return ( resultType & ResultWas::FailureBit ) == 0;
9278             }
9279             bool isJustInfo( int flags ) {
9280             return flags == ResultWas::Info;
9281             }
9282              
9283             ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
9284             return static_cast( static_cast( lhs ) | static_cast( rhs ) );
9285             }
9286              
9287             bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
9288             bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
9289              
9290             } // end namespace Catch
9291             // end catch_result_type.cpp
9292             // start catch_run_context.cpp
9293              
9294             #include
9295             #include
9296             #include
9297              
9298             namespace Catch {
9299              
9300             namespace Generators {
9301             struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
9302             size_t m_index = static_cast( -1 );
9303             GeneratorBasePtr m_generator;
9304              
9305             GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
9306             : TrackerBase( nameAndLocation, ctx, parent )
9307             {}
9308             ~GeneratorTracker();
9309              
9310             static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
9311             std::shared_ptr tracker;
9312              
9313             ITracker& currentTracker = ctx.currentTracker();
9314             if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
9315             assert( childTracker );
9316             assert( childTracker->isIndexTracker() );
9317             tracker = std::static_pointer_cast( childTracker );
9318             }
9319             else {
9320             tracker = std::make_shared( nameAndLocation, ctx, ¤tTracker );
9321             currentTracker.addChild( tracker );
9322             }
9323              
9324             if( !ctx.completedCycle() && !tracker->isComplete() ) {
9325             if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
9326             tracker->moveNext();
9327             tracker->open();
9328             }
9329              
9330             return *tracker;
9331             }
9332              
9333             void moveNext() {
9334             m_index++;
9335             m_children.clear();
9336             }
9337              
9338             // TrackerBase interface
9339             bool isIndexTracker() const override { return true; }
9340             auto hasGenerator() const -> bool override {
9341             return !!m_generator;
9342             }
9343             void close() override {
9344             TrackerBase::close();
9345             if( m_runState == CompletedSuccessfully && m_index < m_generator->size()-1 )
9346             m_runState = Executing;
9347             }
9348              
9349             // IGeneratorTracker interface
9350             auto getGenerator() const -> GeneratorBasePtr const& override {
9351             return m_generator;
9352             }
9353             void setGenerator( GeneratorBasePtr&& generator ) override {
9354             m_generator = std::move( generator );
9355             }
9356             auto getIndex() const -> size_t override {
9357             return m_index;
9358             }
9359             };
9360             GeneratorTracker::~GeneratorTracker() {}
9361             }
9362              
9363             RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
9364             : m_runInfo(_config->name()),
9365             m_context(getCurrentMutableContext()),
9366             m_config(_config),
9367             m_reporter(std::move(reporter)),
9368             m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
9369             m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
9370             {
9371             m_context.setRunner(this);
9372             m_context.setConfig(m_config);
9373             m_context.setResultCapture(this);
9374             m_reporter->testRunStarting(m_runInfo);
9375             }
9376              
9377             RunContext::~RunContext() {
9378             m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
9379             }
9380              
9381             void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
9382             m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
9383             }
9384              
9385             void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
9386             m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
9387             }
9388              
9389             Totals RunContext::runTest(TestCase const& testCase) {
9390             Totals prevTotals = m_totals;
9391              
9392             std::string redirectedCout;
9393             std::string redirectedCerr;
9394              
9395             auto const& testInfo = testCase.getTestCaseInfo();
9396              
9397             m_reporter->testCaseStarting(testInfo);
9398              
9399             m_activeTestCase = &testCase;
9400              
9401             ITracker& rootTracker = m_trackerContext.startRun();
9402             assert(rootTracker.isSectionTracker());
9403             static_cast(rootTracker).addInitialFilters(m_config->getSectionsToRun());
9404             do {
9405             m_trackerContext.startCycle();
9406             m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
9407             runCurrentTest(redirectedCout, redirectedCerr);
9408             } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
9409              
9410             Totals deltaTotals = m_totals.delta(prevTotals);
9411             if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
9412             deltaTotals.assertions.failed++;
9413             deltaTotals.testCases.passed--;
9414             deltaTotals.testCases.failed++;
9415             }
9416             m_totals.testCases += deltaTotals.testCases;
9417             m_reporter->testCaseEnded(TestCaseStats(testInfo,
9418             deltaTotals,
9419             redirectedCout,
9420             redirectedCerr,
9421             aborting()));
9422              
9423             m_activeTestCase = nullptr;
9424             m_testCaseTracker = nullptr;
9425              
9426             return deltaTotals;
9427             }
9428              
9429             IConfigPtr RunContext::config() const {
9430             return m_config;
9431             }
9432              
9433             IStreamingReporter& RunContext::reporter() const {
9434             return *m_reporter;
9435             }
9436              
9437             void RunContext::assertionEnded(AssertionResult const & result) {
9438             if (result.getResultType() == ResultWas::Ok) {
9439             m_totals.assertions.passed++;
9440             m_lastAssertionPassed = true;
9441             } else if (!result.isOk()) {
9442             m_lastAssertionPassed = false;
9443             if( m_activeTestCase->getTestCaseInfo().okToFail() )
9444             m_totals.assertions.failedButOk++;
9445             else
9446             m_totals.assertions.failed++;
9447             }
9448             else {
9449             m_lastAssertionPassed = true;
9450             }
9451              
9452             // We have no use for the return value (whether messages should be cleared), because messages were made scoped
9453             // and should be let to clear themselves out.
9454             static_cast(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
9455              
9456             // Reset working state
9457             resetAssertionInfo();
9458             m_lastResult = result;
9459             }
9460             void RunContext::resetAssertionInfo() {
9461             m_lastAssertionInfo.macroName = StringRef();
9462             m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
9463             }
9464              
9465             bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
9466             ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
9467             if (!sectionTracker.isOpen())
9468             return false;
9469             m_activeSections.push_back(§ionTracker);
9470              
9471             m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
9472              
9473             m_reporter->sectionStarting(sectionInfo);
9474              
9475             assertions = m_totals.assertions;
9476              
9477             return true;
9478             }
9479             auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
9480             using namespace Generators;
9481             GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
9482             assert( tracker.isOpen() );
9483             m_lastAssertionInfo.lineInfo = lineInfo;
9484             return tracker;
9485             }
9486              
9487             bool RunContext::testForMissingAssertions(Counts& assertions) {
9488             if (assertions.total() != 0)
9489             return false;
9490             if (!m_config->warnAboutMissingAssertions())
9491             return false;
9492             if (m_trackerContext.currentTracker().hasChildren())
9493             return false;
9494             m_totals.assertions.failed++;
9495             assertions.failed++;
9496             return true;
9497             }
9498              
9499             void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
9500             Counts assertions = m_totals.assertions - endInfo.prevAssertions;
9501             bool missingAssertions = testForMissingAssertions(assertions);
9502              
9503             if (!m_activeSections.empty()) {
9504             m_activeSections.back()->close();
9505             m_activeSections.pop_back();
9506             }
9507              
9508             m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
9509             m_messages.clear();
9510             }
9511              
9512             void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
9513             if (m_unfinishedSections.empty())
9514             m_activeSections.back()->fail();
9515             else
9516             m_activeSections.back()->close();
9517             m_activeSections.pop_back();
9518              
9519             m_unfinishedSections.push_back(endInfo);
9520             }
9521             void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
9522             m_reporter->benchmarkStarting( info );
9523             }
9524             void RunContext::benchmarkEnded( BenchmarkStats const& stats ) {
9525             m_reporter->benchmarkEnded( stats );
9526             }
9527              
9528             void RunContext::pushScopedMessage(MessageInfo const & message) {
9529             m_messages.push_back(message);
9530             }
9531              
9532             void RunContext::popScopedMessage(MessageInfo const & message) {
9533             m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
9534             }
9535              
9536             std::string RunContext::getCurrentTestName() const {
9537             return m_activeTestCase
9538             ? m_activeTestCase->getTestCaseInfo().name
9539             : std::string();
9540             }
9541              
9542             const AssertionResult * RunContext::getLastResult() const {
9543             return &(*m_lastResult);
9544             }
9545              
9546             void RunContext::exceptionEarlyReported() {
9547             m_shouldReportUnexpected = false;
9548             }
9549              
9550             void RunContext::handleFatalErrorCondition( StringRef message ) {
9551             // First notify reporter that bad things happened
9552             m_reporter->fatalErrorEncountered(message);
9553              
9554             // Don't rebuild the result -- the stringification itself can cause more fatal errors
9555             // Instead, fake a result data.
9556             AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
9557             tempResult.message = message;
9558             AssertionResult result(m_lastAssertionInfo, tempResult);
9559              
9560             assertionEnded(result);
9561              
9562             handleUnfinishedSections();
9563              
9564             // Recreate section for test case (as we will lose the one that was in scope)
9565             auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
9566             SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
9567              
9568             Counts assertions;
9569             assertions.failed = 1;
9570             SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
9571             m_reporter->sectionEnded(testCaseSectionStats);
9572              
9573             auto const& testInfo = m_activeTestCase->getTestCaseInfo();
9574              
9575             Totals deltaTotals;
9576             deltaTotals.testCases.failed = 1;
9577             deltaTotals.assertions.failed = 1;
9578             m_reporter->testCaseEnded(TestCaseStats(testInfo,
9579             deltaTotals,
9580             std::string(),
9581             std::string(),
9582             false));
9583             m_totals.testCases.failed++;
9584             testGroupEnded(std::string(), m_totals, 1, 1);
9585             m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
9586             }
9587              
9588             bool RunContext::lastAssertionPassed() {
9589             return m_lastAssertionPassed;
9590             }
9591              
9592             void RunContext::assertionPassed() {
9593             m_lastAssertionPassed = true;
9594             ++m_totals.assertions.passed;
9595             resetAssertionInfo();
9596             }
9597              
9598             bool RunContext::aborting() const {
9599             return m_totals.assertions.failed == static_cast(m_config->abortAfter());
9600             }
9601              
9602             void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
9603             auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
9604             SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
9605             m_reporter->sectionStarting(testCaseSection);
9606             Counts prevAssertions = m_totals.assertions;
9607             double duration = 0;
9608             m_shouldReportUnexpected = true;
9609             m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
9610              
9611             seedRng(*m_config);
9612              
9613             Timer timer;
9614             CATCH_TRY {
9615             if (m_reporter->getPreferences().shouldRedirectStdOut) {
9616             #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
9617             RedirectedStdOut redirectedStdOut;
9618             RedirectedStdErr redirectedStdErr;
9619              
9620             timer.start();
9621             invokeActiveTestCase();
9622             redirectedCout += redirectedStdOut.str();
9623             redirectedCerr += redirectedStdErr.str();
9624             #else
9625             OutputRedirect r(redirectedCout, redirectedCerr);
9626             timer.start();
9627             invokeActiveTestCase();
9628             #endif
9629             } else {
9630             timer.start();
9631             invokeActiveTestCase();
9632             }
9633             duration = timer.getElapsedSeconds();
9634             } CATCH_CATCH_ANON (TestFailureException&) {
9635             // This just means the test was aborted due to failure
9636             } CATCH_CATCH_ALL {
9637             // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
9638             // are reported without translation at the point of origin.
9639             if( m_shouldReportUnexpected ) {
9640             AssertionReaction dummyReaction;
9641             handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
9642             }
9643             }
9644             Counts assertions = m_totals.assertions - prevAssertions;
9645             bool missingAssertions = testForMissingAssertions(assertions);
9646              
9647             m_testCaseTracker->close();
9648             handleUnfinishedSections();
9649             m_messages.clear();
9650              
9651             SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
9652             m_reporter->sectionEnded(testCaseSectionStats);
9653             }
9654              
9655             void RunContext::invokeActiveTestCase() {
9656             FatalConditionHandler fatalConditionHandler; // Handle signals
9657             m_activeTestCase->invoke();
9658             fatalConditionHandler.reset();
9659             }
9660              
9661             void RunContext::handleUnfinishedSections() {
9662             // If sections ended prematurely due to an exception we stored their
9663             // infos here so we can tear them down outside the unwind process.
9664             for (auto it = m_unfinishedSections.rbegin(),
9665             itEnd = m_unfinishedSections.rend();
9666             it != itEnd;
9667             ++it)
9668             sectionEnded(*it);
9669             m_unfinishedSections.clear();
9670             }
9671              
9672             void RunContext::handleExpr(
9673             AssertionInfo const& info,
9674             ITransientExpression const& expr,
9675             AssertionReaction& reaction
9676             ) {
9677             m_reporter->assertionStarting( info );
9678              
9679             bool negated = isFalseTest( info.resultDisposition );
9680             bool result = expr.getResult() != negated;
9681              
9682             if( result ) {
9683             if (!m_includeSuccessfulResults) {
9684             assertionPassed();
9685             }
9686             else {
9687             reportExpr(info, ResultWas::Ok, &expr, negated);
9688             }
9689             }
9690             else {
9691             reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
9692             populateReaction( reaction );
9693             }
9694             }
9695             void RunContext::reportExpr(
9696             AssertionInfo const &info,
9697             ResultWas::OfType resultType,
9698             ITransientExpression const *expr,
9699             bool negated ) {
9700              
9701             m_lastAssertionInfo = info;
9702             AssertionResultData data( resultType, LazyExpression( negated ) );
9703              
9704             AssertionResult assertionResult{ info, data };
9705             assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
9706              
9707             assertionEnded( assertionResult );
9708             }
9709              
9710             void RunContext::handleMessage(
9711             AssertionInfo const& info,
9712             ResultWas::OfType resultType,
9713             StringRef const& message,
9714             AssertionReaction& reaction
9715             ) {
9716             m_reporter->assertionStarting( info );
9717              
9718             m_lastAssertionInfo = info;
9719              
9720             AssertionResultData data( resultType, LazyExpression( false ) );
9721             data.message = message;
9722             AssertionResult assertionResult{ m_lastAssertionInfo, data };
9723             assertionEnded( assertionResult );
9724             if( !assertionResult.isOk() )
9725             populateReaction( reaction );
9726             }
9727             void RunContext::handleUnexpectedExceptionNotThrown(
9728             AssertionInfo const& info,
9729             AssertionReaction& reaction
9730             ) {
9731             handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
9732             }
9733              
9734             void RunContext::handleUnexpectedInflightException(
9735             AssertionInfo const& info,
9736             std::string const& message,
9737             AssertionReaction& reaction
9738             ) {
9739             m_lastAssertionInfo = info;
9740              
9741             AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
9742             data.message = message;
9743             AssertionResult assertionResult{ info, data };
9744             assertionEnded( assertionResult );
9745             populateReaction( reaction );
9746             }
9747              
9748             void RunContext::populateReaction( AssertionReaction& reaction ) {
9749             reaction.shouldDebugBreak = m_config->shouldDebugBreak();
9750             reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
9751             }
9752              
9753             void RunContext::handleIncomplete(
9754             AssertionInfo const& info
9755             ) {
9756             m_lastAssertionInfo = info;
9757              
9758             AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
9759             data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
9760             AssertionResult assertionResult{ info, data };
9761             assertionEnded( assertionResult );
9762             }
9763             void RunContext::handleNonExpr(
9764             AssertionInfo const &info,
9765             ResultWas::OfType resultType,
9766             AssertionReaction &reaction
9767             ) {
9768             m_lastAssertionInfo = info;
9769              
9770             AssertionResultData data( resultType, LazyExpression( false ) );
9771             AssertionResult assertionResult{ info, data };
9772             assertionEnded( assertionResult );
9773              
9774             if( !assertionResult.isOk() )
9775             populateReaction( reaction );
9776             }
9777              
9778             IResultCapture& getResultCapture() {
9779             if (auto* capture = getCurrentContext().getResultCapture())
9780             return *capture;
9781             else
9782             CATCH_INTERNAL_ERROR("No result capture instance");
9783             }
9784             }
9785             // end catch_run_context.cpp
9786             // start catch_section.cpp
9787              
9788             namespace Catch {
9789              
9790             Section::Section( SectionInfo const& info )
9791             : m_info( info ),
9792             m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
9793             {
9794             m_timer.start();
9795             }
9796              
9797             Section::~Section() {
9798             if( m_sectionIncluded ) {
9799             SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
9800             if( uncaught_exceptions() )
9801             getResultCapture().sectionEndedEarly( endInfo );
9802             else
9803             getResultCapture().sectionEnded( endInfo );
9804             }
9805             }
9806              
9807             // This indicates whether the section should be executed or not
9808             Section::operator bool() const {
9809             return m_sectionIncluded;
9810             }
9811              
9812             } // end namespace Catch
9813             // end catch_section.cpp
9814             // start catch_section_info.cpp
9815              
9816             namespace Catch {
9817              
9818             SectionInfo::SectionInfo
9819             ( SourceLineInfo const& _lineInfo,
9820             std::string const& _name )
9821             : name( _name ),
9822             lineInfo( _lineInfo )
9823             {}
9824              
9825             } // end namespace Catch
9826             // end catch_section_info.cpp
9827             // start catch_session.cpp
9828              
9829             // start catch_session.h
9830              
9831             #include
9832              
9833             namespace Catch {
9834              
9835             class Session : NonCopyable {
9836             public:
9837              
9838             Session();
9839             ~Session() override;
9840              
9841             void showHelp() const;
9842             void libIdentify();
9843              
9844             int applyCommandLine( int argc, char const * const * argv );
9845              
9846             void useConfigData( ConfigData const& configData );
9847              
9848             int run( int argc, char* argv[] );
9849             #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
9850             int run( int argc, wchar_t* const argv[] );
9851             #endif
9852             int run();
9853              
9854             clara::Parser const& cli() const;
9855             void cli( clara::Parser const& newParser );
9856             ConfigData& configData();
9857             Config& config();
9858             private:
9859             int runInternal();
9860              
9861             clara::Parser m_cli;
9862             ConfigData m_configData;
9863             std::shared_ptr m_config;
9864             bool m_startupExceptions = false;
9865             };
9866              
9867             } // end namespace Catch
9868              
9869             // end catch_session.h
9870             // start catch_version.h
9871              
9872             #include
9873              
9874             namespace Catch {
9875              
9876             // Versioning information
9877             struct Version {
9878             Version( Version const& ) = delete;
9879             Version& operator=( Version const& ) = delete;
9880             Version( unsigned int _majorVersion,
9881             unsigned int _minorVersion,
9882             unsigned int _patchNumber,
9883             char const * const _branchName,
9884             unsigned int _buildNumber );
9885              
9886             unsigned int const majorVersion;
9887             unsigned int const minorVersion;
9888             unsigned int const patchNumber;
9889              
9890             // buildNumber is only used if branchName is not null
9891             char const * const branchName;
9892             unsigned int const buildNumber;
9893              
9894             friend std::ostream& operator << ( std::ostream& os, Version const& version );
9895             };
9896              
9897             Version const& libraryVersion();
9898             }
9899              
9900             // end catch_version.h
9901             #include
9902             #include
9903              
9904             namespace Catch {
9905              
9906             namespace {
9907             const int MaxExitCode = 255;
9908              
9909             IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
9910             auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
9911             CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
9912              
9913             return reporter;
9914             }
9915              
9916             IStreamingReporterPtr makeReporter(std::shared_ptr const& config) {
9917             if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
9918             return createReporter(config->getReporterName(), config);
9919             }
9920              
9921             auto multi = std::unique_ptr(new ListeningReporter);
9922              
9923             auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
9924             for (auto const& listener : listeners) {
9925             multi->addListener(listener->create(Catch::ReporterConfig(config)));
9926             }
9927             multi->addReporter(createReporter(config->getReporterName(), config));
9928             return std::move(multi);
9929             }
9930              
9931             Catch::Totals runTests(std::shared_ptr const& config) {
9932             // FixMe: Add listeners in order first, then add reporters.
9933              
9934             auto reporter = makeReporter(config);
9935              
9936             RunContext context(config, std::move(reporter));
9937              
9938             Totals totals;
9939              
9940             context.testGroupStarting(config->name(), 1, 1);
9941              
9942             TestSpec testSpec = config->testSpec();
9943              
9944             auto const& allTestCases = getAllTestCasesSorted(*config);
9945             for (auto const& testCase : allTestCases) {
9946             if (!context.aborting() && matchTest(testCase, testSpec, *config))
9947             totals += context.runTest(testCase);
9948             else
9949             context.reporter().skipTest(testCase);
9950             }
9951              
9952             if (config->warnAboutNoTests() && totals.testCases.total() == 0) {
9953             ReusableStringStream testConfig;
9954              
9955             bool first = true;
9956             for (const auto& input : config->getTestsOrTags()) {
9957             if (!first) { testConfig << ' '; }
9958             first = false;
9959             testConfig << input;
9960             }
9961              
9962             context.reporter().noMatchingTestCases(testConfig.str());
9963             totals.error = -1;
9964             }
9965              
9966             context.testGroupEnded(config->name(), totals, 1, 1);
9967             return totals;
9968             }
9969              
9970             void applyFilenamesAsTags(Catch::IConfig const& config) {
9971             auto& tests = const_cast&>(getAllTestCasesSorted(config));
9972             for (auto& testCase : tests) {
9973             auto tags = testCase.tags;
9974              
9975             std::string filename = testCase.lineInfo.file;
9976             auto lastSlash = filename.find_last_of("\\/");
9977             if (lastSlash != std::string::npos) {
9978             filename.erase(0, lastSlash);
9979             filename[0] = '#';
9980             }
9981              
9982             auto lastDot = filename.find_last_of('.');
9983             if (lastDot != std::string::npos) {
9984             filename.erase(lastDot);
9985             }
9986              
9987             tags.push_back(std::move(filename));
9988             setTags(testCase, tags);
9989             }
9990             }
9991              
9992             } // anon namespace
9993              
9994             Session::Session() {
9995             static bool alreadyInstantiated = false;
9996             if( alreadyInstantiated ) {
9997             CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
9998             CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
9999             }
10000              
10001             // There cannot be exceptions at startup in no-exception mode.
10002             #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10003             const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
10004             if ( !exceptions.empty() ) {
10005             m_startupExceptions = true;
10006             Colour colourGuard( Colour::Red );
10007             Catch::cerr() << "Errors occurred during startup!" << '\n';
10008             // iterate over all exceptions and notify user
10009             for ( const auto& ex_ptr : exceptions ) {
10010             try {
10011             std::rethrow_exception(ex_ptr);
10012             } catch ( std::exception const& ex ) {
10013             Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
10014             }
10015             }
10016             }
10017             #endif
10018              
10019             alreadyInstantiated = true;
10020             m_cli = makeCommandLineParser( m_configData );
10021             }
10022             Session::~Session() {
10023             Catch::cleanUp();
10024             }
10025              
10026             void Session::showHelp() const {
10027             Catch::cout()
10028             << "\nCatch v" << libraryVersion() << "\n"
10029             << m_cli << std::endl
10030             << "For more detailed usage please see the project docs\n" << std::endl;
10031             }
10032             void Session::libIdentify() {
10033             Catch::cout()
10034             << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
10035             << std::left << std::setw(16) << "category: " << "testframework\n"
10036             << std::left << std::setw(16) << "framework: " << "Catch Test\n"
10037             << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
10038             }
10039              
10040             int Session::applyCommandLine( int argc, char const * const * argv ) {
10041             if( m_startupExceptions )
10042             return 1;
10043              
10044             auto result = m_cli.parse( clara::Args( argc, argv ) );
10045             if( !result ) {
10046             Catch::cerr()
10047             << Colour( Colour::Red )
10048             << "\nError(s) in input:\n"
10049             << Column( result.errorMessage() ).indent( 2 )
10050             << "\n\n";
10051             Catch::cerr() << "Run with -? for usage\n" << std::endl;
10052             return MaxExitCode;
10053             }
10054              
10055             if( m_configData.showHelp )
10056             showHelp();
10057             if( m_configData.libIdentify )
10058             libIdentify();
10059             m_config.reset();
10060             return 0;
10061             }
10062              
10063             void Session::useConfigData( ConfigData const& configData ) {
10064             m_configData = configData;
10065             m_config.reset();
10066             }
10067              
10068             int Session::run( int argc, char* argv[] ) {
10069             if( m_startupExceptions )
10070             return 1;
10071             int returnCode = applyCommandLine( argc, argv );
10072             if( returnCode == 0 )
10073             returnCode = run();
10074             return returnCode;
10075             }
10076              
10077             #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
10078             int Session::run( int argc, wchar_t* const argv[] ) {
10079              
10080             char **utf8Argv = new char *[ argc ];
10081              
10082             for ( int i = 0; i < argc; ++i ) {
10083             int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
10084              
10085             utf8Argv[ i ] = new char[ bufSize ];
10086              
10087             WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
10088             }
10089              
10090             int returnCode = run( argc, utf8Argv );
10091              
10092             for ( int i = 0; i < argc; ++i )
10093             delete [] utf8Argv[ i ];
10094              
10095             delete [] utf8Argv;
10096              
10097             return returnCode;
10098             }
10099             #endif
10100             int Session::run() {
10101             if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
10102             Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
10103             static_cast(std::getchar());
10104             }
10105             int exitCode = runInternal();
10106             if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
10107             Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
10108             static_cast(std::getchar());
10109             }
10110             return exitCode;
10111             }
10112              
10113             clara::Parser const& Session::cli() const {
10114             return m_cli;
10115             }
10116             void Session::cli( clara::Parser const& newParser ) {
10117             m_cli = newParser;
10118             }
10119             ConfigData& Session::configData() {
10120             return m_configData;
10121             }
10122             Config& Session::config() {
10123             if( !m_config )
10124             m_config = std::make_shared( m_configData );
10125             return *m_config;
10126             }
10127              
10128             int Session::runInternal() {
10129             if( m_startupExceptions )
10130             return 1;
10131              
10132             if (m_configData.showHelp || m_configData.libIdentify) {
10133             return 0;
10134             }
10135              
10136             CATCH_TRY {
10137             config(); // Force config to be constructed
10138              
10139             seedRng( *m_config );
10140              
10141             if( m_configData.filenamesAsTags )
10142             applyFilenamesAsTags( *m_config );
10143              
10144             // Handle list request
10145             if( Option listed = list( config() ) )
10146             return static_cast( *listed );
10147              
10148             auto totals = runTests( m_config );
10149             // Note that on unices only the lower 8 bits are usually used, clamping
10150             // the return value to 255 prevents false negative when some multiple
10151             // of 256 tests has failed
10152             return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast(totals.assertions.failed)));
10153             }
10154             #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10155             catch( std::exception& ex ) {
10156             Catch::cerr() << ex.what() << std::endl;
10157             return MaxExitCode;
10158             }
10159             #endif
10160             }
10161              
10162             } // end namespace Catch
10163             // end catch_session.cpp
10164             // start catch_singletons.cpp
10165              
10166             #include
10167              
10168             namespace Catch {
10169              
10170             namespace {
10171             static auto getSingletons() -> std::vector*& {
10172             static std::vector* g_singletons = nullptr;
10173             if( !g_singletons )
10174             g_singletons = new std::vector();
10175             return g_singletons;
10176             }
10177             }
10178              
10179             ISingleton::~ISingleton() {}
10180              
10181             void addSingleton(ISingleton* singleton ) {
10182             getSingletons()->push_back( singleton );
10183             }
10184             void cleanupSingletons() {
10185             auto& singletons = getSingletons();
10186             for( auto singleton : *singletons )
10187             delete singleton;
10188             delete singletons;
10189             singletons = nullptr;
10190             }
10191              
10192             } // namespace Catch
10193             // end catch_singletons.cpp
10194             // start catch_startup_exception_registry.cpp
10195              
10196             namespace Catch {
10197             void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
10198             CATCH_TRY {
10199             m_exceptions.push_back(exception);
10200             } CATCH_CATCH_ALL {
10201             // If we run out of memory during start-up there's really not a lot more we can do about it
10202             std::terminate();
10203             }
10204             }
10205              
10206             std::vector const& StartupExceptionRegistry::getExceptions() const noexcept {
10207             return m_exceptions;
10208             }
10209              
10210             } // end namespace Catch
10211             // end catch_startup_exception_registry.cpp
10212             // start catch_stream.cpp
10213              
10214             #include
10215             #include
10216             #include
10217             #include
10218             #include
10219             #include
10220              
10221             namespace Catch {
10222              
10223             Catch::IStream::~IStream() = default;
10224              
10225             namespace detail { namespace {
10226             template
10227             class StreamBufImpl : public std::streambuf {
10228             char data[bufferSize];
10229             WriterF m_writer;
10230              
10231             public:
10232             StreamBufImpl() {
10233             setp( data, data + sizeof(data) );
10234             }
10235              
10236             ~StreamBufImpl() noexcept {
10237             StreamBufImpl::sync();
10238             }
10239              
10240             private:
10241             int overflow( int c ) override {
10242             sync();
10243              
10244             if( c != EOF ) {
10245             if( pbase() == epptr() )
10246             m_writer( std::string( 1, static_cast( c ) ) );
10247             else
10248             sputc( static_cast( c ) );
10249             }
10250             return 0;
10251             }
10252              
10253             int sync() override {
10254             if( pbase() != pptr() ) {
10255             m_writer( std::string( pbase(), static_cast( pptr() - pbase() ) ) );
10256             setp( pbase(), epptr() );
10257             }
10258             return 0;
10259             }
10260             };
10261              
10262             ///////////////////////////////////////////////////////////////////////////
10263              
10264             struct OutputDebugWriter {
10265              
10266             void operator()( std::string const&str ) {
10267             writeToDebugConsole( str );
10268             }
10269             };
10270              
10271             ///////////////////////////////////////////////////////////////////////////
10272              
10273             class FileStream : public IStream {
10274             mutable std::ofstream m_ofs;
10275             public:
10276             FileStream( StringRef filename ) {
10277             m_ofs.open( filename.c_str() );
10278             CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
10279             }
10280             ~FileStream() override = default;
10281             public: // IStream
10282             std::ostream& stream() const override {
10283             return m_ofs;
10284             }
10285             };
10286              
10287             ///////////////////////////////////////////////////////////////////////////
10288              
10289             class CoutStream : public IStream {
10290             mutable std::ostream m_os;
10291             public:
10292             // Store the streambuf from cout up-front because
10293             // cout may get redirected when running tests
10294             CoutStream() : m_os( Catch::cout().rdbuf() ) {}
10295             ~CoutStream() override = default;
10296              
10297             public: // IStream
10298             std::ostream& stream() const override { return m_os; }
10299             };
10300              
10301             ///////////////////////////////////////////////////////////////////////////
10302              
10303             class DebugOutStream : public IStream {
10304             std::unique_ptr> m_streamBuf;
10305             mutable std::ostream m_os;
10306             public:
10307             DebugOutStream()
10308             : m_streamBuf( new StreamBufImpl() ),
10309             m_os( m_streamBuf.get() )
10310             {}
10311              
10312             ~DebugOutStream() override = default;
10313              
10314             public: // IStream
10315             std::ostream& stream() const override { return m_os; }
10316             };
10317              
10318             }} // namespace anon::detail
10319              
10320             ///////////////////////////////////////////////////////////////////////////
10321              
10322             auto makeStream( StringRef const &filename ) -> IStream const* {
10323             if( filename.empty() )
10324             return new detail::CoutStream();
10325             else if( filename[0] == '%' ) {
10326             if( filename == "%debug" )
10327             return new detail::DebugOutStream();
10328             else
10329             CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
10330             }
10331             else
10332             return new detail::FileStream( filename );
10333             }
10334              
10335             // This class encapsulates the idea of a pool of ostringstreams that can be reused.
10336             struct StringStreams {
10337             std::vector> m_streams;
10338             std::vector m_unused;
10339             std::ostringstream m_referenceStream; // Used for copy state/ flags from
10340              
10341             auto add() -> std::size_t {
10342             if( m_unused.empty() ) {
10343             m_streams.push_back( std::unique_ptr( new std::ostringstream ) );
10344             return m_streams.size()-1;
10345             }
10346             else {
10347             auto index = m_unused.back();
10348             m_unused.pop_back();
10349             return index;
10350             }
10351             }
10352              
10353             void release( std::size_t index ) {
10354             m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
10355             m_unused.push_back(index);
10356             }
10357             };
10358              
10359             ReusableStringStream::ReusableStringStream()
10360             : m_index( Singleton::getMutable().add() ),
10361             m_oss( Singleton::getMutable().m_streams[m_index].get() )
10362             {}
10363              
10364             ReusableStringStream::~ReusableStringStream() {
10365             static_cast( m_oss )->str("");
10366             m_oss->clear();
10367             Singleton::getMutable().release( m_index );
10368             }
10369              
10370             auto ReusableStringStream::str() const -> std::string {
10371             return static_cast( m_oss )->str();
10372             }
10373              
10374             ///////////////////////////////////////////////////////////////////////////
10375              
10376             #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
10377             std::ostream& cout() { return std::cout; }
10378             std::ostream& cerr() { return std::cerr; }
10379             std::ostream& clog() { return std::clog; }
10380             #endif
10381             }
10382             // end catch_stream.cpp
10383             // start catch_string_manip.cpp
10384              
10385             #include
10386             #include
10387             #include
10388             #include
10389              
10390             namespace Catch {
10391              
10392             namespace {
10393             char toLowerCh(char c) {
10394             return static_cast( std::tolower( c ) );
10395             }
10396             }
10397              
10398             bool startsWith( std::string const& s, std::string const& prefix ) {
10399             return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
10400             }
10401             bool startsWith( std::string const& s, char prefix ) {
10402             return !s.empty() && s[0] == prefix;
10403             }
10404             bool endsWith( std::string const& s, std::string const& suffix ) {
10405             return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
10406             }
10407             bool endsWith( std::string const& s, char suffix ) {
10408             return !s.empty() && s[s.size()-1] == suffix;
10409             }
10410             bool contains( std::string const& s, std::string const& infix ) {
10411             return s.find( infix ) != std::string::npos;
10412             }
10413             void toLowerInPlace( std::string& s ) {
10414             std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
10415             }
10416             std::string toLower( std::string const& s ) {
10417             std::string lc = s;
10418             toLowerInPlace( lc );
10419             return lc;
10420             }
10421             std::string trim( std::string const& str ) {
10422             static char const* whitespaceChars = "\n\r\t ";
10423             std::string::size_type start = str.find_first_not_of( whitespaceChars );
10424             std::string::size_type end = str.find_last_not_of( whitespaceChars );
10425              
10426             return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
10427             }
10428              
10429             bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
10430             bool replaced = false;
10431             std::size_t i = str.find( replaceThis );
10432             while( i != std::string::npos ) {
10433             replaced = true;
10434             str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
10435             if( i < str.size()-withThis.size() )
10436             i = str.find( replaceThis, i+withThis.size() );
10437             else
10438             i = std::string::npos;
10439             }
10440             return replaced;
10441             }
10442              
10443             pluralise::pluralise( std::size_t count, std::string const& label )
10444             : m_count( count ),
10445             m_label( label )
10446             {}
10447              
10448             std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
10449             os << pluraliser.m_count << ' ' << pluraliser.m_label;
10450             if( pluraliser.m_count != 1 )
10451             os << 's';
10452             return os;
10453             }
10454              
10455             }
10456             // end catch_string_manip.cpp
10457             // start catch_stringref.cpp
10458              
10459             #if defined(__clang__)
10460             # pragma clang diagnostic push
10461             # pragma clang diagnostic ignored "-Wexit-time-destructors"
10462             #endif
10463              
10464             #include
10465             #include
10466             #include
10467              
10468             namespace {
10469             const uint32_t byte_2_lead = 0xC0;
10470             const uint32_t byte_3_lead = 0xE0;
10471             const uint32_t byte_4_lead = 0xF0;
10472             }
10473              
10474             namespace Catch {
10475             StringRef::StringRef( char const* rawChars ) noexcept
10476             : StringRef( rawChars, static_cast(std::strlen(rawChars) ) )
10477             {}
10478              
10479             StringRef::operator std::string() const {
10480             return std::string( m_start, m_size );
10481             }
10482              
10483             void StringRef::swap( StringRef& other ) noexcept {
10484             std::swap( m_start, other.m_start );
10485             std::swap( m_size, other.m_size );
10486             std::swap( m_data, other.m_data );
10487             }
10488              
10489             auto StringRef::c_str() const -> char const* {
10490             if( isSubstring() )
10491             const_cast( this )->takeOwnership();
10492             return m_start;
10493             }
10494             auto StringRef::currentData() const noexcept -> char const* {
10495             return m_start;
10496             }
10497              
10498             auto StringRef::isOwned() const noexcept -> bool {
10499             return m_data != nullptr;
10500             }
10501             auto StringRef::isSubstring() const noexcept -> bool {
10502             return m_start[m_size] != '\0';
10503             }
10504              
10505             void StringRef::takeOwnership() {
10506             if( !isOwned() ) {
10507             m_data = new char[m_size+1];
10508             memcpy( m_data, m_start, m_size );
10509             m_data[m_size] = '\0';
10510             m_start = m_data;
10511             }
10512             }
10513             auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
10514             if( start < m_size )
10515             return StringRef( m_start+start, size );
10516             else
10517             return StringRef();
10518             }
10519             auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
10520             return
10521             size() == other.size() &&
10522             (std::strncmp( m_start, other.m_start, size() ) == 0);
10523             }
10524             auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool {
10525             return !operator==( other );
10526             }
10527              
10528             auto StringRef::operator[](size_type index) const noexcept -> char {
10529             return m_start[index];
10530             }
10531              
10532             auto StringRef::numberOfCharacters() const noexcept -> size_type {
10533             size_type noChars = m_size;
10534             // Make adjustments for uft encodings
10535             for( size_type i=0; i < m_size; ++i ) {
10536             char c = m_start[i];
10537             if( ( c & byte_2_lead ) == byte_2_lead ) {
10538             noChars--;
10539             if (( c & byte_3_lead ) == byte_3_lead )
10540             noChars--;
10541             if( ( c & byte_4_lead ) == byte_4_lead )
10542             noChars--;
10543             }
10544             }
10545             return noChars;
10546             }
10547              
10548             auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string {
10549             std::string str;
10550             str.reserve( lhs.size() + rhs.size() );
10551             str += lhs;
10552             str += rhs;
10553             return str;
10554             }
10555             auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string {
10556             return std::string( lhs ) + std::string( rhs );
10557             }
10558             auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string {
10559             return std::string( lhs ) + std::string( rhs );
10560             }
10561              
10562             auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
10563             return os.write(str.currentData(), str.size());
10564             }
10565              
10566             auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
10567             lhs.append(rhs.currentData(), rhs.size());
10568             return lhs;
10569             }
10570              
10571             } // namespace Catch
10572              
10573             #if defined(__clang__)
10574             # pragma clang diagnostic pop
10575             #endif
10576             // end catch_stringref.cpp
10577             // start catch_tag_alias.cpp
10578              
10579             namespace Catch {
10580             TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
10581             }
10582             // end catch_tag_alias.cpp
10583             // start catch_tag_alias_autoregistrar.cpp
10584              
10585             namespace Catch {
10586              
10587             RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
10588             CATCH_TRY {
10589             getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
10590             } CATCH_CATCH_ALL {
10591             // Do not throw when constructing global objects, instead register the exception to be processed later
10592             getMutableRegistryHub().registerStartupException();
10593             }
10594             }
10595              
10596             }
10597             // end catch_tag_alias_autoregistrar.cpp
10598             // start catch_tag_alias_registry.cpp
10599              
10600             #include
10601              
10602             namespace Catch {
10603              
10604             TagAliasRegistry::~TagAliasRegistry() {}
10605              
10606             TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
10607             auto it = m_registry.find( alias );
10608             if( it != m_registry.end() )
10609             return &(it->second);
10610             else
10611             return nullptr;
10612             }
10613              
10614             std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
10615             std::string expandedTestSpec = unexpandedTestSpec;
10616             for( auto const& registryKvp : m_registry ) {
10617             std::size_t pos = expandedTestSpec.find( registryKvp.first );
10618             if( pos != std::string::npos ) {
10619             expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
10620             registryKvp.second.tag +
10621             expandedTestSpec.substr( pos + registryKvp.first.size() );
10622             }
10623             }
10624             return expandedTestSpec;
10625             }
10626              
10627             void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
10628             CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
10629             "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
10630              
10631             CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
10632             "error: tag alias, '" << alias << "' already registered.\n"
10633             << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
10634             << "\tRedefined at: " << lineInfo );
10635             }
10636              
10637             ITagAliasRegistry::~ITagAliasRegistry() {}
10638              
10639             ITagAliasRegistry const& ITagAliasRegistry::get() {
10640             return getRegistryHub().getTagAliasRegistry();
10641             }
10642              
10643             } // end namespace Catch
10644             // end catch_tag_alias_registry.cpp
10645             // start catch_test_case_info.cpp
10646              
10647             #include
10648             #include
10649             #include
10650             #include
10651              
10652             namespace Catch {
10653              
10654             namespace {
10655             TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
10656             if( startsWith( tag, '.' ) ||
10657             tag == "!hide" )
10658             return TestCaseInfo::IsHidden;
10659             else if( tag == "!throws" )
10660             return TestCaseInfo::Throws;
10661             else if( tag == "!shouldfail" )
10662             return TestCaseInfo::ShouldFail;
10663             else if( tag == "!mayfail" )
10664             return TestCaseInfo::MayFail;
10665             else if( tag == "!nonportable" )
10666             return TestCaseInfo::NonPortable;
10667             else if( tag == "!benchmark" )
10668             return static_cast( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
10669             else
10670             return TestCaseInfo::None;
10671             }
10672             bool isReservedTag( std::string const& tag ) {
10673             return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast(tag[0]) );
10674             }
10675             void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
10676             CATCH_ENFORCE( !isReservedTag(tag),
10677             "Tag name: [" << tag << "] is not allowed.\n"
10678             << "Tag names starting with non alpha-numeric characters are reserved\n"
10679             << _lineInfo );
10680             }
10681             }
10682              
10683             TestCase makeTestCase( ITestInvoker* _testCase,
10684             std::string const& _className,
10685             NameAndTags const& nameAndTags,
10686             SourceLineInfo const& _lineInfo )
10687             {
10688             bool isHidden = false;
10689              
10690             // Parse out tags
10691             std::vector tags;
10692             std::string desc, tag;
10693             bool inTag = false;
10694             std::string _descOrTags = nameAndTags.tags;
10695             for (char c : _descOrTags) {
10696             if( !inTag ) {
10697             if( c == '[' )
10698             inTag = true;
10699             else
10700             desc += c;
10701             }
10702             else {
10703             if( c == ']' ) {
10704             TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
10705             if( ( prop & TestCaseInfo::IsHidden ) != 0 )
10706             isHidden = true;
10707             else if( prop == TestCaseInfo::None )
10708             enforceNotReservedTag( tag, _lineInfo );
10709              
10710             tags.push_back( tag );
10711             tag.clear();
10712             inTag = false;
10713             }
10714             else
10715             tag += c;
10716             }
10717             }
10718             if( isHidden ) {
10719             tags.push_back( "." );
10720             }
10721              
10722             TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo );
10723             return TestCase( _testCase, std::move(info) );
10724             }
10725              
10726             void setTags( TestCaseInfo& testCaseInfo, std::vector tags ) {
10727             std::sort(begin(tags), end(tags));
10728             tags.erase(std::unique(begin(tags), end(tags)), end(tags));
10729             testCaseInfo.lcaseTags.clear();
10730              
10731             for( auto const& tag : tags ) {
10732             std::string lcaseTag = toLower( tag );
10733             testCaseInfo.properties = static_cast( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
10734             testCaseInfo.lcaseTags.push_back( lcaseTag );
10735             }
10736             testCaseInfo.tags = std::move(tags);
10737             }
10738              
10739             TestCaseInfo::TestCaseInfo( std::string const& _name,
10740             std::string const& _className,
10741             std::string const& _description,
10742             std::vector const& _tags,
10743             SourceLineInfo const& _lineInfo )
10744             : name( _name ),
10745             className( _className ),
10746             description( _description ),
10747             lineInfo( _lineInfo ),
10748             properties( None )
10749             {
10750             setTags( *this, _tags );
10751             }
10752              
10753             bool TestCaseInfo::isHidden() const {
10754             return ( properties & IsHidden ) != 0;
10755             }
10756             bool TestCaseInfo::throws() const {
10757             return ( properties & Throws ) != 0;
10758             }
10759             bool TestCaseInfo::okToFail() const {
10760             return ( properties & (ShouldFail | MayFail ) ) != 0;
10761             }
10762             bool TestCaseInfo::expectedToFail() const {
10763             return ( properties & (ShouldFail ) ) != 0;
10764             }
10765              
10766             std::string TestCaseInfo::tagsAsString() const {
10767             std::string ret;
10768             // '[' and ']' per tag
10769             std::size_t full_size = 2 * tags.size();
10770             for (const auto& tag : tags) {
10771             full_size += tag.size();
10772             }
10773             ret.reserve(full_size);
10774             for (const auto& tag : tags) {
10775             ret.push_back('[');
10776             ret.append(tag);
10777             ret.push_back(']');
10778             }
10779              
10780             return ret;
10781             }
10782              
10783             TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
10784              
10785             TestCase TestCase::withName( std::string const& _newName ) const {
10786             TestCase other( *this );
10787             other.name = _newName;
10788             return other;
10789             }
10790              
10791             void TestCase::invoke() const {
10792             test->invoke();
10793             }
10794              
10795             bool TestCase::operator == ( TestCase const& other ) const {
10796             return test.get() == other.test.get() &&
10797             name == other.name &&
10798             className == other.className;
10799             }
10800              
10801             bool TestCase::operator < ( TestCase const& other ) const {
10802             return name < other.name;
10803             }
10804              
10805             TestCaseInfo const& TestCase::getTestCaseInfo() const
10806             {
10807             return *this;
10808             }
10809              
10810             } // end namespace Catch
10811             // end catch_test_case_info.cpp
10812             // start catch_test_case_registry_impl.cpp
10813              
10814             #include
10815              
10816             namespace Catch {
10817              
10818             std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ) {
10819              
10820             std::vector sorted = unsortedTestCases;
10821              
10822             switch( config.runOrder() ) {
10823             case RunTests::InLexicographicalOrder:
10824             std::sort( sorted.begin(), sorted.end() );
10825             break;
10826             case RunTests::InRandomOrder:
10827             seedRng( config );
10828             std::shuffle( sorted.begin(), sorted.end(), rng() );
10829             break;
10830             case RunTests::InDeclarationOrder:
10831             // already in declaration order
10832             break;
10833             }
10834             return sorted;
10835             }
10836             bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
10837             return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
10838             }
10839              
10840             void enforceNoDuplicateTestCases( std::vector const& functions ) {
10841             std::set seenFunctions;
10842             for( auto const& function : functions ) {
10843             auto prev = seenFunctions.insert( function );
10844             CATCH_ENFORCE( prev.second,
10845             "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
10846             << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
10847             << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
10848             }
10849             }
10850              
10851             std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ) {
10852             std::vector filtered;
10853             filtered.reserve( testCases.size() );
10854             for( auto const& testCase : testCases )
10855             if( matchTest( testCase, testSpec, config ) )
10856             filtered.push_back( testCase );
10857             return filtered;
10858             }
10859             std::vector const& getAllTestCasesSorted( IConfig const& config ) {
10860             return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
10861             }
10862              
10863             void TestRegistry::registerTest( TestCase const& testCase ) {
10864             std::string name = testCase.getTestCaseInfo().name;
10865             if( name.empty() ) {
10866             ReusableStringStream rss;
10867             rss << "Anonymous test case " << ++m_unnamedCount;
10868             return registerTest( testCase.withName( rss.str() ) );
10869             }
10870             m_functions.push_back( testCase );
10871             }
10872              
10873             std::vector const& TestRegistry::getAllTests() const {
10874             return m_functions;
10875             }
10876             std::vector const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
10877             if( m_sortedFunctions.empty() )
10878             enforceNoDuplicateTestCases( m_functions );
10879              
10880             if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
10881             m_sortedFunctions = sortTests( config, m_functions );
10882             m_currentSortOrder = config.runOrder();
10883             }
10884             return m_sortedFunctions;
10885             }
10886              
10887             ///////////////////////////////////////////////////////////////////////////
10888             TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
10889              
10890             void TestInvokerAsFunction::invoke() const {
10891             m_testAsFunction();
10892             }
10893              
10894             std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
10895             std::string className = classOrQualifiedMethodName;
10896             if( startsWith( className, '&' ) )
10897             {
10898             std::size_t lastColons = className.rfind( "::" );
10899             std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
10900             if( penultimateColons == std::string::npos )
10901             penultimateColons = 1;
10902             className = className.substr( penultimateColons, lastColons-penultimateColons );
10903             }
10904             return className;
10905             }
10906              
10907             } // end namespace Catch
10908             // end catch_test_case_registry_impl.cpp
10909             // start catch_test_case_tracker.cpp
10910              
10911             #include
10912             #include
10913             #include
10914             #include
10915             #include
10916              
10917             #if defined(__clang__)
10918             # pragma clang diagnostic push
10919             # pragma clang diagnostic ignored "-Wexit-time-destructors"
10920             #endif
10921              
10922             namespace Catch {
10923             namespace TestCaseTracking {
10924              
10925             NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
10926             : name( _name ),
10927             location( _location )
10928             {}
10929              
10930             ITracker::~ITracker() = default;
10931              
10932             TrackerContext& TrackerContext::instance() {
10933             static TrackerContext s_instance;
10934             return s_instance;
10935             }
10936              
10937             ITracker& TrackerContext::startRun() {
10938             m_rootTracker = std::make_shared( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
10939             m_currentTracker = nullptr;
10940             m_runState = Executing;
10941             return *m_rootTracker;
10942             }
10943              
10944             void TrackerContext::endRun() {
10945             m_rootTracker.reset();
10946             m_currentTracker = nullptr;
10947             m_runState = NotStarted;
10948             }
10949              
10950             void TrackerContext::startCycle() {
10951             m_currentTracker = m_rootTracker.get();
10952             m_runState = Executing;
10953             }
10954             void TrackerContext::completeCycle() {
10955             m_runState = CompletedCycle;
10956             }
10957              
10958             bool TrackerContext::completedCycle() const {
10959             return m_runState == CompletedCycle;
10960             }
10961             ITracker& TrackerContext::currentTracker() {
10962             return *m_currentTracker;
10963             }
10964             void TrackerContext::setCurrentTracker( ITracker* tracker ) {
10965             m_currentTracker = tracker;
10966             }
10967              
10968             TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
10969             : m_nameAndLocation( nameAndLocation ),
10970             m_ctx( ctx ),
10971             m_parent( parent )
10972             {}
10973              
10974             NameAndLocation const& TrackerBase::nameAndLocation() const {
10975             return m_nameAndLocation;
10976             }
10977             bool TrackerBase::isComplete() const {
10978             return m_runState == CompletedSuccessfully || m_runState == Failed;
10979             }
10980             bool TrackerBase::isSuccessfullyCompleted() const {
10981             return m_runState == CompletedSuccessfully;
10982             }
10983             bool TrackerBase::isOpen() const {
10984             return m_runState != NotStarted && !isComplete();
10985             }
10986             bool TrackerBase::hasChildren() const {
10987             return !m_children.empty();
10988             }
10989              
10990             void TrackerBase::addChild( ITrackerPtr const& child ) {
10991             m_children.push_back( child );
10992             }
10993              
10994             ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
10995             auto it = std::find_if( m_children.begin(), m_children.end(),
10996             [&nameAndLocation]( ITrackerPtr const& tracker ){
10997             return
10998             tracker->nameAndLocation().location == nameAndLocation.location &&
10999             tracker->nameAndLocation().name == nameAndLocation.name;
11000             } );
11001             return( it != m_children.end() )
11002             ? *it
11003             : nullptr;
11004             }
11005             ITracker& TrackerBase::parent() {
11006             assert( m_parent ); // Should always be non-null except for root
11007             return *m_parent;
11008             }
11009              
11010             void TrackerBase::openChild() {
11011             if( m_runState != ExecutingChildren ) {
11012             m_runState = ExecutingChildren;
11013             if( m_parent )
11014             m_parent->openChild();
11015             }
11016             }
11017              
11018             bool TrackerBase::isSectionTracker() const { return false; }
11019             bool TrackerBase::isIndexTracker() const { return false; }
11020              
11021             void TrackerBase::open() {
11022             m_runState = Executing;
11023             moveToThis();
11024             if( m_parent )
11025             m_parent->openChild();
11026             }
11027              
11028             void TrackerBase::close() {
11029              
11030             // Close any still open children (e.g. generators)
11031             while( &m_ctx.currentTracker() != this )
11032             m_ctx.currentTracker().close();
11033              
11034             switch( m_runState ) {
11035             case NeedsAnotherRun:
11036             break;
11037              
11038             case Executing:
11039             m_runState = CompletedSuccessfully;
11040             break;
11041             case ExecutingChildren:
11042             if( m_children.empty() || m_children.back()->isComplete() )
11043             m_runState = CompletedSuccessfully;
11044             break;
11045              
11046             case NotStarted:
11047             case CompletedSuccessfully:
11048             case Failed:
11049             CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
11050              
11051             default:
11052             CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
11053             }
11054             moveToParent();
11055             m_ctx.completeCycle();
11056             }
11057             void TrackerBase::fail() {
11058             m_runState = Failed;
11059             if( m_parent )
11060             m_parent->markAsNeedingAnotherRun();
11061             moveToParent();
11062             m_ctx.completeCycle();
11063             }
11064             void TrackerBase::markAsNeedingAnotherRun() {
11065             m_runState = NeedsAnotherRun;
11066             }
11067              
11068             void TrackerBase::moveToParent() {
11069             assert( m_parent );
11070             m_ctx.setCurrentTracker( m_parent );
11071             }
11072             void TrackerBase::moveToThis() {
11073             m_ctx.setCurrentTracker( this );
11074             }
11075              
11076             SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
11077             : TrackerBase( nameAndLocation, ctx, parent )
11078             {
11079             if( parent ) {
11080             while( !parent->isSectionTracker() )
11081             parent = &parent->parent();
11082              
11083             SectionTracker& parentSection = static_cast( *parent );
11084             addNextFilters( parentSection.m_filters );
11085             }
11086             }
11087              
11088             bool SectionTracker::isSectionTracker() const { return true; }
11089              
11090             SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
11091             std::shared_ptr section;
11092              
11093             ITracker& currentTracker = ctx.currentTracker();
11094             if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
11095             assert( childTracker );
11096             assert( childTracker->isSectionTracker() );
11097             section = std::static_pointer_cast( childTracker );
11098             }
11099             else {
11100             section = std::make_shared( nameAndLocation, ctx, ¤tTracker );
11101             currentTracker.addChild( section );
11102             }
11103             if( !ctx.completedCycle() )
11104             section->tryOpen();
11105             return *section;
11106             }
11107              
11108             void SectionTracker::tryOpen() {
11109             if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) )
11110             open();
11111             }
11112              
11113             void SectionTracker::addInitialFilters( std::vector const& filters ) {
11114             if( !filters.empty() ) {
11115             m_filters.push_back(""); // Root - should never be consulted
11116             m_filters.push_back(""); // Test Case - not a section filter
11117             m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
11118             }
11119             }
11120             void SectionTracker::addNextFilters( std::vector const& filters ) {
11121             if( filters.size() > 1 )
11122             m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
11123             }
11124              
11125             IndexTracker::IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size )
11126             : TrackerBase( nameAndLocation, ctx, parent ),
11127             m_size( size )
11128             {}
11129              
11130             bool IndexTracker::isIndexTracker() const { return true; }
11131              
11132             IndexTracker& IndexTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) {
11133             std::shared_ptr tracker;
11134              
11135             ITracker& currentTracker = ctx.currentTracker();
11136             if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
11137             assert( childTracker );
11138             assert( childTracker->isIndexTracker() );
11139             tracker = std::static_pointer_cast( childTracker );
11140             }
11141             else {
11142             tracker = std::make_shared( nameAndLocation, ctx, ¤tTracker, size );
11143             currentTracker.addChild( tracker );
11144             }
11145              
11146             if( !ctx.completedCycle() && !tracker->isComplete() ) {
11147             if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
11148             tracker->moveNext();
11149             tracker->open();
11150             }
11151              
11152             return *tracker;
11153             }
11154              
11155             int IndexTracker::index() const { return m_index; }
11156              
11157             void IndexTracker::moveNext() {
11158             m_index++;
11159             m_children.clear();
11160             }
11161              
11162             void IndexTracker::close() {
11163             TrackerBase::close();
11164             if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
11165             m_runState = Executing;
11166             }
11167              
11168             } // namespace TestCaseTracking
11169              
11170             using TestCaseTracking::ITracker;
11171             using TestCaseTracking::TrackerContext;
11172             using TestCaseTracking::SectionTracker;
11173             using TestCaseTracking::IndexTracker;
11174              
11175             } // namespace Catch
11176              
11177             #if defined(__clang__)
11178             # pragma clang diagnostic pop
11179             #endif
11180             // end catch_test_case_tracker.cpp
11181             // start catch_test_registry.cpp
11182              
11183             namespace Catch {
11184              
11185             auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
11186             return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
11187             }
11188              
11189             NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
11190              
11191             AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
11192             CATCH_TRY {
11193             getMutableRegistryHub()
11194             .registerTest(
11195             makeTestCase(
11196             invoker,
11197             extractClassName( classOrMethod ),
11198             nameAndTags,
11199             lineInfo));
11200             } CATCH_CATCH_ALL {
11201             // Do not throw when constructing global objects, instead register the exception to be processed later
11202             getMutableRegistryHub().registerStartupException();
11203             }
11204             }
11205              
11206             AutoReg::~AutoReg() = default;
11207             }
11208             // end catch_test_registry.cpp
11209             // start catch_test_spec.cpp
11210              
11211             #include
11212             #include
11213             #include
11214             #include
11215              
11216             namespace Catch {
11217              
11218             TestSpec::Pattern::~Pattern() = default;
11219             TestSpec::NamePattern::~NamePattern() = default;
11220             TestSpec::TagPattern::~TagPattern() = default;
11221             TestSpec::ExcludedPattern::~ExcludedPattern() = default;
11222              
11223             TestSpec::NamePattern::NamePattern( std::string const& name )
11224             : m_wildcardPattern( toLower( name ), CaseSensitive::No )
11225             {}
11226             bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
11227             return m_wildcardPattern.matches( toLower( testCase.name ) );
11228             }
11229              
11230             TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
11231             bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
11232             return std::find(begin(testCase.lcaseTags),
11233             end(testCase.lcaseTags),
11234             m_tag) != end(testCase.lcaseTags);
11235             }
11236              
11237             TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
11238             bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
11239              
11240             bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
11241             // All patterns in a filter must match for the filter to be a match
11242             for( auto const& pattern : m_patterns ) {
11243             if( !pattern->matches( testCase ) )
11244             return false;
11245             }
11246             return true;
11247             }
11248              
11249             bool TestSpec::hasFilters() const {
11250             return !m_filters.empty();
11251             }
11252             bool TestSpec::matches( TestCaseInfo const& testCase ) const {
11253             // A TestSpec matches if any filter matches
11254             for( auto const& filter : m_filters )
11255             if( filter.matches( testCase ) )
11256             return true;
11257             return false;
11258             }
11259             }
11260             // end catch_test_spec.cpp
11261             // start catch_test_spec_parser.cpp
11262              
11263             namespace Catch {
11264              
11265             TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
11266              
11267             TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
11268             m_mode = None;
11269             m_exclusion = false;
11270             m_start = std::string::npos;
11271             m_arg = m_tagAliases->expandAliases( arg );
11272             m_escapeChars.clear();
11273             for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
11274             visitChar( m_arg[m_pos] );
11275             if( m_mode == Name )
11276             addPattern();
11277             return *this;
11278             }
11279             TestSpec TestSpecParser::testSpec() {
11280             addFilter();
11281             return m_testSpec;
11282             }
11283              
11284             void TestSpecParser::visitChar( char c ) {
11285             if( m_mode == None ) {
11286             switch( c ) {
11287             case ' ': return;
11288             case '~': m_exclusion = true; return;
11289             case '[': return startNewMode( Tag, ++m_pos );
11290             case '"': return startNewMode( QuotedName, ++m_pos );
11291             case '\\': return escape();
11292             default: startNewMode( Name, m_pos ); break;
11293             }
11294             }
11295             if( m_mode == Name ) {
11296             if( c == ',' ) {
11297             addPattern();
11298             addFilter();
11299             }
11300             else if( c == '[' ) {
11301             if( subString() == "exclude:" )
11302             m_exclusion = true;
11303             else
11304             addPattern();
11305             startNewMode( Tag, ++m_pos );
11306             }
11307             else if( c == '\\' )
11308             escape();
11309             }
11310             else if( m_mode == EscapedName )
11311             m_mode = Name;
11312             else if( m_mode == QuotedName && c == '"' )
11313             addPattern();
11314             else if( m_mode == Tag && c == ']' )
11315             addPattern();
11316             }
11317             void TestSpecParser::startNewMode( Mode mode, std::size_t start ) {
11318             m_mode = mode;
11319             m_start = start;
11320             }
11321             void TestSpecParser::escape() {
11322             if( m_mode == None )
11323             m_start = m_pos;
11324             m_mode = EscapedName;
11325             m_escapeChars.push_back( m_pos );
11326             }
11327             std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
11328              
11329             void TestSpecParser::addFilter() {
11330             if( !m_currentFilter.m_patterns.empty() ) {
11331             m_testSpec.m_filters.push_back( m_currentFilter );
11332             m_currentFilter = TestSpec::Filter();
11333             }
11334             }
11335              
11336             TestSpec parseTestSpec( std::string const& arg ) {
11337             return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
11338             }
11339              
11340             } // namespace Catch
11341             // end catch_test_spec_parser.cpp
11342             // start catch_timer.cpp
11343              
11344             #include
11345              
11346             static const uint64_t nanosecondsInSecond = 1000000000;
11347              
11348             namespace Catch {
11349              
11350             auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
11351             return std::chrono::duration_cast( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
11352             }
11353              
11354             namespace {
11355             auto estimateClockResolution() -> uint64_t {
11356             uint64_t sum = 0;
11357             static const uint64_t iterations = 1000000;
11358              
11359             auto startTime = getCurrentNanosecondsSinceEpoch();
11360              
11361             for( std::size_t i = 0; i < iterations; ++i ) {
11362              
11363             uint64_t ticks;
11364             uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
11365             do {
11366             ticks = getCurrentNanosecondsSinceEpoch();
11367             } while( ticks == baseTicks );
11368              
11369             auto delta = ticks - baseTicks;
11370             sum += delta;
11371              
11372             // If we have been calibrating for over 3 seconds -- the clock
11373             // is terrible and we should move on.
11374             // TBD: How to signal that the measured resolution is probably wrong?
11375             if (ticks > startTime + 3 * nanosecondsInSecond) {
11376             return sum / i;
11377             }
11378             }
11379              
11380             // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
11381             // - and potentially do more iterations if there's a high variance.
11382             return sum/iterations;
11383             }
11384             }
11385             auto getEstimatedClockResolution() -> uint64_t {
11386             static auto s_resolution = estimateClockResolution();
11387             return s_resolution;
11388             }
11389              
11390             void Timer::start() {
11391             m_nanoseconds = getCurrentNanosecondsSinceEpoch();
11392             }
11393             auto Timer::getElapsedNanoseconds() const -> uint64_t {
11394             return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
11395             }
11396             auto Timer::getElapsedMicroseconds() const -> uint64_t {
11397             return getElapsedNanoseconds()/1000;
11398             }
11399             auto Timer::getElapsedMilliseconds() const -> unsigned int {
11400             return static_cast(getElapsedMicroseconds()/1000);
11401             }
11402             auto Timer::getElapsedSeconds() const -> double {
11403             return getElapsedMicroseconds()/1000000.0;
11404             }
11405              
11406             } // namespace Catch
11407             // end catch_timer.cpp
11408             // start catch_tostring.cpp
11409              
11410             #if defined(__clang__)
11411             # pragma clang diagnostic push
11412             # pragma clang diagnostic ignored "-Wexit-time-destructors"
11413             # pragma clang diagnostic ignored "-Wglobal-constructors"
11414             #endif
11415              
11416             // Enable specific decls locally
11417             #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
11418             #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
11419             #endif
11420              
11421             #include
11422             #include
11423              
11424             namespace Catch {
11425              
11426             namespace Detail {
11427              
11428             const std::string unprintableString = "{?}";
11429              
11430             namespace {
11431             const int hexThreshold = 255;
11432              
11433             struct Endianness {
11434             enum Arch { Big, Little };
11435              
11436             static Arch which() {
11437             union _{
11438             int asInt;
11439             char asChar[sizeof (int)];
11440             } u;
11441              
11442             u.asInt = 1;
11443             return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
11444             }
11445             };
11446             }
11447              
11448             std::string rawMemoryToString( const void *object, std::size_t size ) {
11449             // Reverse order for little endian architectures
11450             int i = 0, end = static_cast( size ), inc = 1;
11451             if( Endianness::which() == Endianness::Little ) {
11452             i = end-1;
11453             end = inc = -1;
11454             }
11455              
11456             unsigned char const *bytes = static_cast(object);
11457             ReusableStringStream rss;
11458             rss << "0x" << std::setfill('0') << std::hex;
11459             for( ; i != end; i += inc )
11460             rss << std::setw(2) << static_cast(bytes[i]);
11461             return rss.str();
11462             }
11463             }
11464              
11465             template
11466             std::string fpToString( T value, int precision ) {
11467             if (std::isnan(value)) {
11468             return "nan";
11469             }
11470              
11471             ReusableStringStream rss;
11472             rss << std::setprecision( precision )
11473             << std::fixed
11474             << value;
11475             std::string d = rss.str();
11476             std::size_t i = d.find_last_not_of( '0' );
11477             if( i != std::string::npos && i != d.size()-1 ) {
11478             if( d[i] == '.' )
11479             i++;
11480             d = d.substr( 0, i+1 );
11481             }
11482             return d;
11483             }
11484              
11485             //// ======================================================= ////
11486             //
11487             // Out-of-line defs for full specialization of StringMaker
11488             //
11489             //// ======================================================= ////
11490              
11491             std::string StringMaker::convert(const std::string& str) {
11492             if (!getCurrentContext().getConfig()->showInvisibles()) {
11493             return '"' + str + '"';
11494             }
11495              
11496             std::string s("\"");
11497             for (char c : str) {
11498             switch (c) {
11499             case '\n':
11500             s.append("\\n");
11501             break;
11502             case '\t':
11503             s.append("\\t");
11504             break;
11505             default:
11506             s.push_back(c);
11507             break;
11508             }
11509             }
11510             s.append("\"");
11511             return s;
11512             }
11513              
11514             #ifdef CATCH_CONFIG_WCHAR
11515             std::string StringMaker::convert(const std::wstring& wstr) {
11516             std::string s;
11517             s.reserve(wstr.size());
11518             for (auto c : wstr) {
11519             s += (c <= 0xff) ? static_cast(c) : '?';
11520             }
11521             return ::Catch::Detail::stringify(s);
11522             }
11523             #endif
11524              
11525             std::string StringMaker::convert(char const* str) {
11526             if (str) {
11527             return ::Catch::Detail::stringify(std::string{ str });
11528             } else {
11529             return{ "{null string}" };
11530             }
11531             }
11532             std::string StringMaker::convert(char* str) {
11533             if (str) {
11534             return ::Catch::Detail::stringify(std::string{ str });
11535             } else {
11536             return{ "{null string}" };
11537             }
11538             }
11539             #ifdef CATCH_CONFIG_WCHAR
11540             std::string StringMaker::convert(wchar_t const * str) {
11541             if (str) {
11542             return ::Catch::Detail::stringify(std::wstring{ str });
11543             } else {
11544             return{ "{null string}" };
11545             }
11546             }
11547             std::string StringMaker::convert(wchar_t * str) {
11548             if (str) {
11549             return ::Catch::Detail::stringify(std::wstring{ str });
11550             } else {
11551             return{ "{null string}" };
11552             }
11553             }
11554             #endif
11555              
11556             std::string StringMaker::convert(int value) {
11557             return ::Catch::Detail::stringify(static_cast(value));
11558             }
11559             std::string StringMaker::convert(long value) {
11560             return ::Catch::Detail::stringify(static_cast(value));
11561             }
11562             std::string StringMaker::convert(long long value) {
11563             ReusableStringStream rss;
11564             rss << value;
11565             if (value > Detail::hexThreshold) {
11566             rss << " (0x" << std::hex << value << ')';
11567             }
11568             return rss.str();
11569             }
11570              
11571             std::string StringMaker::convert(unsigned int value) {
11572             return ::Catch::Detail::stringify(static_cast(value));
11573             }
11574             std::string StringMaker::convert(unsigned long value) {
11575             return ::Catch::Detail::stringify(static_cast(value));
11576             }
11577             std::string StringMaker::convert(unsigned long long value) {
11578             ReusableStringStream rss;
11579             rss << value;
11580             if (value > Detail::hexThreshold) {
11581             rss << " (0x" << std::hex << value << ')';
11582             }
11583             return rss.str();
11584             }
11585              
11586             std::string StringMaker::convert(bool b) {
11587             return b ? "true" : "false";
11588             }
11589              
11590             std::string StringMaker::convert(char value) {
11591             if (value == '\r') {
11592             return "'\\r'";
11593             } else if (value == '\f') {
11594             return "'\\f'";
11595             } else if (value == '\n') {
11596             return "'\\n'";
11597             } else if (value == '\t') {
11598             return "'\\t'";
11599             } else if ('\0' <= value && value < ' ') {
11600             return ::Catch::Detail::stringify(static_cast(value));
11601             } else {
11602             char chstr[] = "' '";
11603             chstr[1] = value;
11604             return chstr;
11605             }
11606             }
11607             std::string StringMaker::convert(signed char c) {
11608             return ::Catch::Detail::stringify(static_cast(c));
11609             }
11610             std::string StringMaker::convert(unsigned char c) {
11611             return ::Catch::Detail::stringify(static_cast(c));
11612             }
11613              
11614             std::string StringMaker::convert(std::nullptr_t) {
11615             return "nullptr";
11616             }
11617              
11618             std::string StringMaker::convert(float value) {
11619             return fpToString(value, 5) + 'f';
11620             }
11621             std::string StringMaker::convert(double value) {
11622             return fpToString(value, 10);
11623             }
11624              
11625             std::string ratio_string::symbol() { return "a"; }
11626             std::string ratio_string::symbol() { return "f"; }
11627             std::string ratio_string::symbol() { return "p"; }
11628             std::string ratio_string::symbol() { return "n"; }
11629             std::string ratio_string::symbol() { return "u"; }
11630             std::string ratio_string::symbol() { return "m"; }
11631              
11632             } // end namespace Catch
11633              
11634             #if defined(__clang__)
11635             # pragma clang diagnostic pop
11636             #endif
11637              
11638             // end catch_tostring.cpp
11639             // start catch_totals.cpp
11640              
11641             namespace Catch {
11642              
11643             Counts Counts::operator - ( Counts const& other ) const {
11644             Counts diff;
11645             diff.passed = passed - other.passed;
11646             diff.failed = failed - other.failed;
11647             diff.failedButOk = failedButOk - other.failedButOk;
11648             return diff;
11649             }
11650              
11651             Counts& Counts::operator += ( Counts const& other ) {
11652             passed += other.passed;
11653             failed += other.failed;
11654             failedButOk += other.failedButOk;
11655             return *this;
11656             }
11657              
11658             std::size_t Counts::total() const {
11659             return passed + failed + failedButOk;
11660             }
11661             bool Counts::allPassed() const {
11662             return failed == 0 && failedButOk == 0;
11663             }
11664             bool Counts::allOk() const {
11665             return failed == 0;
11666             }
11667              
11668             Totals Totals::operator - ( Totals const& other ) const {
11669             Totals diff;
11670             diff.assertions = assertions - other.assertions;
11671             diff.testCases = testCases - other.testCases;
11672             return diff;
11673             }
11674              
11675             Totals& Totals::operator += ( Totals const& other ) {
11676             assertions += other.assertions;
11677             testCases += other.testCases;
11678             return *this;
11679             }
11680              
11681             Totals Totals::delta( Totals const& prevTotals ) const {
11682             Totals diff = *this - prevTotals;
11683             if( diff.assertions.failed > 0 )
11684             ++diff.testCases.failed;
11685             else if( diff.assertions.failedButOk > 0 )
11686             ++diff.testCases.failedButOk;
11687             else
11688             ++diff.testCases.passed;
11689             return diff;
11690             }
11691              
11692             }
11693             // end catch_totals.cpp
11694             // start catch_uncaught_exceptions.cpp
11695              
11696             #include
11697              
11698             namespace Catch {
11699             bool uncaught_exceptions() {
11700             #if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
11701             return std::uncaught_exceptions() > 0;
11702             #else
11703             return std::uncaught_exception();
11704             #endif
11705             }
11706             } // end namespace Catch
11707             // end catch_uncaught_exceptions.cpp
11708             // start catch_version.cpp
11709              
11710             #include
11711              
11712             namespace Catch {
11713              
11714             Version::Version
11715             ( unsigned int _majorVersion,
11716             unsigned int _minorVersion,
11717             unsigned int _patchNumber,
11718             char const * const _branchName,
11719             unsigned int _buildNumber )
11720             : majorVersion( _majorVersion ),
11721             minorVersion( _minorVersion ),
11722             patchNumber( _patchNumber ),
11723             branchName( _branchName ),
11724             buildNumber( _buildNumber )
11725             {}
11726              
11727             std::ostream& operator << ( std::ostream& os, Version const& version ) {
11728             os << version.majorVersion << '.'
11729             << version.minorVersion << '.'
11730             << version.patchNumber;
11731             // branchName is never null -> 0th char is \0 if it is empty
11732             if (version.branchName[0]) {
11733             os << '-' << version.branchName
11734             << '.' << version.buildNumber;
11735             }
11736             return os;
11737             }
11738              
11739             Version const& libraryVersion() {
11740             static Version version( 2, 4, 0, "", 0 );
11741             return version;
11742             }
11743              
11744             }
11745             // end catch_version.cpp
11746             // start catch_wildcard_pattern.cpp
11747              
11748             #include
11749              
11750             namespace Catch {
11751              
11752             WildcardPattern::WildcardPattern( std::string const& pattern,
11753             CaseSensitive::Choice caseSensitivity )
11754             : m_caseSensitivity( caseSensitivity ),
11755             m_pattern( adjustCase( pattern ) )
11756             {
11757             if( startsWith( m_pattern, '*' ) ) {
11758             m_pattern = m_pattern.substr( 1 );
11759             m_wildcard = WildcardAtStart;
11760             }
11761             if( endsWith( m_pattern, '*' ) ) {
11762             m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
11763             m_wildcard = static_cast( m_wildcard | WildcardAtEnd );
11764             }
11765             }
11766              
11767             bool WildcardPattern::matches( std::string const& str ) const {
11768             switch( m_wildcard ) {
11769             case NoWildcard:
11770             return m_pattern == adjustCase( str );
11771             case WildcardAtStart:
11772             return endsWith( adjustCase( str ), m_pattern );
11773             case WildcardAtEnd:
11774             return startsWith( adjustCase( str ), m_pattern );
11775             case WildcardAtBothEnds:
11776             return contains( adjustCase( str ), m_pattern );
11777             default:
11778             CATCH_INTERNAL_ERROR( "Unknown enum" );
11779             }
11780             }
11781              
11782             std::string WildcardPattern::adjustCase( std::string const& str ) const {
11783             return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
11784             }
11785             }
11786             // end catch_wildcard_pattern.cpp
11787             // start catch_xmlwriter.cpp
11788              
11789             #include
11790              
11791             using uchar = unsigned char;
11792              
11793             namespace Catch {
11794              
11795             namespace {
11796              
11797             size_t trailingBytes(unsigned char c) {
11798             if ((c & 0xE0) == 0xC0) {
11799             return 2;
11800             }
11801             if ((c & 0xF0) == 0xE0) {
11802             return 3;
11803             }
11804             if ((c & 0xF8) == 0xF0) {
11805             return 4;
11806             }
11807             CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
11808             }
11809              
11810             uint32_t headerValue(unsigned char c) {
11811             if ((c & 0xE0) == 0xC0) {
11812             return c & 0x1F;
11813             }
11814             if ((c & 0xF0) == 0xE0) {
11815             return c & 0x0F;
11816             }
11817             if ((c & 0xF8) == 0xF0) {
11818             return c & 0x07;
11819             }
11820             CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
11821             }
11822              
11823             void hexEscapeChar(std::ostream& os, unsigned char c) {
11824             os << "\\x"
11825             << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
11826             << static_cast(c);
11827             }
11828              
11829             } // anonymous namespace
11830              
11831             XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
11832             : m_str( str ),
11833             m_forWhat( forWhat )
11834             {}
11835              
11836             void XmlEncode::encodeTo( std::ostream& os ) const {
11837             // Apostrophe escaping not necessary if we always use " to write attributes
11838             // (see: http://www.w3.org/TR/xml/#syntax)
11839              
11840             for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
11841             uchar c = m_str[idx];
11842             switch (c) {
11843             case '<': os << "<"; break;
11844             case '&': os << "&"; break;
11845              
11846             case '>':
11847             // See: http://www.w3.org/TR/xml/#syntax
11848             if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
11849             os << ">";
11850             else
11851             os << c;
11852             break;
11853              
11854             case '\"':
11855             if (m_forWhat == ForAttributes)
11856             os << """;
11857             else
11858             os << c;
11859             break;
11860              
11861             default:
11862             // Check for control characters and invalid utf-8
11863              
11864             // Escape control characters in standard ascii
11865             // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
11866             if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
11867             hexEscapeChar(os, c);
11868             break;
11869             }
11870              
11871             // Plain ASCII: Write it to stream
11872             if (c < 0x7F) {
11873             os << c;
11874             break;
11875             }
11876              
11877             // UTF-8 territory
11878             // Check if the encoding is valid and if it is not, hex escape bytes.
11879             // Important: We do not check the exact decoded values for validity, only the encoding format
11880             // First check that this bytes is a valid lead byte:
11881             // This means that it is not encoded as 1111 1XXX
11882             // Or as 10XX XXXX
11883             if (c < 0xC0 ||
11884             c >= 0xF8) {
11885             hexEscapeChar(os, c);
11886             break;
11887             }
11888              
11889             auto encBytes = trailingBytes(c);
11890             // Are there enough bytes left to avoid accessing out-of-bounds memory?
11891             if (idx + encBytes - 1 >= m_str.size()) {
11892             hexEscapeChar(os, c);
11893             break;
11894             }
11895             // The header is valid, check data
11896             // The next encBytes bytes must together be a valid utf-8
11897             // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
11898             bool valid = true;
11899             uint32_t value = headerValue(c);
11900             for (std::size_t n = 1; n < encBytes; ++n) {
11901             uchar nc = m_str[idx + n];
11902             valid &= ((nc & 0xC0) == 0x80);
11903             value = (value << 6) | (nc & 0x3F);
11904             }
11905              
11906             if (
11907             // Wrong bit pattern of following bytes
11908             (!valid) ||
11909             // Overlong encodings
11910             (value < 0x80) ||
11911             (0x80 <= value && value < 0x800 && encBytes > 2) ||
11912             (0x800 < value && value < 0x10000 && encBytes > 3) ||
11913             // Encoded value out of range
11914             (value >= 0x110000)
11915             ) {
11916             hexEscapeChar(os, c);
11917             break;
11918             }
11919              
11920             // If we got here, this is in fact a valid(ish) utf-8 sequence
11921             for (std::size_t n = 0; n < encBytes; ++n) {
11922             os << m_str[idx + n];
11923             }
11924             idx += encBytes - 1;
11925             break;
11926             }
11927             }
11928             }
11929              
11930             std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
11931             xmlEncode.encodeTo( os );
11932             return os;
11933             }
11934              
11935             XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
11936             : m_writer( writer )
11937             {}
11938              
11939             XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
11940             : m_writer( other.m_writer ){
11941             other.m_writer = nullptr;
11942             }
11943             XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
11944             if ( m_writer ) {
11945             m_writer->endElement();
11946             }
11947             m_writer = other.m_writer;
11948             other.m_writer = nullptr;
11949             return *this;
11950             }
11951              
11952             XmlWriter::ScopedElement::~ScopedElement() {
11953             if( m_writer )
11954             m_writer->endElement();
11955             }
11956              
11957             XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
11958             m_writer->writeText( text, indent );
11959             return *this;
11960             }
11961              
11962             XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
11963             {
11964             writeDeclaration();
11965             }
11966              
11967             XmlWriter::~XmlWriter() {
11968             while( !m_tags.empty() )
11969             endElement();
11970             }
11971              
11972             XmlWriter& XmlWriter::startElement( std::string const& name ) {
11973             ensureTagClosed();
11974             newlineIfNecessary();
11975             m_os << m_indent << '<' << name;
11976             m_tags.push_back( name );
11977             m_indent += " ";
11978             m_tagIsOpen = true;
11979             return *this;
11980             }
11981              
11982             XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
11983             ScopedElement scoped( this );
11984             startElement( name );
11985             return scoped;
11986             }
11987              
11988             XmlWriter& XmlWriter::endElement() {
11989             newlineIfNecessary();
11990             m_indent = m_indent.substr( 0, m_indent.size()-2 );
11991             if( m_tagIsOpen ) {
11992             m_os << "/>";
11993             m_tagIsOpen = false;
11994             }
11995             else {
11996             m_os << m_indent << "";
11997             }
11998             m_os << std::endl;
11999             m_tags.pop_back();
12000             return *this;
12001             }
12002              
12003             XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
12004             if( !name.empty() && !attribute.empty() )
12005             m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
12006             return *this;
12007             }
12008              
12009             XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
12010             m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
12011             return *this;
12012             }
12013              
12014             XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
12015             if( !text.empty() ){
12016             bool tagWasOpen = m_tagIsOpen;
12017             ensureTagClosed();
12018             if( tagWasOpen && indent )
12019             m_os << m_indent;
12020             m_os << XmlEncode( text );
12021             m_needsNewline = true;
12022             }
12023             return *this;
12024             }
12025              
12026             XmlWriter& XmlWriter::writeComment( std::string const& text ) {
12027             ensureTagClosed();
12028             m_os << m_indent << "";
12029             m_needsNewline = true;
12030             return *this;
12031             }
12032              
12033             void XmlWriter::writeStylesheetRef( std::string const& url ) {
12034             m_os << "\n";
12035             }
12036              
12037             XmlWriter& XmlWriter::writeBlankLine() {
12038             ensureTagClosed();
12039             m_os << '\n';
12040             return *this;
12041             }
12042              
12043             void XmlWriter::ensureTagClosed() {
12044             if( m_tagIsOpen ) {
12045             m_os << ">" << std::endl;
12046             m_tagIsOpen = false;
12047             }
12048             }
12049              
12050             void XmlWriter::writeDeclaration() {
12051             m_os << "\n";
12052             }
12053              
12054             void XmlWriter::newlineIfNecessary() {
12055             if( m_needsNewline ) {
12056             m_os << std::endl;
12057             m_needsNewline = false;
12058             }
12059             }
12060             }
12061             // end catch_xmlwriter.cpp
12062             // start catch_reporter_bases.cpp
12063              
12064             #include
12065             #include
12066             #include
12067             #include
12068             #include
12069              
12070             namespace Catch {
12071             void prepareExpandedExpression(AssertionResult& result) {
12072             result.getExpandedExpression();
12073             }
12074              
12075             // Because formatting using c++ streams is stateful, drop down to C is required
12076             // Alternatively we could use stringstream, but its performance is... not good.
12077             std::string getFormattedDuration( double duration ) {
12078             // Max exponent + 1 is required to represent the whole part
12079             // + 1 for decimal point
12080             // + 3 for the 3 decimal places
12081             // + 1 for null terminator
12082             const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
12083             char buffer[maxDoubleSize];
12084              
12085             // Save previous errno, to prevent sprintf from overwriting it
12086             ErrnoGuard guard;
12087             #ifdef _MSC_VER
12088             sprintf_s(buffer, "%.3f", duration);
12089             #else
12090             sprintf(buffer, "%.3f", duration);
12091             #endif
12092             return std::string(buffer);
12093             }
12094              
12095             TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
12096             :StreamingReporterBase(_config) {}
12097              
12098             void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
12099              
12100             bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
12101             return false;
12102             }
12103              
12104             } // end namespace Catch
12105             // end catch_reporter_bases.cpp
12106             // start catch_reporter_compact.cpp
12107              
12108             namespace {
12109              
12110             #ifdef CATCH_PLATFORM_MAC
12111             const char* failedString() { return "FAILED"; }
12112             const char* passedString() { return "PASSED"; }
12113             #else
12114             const char* failedString() { return "failed"; }
12115             const char* passedString() { return "passed"; }
12116             #endif
12117              
12118             // Colour::LightGrey
12119             Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
12120              
12121             std::string bothOrAll( std::size_t count ) {
12122             return count == 1 ? std::string() :
12123             count == 2 ? "both " : "all " ;
12124             }
12125              
12126             } // anon namespace
12127              
12128             namespace Catch {
12129             namespace {
12130             // Colour, message variants:
12131             // - white: No tests ran.
12132             // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
12133             // - white: Passed [both/all] N test cases (no assertions).
12134             // - red: Failed N tests cases, failed M assertions.
12135             // - green: Passed [both/all] N tests cases with M assertions.
12136             void printTotals(std::ostream& out, const Totals& totals) {
12137             if (totals.testCases.total() == 0) {
12138             out << "No tests ran.";
12139             } else if (totals.testCases.failed == totals.testCases.total()) {
12140             Colour colour(Colour::ResultError);
12141             const std::string qualify_assertions_failed =
12142             totals.assertions.failed == totals.assertions.total() ?
12143             bothOrAll(totals.assertions.failed) : std::string();
12144             out <<
12145             "Failed " << bothOrAll(totals.testCases.failed)
12146             << pluralise(totals.testCases.failed, "test case") << ", "
12147             "failed " << qualify_assertions_failed <<
12148             pluralise(totals.assertions.failed, "assertion") << '.';
12149             } else if (totals.assertions.total() == 0) {
12150             out <<
12151             "Passed " << bothOrAll(totals.testCases.total())
12152             << pluralise(totals.testCases.total(), "test case")
12153             << " (no assertions).";
12154             } else if (totals.assertions.failed) {
12155             Colour colour(Colour::ResultError);
12156             out <<
12157             "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
12158             "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
12159             } else {
12160             Colour colour(Colour::ResultSuccess);
12161             out <<
12162             "Passed " << bothOrAll(totals.testCases.passed)
12163             << pluralise(totals.testCases.passed, "test case") <<
12164             " with " << pluralise(totals.assertions.passed, "assertion") << '.';
12165             }
12166             }
12167              
12168             // Implementation of CompactReporter formatting
12169             class AssertionPrinter {
12170             public:
12171             AssertionPrinter& operator= (AssertionPrinter const&) = delete;
12172             AssertionPrinter(AssertionPrinter const&) = delete;
12173             AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
12174             : stream(_stream)
12175             , result(_stats.assertionResult)
12176             , messages(_stats.infoMessages)
12177             , itMessage(_stats.infoMessages.begin())
12178             , printInfoMessages(_printInfoMessages) {}
12179              
12180             void print() {
12181             printSourceInfo();
12182              
12183             itMessage = messages.begin();
12184              
12185             switch (result.getResultType()) {
12186             case ResultWas::Ok:
12187             printResultType(Colour::ResultSuccess, passedString());
12188             printOriginalExpression();
12189             printReconstructedExpression();
12190             if (!result.hasExpression())
12191             printRemainingMessages(Colour::None);
12192             else
12193             printRemainingMessages();
12194             break;
12195             case ResultWas::ExpressionFailed:
12196             if (result.isOk())
12197             printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
12198             else
12199             printResultType(Colour::Error, failedString());
12200             printOriginalExpression();
12201             printReconstructedExpression();
12202             printRemainingMessages();
12203             break;
12204             case ResultWas::ThrewException:
12205             printResultType(Colour::Error, failedString());
12206             printIssue("unexpected exception with message:");
12207             printMessage();
12208             printExpressionWas();
12209             printRemainingMessages();
12210             break;
12211             case ResultWas::FatalErrorCondition:
12212             printResultType(Colour::Error, failedString());
12213             printIssue("fatal error condition with message:");
12214             printMessage();
12215             printExpressionWas();
12216             printRemainingMessages();
12217             break;
12218             case ResultWas::DidntThrowException:
12219             printResultType(Colour::Error, failedString());
12220             printIssue("expected exception, got none");
12221             printExpressionWas();
12222             printRemainingMessages();
12223             break;
12224             case ResultWas::Info:
12225             printResultType(Colour::None, "info");
12226             printMessage();
12227             printRemainingMessages();
12228             break;
12229             case ResultWas::Warning:
12230             printResultType(Colour::None, "warning");
12231             printMessage();
12232             printRemainingMessages();
12233             break;
12234             case ResultWas::ExplicitFailure:
12235             printResultType(Colour::Error, failedString());
12236             printIssue("explicitly");
12237             printRemainingMessages(Colour::None);
12238             break;
12239             // These cases are here to prevent compiler warnings
12240             case ResultWas::Unknown:
12241             case ResultWas::FailureBit:
12242             case ResultWas::Exception:
12243             printResultType(Colour::Error, "** internal error **");
12244             break;
12245             }
12246             }
12247              
12248             private:
12249             void printSourceInfo() const {
12250             Colour colourGuard(Colour::FileName);
12251             stream << result.getSourceInfo() << ':';
12252             }
12253              
12254             void printResultType(Colour::Code colour, std::string const& passOrFail) const {
12255             if (!passOrFail.empty()) {
12256             {
12257             Colour colourGuard(colour);
12258             stream << ' ' << passOrFail;
12259             }
12260             stream << ':';
12261             }
12262             }
12263              
12264             void printIssue(std::string const& issue) const {
12265             stream << ' ' << issue;
12266             }
12267              
12268             void printExpressionWas() {
12269             if (result.hasExpression()) {
12270             stream << ';';
12271             {
12272             Colour colour(dimColour());
12273             stream << " expression was:";
12274             }
12275             printOriginalExpression();
12276             }
12277             }
12278              
12279             void printOriginalExpression() const {
12280             if (result.hasExpression()) {
12281             stream << ' ' << result.getExpression();
12282             }
12283             }
12284              
12285             void printReconstructedExpression() const {
12286             if (result.hasExpandedExpression()) {
12287             {
12288             Colour colour(dimColour());
12289             stream << " for: ";
12290             }
12291             stream << result.getExpandedExpression();
12292             }
12293             }
12294              
12295             void printMessage() {
12296             if (itMessage != messages.end()) {
12297             stream << " '" << itMessage->message << '\'';
12298             ++itMessage;
12299             }
12300             }
12301              
12302             void printRemainingMessages(Colour::Code colour = dimColour()) {
12303             if (itMessage == messages.end())
12304             return;
12305              
12306             // using messages.end() directly yields (or auto) compilation error:
12307             std::vector::const_iterator itEnd = messages.end();
12308             const std::size_t N = static_cast(std::distance(itMessage, itEnd));
12309              
12310             {
12311             Colour colourGuard(colour);
12312             stream << " with " << pluralise(N, "message") << ':';
12313             }
12314              
12315             for (; itMessage != itEnd; ) {
12316             // If this assertion is a warning ignore any INFO messages
12317             if (printInfoMessages || itMessage->type != ResultWas::Info) {
12318             stream << " '" << itMessage->message << '\'';
12319             if (++itMessage != itEnd) {
12320             Colour colourGuard(dimColour());
12321             stream << " and";
12322             }
12323             }
12324             }
12325             }
12326              
12327             private:
12328             std::ostream& stream;
12329             AssertionResult const& result;
12330             std::vector messages;
12331             std::vector::const_iterator itMessage;
12332             bool printInfoMessages;
12333             };
12334              
12335             } // anon namespace
12336              
12337             std::string CompactReporter::getDescription() {
12338             return "Reports test results on a single line, suitable for IDEs";
12339             }
12340              
12341             ReporterPreferences CompactReporter::getPreferences() const {
12342             return m_reporterPrefs;
12343             }
12344              
12345             void CompactReporter::noMatchingTestCases( std::string const& spec ) {
12346             stream << "No test cases matched '" << spec << '\'' << std::endl;
12347             }
12348              
12349             void CompactReporter::assertionStarting( AssertionInfo const& ) {}
12350              
12351             bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
12352             AssertionResult const& result = _assertionStats.assertionResult;
12353              
12354             bool printInfoMessages = true;
12355              
12356             // Drop out if result was successful and we're not printing those
12357             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
12358             if( result.getResultType() != ResultWas::Warning )
12359             return false;
12360             printInfoMessages = false;
12361             }
12362              
12363             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
12364             printer.print();
12365              
12366             stream << std::endl;
12367             return true;
12368             }
12369              
12370             void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
12371             if (m_config->showDurations() == ShowDurations::Always) {
12372             stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
12373             }
12374             }
12375              
12376             void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
12377             printTotals( stream, _testRunStats.totals );
12378             stream << '\n' << std::endl;
12379             StreamingReporterBase::testRunEnded( _testRunStats );
12380             }
12381              
12382             CompactReporter::~CompactReporter() {}
12383              
12384             CATCH_REGISTER_REPORTER( "compact", CompactReporter )
12385              
12386             } // end namespace Catch
12387             // end catch_reporter_compact.cpp
12388             // start catch_reporter_console.cpp
12389              
12390             #include
12391             #include
12392              
12393             #if defined(_MSC_VER)
12394             #pragma warning(push)
12395             #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
12396             // Note that 4062 (not all labels are handled
12397             // and default is missing) is enabled
12398             #endif
12399              
12400             namespace Catch {
12401              
12402             namespace {
12403              
12404             // Formatter impl for ConsoleReporter
12405             class ConsoleAssertionPrinter {
12406             public:
12407             ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
12408             ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
12409             ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
12410             : stream(_stream),
12411             stats(_stats),
12412             result(_stats.assertionResult),
12413             colour(Colour::None),
12414             message(result.getMessage()),
12415             messages(_stats.infoMessages),
12416             printInfoMessages(_printInfoMessages) {
12417             switch (result.getResultType()) {
12418             case ResultWas::Ok:
12419             colour = Colour::Success;
12420             passOrFail = "PASSED";
12421             //if( result.hasMessage() )
12422             if (_stats.infoMessages.size() == 1)
12423             messageLabel = "with message";
12424             if (_stats.infoMessages.size() > 1)
12425             messageLabel = "with messages";
12426             break;
12427             case ResultWas::ExpressionFailed:
12428             if (result.isOk()) {
12429             colour = Colour::Success;
12430             passOrFail = "FAILED - but was ok";
12431             } else {
12432             colour = Colour::Error;
12433             passOrFail = "FAILED";
12434             }
12435             if (_stats.infoMessages.size() == 1)
12436             messageLabel = "with message";
12437             if (_stats.infoMessages.size() > 1)
12438             messageLabel = "with messages";
12439             break;
12440             case ResultWas::ThrewException:
12441             colour = Colour::Error;
12442             passOrFail = "FAILED";
12443             messageLabel = "due to unexpected exception with ";
12444             if (_stats.infoMessages.size() == 1)
12445             messageLabel += "message";
12446             if (_stats.infoMessages.size() > 1)
12447             messageLabel += "messages";
12448             break;
12449             case ResultWas::FatalErrorCondition:
12450             colour = Colour::Error;
12451             passOrFail = "FAILED";
12452             messageLabel = "due to a fatal error condition";
12453             break;
12454             case ResultWas::DidntThrowException:
12455             colour = Colour::Error;
12456             passOrFail = "FAILED";
12457             messageLabel = "because no exception was thrown where one was expected";
12458             break;
12459             case ResultWas::Info:
12460             messageLabel = "info";
12461             break;
12462             case ResultWas::Warning:
12463             messageLabel = "warning";
12464             break;
12465             case ResultWas::ExplicitFailure:
12466             passOrFail = "FAILED";
12467             colour = Colour::Error;
12468             if (_stats.infoMessages.size() == 1)
12469             messageLabel = "explicitly with message";
12470             if (_stats.infoMessages.size() > 1)
12471             messageLabel = "explicitly with messages";
12472             break;
12473             // These cases are here to prevent compiler warnings
12474             case ResultWas::Unknown:
12475             case ResultWas::FailureBit:
12476             case ResultWas::Exception:
12477             passOrFail = "** internal error **";
12478             colour = Colour::Error;
12479             break;
12480             }
12481             }
12482              
12483             void print() const {
12484             printSourceInfo();
12485             if (stats.totals.assertions.total() > 0) {
12486             if (result.isOk())
12487             stream << '\n';
12488             printResultType();
12489             printOriginalExpression();
12490             printReconstructedExpression();
12491             } else {
12492             stream << '\n';
12493             }
12494             printMessage();
12495             }
12496              
12497             private:
12498             void printResultType() const {
12499             if (!passOrFail.empty()) {
12500             Colour colourGuard(colour);
12501             stream << passOrFail << ":\n";
12502             }
12503             }
12504             void printOriginalExpression() const {
12505             if (result.hasExpression()) {
12506             Colour colourGuard(Colour::OriginalExpression);
12507             stream << " ";
12508             stream << result.getExpressionInMacro();
12509             stream << '\n';
12510             }
12511             }
12512             void printReconstructedExpression() const {
12513             if (result.hasExpandedExpression()) {
12514             stream << "with expansion:\n";
12515             Colour colourGuard(Colour::ReconstructedExpression);
12516             stream << Column(result.getExpandedExpression()).indent(2) << '\n';
12517             }
12518             }
12519             void printMessage() const {
12520             if (!messageLabel.empty())
12521             stream << messageLabel << ':' << '\n';
12522             for (auto const& msg : messages) {
12523             // If this assertion is a warning ignore any INFO messages
12524             if (printInfoMessages || msg.type != ResultWas::Info)
12525             stream << Column(msg.message).indent(2) << '\n';
12526             }
12527             }
12528             void printSourceInfo() const {
12529             Colour colourGuard(Colour::FileName);
12530             stream << result.getSourceInfo() << ": ";
12531             }
12532              
12533             std::ostream& stream;
12534             AssertionStats const& stats;
12535             AssertionResult const& result;
12536             Colour::Code colour;
12537             std::string passOrFail;
12538             std::string messageLabel;
12539             std::string message;
12540             std::vector messages;
12541             bool printInfoMessages;
12542             };
12543              
12544             std::size_t makeRatio(std::size_t number, std::size_t total) {
12545             std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
12546             return (ratio == 0 && number > 0) ? 1 : ratio;
12547             }
12548              
12549             std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
12550             if (i > j && i > k)
12551             return i;
12552             else if (j > k)
12553             return j;
12554             else
12555             return k;
12556             }
12557              
12558             struct ColumnInfo {
12559             enum Justification { Left, Right };
12560             std::string name;
12561             int width;
12562             Justification justification;
12563             };
12564             struct ColumnBreak {};
12565             struct RowBreak {};
12566              
12567             class Duration {
12568             enum class Unit {
12569             Auto,
12570             Nanoseconds,
12571             Microseconds,
12572             Milliseconds,
12573             Seconds,
12574             Minutes
12575             };
12576             static const uint64_t s_nanosecondsInAMicrosecond = 1000;
12577             static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
12578             static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
12579             static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
12580              
12581             uint64_t m_inNanoseconds;
12582             Unit m_units;
12583              
12584             public:
12585             explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
12586             : m_inNanoseconds(inNanoseconds),
12587             m_units(units) {
12588             if (m_units == Unit::Auto) {
12589             if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
12590             m_units = Unit::Nanoseconds;
12591             else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
12592             m_units = Unit::Microseconds;
12593             else if (m_inNanoseconds < s_nanosecondsInASecond)
12594             m_units = Unit::Milliseconds;
12595             else if (m_inNanoseconds < s_nanosecondsInAMinute)
12596             m_units = Unit::Seconds;
12597             else
12598             m_units = Unit::Minutes;
12599             }
12600              
12601             }
12602              
12603             auto value() const -> double {
12604             switch (m_units) {
12605             case Unit::Microseconds:
12606             return m_inNanoseconds / static_cast(s_nanosecondsInAMicrosecond);
12607             case Unit::Milliseconds:
12608             return m_inNanoseconds / static_cast(s_nanosecondsInAMillisecond);
12609             case Unit::Seconds:
12610             return m_inNanoseconds / static_cast(s_nanosecondsInASecond);
12611             case Unit::Minutes:
12612             return m_inNanoseconds / static_cast(s_nanosecondsInAMinute);
12613             default:
12614             return static_cast(m_inNanoseconds);
12615             }
12616             }
12617             auto unitsAsString() const -> std::string {
12618             switch (m_units) {
12619             case Unit::Nanoseconds:
12620             return "ns";
12621             case Unit::Microseconds:
12622             return "µs";
12623             case Unit::Milliseconds:
12624             return "ms";
12625             case Unit::Seconds:
12626             return "s";
12627             case Unit::Minutes:
12628             return "m";
12629             default:
12630             return "** internal error **";
12631             }
12632              
12633             }
12634             friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
12635             return os << duration.value() << " " << duration.unitsAsString();
12636             }
12637             };
12638             } // end anon namespace
12639              
12640             class TablePrinter {
12641             std::ostream& m_os;
12642             std::vector m_columnInfos;
12643             std::ostringstream m_oss;
12644             int m_currentColumn = -1;
12645             bool m_isOpen = false;
12646              
12647             public:
12648             TablePrinter( std::ostream& os, std::vector columnInfos )
12649             : m_os( os ),
12650             m_columnInfos( std::move( columnInfos ) ) {}
12651              
12652             auto columnInfos() const -> std::vector const& {
12653             return m_columnInfos;
12654             }
12655              
12656             void open() {
12657             if (!m_isOpen) {
12658             m_isOpen = true;
12659             *this << RowBreak();
12660             for (auto const& info : m_columnInfos)
12661             *this << info.name << ColumnBreak();
12662             *this << RowBreak();
12663             m_os << Catch::getLineOfChars<'-'>() << "\n";
12664             }
12665             }
12666             void close() {
12667             if (m_isOpen) {
12668             *this << RowBreak();
12669             m_os << std::endl;
12670             m_isOpen = false;
12671             }
12672             }
12673              
12674             template
12675             friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
12676             tp.m_oss << value;
12677             return tp;
12678             }
12679              
12680             friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
12681             auto colStr = tp.m_oss.str();
12682             // This takes account of utf8 encodings
12683             auto strSize = Catch::StringRef(colStr).numberOfCharacters();
12684             tp.m_oss.str("");
12685             tp.open();
12686             if (tp.m_currentColumn == static_cast(tp.m_columnInfos.size() - 1)) {
12687             tp.m_currentColumn = -1;
12688             tp.m_os << "\n";
12689             }
12690             tp.m_currentColumn++;
12691              
12692             auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
12693             auto padding = (strSize + 2 < static_cast(colInfo.width))
12694             ? std::string(colInfo.width - (strSize + 2), ' ')
12695             : std::string();
12696             if (colInfo.justification == ColumnInfo::Left)
12697             tp.m_os << colStr << padding << " ";
12698             else
12699             tp.m_os << padding << colStr << " ";
12700             return tp;
12701             }
12702              
12703             friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
12704             if (tp.m_currentColumn > 0) {
12705             tp.m_os << "\n";
12706             tp.m_currentColumn = -1;
12707             }
12708             return tp;
12709             }
12710             };
12711              
12712             ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
12713             : StreamingReporterBase(config),
12714             m_tablePrinter(new TablePrinter(config.stream(),
12715             {
12716             { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
12717             { "iters", 8, ColumnInfo::Right },
12718             { "elapsed ns", 14, ColumnInfo::Right },
12719             { "average", 14, ColumnInfo::Right }
12720             })) {}
12721             ConsoleReporter::~ConsoleReporter() = default;
12722              
12723             std::string ConsoleReporter::getDescription() {
12724             return "Reports test results as plain lines of text";
12725             }
12726              
12727             void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
12728             stream << "No test cases matched '" << spec << '\'' << std::endl;
12729             }
12730              
12731             void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
12732              
12733             bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
12734             AssertionResult const& result = _assertionStats.assertionResult;
12735              
12736             bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
12737              
12738             // Drop out if result was successful but we're not printing them.
12739             if (!includeResults && result.getResultType() != ResultWas::Warning)
12740             return false;
12741              
12742             lazyPrint();
12743              
12744             ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
12745             printer.print();
12746             stream << std::endl;
12747             return true;
12748             }
12749              
12750             void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
12751             m_headerPrinted = false;
12752             StreamingReporterBase::sectionStarting(_sectionInfo);
12753             }
12754             void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
12755             m_tablePrinter->close();
12756             if (_sectionStats.missingAssertions) {
12757             lazyPrint();
12758             Colour colour(Colour::ResultError);
12759             if (m_sectionStack.size() > 1)
12760             stream << "\nNo assertions in section";
12761             else
12762             stream << "\nNo assertions in test case";
12763             stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
12764             }
12765             if (m_config->showDurations() == ShowDurations::Always) {
12766             stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
12767             }
12768             if (m_headerPrinted) {
12769             m_headerPrinted = false;
12770             }
12771             StreamingReporterBase::sectionEnded(_sectionStats);
12772             }
12773              
12774             void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
12775             lazyPrintWithoutClosingBenchmarkTable();
12776              
12777             auto nameCol = Column( info.name ).width( static_cast( m_tablePrinter->columnInfos()[0].width - 2 ) );
12778              
12779             bool firstLine = true;
12780             for (auto line : nameCol) {
12781             if (!firstLine)
12782             (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
12783             else
12784             firstLine = false;
12785              
12786             (*m_tablePrinter) << line << ColumnBreak();
12787             }
12788             }
12789             void ConsoleReporter::benchmarkEnded(BenchmarkStats const& stats) {
12790             Duration average(stats.elapsedTimeInNanoseconds / stats.iterations);
12791             (*m_tablePrinter)
12792             << stats.iterations << ColumnBreak()
12793             << stats.elapsedTimeInNanoseconds << ColumnBreak()
12794             << average << ColumnBreak();
12795             }
12796              
12797             void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
12798             m_tablePrinter->close();
12799             StreamingReporterBase::testCaseEnded(_testCaseStats);
12800             m_headerPrinted = false;
12801             }
12802             void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
12803             if (currentGroupInfo.used) {
12804             printSummaryDivider();
12805             stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
12806             printTotals(_testGroupStats.totals);
12807             stream << '\n' << std::endl;
12808             }
12809             StreamingReporterBase::testGroupEnded(_testGroupStats);
12810             }
12811             void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
12812             printTotalsDivider(_testRunStats.totals);
12813             printTotals(_testRunStats.totals);
12814             stream << std::endl;
12815             StreamingReporterBase::testRunEnded(_testRunStats);
12816             }
12817              
12818             void ConsoleReporter::lazyPrint() {
12819              
12820             m_tablePrinter->close();
12821             lazyPrintWithoutClosingBenchmarkTable();
12822             }
12823              
12824             void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
12825              
12826             if (!currentTestRunInfo.used)
12827             lazyPrintRunInfo();
12828             if (!currentGroupInfo.used)
12829             lazyPrintGroupInfo();
12830              
12831             if (!m_headerPrinted) {
12832             printTestCaseAndSectionHeader();
12833             m_headerPrinted = true;
12834             }
12835             }
12836             void ConsoleReporter::lazyPrintRunInfo() {
12837             stream << '\n' << getLineOfChars<'~'>() << '\n';
12838             Colour colour(Colour::SecondaryText);
12839             stream << currentTestRunInfo->name
12840             << " is a Catch v" << libraryVersion() << " host application.\n"
12841             << "Run with -? for options\n\n";
12842              
12843             if (m_config->rngSeed() != 0)
12844             stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
12845              
12846             currentTestRunInfo.used = true;
12847             }
12848             void ConsoleReporter::lazyPrintGroupInfo() {
12849             if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
12850             printClosedHeader("Group: " + currentGroupInfo->name);
12851             currentGroupInfo.used = true;
12852             }
12853             }
12854             void ConsoleReporter::printTestCaseAndSectionHeader() {
12855             assert(!m_sectionStack.empty());
12856             printOpenHeader(currentTestCaseInfo->name);
12857              
12858             if (m_sectionStack.size() > 1) {
12859             Colour colourGuard(Colour::Headers);
12860              
12861             auto
12862             it = m_sectionStack.begin() + 1, // Skip first section (test case)
12863             itEnd = m_sectionStack.end();
12864             for (; it != itEnd; ++it)
12865             printHeaderString(it->name, 2);
12866             }
12867              
12868             SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
12869              
12870             if (!lineInfo.empty()) {
12871             stream << getLineOfChars<'-'>() << '\n';
12872             Colour colourGuard(Colour::FileName);
12873             stream << lineInfo << '\n';
12874             }
12875             stream << getLineOfChars<'.'>() << '\n' << std::endl;
12876             }
12877              
12878             void ConsoleReporter::printClosedHeader(std::string const& _name) {
12879             printOpenHeader(_name);
12880             stream << getLineOfChars<'.'>() << '\n';
12881             }
12882             void ConsoleReporter::printOpenHeader(std::string const& _name) {
12883             stream << getLineOfChars<'-'>() << '\n';
12884             {
12885             Colour colourGuard(Colour::Headers);
12886             printHeaderString(_name);
12887             }
12888             }
12889              
12890             // if string has a : in first line will set indent to follow it on
12891             // subsequent lines
12892             void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
12893             std::size_t i = _string.find(": ");
12894             if (i != std::string::npos)
12895             i += 2;
12896             else
12897             i = 0;
12898             stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
12899             }
12900              
12901             struct SummaryColumn {
12902              
12903             SummaryColumn( std::string _label, Colour::Code _colour )
12904             : label( std::move( _label ) ),
12905             colour( _colour ) {}
12906             SummaryColumn addRow( std::size_t count ) {
12907             ReusableStringStream rss;
12908             rss << count;
12909             std::string row = rss.str();
12910             for (auto& oldRow : rows) {
12911             while (oldRow.size() < row.size())
12912             oldRow = ' ' + oldRow;
12913             while (oldRow.size() > row.size())
12914             row = ' ' + row;
12915             }
12916             rows.push_back(row);
12917             return *this;
12918             }
12919              
12920             std::string label;
12921             Colour::Code colour;
12922             std::vector rows;
12923              
12924             };
12925              
12926             void ConsoleReporter::printTotals( Totals const& totals ) {
12927             if (totals.testCases.total() == 0) {
12928             stream << Colour(Colour::Warning) << "No tests ran\n";
12929             } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
12930             stream << Colour(Colour::ResultSuccess) << "All tests passed";
12931             stream << " ("
12932             << pluralise(totals.assertions.passed, "assertion") << " in "
12933             << pluralise(totals.testCases.passed, "test case") << ')'
12934             << '\n';
12935             } else {
12936              
12937             std::vector columns;
12938             columns.push_back(SummaryColumn("", Colour::None)
12939             .addRow(totals.testCases.total())
12940             .addRow(totals.assertions.total()));
12941             columns.push_back(SummaryColumn("passed", Colour::Success)
12942             .addRow(totals.testCases.passed)
12943             .addRow(totals.assertions.passed));
12944             columns.push_back(SummaryColumn("failed", Colour::ResultError)
12945             .addRow(totals.testCases.failed)
12946             .addRow(totals.assertions.failed));
12947             columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
12948             .addRow(totals.testCases.failedButOk)
12949             .addRow(totals.assertions.failedButOk));
12950              
12951             printSummaryRow("test cases", columns, 0);
12952             printSummaryRow("assertions", columns, 1);
12953             }
12954             }
12955             void ConsoleReporter::printSummaryRow(std::string const& label, std::vector const& cols, std::size_t row) {
12956             for (auto col : cols) {
12957             std::string value = col.rows[row];
12958             if (col.label.empty()) {
12959             stream << label << ": ";
12960             if (value != "0")
12961             stream << value;
12962             else
12963             stream << Colour(Colour::Warning) << "- none -";
12964             } else if (value != "0") {
12965             stream << Colour(Colour::LightGrey) << " | ";
12966             stream << Colour(col.colour)
12967             << value << ' ' << col.label;
12968             }
12969             }
12970             stream << '\n';
12971             }
12972              
12973             void ConsoleReporter::printTotalsDivider(Totals const& totals) {
12974             if (totals.testCases.total() > 0) {
12975             std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
12976             std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
12977             std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
12978             while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
12979             findMax(failedRatio, failedButOkRatio, passedRatio)++;
12980             while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
12981             findMax(failedRatio, failedButOkRatio, passedRatio)--;
12982              
12983             stream << Colour(Colour::Error) << std::string(failedRatio, '=');
12984             stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
12985             if (totals.testCases.allPassed())
12986             stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
12987             else
12988             stream << Colour(Colour::Success) << std::string(passedRatio, '=');
12989             } else {
12990             stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
12991             }
12992             stream << '\n';
12993             }
12994             void ConsoleReporter::printSummaryDivider() {
12995             stream << getLineOfChars<'-'>() << '\n';
12996             }
12997              
12998             CATCH_REGISTER_REPORTER("console", ConsoleReporter)
12999              
13000             } // end namespace Catch
13001              
13002             #if defined(_MSC_VER)
13003             #pragma warning(pop)
13004             #endif
13005             // end catch_reporter_console.cpp
13006             // start catch_reporter_junit.cpp
13007              
13008             #include
13009             #include
13010             #include
13011             #include
13012              
13013             namespace Catch {
13014              
13015             namespace {
13016             std::string getCurrentTimestamp() {
13017             // Beware, this is not reentrant because of backward compatibility issues
13018             // Also, UTC only, again because of backward compatibility (%z is C++11)
13019             time_t rawtime;
13020             std::time(&rawtime);
13021             auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
13022              
13023             #ifdef _MSC_VER
13024             std::tm timeInfo = {};
13025             gmtime_s(&timeInfo, &rawtime);
13026             #else
13027             std::tm* timeInfo;
13028             timeInfo = std::gmtime(&rawtime);
13029             #endif
13030              
13031             char timeStamp[timeStampSize];
13032             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
13033              
13034             #ifdef _MSC_VER
13035             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
13036             #else
13037             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
13038             #endif
13039             return std::string(timeStamp);
13040             }
13041              
13042             std::string fileNameTag(const std::vector &tags) {
13043             auto it = std::find_if(begin(tags),
13044             end(tags),
13045             [] (std::string const& tag) {return tag.front() == '#'; });
13046             if (it != tags.end())
13047             return it->substr(1);
13048             return std::string();
13049             }
13050             } // anonymous namespace
13051              
13052             JunitReporter::JunitReporter( ReporterConfig const& _config )
13053             : CumulativeReporterBase( _config ),
13054             xml( _config.stream() )
13055             {
13056             m_reporterPrefs.shouldRedirectStdOut = true;
13057             m_reporterPrefs.shouldReportAllAssertions = true;
13058             }
13059              
13060             JunitReporter::~JunitReporter() {}
13061              
13062             std::string JunitReporter::getDescription() {
13063             return "Reports test results in an XML format that looks like Ant's junitreport target";
13064             }
13065              
13066             void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
13067              
13068             void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
13069             CumulativeReporterBase::testRunStarting( runInfo );
13070             xml.startElement( "testsuites" );
13071             }
13072              
13073             void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
13074             suiteTimer.start();
13075             stdOutForSuite.clear();
13076             stdErrForSuite.clear();
13077             unexpectedExceptions = 0;
13078             CumulativeReporterBase::testGroupStarting( groupInfo );
13079             }
13080              
13081             void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
13082             m_okToFail = testCaseInfo.okToFail();
13083             }
13084              
13085             bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
13086             if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
13087             unexpectedExceptions++;
13088             return CumulativeReporterBase::assertionEnded( assertionStats );
13089             }
13090              
13091             void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
13092             stdOutForSuite += testCaseStats.stdOut;
13093             stdErrForSuite += testCaseStats.stdErr;
13094             CumulativeReporterBase::testCaseEnded( testCaseStats );
13095             }
13096              
13097             void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
13098             double suiteTime = suiteTimer.getElapsedSeconds();
13099             CumulativeReporterBase::testGroupEnded( testGroupStats );
13100             writeGroup( *m_testGroups.back(), suiteTime );
13101             }
13102              
13103             void JunitReporter::testRunEndedCumulative() {
13104             xml.endElement();
13105             }
13106              
13107             void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
13108             XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
13109             TestGroupStats const& stats = groupNode.value;
13110             xml.writeAttribute( "name", stats.groupInfo.name );
13111             xml.writeAttribute( "errors", unexpectedExceptions );
13112             xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
13113             xml.writeAttribute( "tests", stats.totals.assertions.total() );
13114             xml.writeAttribute( "hostname", "tbd" ); // !TBD
13115             if( m_config->showDurations() == ShowDurations::Never )
13116             xml.writeAttribute( "time", "" );
13117             else
13118             xml.writeAttribute( "time", suiteTime );
13119             xml.writeAttribute( "timestamp", getCurrentTimestamp() );
13120              
13121             // Write test cases
13122             for( auto const& child : groupNode.children )
13123             writeTestCase( *child );
13124              
13125             xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false );
13126             xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false );
13127             }
13128              
13129             void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
13130             TestCaseStats const& stats = testCaseNode.value;
13131              
13132             // All test cases have exactly one section - which represents the
13133             // test case itself. That section may have 0-n nested sections
13134             assert( testCaseNode.children.size() == 1 );
13135             SectionNode const& rootSection = *testCaseNode.children.front();
13136              
13137             std::string className = stats.testInfo.className;
13138              
13139             if( className.empty() ) {
13140             className = fileNameTag(stats.testInfo.tags);
13141             if ( className.empty() )
13142             className = "global";
13143             }
13144              
13145             if ( !m_config->name().empty() )
13146             className = m_config->name() + "." + className;
13147              
13148             writeSection( className, "", rootSection );
13149             }
13150              
13151             void JunitReporter::writeSection( std::string const& className,
13152             std::string const& rootName,
13153             SectionNode const& sectionNode ) {
13154             std::string name = trim( sectionNode.stats.sectionInfo.name );
13155             if( !rootName.empty() )
13156             name = rootName + '/' + name;
13157              
13158             if( !sectionNode.assertions.empty() ||
13159             !sectionNode.stdOut.empty() ||
13160             !sectionNode.stdErr.empty() ) {
13161             XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
13162             if( className.empty() ) {
13163             xml.writeAttribute( "classname", name );
13164             xml.writeAttribute( "name", "root" );
13165             }
13166             else {
13167             xml.writeAttribute( "classname", className );
13168             xml.writeAttribute( "name", name );
13169             }
13170             xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
13171              
13172             writeAssertions( sectionNode );
13173              
13174             if( !sectionNode.stdOut.empty() )
13175             xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
13176             if( !sectionNode.stdErr.empty() )
13177             xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
13178             }
13179             for( auto const& childNode : sectionNode.childSections )
13180             if( className.empty() )
13181             writeSection( name, "", *childNode );
13182             else
13183             writeSection( className, name, *childNode );
13184             }
13185              
13186             void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
13187             for( auto const& assertion : sectionNode.assertions )
13188             writeAssertion( assertion );
13189             }
13190              
13191             void JunitReporter::writeAssertion( AssertionStats const& stats ) {
13192             AssertionResult const& result = stats.assertionResult;
13193             if( !result.isOk() ) {
13194             std::string elementName;
13195             switch( result.getResultType() ) {
13196             case ResultWas::ThrewException:
13197             case ResultWas::FatalErrorCondition:
13198             elementName = "error";
13199             break;
13200             case ResultWas::ExplicitFailure:
13201             elementName = "failure";
13202             break;
13203             case ResultWas::ExpressionFailed:
13204             elementName = "failure";
13205             break;
13206             case ResultWas::DidntThrowException:
13207             elementName = "failure";
13208             break;
13209              
13210             // We should never see these here:
13211             case ResultWas::Info:
13212             case ResultWas::Warning:
13213             case ResultWas::Ok:
13214             case ResultWas::Unknown:
13215             case ResultWas::FailureBit:
13216             case ResultWas::Exception:
13217             elementName = "internalError";
13218             break;
13219             }
13220              
13221             XmlWriter::ScopedElement e = xml.scopedElement( elementName );
13222              
13223             xml.writeAttribute( "message", result.getExpandedExpression() );
13224             xml.writeAttribute( "type", result.getTestMacroName() );
13225              
13226             ReusableStringStream rss;
13227             if( !result.getMessage().empty() )
13228             rss << result.getMessage() << '\n';
13229             for( auto const& msg : stats.infoMessages )
13230             if( msg.type == ResultWas::Info )
13231             rss << msg.message << '\n';
13232              
13233             rss << "at " << result.getSourceInfo();
13234             xml.writeText( rss.str(), false );
13235             }
13236             }
13237              
13238             CATCH_REGISTER_REPORTER( "junit", JunitReporter )
13239              
13240             } // end namespace Catch
13241             // end catch_reporter_junit.cpp
13242             // start catch_reporter_listening.cpp
13243              
13244             #include
13245              
13246             namespace Catch {
13247              
13248             ListeningReporter::ListeningReporter() {
13249             // We will assume that listeners will always want all assertions
13250             m_preferences.shouldReportAllAssertions = true;
13251             }
13252              
13253             void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
13254             m_listeners.push_back( std::move( listener ) );
13255             }
13256              
13257             void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
13258             assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
13259             m_reporter = std::move( reporter );
13260             m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
13261             }
13262              
13263             ReporterPreferences ListeningReporter::getPreferences() const {
13264             return m_preferences;
13265             }
13266              
13267             std::set ListeningReporter::getSupportedVerbosities() {
13268             return std::set{ };
13269             }
13270              
13271             void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
13272             for ( auto const& listener : m_listeners ) {
13273             listener->noMatchingTestCases( spec );
13274             }
13275             m_reporter->noMatchingTestCases( spec );
13276             }
13277              
13278             void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
13279             for ( auto const& listener : m_listeners ) {
13280             listener->benchmarkStarting( benchmarkInfo );
13281             }
13282             m_reporter->benchmarkStarting( benchmarkInfo );
13283             }
13284             void ListeningReporter::benchmarkEnded( BenchmarkStats const& benchmarkStats ) {
13285             for ( auto const& listener : m_listeners ) {
13286             listener->benchmarkEnded( benchmarkStats );
13287             }
13288             m_reporter->benchmarkEnded( benchmarkStats );
13289             }
13290              
13291             void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
13292             for ( auto const& listener : m_listeners ) {
13293             listener->testRunStarting( testRunInfo );
13294             }
13295             m_reporter->testRunStarting( testRunInfo );
13296             }
13297              
13298             void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
13299             for ( auto const& listener : m_listeners ) {
13300             listener->testGroupStarting( groupInfo );
13301             }
13302             m_reporter->testGroupStarting( groupInfo );
13303             }
13304              
13305             void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
13306             for ( auto const& listener : m_listeners ) {
13307             listener->testCaseStarting( testInfo );
13308             }
13309             m_reporter->testCaseStarting( testInfo );
13310             }
13311              
13312             void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
13313             for ( auto const& listener : m_listeners ) {
13314             listener->sectionStarting( sectionInfo );
13315             }
13316             m_reporter->sectionStarting( sectionInfo );
13317             }
13318              
13319             void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
13320             for ( auto const& listener : m_listeners ) {
13321             listener->assertionStarting( assertionInfo );
13322             }
13323             m_reporter->assertionStarting( assertionInfo );
13324             }
13325              
13326             // The return value indicates if the messages buffer should be cleared:
13327             bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
13328             for( auto const& listener : m_listeners ) {
13329             static_cast( listener->assertionEnded( assertionStats ) );
13330             }
13331             return m_reporter->assertionEnded( assertionStats );
13332             }
13333              
13334             void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
13335             for ( auto const& listener : m_listeners ) {
13336             listener->sectionEnded( sectionStats );
13337             }
13338             m_reporter->sectionEnded( sectionStats );
13339             }
13340              
13341             void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
13342             for ( auto const& listener : m_listeners ) {
13343             listener->testCaseEnded( testCaseStats );
13344             }
13345             m_reporter->testCaseEnded( testCaseStats );
13346             }
13347              
13348             void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
13349             for ( auto const& listener : m_listeners ) {
13350             listener->testGroupEnded( testGroupStats );
13351             }
13352             m_reporter->testGroupEnded( testGroupStats );
13353             }
13354              
13355             void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
13356             for ( auto const& listener : m_listeners ) {
13357             listener->testRunEnded( testRunStats );
13358             }
13359             m_reporter->testRunEnded( testRunStats );
13360             }
13361              
13362             void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
13363             for ( auto const& listener : m_listeners ) {
13364             listener->skipTest( testInfo );
13365             }
13366             m_reporter->skipTest( testInfo );
13367             }
13368              
13369             bool ListeningReporter::isMulti() const {
13370             return true;
13371             }
13372              
13373             } // end namespace Catch
13374             // end catch_reporter_listening.cpp
13375             // start catch_reporter_xml.cpp
13376              
13377             #if defined(_MSC_VER)
13378             #pragma warning(push)
13379             #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
13380             // Note that 4062 (not all labels are handled
13381             // and default is missing) is enabled
13382             #endif
13383              
13384             namespace Catch {
13385             XmlReporter::XmlReporter( ReporterConfig const& _config )
13386             : StreamingReporterBase( _config ),
13387             m_xml(_config.stream())
13388             {
13389             m_reporterPrefs.shouldRedirectStdOut = true;
13390             m_reporterPrefs.shouldReportAllAssertions = true;
13391             }
13392              
13393             XmlReporter::~XmlReporter() = default;
13394              
13395             std::string XmlReporter::getDescription() {
13396             return "Reports test results as an XML document";
13397             }
13398              
13399             std::string XmlReporter::getStylesheetRef() const {
13400             return std::string();
13401             }
13402              
13403             void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
13404             m_xml
13405             .writeAttribute( "filename", sourceInfo.file )
13406             .writeAttribute( "line", sourceInfo.line );
13407             }
13408              
13409             void XmlReporter::noMatchingTestCases( std::string const& s ) {
13410             StreamingReporterBase::noMatchingTestCases( s );
13411             }
13412              
13413             void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
13414             StreamingReporterBase::testRunStarting( testInfo );
13415             std::string stylesheetRef = getStylesheetRef();
13416             if( !stylesheetRef.empty() )
13417             m_xml.writeStylesheetRef( stylesheetRef );
13418             m_xml.startElement( "Catch" );
13419             if( !m_config->name().empty() )
13420             m_xml.writeAttribute( "name", m_config->name() );
13421             }
13422              
13423             void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
13424             StreamingReporterBase::testGroupStarting( groupInfo );
13425             m_xml.startElement( "Group" )
13426             .writeAttribute( "name", groupInfo.name );
13427             }
13428              
13429             void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
13430             StreamingReporterBase::testCaseStarting(testInfo);
13431             m_xml.startElement( "TestCase" )
13432             .writeAttribute( "name", trim( testInfo.name ) )
13433             .writeAttribute( "description", testInfo.description )
13434             .writeAttribute( "tags", testInfo.tagsAsString() );
13435              
13436             writeSourceInfo( testInfo.lineInfo );
13437              
13438             if ( m_config->showDurations() == ShowDurations::Always )
13439             m_testCaseTimer.start();
13440             m_xml.ensureTagClosed();
13441             }
13442              
13443             void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
13444             StreamingReporterBase::sectionStarting( sectionInfo );
13445             if( m_sectionDepth++ > 0 ) {
13446             m_xml.startElement( "Section" )
13447             .writeAttribute( "name", trim( sectionInfo.name ) );
13448             writeSourceInfo( sectionInfo.lineInfo );
13449             m_xml.ensureTagClosed();
13450             }
13451             }
13452              
13453             void XmlReporter::assertionStarting( AssertionInfo const& ) { }
13454              
13455             bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
13456              
13457             AssertionResult const& result = assertionStats.assertionResult;
13458              
13459             bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
13460              
13461             if( includeResults || result.getResultType() == ResultWas::Warning ) {
13462             // Print any info messages in tags.
13463             for( auto const& msg : assertionStats.infoMessages ) {
13464             if( msg.type == ResultWas::Info && includeResults ) {
13465             m_xml.scopedElement( "Info" )
13466             .writeText( msg.message );
13467             } else if ( msg.type == ResultWas::Warning ) {
13468             m_xml.scopedElement( "Warning" )
13469             .writeText( msg.message );
13470             }
13471             }
13472             }
13473              
13474             // Drop out if result was successful but we're not printing them.
13475             if( !includeResults && result.getResultType() != ResultWas::Warning )
13476             return true;
13477              
13478             // Print the expression if there is one.
13479             if( result.hasExpression() ) {
13480             m_xml.startElement( "Expression" )
13481             .writeAttribute( "success", result.succeeded() )
13482             .writeAttribute( "type", result.getTestMacroName() );
13483              
13484             writeSourceInfo( result.getSourceInfo() );
13485              
13486             m_xml.scopedElement( "Original" )
13487             .writeText( result.getExpression() );
13488             m_xml.scopedElement( "Expanded" )
13489             .writeText( result.getExpandedExpression() );
13490             }
13491              
13492             // And... Print a result applicable to each result type.
13493             switch( result.getResultType() ) {
13494             case ResultWas::ThrewException:
13495             m_xml.startElement( "Exception" );
13496             writeSourceInfo( result.getSourceInfo() );
13497             m_xml.writeText( result.getMessage() );
13498             m_xml.endElement();
13499             break;
13500             case ResultWas::FatalErrorCondition:
13501             m_xml.startElement( "FatalErrorCondition" );
13502             writeSourceInfo( result.getSourceInfo() );
13503             m_xml.writeText( result.getMessage() );
13504             m_xml.endElement();
13505             break;
13506             case ResultWas::Info:
13507             m_xml.scopedElement( "Info" )
13508             .writeText( result.getMessage() );
13509             break;
13510             case ResultWas::Warning:
13511             // Warning will already have been written
13512             break;
13513             case ResultWas::ExplicitFailure:
13514             m_xml.startElement( "Failure" );
13515             writeSourceInfo( result.getSourceInfo() );
13516             m_xml.writeText( result.getMessage() );
13517             m_xml.endElement();
13518             break;
13519             default:
13520             break;
13521             }
13522              
13523             if( result.hasExpression() )
13524             m_xml.endElement();
13525              
13526             return true;
13527             }
13528              
13529             void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
13530             StreamingReporterBase::sectionEnded( sectionStats );
13531             if( --m_sectionDepth > 0 ) {
13532             XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
13533             e.writeAttribute( "successes", sectionStats.assertions.passed );
13534             e.writeAttribute( "failures", sectionStats.assertions.failed );
13535             e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
13536              
13537             if ( m_config->showDurations() == ShowDurations::Always )
13538             e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
13539              
13540             m_xml.endElement();
13541             }
13542             }
13543              
13544             void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
13545             StreamingReporterBase::testCaseEnded( testCaseStats );
13546             XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
13547             e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
13548              
13549             if ( m_config->showDurations() == ShowDurations::Always )
13550             e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
13551              
13552             if( !testCaseStats.stdOut.empty() )
13553             m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
13554             if( !testCaseStats.stdErr.empty() )
13555             m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
13556              
13557             m_xml.endElement();
13558             }
13559              
13560             void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
13561             StreamingReporterBase::testGroupEnded( testGroupStats );
13562             // TODO: Check testGroupStats.aborting and act accordingly.
13563             m_xml.scopedElement( "OverallResults" )
13564             .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
13565             .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
13566             .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
13567             m_xml.endElement();
13568             }
13569              
13570             void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
13571             StreamingReporterBase::testRunEnded( testRunStats );
13572             m_xml.scopedElement( "OverallResults" )
13573             .writeAttribute( "successes", testRunStats.totals.assertions.passed )
13574             .writeAttribute( "failures", testRunStats.totals.assertions.failed )
13575             .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
13576             m_xml.endElement();
13577             }
13578              
13579             CATCH_REGISTER_REPORTER( "xml", XmlReporter )
13580              
13581             } // end namespace Catch
13582              
13583             #if defined(_MSC_VER)
13584             #pragma warning(pop)
13585             #endif
13586             // end catch_reporter_xml.cpp
13587              
13588             namespace Catch {
13589             LeakDetector leakDetector;
13590             }
13591              
13592             #ifdef __clang__
13593             #pragma clang diagnostic pop
13594             #endif
13595              
13596             // end catch_impl.hpp
13597             #endif
13598              
13599             #ifdef CATCH_CONFIG_MAIN
13600             // start catch_default_main.hpp
13601              
13602             #ifndef __OBJC__
13603              
13604             #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
13605             // Standard C/C++ Win32 Unicode wmain entry point
13606             extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
13607             #else
13608             // Standard C/C++ main entry point
13609             int main (int argc, char * argv[]) {
13610             #endif
13611              
13612             return Catch::Session().run( argc, argv );
13613             }
13614              
13615             #else // __OBJC__
13616              
13617             // Objective-C entry point
13618             int main (int argc, char * const argv[]) {
13619             #if !CATCH_ARC_ENABLED
13620             NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
13621             #endif
13622              
13623             Catch::registerTestMethods();
13624             int result = Catch::Session().run( argc, (char**)argv );
13625              
13626             #if !CATCH_ARC_ENABLED
13627             [pool drain];
13628             #endif
13629              
13630             return result;
13631             }
13632              
13633             #endif // __OBJC__
13634              
13635             // end catch_default_main.hpp
13636             #endif
13637              
13638             #if !defined(CATCH_CONFIG_IMPL_ONLY)
13639              
13640             #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
13641             # undef CLARA_CONFIG_MAIN
13642             #endif
13643              
13644             #if !defined(CATCH_CONFIG_DISABLE)
13645             //////
13646             // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
13647             #ifdef CATCH_CONFIG_PREFIX_ALL
13648              
13649             #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
13650             #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
13651              
13652             #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", __VA_ARGS__ )
13653             #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
13654             #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
13655             #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13656             #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
13657             #endif// CATCH_CONFIG_DISABLE_MATCHERS
13658             #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
13659              
13660             #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13661             #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
13662             #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13663             #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13664             #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
13665              
13666             #define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", __VA_ARGS__ )
13667             #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
13668             #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
13669             #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13670             #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
13671             #endif // CATCH_CONFIG_DISABLE_MATCHERS
13672             #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13673              
13674             #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13675             #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
13676              
13677             #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
13678             #endif // CATCH_CONFIG_DISABLE_MATCHERS
13679              
13680             #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
13681             #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
13682             #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
13683              
13684             #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
13685             #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
13686             #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
13687             #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
13688             #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
13689             #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
13690             #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
13691             #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13692             #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13693              
13694             #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
13695              
13696             // "BDD-style" convenience wrappers
13697             #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
13698             #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
13699             #define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
13700             #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
13701             #define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
13702             #define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
13703             #define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
13704             #define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
13705              
13706             // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
13707             #else
13708              
13709             #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
13710             #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
13711              
13712             #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
13713             #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
13714             #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
13715             #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13716             #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
13717             #endif // CATCH_CONFIG_DISABLE_MATCHERS
13718             #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
13719              
13720             #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13721             #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
13722             #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13723             #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13724             #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
13725              
13726             #define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13727             #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
13728             #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
13729             #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13730             #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
13731             #endif // CATCH_CONFIG_DISABLE_MATCHERS
13732             #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13733              
13734             #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13735             #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
13736              
13737             #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
13738             #endif // CATCH_CONFIG_DISABLE_MATCHERS
13739              
13740             #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
13741             #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
13742             #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
13743              
13744             #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
13745             #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
13746             #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
13747             #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
13748             #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
13749             #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
13750             #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
13751             #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13752             #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13753             #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
13754              
13755             #endif
13756              
13757             #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
13758              
13759             // "BDD-style" convenience wrappers
13760             #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
13761             #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
13762              
13763             #define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
13764             #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
13765             #define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
13766             #define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
13767             #define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
13768             #define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
13769              
13770             using Catch::Detail::Approx;
13771              
13772             #else // CATCH_CONFIG_DISABLE
13773              
13774             //////
13775             // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
13776             #ifdef CATCH_CONFIG_PREFIX_ALL
13777              
13778             #define CATCH_REQUIRE( ... ) (void)(0)
13779             #define CATCH_REQUIRE_FALSE( ... ) (void)(0)
13780              
13781             #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
13782             #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
13783             #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
13784             #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13785             #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
13786             #endif// CATCH_CONFIG_DISABLE_MATCHERS
13787             #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
13788              
13789             #define CATCH_CHECK( ... ) (void)(0)
13790             #define CATCH_CHECK_FALSE( ... ) (void)(0)
13791             #define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
13792             #define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
13793             #define CATCH_CHECK_NOFAIL( ... ) (void)(0)
13794              
13795             #define CATCH_CHECK_THROWS( ... ) (void)(0)
13796             #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
13797             #define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
13798             #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13799             #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
13800             #endif // CATCH_CONFIG_DISABLE_MATCHERS
13801             #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
13802              
13803             #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13804             #define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
13805              
13806             #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
13807             #endif // CATCH_CONFIG_DISABLE_MATCHERS
13808              
13809             #define CATCH_INFO( msg ) (void)(0)
13810             #define CATCH_WARN( msg ) (void)(0)
13811             #define CATCH_CAPTURE( msg ) (void)(0)
13812              
13813             #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
13814             #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
13815             #define CATCH_METHOD_AS_TEST_CASE( method, ... )
13816             #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
13817             #define CATCH_SECTION( ... )
13818             #define CATCH_DYNAMIC_SECTION( ... )
13819             #define CATCH_FAIL( ... ) (void)(0)
13820             #define CATCH_FAIL_CHECK( ... ) (void)(0)
13821             #define CATCH_SUCCEED( ... ) (void)(0)
13822              
13823             #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
13824              
13825             // "BDD-style" convenience wrappers
13826             #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
13827             #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
13828             #define CATCH_GIVEN( desc )
13829             #define CATCH_AND_GIVEN( desc )
13830             #define CATCH_WHEN( desc )
13831             #define CATCH_AND_WHEN( desc )
13832             #define CATCH_THEN( desc )
13833             #define CATCH_AND_THEN( desc )
13834              
13835             // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
13836             #else
13837              
13838             #define REQUIRE( ... ) (void)(0)
13839             #define REQUIRE_FALSE( ... ) (void)(0)
13840              
13841             #define REQUIRE_THROWS( ... ) (void)(0)
13842             #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
13843             #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
13844             #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13845             #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
13846             #endif // CATCH_CONFIG_DISABLE_MATCHERS
13847             #define REQUIRE_NOTHROW( ... ) (void)(0)
13848              
13849             #define CHECK( ... ) (void)(0)
13850             #define CHECK_FALSE( ... ) (void)(0)
13851             #define CHECKED_IF( ... ) if (__VA_ARGS__)
13852             #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
13853             #define CHECK_NOFAIL( ... ) (void)(0)
13854              
13855             #define CHECK_THROWS( ... ) (void)(0)
13856             #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
13857             #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
13858             #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13859             #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
13860             #endif // CATCH_CONFIG_DISABLE_MATCHERS
13861             #define CHECK_NOTHROW( ... ) (void)(0)
13862              
13863             #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13864             #define CHECK_THAT( arg, matcher ) (void)(0)
13865              
13866             #define REQUIRE_THAT( arg, matcher ) (void)(0)
13867             #endif // CATCH_CONFIG_DISABLE_MATCHERS
13868              
13869             #define INFO( msg ) (void)(0)
13870             #define WARN( msg ) (void)(0)
13871             #define CAPTURE( msg ) (void)(0)
13872              
13873             #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
13874             #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
13875             #define METHOD_AS_TEST_CASE( method, ... )
13876             #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
13877             #define SECTION( ... )
13878             #define DYNAMIC_SECTION( ... )
13879             #define FAIL( ... ) (void)(0)
13880             #define FAIL_CHECK( ... ) (void)(0)
13881             #define SUCCEED( ... ) (void)(0)
13882             #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
13883              
13884             #endif
13885              
13886             #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
13887              
13888             // "BDD-style" convenience wrappers
13889             #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
13890             #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
13891              
13892             #define GIVEN( desc )
13893             #define AND_GIVEN( desc )
13894             #define WHEN( desc )
13895             #define AND_WHEN( desc )
13896             #define THEN( desc )
13897             #define AND_THEN( desc )
13898              
13899             using Catch::Detail::Approx;
13900              
13901             #endif
13902              
13903             #endif // ! CATCH_CONFIG_IMPL_ONLY
13904              
13905             // start catch_reenable_warnings.h
13906              
13907              
13908             #ifdef __clang__
13909             # ifdef __ICC // icpc defines the __clang__ macro
13910             # pragma warning(pop)
13911             # else
13912             # pragma clang diagnostic pop
13913             # endif
13914             #elif defined __GNUC__
13915             # pragma GCC diagnostic pop
13916             #endif
13917              
13918             // end catch_reenable_warnings.h
13919             // end catch.hpp
13920             #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
13921