Gistrec

catch.hpp

Dec 4th, 2017
355
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 358.52 KB | None | 0 0
  1. /*
  2. *  Catch v2.0.1
  3. *  Generated: 2017-11-03 11:53:39.642003
  4. *  ----------------------------------------------------------
  5. *  This file has been merged from multiple headers. Please don't edit it directly
  6. *  Copyright (c) 2017 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.  
  16. #ifdef __clang__
  17. #    pragma clang system_header
  18. #elif defined __GNUC__
  19. #    pragma GCC system_header
  20. #endif
  21.  
  22. // start catch_suppress_warnings.h
  23.  
  24. #ifdef __clang__
  25. #   ifdef __ICC // icpc defines the __clang__ macro
  26. #       pragma warning(push)
  27. #       pragma warning(disable: 161 1682)
  28. #   else // __ICC
  29. #       pragma clang diagnostic ignored "-Wglobal-constructors"
  30. #       pragma clang diagnostic ignored "-Wvariadic-macros"
  31. #       pragma clang diagnostic ignored "-Wc99-extensions"
  32. #       pragma clang diagnostic ignored "-Wunused-variable"
  33. #       pragma clang diagnostic push
  34. #       pragma clang diagnostic ignored "-Wpadded"
  35. #       pragma clang diagnostic ignored "-Wswitch-enum"
  36. #       pragma clang diagnostic ignored "-Wcovered-switch-default"
  37. #    endif
  38. #elif defined __GNUC__
  39. #    pragma GCC diagnostic ignored "-Wvariadic-macros"
  40. #    pragma GCC diagnostic ignored "-Wunused-variable"
  41. #    pragma GCC diagnostic ignored "-Wparentheses"
  42.  
  43. #    pragma GCC diagnostic push
  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_EXTERNAL_INTERFACES
  50. #  if defined(CATCH_CONFIG_DISABLE_MATCHERS)
  51. #    undef CATCH_CONFIG_DISABLE_MATCHERS
  52. #  endif
  53. #endif
  54.  
  55. // start catch_platform.h
  56.  
  57. #ifdef __APPLE__
  58. # include <TargetConditionals.h>
  59. # if TARGET_OS_MAC == 1
  60. #  define CATCH_PLATFORM_MAC
  61. # elif TARGET_OS_IPHONE == 1
  62. #  define CATCH_PLATFORM_IPHONE
  63. # endif
  64.  
  65. #elif defined(linux) || defined(__linux) || defined(__linux__)
  66. #  define CATCH_PLATFORM_LINUX
  67.  
  68. #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
  69. #  define CATCH_PLATFORM_WINDOWS
  70. #endif
  71.  
  72. // end catch_platform.h
  73. #ifdef CATCH_IMPL
  74. #  ifndef CLARA_CONFIG_MAIN
  75. #    define CLARA_CONFIG_MAIN_NOT_DEFINED
  76. #    define CLARA_CONFIG_MAIN
  77. #  endif
  78. #endif
  79.  
  80. // start catch_tag_alias_autoregistrar.h
  81.  
  82. // start catch_common.h
  83.  
  84. // start catch_compiler_capabilities.h
  85.  
  86. // Detect a number of compiler features - by compiler
  87. // The following features are defined:
  88. //
  89. // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
  90. // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
  91. // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
  92. // ****************
  93. // Note to maintainers: if new toggles are added please document them
  94. // in configuration.md, too
  95. // ****************
  96.  
  97. // In general each macro has a _NO_<feature name> form
  98. // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
  99. // Many features, at point of detection, define an _INTERNAL_ macro, so they
  100. // can be combined, en-mass, with the _NO_ forms later.
  101.  
  102. #ifdef __cplusplus
  103.  
  104. #  if __cplusplus >= 201402L
  105. #    define CATCH_CPP14_OR_GREATER
  106. #  endif
  107.  
  108. #endif
  109.  
  110. #ifdef __clang__
  111.  
  112. #       define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  113.             _Pragma( "clang diagnostic push" ) \
  114.             _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
  115.             _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
  116. #       define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  117.             _Pragma( "clang diagnostic pop" )
  118.  
  119. #       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
  120.             _Pragma( "clang diagnostic push" ) \
  121.             _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
  122. #       define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
  123.             _Pragma( "clang diagnostic pop" )
  124.  
  125. #endif // __clang__
  126.  
  127. ////////////////////////////////////////////////////////////////////////////////
  128. // We know some environments not to support full POSIX signals
  129. #if defined(__CYGWIN__) || defined(__QNX__)
  130.  
  131. #   if !defined(CATCH_CONFIG_POSIX_SIGNALS)
  132. #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  133. #   endif
  134.  
  135. #endif
  136.  
  137. #ifdef __OS400__
  138. #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  139. #       define CATCH_CONFIG_COLOUR_NONE
  140. #endif
  141.  
  142. ////////////////////////////////////////////////////////////////////////////////
  143. // Cygwin
  144. #ifdef __CYGWIN__
  145.  
  146. // Required for some versions of Cygwin to declare gettimeofday
  147. // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
  148. #   define _BSD_SOURCE
  149.  
  150. #endif // __CYGWIN__
  151.  
  152. ////////////////////////////////////////////////////////////////////////////////
  153. // Visual C++
  154. #ifdef _MSC_VER
  155.  
  156. // Universal Windows platform does not support SEH
  157. // Or console colours (or console at all...)
  158. #  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
  159. #    define CATCH_CONFIG_COLOUR_NONE
  160. #  else
  161. #    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
  162. #  endif
  163.  
  164. #endif // _MSC_VER
  165.  
  166. ////////////////////////////////////////////////////////////////////////////////
  167.  
  168. // Use of __COUNTER__ is suppressed during code analysis in
  169. // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
  170. // handled by it.
  171. // Otherwise all supported compilers support COUNTER macro,
  172. // but user still might want to turn it off
  173. #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
  174. #define CATCH_INTERNAL_CONFIG_COUNTER
  175. #endif
  176.  
  177. #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
  178. #   define CATCH_CONFIG_COUNTER
  179. #endif
  180. #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
  181. #   define CATCH_CONFIG_WINDOWS_SEH
  182. #endif
  183. // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
  184. #if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
  185. #   define CATCH_CONFIG_POSIX_SIGNALS
  186. #endif
  187.  
  188. #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
  189. #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
  190. #   define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
  191. #endif
  192. #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
  193. #   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
  194. #   define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  195. #endif
  196.  
  197. // end catch_compiler_capabilities.h
  198. #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
  199. #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
  200. #ifdef CATCH_CONFIG_COUNTER
  201. #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
  202. #else
  203. #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
  204. #endif
  205.  
  206. #include <iosfwd>
  207. #include <string>
  208. #include <cstdint>
  209.  
  210. namespace Catch {
  211.  
  212.     struct CaseSensitive {
  213.         enum Choice {
  214.             Yes,
  215.             No
  216.         };
  217.     };
  218.  
  219.     class NonCopyable {
  220.         NonCopyable(NonCopyable const&) = delete;
  221.         NonCopyable(NonCopyable &&) = delete;
  222.         NonCopyable& operator = (NonCopyable const&) = delete;
  223.         NonCopyable& operator = (NonCopyable &&) = delete;
  224.  
  225.     protected:
  226.         NonCopyable();
  227.         virtual ~NonCopyable();
  228.     };
  229.  
  230.     struct SourceLineInfo {
  231.  
  232.         SourceLineInfo() = delete;
  233.         SourceLineInfo(char const* _file, std::size_t _line) noexcept;
  234.  
  235.         SourceLineInfo(SourceLineInfo const& other) = default;
  236.         SourceLineInfo(SourceLineInfo &&) = default;
  237.         SourceLineInfo& operator = (SourceLineInfo const&) = default;
  238.         SourceLineInfo& operator = (SourceLineInfo &&) = default;
  239.  
  240.         bool empty() const noexcept;
  241.         bool operator == (SourceLineInfo const& other) const noexcept;
  242.         bool operator < (SourceLineInfo const& other) const noexcept;
  243.  
  244.         char const* file;
  245.         std::size_t line;
  246.     };
  247.  
  248.     std::ostream& operator << (std::ostream& os, SourceLineInfo const& info);
  249.  
  250.     // This is just here to avoid compiler warnings with macro constants and boolean literals
  251.     bool isTrue(bool value);
  252.     bool alwaysTrue();
  253.     bool alwaysFalse();
  254.  
  255.     // Use this in variadic streaming macros to allow
  256.     //    >> +StreamEndStop
  257.     // as well as
  258.     //    >> stuff +StreamEndStop
  259.     struct StreamEndStop {
  260.         std::string operator+() const;
  261.     };
  262.     template<typename T>
  263.     T const& operator + (T const& value, StreamEndStop) {
  264.         return value;
  265.     }
  266. }
  267.  
  268. #define CATCH_INTERNAL_LINEINFO \
  269.     ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
  270.  
  271. // end catch_common.h
  272. namespace Catch {
  273.  
  274.     struct RegistrarForTagAliases {
  275.         RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo);
  276.     };
  277.  
  278. } // end namespace Catch
  279.  
  280. #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
  281.  
  282.   // end catch_tag_alias_autoregistrar.h
  283.   // start catch_test_registry.h
  284.  
  285.   // start catch_interfaces_testcase.h
  286.  
  287. #include <vector>
  288. #include <memory>
  289.  
  290. namespace Catch {
  291.  
  292.     class TestSpec;
  293.  
  294.     struct ITestInvoker {
  295.         virtual void invoke() const = 0;
  296.         virtual ~ITestInvoker();
  297.     };
  298.  
  299.     using ITestCasePtr = std::shared_ptr<ITestInvoker>;
  300.  
  301.     class TestCase;
  302.     struct IConfig;
  303.  
  304.     struct ITestCaseRegistry {
  305.         virtual ~ITestCaseRegistry();
  306.         virtual std::vector<TestCase> const& getAllTests() const = 0;
  307.         virtual std::vector<TestCase> const& getAllTestsSorted(IConfig const& config) const = 0;
  308.     };
  309.  
  310.     bool matchTest(TestCase const& testCase, TestSpec const& testSpec, IConfig const& config);
  311.     std::vector<TestCase> filterTests(std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config);
  312.     std::vector<TestCase> const& getAllTestCasesSorted(IConfig const& config);
  313.  
  314. }
  315.  
  316. // end catch_interfaces_testcase.h
  317. // start catch_stringref.h
  318.  
  319. #include <cstddef>
  320. #include <string>
  321. #include <iosfwd>
  322.  
  323. namespace Catch {
  324.  
  325.     class StringData;
  326.  
  327.     /// A non-owning string class (similar to the forthcoming std::string_view)
  328.     /// Note that, because a StringRef may be a substring of another string,
  329.     /// it may not be null terminated. c_str() must return a null terminated
  330.     /// string, however, and so the StringRef will internally take ownership
  331.     /// (taking a copy), if necessary. In theory this ownership is not externally
  332.     /// visible - but it does mean (substring) StringRefs should not be shared between
  333.     /// threads.
  334.     class StringRef {
  335.         friend struct StringRefTestAccess;
  336.  
  337.         using size_type = std::size_t;
  338.  
  339.         char const* m_start;
  340.         size_type m_size;
  341.  
  342.         char* m_data = nullptr;
  343.  
  344.         void takeOwnership();
  345.  
  346.     public: // construction/ assignment
  347.         StringRef() noexcept;
  348.         StringRef(StringRef const& other) noexcept;
  349.         StringRef(StringRef&& other) noexcept;
  350.         StringRef(char const* rawChars) noexcept;
  351.         StringRef(char const* rawChars, size_type size) noexcept;
  352.         StringRef(std::string const& stdString) noexcept;
  353.         ~StringRef() noexcept;
  354.  
  355.         auto operator = (StringRef other) noexcept->StringRef&;
  356.         operator std::string() const;
  357.  
  358.         void swap(StringRef& other) noexcept;
  359.  
  360.     public: // operators
  361.         auto operator == (StringRef const& other) const noexcept -> bool;
  362.         auto operator != (StringRef const& other) const noexcept -> bool;
  363.  
  364.         auto operator[] (size_type index) const noexcept -> char;
  365.  
  366.     public: // named queries
  367.         auto empty() const noexcept -> bool;
  368.         auto size() const noexcept->size_type;
  369.         auto numberOfCharacters() const noexcept->size_type;
  370.         auto c_str() const -> char const*;
  371.  
  372.     public: // substrings and searches
  373.         auto substr(size_type start, size_type size) const noexcept->StringRef;
  374.  
  375.     private: // ownership queries - may not be consistent between calls
  376.         auto isOwned() const noexcept -> bool;
  377.         auto isSubstring() const noexcept -> bool;
  378.         auto data() const noexcept -> char const*;
  379.     };
  380.  
  381.     auto operator + (StringRef const& lhs, StringRef const& rhs)->std::string;
  382.     auto operator + (StringRef const& lhs, char const* rhs)->std::string;
  383.     auto operator + (char const* lhs, StringRef const& rhs)->std::string;
  384.  
  385.     auto operator << (std::ostream& os, StringRef const& sr)->std::ostream&;
  386.  
  387. } // namespace Catch
  388.  
  389.   // end catch_stringref.h
  390. namespace Catch {
  391.  
  392.     template<typename C>
  393.     class TestInvokerAsMethod : public ITestInvoker {
  394.         void (C::*m_testAsMethod)();
  395.     public:
  396.         TestInvokerAsMethod(void (C::*testAsMethod)()) noexcept : m_testAsMethod(testAsMethod) {}
  397.  
  398.         void invoke() const override {
  399.             C obj;
  400.             (obj.*m_testAsMethod)();
  401.         }
  402.     };
  403.  
  404.     auto makeTestInvoker(void(*testAsFunction)()) noexcept->ITestInvoker*;
  405.  
  406.     template<typename C>
  407.     auto makeTestInvoker(void (C::*testAsMethod)()) noexcept -> ITestInvoker* {
  408.         return new(std::nothrow) TestInvokerAsMethod<C>(testAsMethod);
  409.     }
  410.  
  411.     struct NameAndTags {
  412.         NameAndTags(StringRef name_ = "", StringRef tags_ = "") noexcept;
  413.         StringRef name;
  414.         StringRef tags;
  415.     };
  416.  
  417.     struct AutoReg : NonCopyable {
  418.         AutoReg(ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef classOrMethod, NameAndTags const& nameAndTags) noexcept;
  419.         ~AutoReg();
  420.     };
  421.  
  422. } // end namespace Catch
  423.  
  424. #if defined(CATCH_CONFIG_DISABLE)
  425. #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
  426.         static void TestName()
  427. #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
  428.         namespace{                        \
  429.             struct TestName : ClassName { \
  430.                 void test();              \
  431.             };                            \
  432.         }                                 \
  433.         void TestName::test()
  434.  
  435. #endif
  436.  
  437.   ///////////////////////////////////////////////////////////////////////////////
  438. #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
  439.         static void TestName(); \
  440.         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  441.         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  442.         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  443.         static void TestName()
  444. #define INTERNAL_CATCH_TESTCASE( ... ) \
  445.         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
  446.  
  447.   ///////////////////////////////////////////////////////////////////////////////
  448. #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
  449.         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  450.         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  451.         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  452.  
  453.   ///////////////////////////////////////////////////////////////////////////////
  454. #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
  455.         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  456.         namespace{ \
  457.             struct TestName : ClassName{ \
  458.                 void test(); \
  459.             }; \
  460.             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  461.         } \
  462.         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  463.         void TestName::test()
  464. #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
  465.         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
  466.  
  467.   ///////////////////////////////////////////////////////////////////////////////
  468. #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
  469.         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  470.         Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  471.         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  472.  
  473.   // end catch_test_registry.h
  474.   // start catch_capture.hpp
  475.  
  476.   // start catch_assertionhandler.h
  477.  
  478.   // start catch_decomposer.h
  479.  
  480.   // start catch_tostring.h
  481.  
  482. #include <sstream>
  483. #include <vector>
  484. #include <cstddef>
  485. #include <type_traits>
  486. #include <string>
  487.  
  488. #ifdef __OBJC__
  489.   // start catch_objc_arc.hpp
  490.  
  491. #import <Foundation/Foundation.h>
  492.  
  493. #ifdef __has_feature
  494. #define CATCH_ARC_ENABLED __has_feature(objc_arc)
  495. #else
  496. #define CATCH_ARC_ENABLED 0
  497. #endif
  498.  
  499. void arcSafeRelease(NSObject* obj);
  500. id performOptionalSelector(id obj, SEL sel);
  501.  
  502. #if !CATCH_ARC_ENABLED
  503. inline void arcSafeRelease(NSObject* obj) {
  504.     [obj release];
  505. }
  506. inline id performOptionalSelector(id obj, SEL sel) {
  507.     if ([obj respondsToSelector : sel])
  508.         return[obj performSelector : sel];
  509.     return nil;
  510. }
  511. #define CATCH_UNSAFE_UNRETAINED
  512. #define CATCH_ARC_STRONG
  513. #else
  514. inline void arcSafeRelease(NSObject*) {}
  515. inline id performOptionalSelector(id obj, SEL sel) {
  516. #ifdef __clang__
  517. #pragma clang diagnostic push
  518. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  519. #endif
  520.     if ([obj respondsToSelector : sel])
  521.         return[obj performSelector : sel];
  522. #ifdef __clang__
  523. #pragma clang diagnostic pop
  524. #endif
  525.     return nil;
  526. }
  527. #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
  528. #define CATCH_ARC_STRONG __strong
  529. #endif
  530.  
  531. // end catch_objc_arc.hpp
  532. #endif
  533.  
  534. #ifdef _MSC_VER
  535. #pragma warning(push)
  536. #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
  537. #endif
  538.  
  539. // We need a dummy global operator<< so we can bring it into Catch namespace later
  540. struct Catch_global_namespace_dummy;
  541. std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
  542.  
  543. namespace Catch {
  544.     // Bring in operator<< from global namespace into Catch namespace
  545.     using ::operator<<;
  546.  
  547.     namespace Detail {
  548.  
  549.         extern const std::string unprintableString;
  550.  
  551.         std::string rawMemoryToString(const void *object, std::size_t size);
  552.  
  553.         template<typename T>
  554.         std::string rawMemoryToString(const T& object) {
  555.             return rawMemoryToString(&object, sizeof(object));
  556.         }
  557.  
  558.         template<typename T>
  559.         class IsStreamInsertable {
  560.             template<typename SS, typename TT>
  561.             static auto test(int)
  562.                 -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
  563.  
  564.             template<typename, typename>
  565.             static auto test(...)->std::false_type;
  566.  
  567.         public:
  568.             static const bool value = decltype(test<std::ostream, const T&>(0))::value;
  569.         };
  570.  
  571.     } // namespace Detail
  572.  
  573.       // If we decide for C++14, change these to enable_if_ts
  574.     template <typename T>
  575.     struct StringMaker {
  576.         template <typename Fake = T>
  577.         static
  578.             typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
  579.             convert(const Fake& t) {
  580.             std::ostringstream sstr;
  581.             sstr << t;
  582.             return sstr.str();
  583.         }
  584.  
  585.         template <typename Fake = T>
  586.         static
  587.             typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
  588.             convert(const Fake&) {
  589.             return Detail::unprintableString;
  590.         }
  591.     };
  592.  
  593.     namespace Detail {
  594.  
  595.         // This function dispatches all stringification requests inside of Catch.
  596.         // Should be preferably called fully qualified, like ::Catch::Detail::stringify
  597.         template <typename T>
  598.         std::string stringify(const T& e) {
  599.             return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
  600.         }
  601.  
  602.     } // namespace Detail
  603.  
  604.       // Some predefined specializations
  605.  
  606.     template<>
  607.     struct StringMaker<std::string> {
  608.         static std::string convert(const std::string& str);
  609.     };
  610.     template<>
  611.     struct StringMaker<std::wstring> {
  612.         static std::string convert(const std::wstring& wstr);
  613.     };
  614.  
  615.     template<>
  616.     struct StringMaker<char const *> {
  617.         static std::string convert(char const * str);
  618.     };
  619.     template<>
  620.     struct StringMaker<char *> {
  621.         static std::string convert(char * str);
  622.     };
  623.     template<>
  624.     struct StringMaker<wchar_t const *> {
  625.         static std::string convert(wchar_t const * str);
  626.     };
  627.     template<>
  628.     struct StringMaker<wchar_t *> {
  629.         static std::string convert(wchar_t * str);
  630.     };
  631.  
  632.     template<int SZ>
  633.     struct StringMaker<char[SZ]> {
  634.         static std::string convert(const char* str) {
  635.             return ::Catch::Detail::stringify(std::string{ str });
  636.         }
  637.     };
  638.     template<int SZ>
  639.     struct StringMaker<signed char[SZ]> {
  640.         static std::string convert(const char* str) {
  641.             return ::Catch::Detail::stringify(std::string{ str });
  642.         }
  643.     };
  644.     template<int SZ>
  645.     struct StringMaker<unsigned char[SZ]> {
  646.         static std::string convert(const char* str) {
  647.             return ::Catch::Detail::stringify(std::string{ str });
  648.         }
  649.     };
  650.  
  651.     template<>
  652.     struct StringMaker<int> {
  653.         static std::string convert(int value);
  654.     };
  655.     template<>
  656.     struct StringMaker<long> {
  657.         static std::string convert(long value);
  658.     };
  659.     template<>
  660.     struct StringMaker<long long> {
  661.         static std::string convert(long long value);
  662.     };
  663.     template<>
  664.     struct StringMaker<unsigned int> {
  665.         static std::string convert(unsigned int value);
  666.     };
  667.     template<>
  668.     struct StringMaker<unsigned long> {
  669.         static std::string convert(unsigned long value);
  670.     };
  671.     template<>
  672.     struct StringMaker<unsigned long long> {
  673.         static std::string convert(unsigned long long value);
  674.     };
  675.  
  676.     template<>
  677.     struct StringMaker<bool> {
  678.         static std::string convert(bool b);
  679.     };
  680.  
  681.     template<>
  682.     struct StringMaker<char> {
  683.         static std::string convert(char c);
  684.     };
  685.     template<>
  686.     struct StringMaker<signed char> {
  687.         static std::string convert(signed char c);
  688.     };
  689.     template<>
  690.     struct StringMaker<unsigned char> {
  691.         static std::string convert(unsigned char c);
  692.     };
  693.  
  694.     template<>
  695.     struct StringMaker<std::nullptr_t> {
  696.         static std::string convert(std::nullptr_t);
  697.     };
  698.  
  699.     template<>
  700.     struct StringMaker<float> {
  701.         static std::string convert(float value);
  702.     };
  703.     template<>
  704.     struct StringMaker<double> {
  705.         static std::string convert(double value);
  706.     };
  707.  
  708.     template <typename T>
  709.     struct StringMaker<T*> {
  710.         template <typename U>
  711.         static std::string convert(U* p) {
  712.             if (p) {
  713.                 return ::Catch::Detail::rawMemoryToString(p);
  714.             } else {
  715.                 return "nullptr";
  716.             }
  717.         }
  718.     };
  719.  
  720.     template <typename R, typename C>
  721.     struct StringMaker<R C::*> {
  722.         static std::string convert(R C::* p) {
  723.             if (p) {
  724.                 return ::Catch::Detail::rawMemoryToString(p);
  725.             } else {
  726.                 return "nullptr";
  727.             }
  728.         }
  729.     };
  730.  
  731.     namespace Detail {
  732.         template<typename InputIterator>
  733.         std::string rangeToString(InputIterator first, InputIterator last) {
  734.             std::ostringstream oss;
  735.             oss << "{ ";
  736.             if (first != last) {
  737.                 oss << ::Catch::Detail::stringify(*first);
  738.                 for (++first; first != last; ++first)
  739.                     oss << ", " << ::Catch::Detail::stringify(*first);
  740.             }
  741.             oss << " }";
  742.             return oss.str();
  743.         }
  744.     }
  745.  
  746.     template<typename T, typename Allocator>
  747.     struct StringMaker<std::vector<T, Allocator> > {
  748.         static std::string convert(std::vector<T, Allocator> const& v) {
  749.             return ::Catch::Detail::rangeToString(v.begin(), v.end());
  750.         }
  751.     };
  752.  
  753.     template<typename T>
  754.     struct EnumStringMaker {
  755.         static std::string convert(const T& t) {
  756.             return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<T>::type>(t));
  757.         }
  758.     };
  759.  
  760. #ifdef __OBJC__
  761.     template<>
  762.     struct StringMaker<NSString*> {
  763.         static std::string convert(NSString * nsstring) {
  764.             if (!nsstring)
  765.                 return "nil";
  766.             return std::string("@") + [nsstring UTF8String];
  767.         }
  768.     };
  769.     template<>
  770.     struct StringMaker<NSObject*> {
  771.         static std::string convert(NSObject* nsObject) {
  772.             return ::Catch::Detail::stringify([nsObject description]);
  773.         }
  774.  
  775.     };
  776.     namespace Detail {
  777.         inline std::string stringify(NSString* nsstring) {
  778.             return StringMaker<NSString*>::convert(nsstring);
  779.         }
  780.  
  781.     } // namespace Detail
  782. #endif // __OBJC__
  783.  
  784. } // namespace Catch
  785.  
  786.   //////////////////////////////////////////////////////
  787.   // Separate std-lib types stringification, so it can be selectively enabled
  788.   // This means that we do not bring in
  789.  
  790. #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
  791. #  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
  792. #  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
  793. #  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  794. #endif
  795.  
  796.   // Separate std::pair specialization
  797. #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
  798. #include <utility>
  799. namespace Catch {
  800.     template<typename T1, typename T2>
  801.     struct StringMaker<std::pair<T1, T2> > {
  802.         static std::string convert(const std::pair<T1, T2>& pair) {
  803.             std::ostringstream oss;
  804.             oss << "{ "
  805.                 << ::Catch::Detail::stringify(pair.first)
  806.                 << ", "
  807.                 << ::Catch::Detail::stringify(pair.second)
  808.                 << " }";
  809.             return oss.str();
  810.         }
  811.     };
  812. }
  813. #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
  814.  
  815. // Separate std::tuple specialization
  816. #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
  817. #include <tuple>
  818. namespace Catch {
  819.     namespace Detail {
  820.         template<
  821.             typename Tuple,
  822.             std::size_t N = 0,
  823.             bool = (N < std::tuple_size<Tuple>::value)
  824.             >
  825.             struct TupleElementPrinter {
  826.             static void print(const Tuple& tuple, std::ostream& os) {
  827.                 os << (N ? ", " : " ")
  828.                     << ::Catch::Detail::stringify(std::get<N>(tuple));
  829.                 TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
  830.             }
  831.         };
  832.  
  833.         template<
  834.             typename Tuple,
  835.             std::size_t N
  836.         >
  837.             struct TupleElementPrinter<Tuple, N, false> {
  838.             static void print(const Tuple&, std::ostream&) {}
  839.         };
  840.  
  841.     }
  842.  
  843.     template<typename ...Types>
  844.     struct StringMaker<std::tuple<Types...>> {
  845.         static std::string convert(const std::tuple<Types...>& tuple) {
  846.             std::ostringstream os;
  847.             os << '{';
  848.             Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, os);
  849.             os << " }";
  850.             return os.str();
  851.         }
  852.     };
  853. }
  854. #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
  855.  
  856. // Separate std::chrono::duration specialization
  857. #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  858. #include <ctime>
  859. #include <ratio>
  860. #include <chrono>
  861.  
  862. template <class Ratio>
  863. struct ratio_string {
  864.     static std::string symbol();
  865. };
  866.  
  867. template <class Ratio>
  868. std::string ratio_string<Ratio>::symbol() {
  869.     std::ostringstream oss;
  870.     oss << '[' << Ratio::num << '/'
  871.         << Ratio::den << ']';
  872.     return oss.str();
  873. }
  874. template <>
  875. struct ratio_string<std::atto> {
  876.     static std::string symbol() { return "a"; }
  877. };
  878. template <>
  879. struct ratio_string<std::femto> {
  880.     static std::string symbol() { return "f"; }
  881. };
  882. template <>
  883. struct ratio_string<std::pico> {
  884.     static std::string symbol() { return "p"; }
  885. };
  886. template <>
  887. struct ratio_string<std::nano> {
  888.     static std::string symbol() { return "n"; }
  889. };
  890. template <>
  891. struct ratio_string<std::micro> {
  892.     static std::string symbol() { return "u"; }
  893. };
  894. template <>
  895. struct ratio_string<std::milli> {
  896.     static std::string symbol() { return "m"; }
  897. };
  898.  
  899. namespace Catch {
  900.     ////////////
  901.     // std::chrono::duration specializations
  902.     template<typename Value, typename Ratio>
  903.     struct StringMaker<std::chrono::duration<Value, Ratio>> {
  904.         static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
  905.             std::ostringstream oss;
  906.             oss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
  907.             return oss.str();
  908.         }
  909.     };
  910.     template<typename Value>
  911.     struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
  912.         static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
  913.             std::ostringstream oss;
  914.             oss << duration.count() << " s";
  915.             return oss.str();
  916.         }
  917.     };
  918.     template<typename Value>
  919.     struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
  920.         static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
  921.             std::ostringstream oss;
  922.             oss << duration.count() << " m";
  923.             return oss.str();
  924.         }
  925.     };
  926.     template<typename Value>
  927.     struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
  928.         static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
  929.             std::ostringstream oss;
  930.             oss << duration.count() << " h";
  931.             return oss.str();
  932.         }
  933.     };
  934.  
  935.     ////////////
  936.     // std::chrono::time_point specialization
  937.     // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
  938.     template<typename Clock, typename Duration>
  939.     struct StringMaker<std::chrono::time_point<Clock, Duration>> {
  940.         static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
  941.             return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
  942.         }
  943.     };
  944.     // std::chrono::time_point<system_clock> specialization
  945.     template<typename Duration>
  946.     struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
  947.         static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
  948.             auto converted = std::chrono::system_clock::to_time_t(time_point);
  949.  
  950. #ifdef _MSC_VER
  951.             std::tm timeInfo = {};
  952.             gmtime_s(&timeInfo, &converted);
  953. #else
  954.             std::tm* timeInfo = std::gmtime(&converted);
  955. #endif
  956.  
  957.             auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  958.             char timeStamp[timeStampSize];
  959.             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
  960.  
  961. #ifdef _MSC_VER
  962.             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  963. #else
  964.             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
  965. #endif
  966.             return std::string(timeStamp);
  967.         }
  968.     };
  969. }
  970. #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  971.  
  972. #ifdef _MSC_VER
  973. #pragma warning(pop)
  974. #endif
  975.  
  976. // end catch_tostring.h
  977. #include <ostream>
  978.  
  979. #ifdef _MSC_VER
  980. #pragma warning(push)
  981. #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
  982. #pragma warning(disable:4018) // more "signed/unsigned mismatch"
  983. #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
  984. #pragma warning(disable:4180) // qualifier applied to function type has no meaning
  985. #endif
  986.  
  987. namespace Catch {
  988.  
  989.     struct ITransientExpression {
  990.         virtual auto isBinaryExpression() const -> bool = 0;
  991.         virtual auto getResult() const -> bool = 0;
  992.         virtual void streamReconstructedExpression(std::ostream &os) const = 0;
  993.  
  994.         // We don't actually need a virtual destructore, but many static analysers
  995.         // complain if it's not here :-(
  996.         virtual ~ITransientExpression();
  997.     };
  998.  
  999.     void formatReconstructedExpression(std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs);
  1000.  
  1001.     template<typename LhsT, typename RhsT>
  1002.     class BinaryExpr : public ITransientExpression {
  1003.         bool m_result;
  1004.         LhsT m_lhs;
  1005.         StringRef m_op;
  1006.         RhsT m_rhs;
  1007.  
  1008.         auto isBinaryExpression() const -> bool override { return true; }
  1009.         auto getResult() const -> bool override { return m_result; }
  1010.  
  1011.         void streamReconstructedExpression(std::ostream &os) const override {
  1012.             formatReconstructedExpression
  1013.             (os, Catch::Detail::stringify(m_lhs), m_op, Catch::Detail::stringify(m_rhs));
  1014.         }
  1015.  
  1016.     public:
  1017.         BinaryExpr(bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs)
  1018.             : m_result(comparisonResult),
  1019.             m_lhs(lhs),
  1020.             m_op(op),
  1021.             m_rhs(rhs) {
  1022.         }
  1023.     };
  1024.  
  1025.     template<typename LhsT>
  1026.     class UnaryExpr : public ITransientExpression {
  1027.         LhsT m_lhs;
  1028.  
  1029.         auto isBinaryExpression() const -> bool override { return false; }
  1030.         auto getResult() const -> bool override { return m_lhs ? true : false; }
  1031.  
  1032.         void streamReconstructedExpression(std::ostream &os) const override {
  1033.             os << Catch::Detail::stringify(m_lhs);
  1034.         }
  1035.  
  1036.     public:
  1037.         UnaryExpr(LhsT lhs) : m_lhs(lhs) {}
  1038.     };
  1039.  
  1040.     // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
  1041.     template<typename LhsT, typename RhsT>
  1042.     auto compareEqual(LhsT const& lhs, RhsT const& rhs) -> bool { return lhs == rhs; };
  1043.     template<typename T>
  1044.     auto compareEqual(T* const& lhs, int rhs) -> bool { return lhs == reinterpret_cast<void const*>(rhs); }
  1045.     template<typename T>
  1046.     auto compareEqual(T* const& lhs, long rhs) -> bool { return lhs == reinterpret_cast<void const*>(rhs); }
  1047.     template<typename T>
  1048.     auto compareEqual(int lhs, T* const& rhs) -> bool { return reinterpret_cast<void const*>(lhs) == rhs; }
  1049.     template<typename T>
  1050.     auto compareEqual(long lhs, T* const& rhs) -> bool { return reinterpret_cast<void const*>(lhs) == rhs; }
  1051.  
  1052.     template<typename LhsT, typename RhsT>
  1053.     auto compareNotEqual(LhsT const& lhs, RhsT&& rhs) -> bool { return lhs != rhs; };
  1054.     template<typename T>
  1055.     auto compareNotEqual(T* const& lhs, int rhs) -> bool { return lhs != reinterpret_cast<void const*>(rhs); }
  1056.     template<typename T>
  1057.     auto compareNotEqual(T* const& lhs, long rhs) -> bool { return lhs != reinterpret_cast<void const*>(rhs); }
  1058.     template<typename T>
  1059.     auto compareNotEqual(int lhs, T* const& rhs) -> bool { return reinterpret_cast<void const*>(lhs) != rhs; }
  1060.     template<typename T>
  1061.     auto compareNotEqual(long lhs, T* const& rhs) -> bool { return reinterpret_cast<void const*>(lhs) != rhs; }
  1062.  
  1063.     template<typename LhsT>
  1064.     class ExprLhs {
  1065.         LhsT m_lhs;
  1066.     public:
  1067.         ExprLhs(LhsT lhs) : m_lhs(lhs) {}
  1068.  
  1069.         template<typename RhsT>
  1070.         auto operator == (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  1071.             return BinaryExpr<LhsT, RhsT const&>(compareEqual(m_lhs, rhs), m_lhs, "==", rhs);
  1072.         }
  1073.         auto operator == (bool rhs) -> BinaryExpr<LhsT, bool> const {
  1074.             return BinaryExpr<LhsT, bool>(m_lhs == rhs, m_lhs, "==", rhs);
  1075.         }
  1076.  
  1077.         template<typename RhsT>
  1078.         auto operator != (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  1079.             return BinaryExpr<LhsT, RhsT const&>(compareNotEqual(m_lhs, rhs), m_lhs, "!=", rhs);
  1080.         }
  1081.         auto operator != (bool rhs) -> BinaryExpr<LhsT, bool> const {
  1082.             return BinaryExpr<LhsT, bool>(m_lhs != rhs, m_lhs, "!=", rhs);
  1083.         }
  1084.  
  1085.         template<typename RhsT>
  1086.         auto operator > (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  1087.             return BinaryExpr<LhsT, RhsT const&>(m_lhs > rhs, m_lhs, ">", rhs);
  1088.         }
  1089.         template<typename RhsT>
  1090.         auto operator < (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  1091.             return BinaryExpr<LhsT, RhsT const&>(m_lhs < rhs, m_lhs, "<", rhs);
  1092.         }
  1093.         template<typename RhsT>
  1094.         auto operator >= (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  1095.             return BinaryExpr<LhsT, RhsT const&>(m_lhs >= rhs, m_lhs, ">=", rhs);
  1096.         }
  1097.         template<typename RhsT>
  1098.         auto operator <= (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  1099.             return BinaryExpr<LhsT, RhsT const&>(m_lhs <= rhs, m_lhs, "<=", rhs);
  1100.         }
  1101.  
  1102.         auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
  1103.             return UnaryExpr<LhsT>(m_lhs);
  1104.         }
  1105.     };
  1106.  
  1107.     void handleExpression(ITransientExpression const& expr);
  1108.  
  1109.     template<typename T>
  1110.     void handleExpression(ExprLhs<T> const& expr) {
  1111.         handleExpression(expr.makeUnaryExpr());
  1112.     }
  1113.  
  1114.     struct Decomposer {
  1115.         template<typename T>
  1116.         auto operator <= (T const& lhs) -> ExprLhs<T const&> {
  1117.             return ExprLhs<T const&>(lhs);
  1118.         }
  1119.         auto operator <=(bool value) -> ExprLhs<bool> {
  1120.             return ExprLhs<bool>(value);
  1121.         }
  1122.     };
  1123.  
  1124. } // end namespace Catch
  1125.  
  1126. #ifdef _MSC_VER
  1127. #pragma warning(pop)
  1128. #endif
  1129.  
  1130.   // end catch_decomposer.h
  1131.   // start catch_assertioninfo.h
  1132.  
  1133.   // start catch_result_type.h
  1134.  
  1135. namespace Catch {
  1136.  
  1137.     // ResultWas::OfType enum
  1138.     struct ResultWas {
  1139.         enum OfType {
  1140.             Unknown = -1,
  1141.             Ok = 0,
  1142.             Info = 1,
  1143.             Warning = 2,
  1144.  
  1145.             FailureBit = 0x10,
  1146.  
  1147.             ExpressionFailed = FailureBit | 1,
  1148.             ExplicitFailure = FailureBit | 2,
  1149.  
  1150.             Exception = 0x100 | FailureBit,
  1151.  
  1152.             ThrewException = Exception | 1,
  1153.             DidntThrowException = Exception | 2,
  1154.  
  1155.             FatalErrorCondition = 0x200 | FailureBit
  1156.  
  1157.         };
  1158.     };
  1159.  
  1160.     bool isOk(ResultWas::OfType resultType);
  1161.     bool isJustInfo(int flags);
  1162.  
  1163.     // ResultDisposition::Flags enum
  1164.     struct ResultDisposition {
  1165.         enum Flags {
  1166.             Normal = 0x01,
  1167.  
  1168.             ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
  1169.             FalseTest = 0x04,           // Prefix expression with !
  1170.             SuppressFail = 0x08         // Failures are reported but do not fail the test
  1171.         };
  1172.     };
  1173.  
  1174.     ResultDisposition::Flags operator | (ResultDisposition::Flags lhs, ResultDisposition::Flags rhs);
  1175.  
  1176.     bool shouldContinueOnFailure(int flags);
  1177.     bool isFalseTest(int flags);
  1178.     bool shouldSuppressFailure(int flags);
  1179.  
  1180. } // end namespace Catch
  1181.  
  1182.   // end catch_result_type.h
  1183. namespace Catch {
  1184.  
  1185.     struct AssertionInfo {
  1186.         StringRef macroName;
  1187.         SourceLineInfo lineInfo;
  1188.         StringRef capturedExpression;
  1189.         ResultDisposition::Flags resultDisposition;
  1190.  
  1191.         // We want to delete this constructor but a compiler bug in 4.8 means
  1192.         // the struct is then treated as non-aggregate
  1193.         //AssertionInfo() = delete;
  1194.     };
  1195.  
  1196. } // end namespace Catch
  1197.  
  1198.   // end catch_assertioninfo.h
  1199. namespace Catch {
  1200.  
  1201.     struct TestFailureException {};
  1202.     struct AssertionResultData;
  1203.  
  1204.     class LazyExpression {
  1205.         friend class AssertionHandler;
  1206.         friend struct AssertionStats;
  1207.  
  1208.         ITransientExpression const* m_transientExpression = nullptr;
  1209.         bool m_isNegated;
  1210.     public:
  1211.         LazyExpression(bool isNegated);
  1212.         LazyExpression(LazyExpression const& other);
  1213.         LazyExpression& operator = (LazyExpression const&) = delete;
  1214.  
  1215.         explicit operator bool() const;
  1216.  
  1217.         friend auto operator << (std::ostream& os, LazyExpression const& lazyExpr)->std::ostream&;
  1218.     };
  1219.  
  1220.     class AssertionHandler {
  1221.         AssertionInfo m_assertionInfo;
  1222.         bool m_shouldDebugBreak = false;
  1223.         bool m_shouldThrow = false;
  1224.         bool m_inExceptionGuard = false;
  1225.  
  1226.     public:
  1227.         AssertionHandler
  1228.         (StringRef macroName,
  1229.          SourceLineInfo const& lineInfo,
  1230.          StringRef capturedExpression,
  1231.          ResultDisposition::Flags resultDisposition);
  1232.         ~AssertionHandler();
  1233.  
  1234.         void handle(ITransientExpression const& expr);
  1235.  
  1236.         template<typename T>
  1237.         void handle(ExprLhs<T> const& expr) {
  1238.             handle(expr.makeUnaryExpr());
  1239.         }
  1240.         void handle(ResultWas::OfType resultType);
  1241.         void handle(ResultWas::OfType resultType, StringRef const& message);
  1242.         void handle(ResultWas::OfType resultType, ITransientExpression const* expr, bool negated);
  1243.         void handle(AssertionResultData const& resultData, ITransientExpression const* expr);
  1244.  
  1245.         auto shouldDebugBreak() const -> bool;
  1246.         auto allowThrows() const -> bool;
  1247.         void reactWithDebugBreak() const;
  1248.         void reactWithoutDebugBreak() const;
  1249.         void useActiveException();
  1250.         void setExceptionGuard();
  1251.         void unsetExceptionGuard();
  1252.     };
  1253.  
  1254.     void handleExceptionMatchExpr(AssertionHandler& handler, std::string const& str, StringRef matcherString);
  1255.  
  1256. } // namespace Catch
  1257.  
  1258.   // end catch_assertionhandler.h
  1259.   // start catch_message.h
  1260.  
  1261. #include <string>
  1262. #include <sstream>
  1263.  
  1264. namespace Catch {
  1265.  
  1266.     struct MessageInfo {
  1267.         MessageInfo(std::string const& _macroName,
  1268.                     SourceLineInfo const& _lineInfo,
  1269.                     ResultWas::OfType _type);
  1270.  
  1271.         std::string macroName;
  1272.         std::string message;
  1273.         SourceLineInfo lineInfo;
  1274.         ResultWas::OfType type;
  1275.         unsigned int sequence;
  1276.  
  1277.         bool operator == (MessageInfo const& other) const;
  1278.         bool operator < (MessageInfo const& other) const;
  1279.     private:
  1280.         static unsigned int globalCount;
  1281.     };
  1282.  
  1283.     struct MessageStream {
  1284.  
  1285.         template<typename T>
  1286.         MessageStream& operator << (T const& value) {
  1287.             m_stream << value;
  1288.             return *this;
  1289.         }
  1290.  
  1291.         // !TBD reuse a global/ thread-local stream
  1292.         std::ostringstream m_stream;
  1293.     };
  1294.  
  1295.     struct MessageBuilder : MessageStream {
  1296.         MessageBuilder(std::string const& macroName,
  1297.                        SourceLineInfo const& lineInfo,
  1298.                        ResultWas::OfType type);
  1299.  
  1300.         template<typename T>
  1301.         MessageBuilder& operator << (T const& value) {
  1302.             m_stream << value;
  1303.             return *this;
  1304.         }
  1305.  
  1306.         MessageInfo m_info;
  1307.     };
  1308.  
  1309.     class ScopedMessage {
  1310.     public:
  1311.         ScopedMessage(MessageBuilder const& builder);
  1312.         ~ScopedMessage();
  1313.  
  1314.         MessageInfo m_info;
  1315.     };
  1316.  
  1317. } // end namespace Catch
  1318.  
  1319.   // end catch_message.h
  1320.   // start catch_interfaces_capture.h
  1321.  
  1322. #include <string>
  1323.  
  1324. namespace Catch {
  1325.  
  1326.     class AssertionResult;
  1327.     struct AssertionInfo;
  1328.     struct SectionInfo;
  1329.     struct SectionEndInfo;
  1330.     struct MessageInfo;
  1331.     struct Counts;
  1332.     struct BenchmarkInfo;
  1333.     struct BenchmarkStats;
  1334.  
  1335.     struct IResultCapture {
  1336.  
  1337.         virtual ~IResultCapture();
  1338.  
  1339.         virtual void assertionStarting(AssertionInfo const& info) = 0;
  1340.         virtual void assertionEnded(AssertionResult const& result) = 0;
  1341.         virtual bool sectionStarted(SectionInfo const& sectionInfo,
  1342.                                     Counts& assertions) = 0;
  1343.         virtual void sectionEnded(SectionEndInfo const& endInfo) = 0;
  1344.         virtual void sectionEndedEarly(SectionEndInfo const& endInfo) = 0;
  1345.  
  1346.         virtual void benchmarkStarting(BenchmarkInfo const& info) = 0;
  1347.         virtual void benchmarkEnded(BenchmarkStats const& stats) = 0;
  1348.  
  1349.         virtual void pushScopedMessage(MessageInfo const& message) = 0;
  1350.         virtual void popScopedMessage(MessageInfo const& message) = 0;
  1351.  
  1352.         virtual std::string getCurrentTestName() const = 0;
  1353.         virtual const AssertionResult* getLastResult() const = 0;
  1354.  
  1355.         virtual void exceptionEarlyReported() = 0;
  1356.  
  1357.         virtual void handleFatalErrorCondition(StringRef message) = 0;
  1358.  
  1359.         virtual bool lastAssertionPassed() = 0;
  1360.         virtual void assertionPassed() = 0;
  1361.         virtual void assertionRun() = 0;
  1362.     };
  1363.  
  1364.     IResultCapture& getResultCapture();
  1365. }
  1366.  
  1367. // end catch_interfaces_capture.h
  1368. // start catch_debugger.h
  1369.  
  1370. namespace Catch {
  1371.     bool isDebuggerActive();
  1372. }
  1373.  
  1374. #ifdef CATCH_PLATFORM_MAC
  1375.  
  1376. #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
  1377.  
  1378. #elif defined(CATCH_PLATFORM_LINUX)
  1379. // If we can use inline assembler, do it because this allows us to break
  1380. // directly at the location of the failing check instead of breaking inside
  1381. // raise() called from it, i.e. one stack frame below.
  1382. #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
  1383. #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
  1384. #else // Fall back to the generic way.
  1385. #include <signal.h>
  1386.  
  1387. #define CATCH_TRAP() raise(SIGTRAP)
  1388. #endif
  1389. #elif defined(_MSC_VER)
  1390. #define CATCH_TRAP() __debugbreak()
  1391. #elif defined(__MINGW32__)
  1392. extern "C" __declspec(dllimport) void __stdcall DebugBreak();
  1393. #define CATCH_TRAP() DebugBreak()
  1394. #endif
  1395.  
  1396. #ifdef CATCH_TRAP
  1397. #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
  1398. #else
  1399. #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
  1400. #endif
  1401.  
  1402. // end catch_debugger.h
  1403. #if !defined(CATCH_CONFIG_DISABLE)
  1404.  
  1405. #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
  1406. #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
  1407. #else
  1408. #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
  1409. #endif
  1410.  
  1411. #if defined(CATCH_CONFIG_FAST_COMPILE)
  1412. ///////////////////////////////////////////////////////////////////////////////
  1413. // We can speedup compilation significantly by breaking into debugger lower in
  1414. // the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER
  1415. // macro in each assertion
  1416. #define INTERNAL_CATCH_REACT( handler ) \
  1417.     handler.reactWithDebugBreak();
  1418.  
  1419. ///////////////////////////////////////////////////////////////////////////////
  1420. // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
  1421. // macros.
  1422. // This can potentially cause false negative, if the test code catches
  1423. // the exception before it propagates back up to the runner.
  1424. #define INTERNAL_CATCH_TRY( capturer ) capturer.setExceptionGuard();
  1425. #define INTERNAL_CATCH_CATCH( capturer ) capturer.unsetExceptionGuard();
  1426.  
  1427. #else // CATCH_CONFIG_FAST_COMPILE
  1428.  
  1429. ///////////////////////////////////////////////////////////////////////////////
  1430. // In the event of a failure works out if the debugger needs to be invoked
  1431. // and/or an exception thrown and takes appropriate action.
  1432. // This needs to be done as a macro so the debugger will stop in the user
  1433. // source code rather than in Catch library code
  1434. #define INTERNAL_CATCH_REACT( handler ) \
  1435.     if( handler.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
  1436.     handler.reactWithoutDebugBreak();
  1437.  
  1438. #define INTERNAL_CATCH_TRY( capturer ) try
  1439. #define INTERNAL_CATCH_CATCH( capturer ) catch(...) { capturer.useActiveException(); }
  1440.  
  1441. #endif
  1442.  
  1443. ///////////////////////////////////////////////////////////////////////////////
  1444. #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
  1445.     do { \
  1446.         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
  1447.         INTERNAL_CATCH_TRY( catchAssertionHandler ) { \
  1448.             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
  1449.             catchAssertionHandler.handle( Catch::Decomposer() <= __VA_ARGS__ ); \
  1450.             CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
  1451.         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
  1452.         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1453.     } while( Catch::isTrue( false && static_cast<bool>( !!(__VA_ARGS__) ) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
  1454. // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
  1455.  
  1456. ///////////////////////////////////////////////////////////////////////////////
  1457. #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
  1458.     INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
  1459.     if( Catch::getResultCapture().lastAssertionPassed() )
  1460.  
  1461. ///////////////////////////////////////////////////////////////////////////////
  1462. #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
  1463.     INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
  1464.     if( !Catch::getResultCapture().lastAssertionPassed() )
  1465.  
  1466. ///////////////////////////////////////////////////////////////////////////////
  1467. #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
  1468.     do { \
  1469.         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
  1470.         try { \
  1471.             static_cast<void>(__VA_ARGS__); \
  1472.             catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  1473.         } \
  1474.         catch( ... ) { \
  1475.             catchAssertionHandler.useActiveException(); \
  1476.         } \
  1477.         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1478.     } while( Catch::alwaysFalse() )
  1479.  
  1480. ///////////////////////////////////////////////////////////////////////////////
  1481. #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
  1482.     do { \
  1483.         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
  1484.         if( catchAssertionHandler.allowThrows() ) \
  1485.             try { \
  1486.                 static_cast<void>(__VA_ARGS__); \
  1487.                 catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \
  1488.             } \
  1489.             catch( ... ) { \
  1490.                 catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  1491.             } \
  1492.         else \
  1493.             catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  1494.         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1495.     } while( Catch::alwaysFalse() )
  1496.  
  1497. ///////////////////////////////////////////////////////////////////////////////
  1498. #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
  1499.     do { \
  1500.         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
  1501.         if( catchAssertionHandler.allowThrows() ) \
  1502.             try { \
  1503.                 static_cast<void>(expr); \
  1504.                 catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \
  1505.             } \
  1506.             catch( exceptionType const& ) { \
  1507.                 catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  1508.             } \
  1509.             catch( ... ) { \
  1510.                 catchAssertionHandler.useActiveException(); \
  1511.             } \
  1512.         else \
  1513.             catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  1514.         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1515.     } while( Catch::alwaysFalse() )
  1516.  
  1517. ///////////////////////////////////////////////////////////////////////////////
  1518. #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
  1519.     do { \
  1520.         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
  1521.         catchAssertionHandler.handle( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
  1522.         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1523.     } while( Catch::alwaysFalse() )
  1524.  
  1525. ///////////////////////////////////////////////////////////////////////////////
  1526. #define INTERNAL_CATCH_INFO( macroName, log ) \
  1527.     Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
  1528.  
  1529. ///////////////////////////////////////////////////////////////////////////////
  1530. // Although this is matcher-based, it can be used with just a string
  1531. #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
  1532.     do { \
  1533.         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  1534.         if( catchAssertionHandler.allowThrows() ) \
  1535.             try { \
  1536.                 static_cast<void>(__VA_ARGS__); \
  1537.                 catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \
  1538.             } \
  1539.             catch( ... ) { \
  1540.                 handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \
  1541.             } \
  1542.         else \
  1543.             catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  1544.         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  1545.     } while( Catch::alwaysFalse() )
  1546.  
  1547. #endif // CATCH_CONFIG_DISABLE
  1548.  
  1549. // end catch_capture.hpp
  1550. // start catch_section.h
  1551.  
  1552. // start catch_section_info.h
  1553.  
  1554. // start catch_totals.h
  1555.  
  1556. #include <cstddef>
  1557.  
  1558. namespace Catch {
  1559.  
  1560.     struct Counts {
  1561.         Counts operator - (Counts const& other) const;
  1562.         Counts& operator += (Counts const& other);
  1563.  
  1564.         std::size_t total() const;
  1565.         bool allPassed() const;
  1566.         bool allOk() const;
  1567.  
  1568.         std::size_t passed = 0;
  1569.         std::size_t failed = 0;
  1570.         std::size_t failedButOk = 0;
  1571.     };
  1572.  
  1573.     struct Totals {
  1574.  
  1575.         Totals operator - (Totals const& other) const;
  1576.         Totals& operator += (Totals const& other);
  1577.  
  1578.         Totals delta(Totals const& prevTotals) const;
  1579.  
  1580.         Counts assertions;
  1581.         Counts testCases;
  1582.     };
  1583. }
  1584.  
  1585. // end catch_totals.h
  1586. #include <string>
  1587.  
  1588. namespace Catch {
  1589.  
  1590.     struct SectionInfo {
  1591.         SectionInfo
  1592.         (SourceLineInfo const& _lineInfo,
  1593.          std::string const& _name,
  1594.          std::string const& _description = std::string());
  1595.  
  1596.         std::string name;
  1597.         std::string description;
  1598.         SourceLineInfo lineInfo;
  1599.     };
  1600.  
  1601.     struct SectionEndInfo {
  1602.         SectionEndInfo(SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds);
  1603.  
  1604.         SectionInfo sectionInfo;
  1605.         Counts prevAssertions;
  1606.         double durationInSeconds;
  1607.     };
  1608.  
  1609. } // end namespace Catch
  1610.  
  1611.   // end catch_section_info.h
  1612.   // start catch_timer.h
  1613.  
  1614. #include <cstdint>
  1615.  
  1616. namespace Catch {
  1617.  
  1618.     auto getCurrentNanosecondsSinceEpoch()->uint64_t;
  1619.     auto getEstimatedClockResolution()->uint64_t;
  1620.  
  1621.     class Timer {
  1622.         uint64_t m_nanoseconds = 0;
  1623.     public:
  1624.         void start();
  1625.         auto getElapsedNanoseconds() const -> unsigned int;
  1626.         auto getElapsedMicroseconds() const -> unsigned int;
  1627.         auto getElapsedMilliseconds() const -> unsigned int;
  1628.         auto getElapsedSeconds() const -> double;
  1629.     };
  1630.  
  1631. } // namespace Catch
  1632.  
  1633.   // end catch_timer.h
  1634. #include <string>
  1635.  
  1636. namespace Catch {
  1637.  
  1638.     class Section : NonCopyable {
  1639.     public:
  1640.         Section(SectionInfo const& info);
  1641.         ~Section();
  1642.  
  1643.         // This indicates whether the section should be executed or not
  1644.         explicit operator bool() const;
  1645.  
  1646.     private:
  1647.         SectionInfo m_info;
  1648.  
  1649.         std::string m_name;
  1650.         Counts m_assertions;
  1651.         bool m_sectionIncluded;
  1652.         Timer m_timer;
  1653.     };
  1654.  
  1655. } // end namespace Catch
  1656.  
  1657. #define INTERNAL_CATCH_SECTION( ... ) \
  1658.         if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
  1659.  
  1660.   // end catch_section.h
  1661.   // start catch_benchmark.h
  1662.  
  1663. #include <cstdint>
  1664. #include <string>
  1665.  
  1666. namespace Catch {
  1667.  
  1668.     class BenchmarkLooper {
  1669.  
  1670.         std::string m_name;
  1671.         std::size_t m_count = 0;
  1672.         std::size_t m_iterationsToRun = 1;
  1673.         uint64_t m_resolution;
  1674.         Timer m_timer;
  1675.  
  1676.         static auto getResolution()->uint64_t;
  1677.     public:
  1678.         // Keep most of this inline as it's on the code path that is being timed
  1679.         BenchmarkLooper(StringRef name)
  1680.             : m_name(name),
  1681.             m_resolution(getResolution()) {
  1682.             reportStart();
  1683.             m_timer.start();
  1684.         }
  1685.  
  1686.         explicit operator bool() {
  1687.             if (m_count < m_iterationsToRun)
  1688.                 return true;
  1689.             return needsMoreIterations();
  1690.         }
  1691.  
  1692.         void increment() {
  1693.             ++m_count;
  1694.         }
  1695.  
  1696.         void reportStart();
  1697.         auto needsMoreIterations() -> bool;
  1698.     };
  1699.  
  1700. } // end namespace Catch
  1701.  
  1702. #define BENCHMARK( name ) \
  1703.     for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() )
  1704.  
  1705.   // end catch_benchmark.h
  1706.   // start catch_interfaces_exception.h
  1707.  
  1708.   // start catch_interfaces_registry_hub.h
  1709.  
  1710. #include <string>
  1711. #include <memory>
  1712.  
  1713. namespace Catch {
  1714.  
  1715.     class TestCase;
  1716.     struct ITestCaseRegistry;
  1717.     struct IExceptionTranslatorRegistry;
  1718.     struct IExceptionTranslator;
  1719.     struct IReporterRegistry;
  1720.     struct IReporterFactory;
  1721.     struct ITagAliasRegistry;
  1722.     class StartupExceptionRegistry;
  1723.  
  1724.     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
  1725.  
  1726.     struct IRegistryHub {
  1727.         virtual ~IRegistryHub();
  1728.  
  1729.         virtual IReporterRegistry const& getReporterRegistry() const = 0;
  1730.         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
  1731.         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
  1732.  
  1733.         virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
  1734.  
  1735.         virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
  1736.     };
  1737.  
  1738.     struct IMutableRegistryHub {
  1739.         virtual ~IMutableRegistryHub();
  1740.         virtual void registerReporter(std::string const& name, IReporterFactoryPtr const& factory) = 0;
  1741.         virtual void registerListener(IReporterFactoryPtr const& factory) = 0;
  1742.         virtual void registerTest(TestCase const& testInfo) = 0;
  1743.         virtual void registerTranslator(const IExceptionTranslator* translator) = 0;
  1744.         virtual void registerTagAlias(std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo) = 0;
  1745.         virtual void registerStartupException() noexcept = 0;
  1746.     };
  1747.  
  1748.     IRegistryHub& getRegistryHub();
  1749.     IMutableRegistryHub& getMutableRegistryHub();
  1750.     void cleanUp();
  1751.     std::string translateActiveException();
  1752.  
  1753. }
  1754.  
  1755. // end catch_interfaces_registry_hub.h
  1756. #if defined(CATCH_CONFIG_DISABLE)
  1757. #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
  1758.         static std::string translatorName( signature )
  1759. #endif
  1760.  
  1761. #include <exception>
  1762. #include <string>
  1763. #include <vector>
  1764.  
  1765. namespace Catch {
  1766.     using exceptionTranslateFunction = std::string(*)();
  1767.  
  1768.     struct IExceptionTranslator;
  1769.     using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
  1770.  
  1771.     struct IExceptionTranslator {
  1772.         virtual ~IExceptionTranslator();
  1773.         virtual std::string translate(ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd) const = 0;
  1774.     };
  1775.  
  1776.     struct IExceptionTranslatorRegistry {
  1777.         virtual ~IExceptionTranslatorRegistry();
  1778.  
  1779.         virtual std::string translateActiveException() const = 0;
  1780.     };
  1781.  
  1782.     class ExceptionTranslatorRegistrar {
  1783.         template<typename T>
  1784.         class ExceptionTranslator : public IExceptionTranslator {
  1785.         public:
  1786.  
  1787.             ExceptionTranslator(std::string(*translateFunction)(T&))
  1788.                 : m_translateFunction(translateFunction) {
  1789.             }
  1790.  
  1791.             std::string translate(ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd) const override {
  1792.                 try {
  1793.                     if (it == itEnd)
  1794.                         std::rethrow_exception(std::current_exception());
  1795.                     else
  1796.                         return (*it)->translate(it + 1, itEnd);
  1797.                 } catch (T& ex) {
  1798.                     return m_translateFunction(ex);
  1799.                 }
  1800.             }
  1801.  
  1802.         protected:
  1803.             std::string(*m_translateFunction)(T&);
  1804.         };
  1805.  
  1806.     public:
  1807.         template<typename T>
  1808.         ExceptionTranslatorRegistrar(std::string(*translateFunction)(T&)) {
  1809.             getMutableRegistryHub().registerTranslator
  1810.             (new ExceptionTranslator<T>(translateFunction));
  1811.         }
  1812.     };
  1813. }
  1814.  
  1815. ///////////////////////////////////////////////////////////////////////////////
  1816. #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
  1817.     static std::string translatorName( signature ); \
  1818.     namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
  1819.     static std::string translatorName( signature )
  1820.  
  1821. #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
  1822.  
  1823. // end catch_interfaces_exception.h
  1824. // start catch_approx.h
  1825.  
  1826. // start catch_enforce.h
  1827.  
  1828. #include <sstream>
  1829. #include <stdexcept>
  1830.  
  1831. #define CATCH_PREPARE_EXCEPTION( type, msg ) \
  1832.     type( static_cast<std::ostringstream&&>( std::ostringstream() << msg ).str() )
  1833. #define CATCH_INTERNAL_ERROR( msg ) \
  1834.     throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
  1835. #define CATCH_ERROR( msg ) \
  1836.     throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg )
  1837. #define CATCH_ENFORCE( condition, msg ) \
  1838.     do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
  1839.  
  1840. // end catch_enforce.h
  1841. #include <type_traits>
  1842.  
  1843. namespace Catch {
  1844.     namespace Detail {
  1845.  
  1846.         class Approx {
  1847.         private:
  1848.             bool equalityComparisonImpl(double other) const;
  1849.  
  1850.         public:
  1851.             explicit Approx(double value);
  1852.  
  1853.             static Approx custom();
  1854.  
  1855.             template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1856.             Approx operator()(T const& value) {
  1857.                 Approx approx(static_cast<double>(value));
  1858.                 approx.epsilon(m_epsilon);
  1859.                 approx.margin(m_margin);
  1860.                 approx.scale(m_scale);
  1861.                 return approx;
  1862.             }
  1863.  
  1864.             template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1865.             explicit Approx(T const& value) : Approx(static_cast<double>(value)) {}
  1866.  
  1867.             template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1868.             friend bool operator == (const T& lhs, Approx const& rhs) {
  1869.                 auto lhs_v = static_cast<double>(lhs);
  1870.                 return rhs.equalityComparisonImpl(lhs_v);
  1871.             }
  1872.  
  1873.             template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1874.             friend bool operator == (Approx const& lhs, const T& rhs) {
  1875.                 return operator==(rhs, lhs);
  1876.             }
  1877.  
  1878.             template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1879.             friend bool operator != (T const& lhs, Approx const& rhs) {
  1880.                 return !operator==(lhs, rhs);
  1881.             }
  1882.  
  1883.             template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1884.             friend bool operator != (Approx const& lhs, T const& rhs) {
  1885.                 return !operator==(rhs, lhs);
  1886.             }
  1887.  
  1888.             template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1889.             friend bool operator <= (T const& lhs, Approx const& rhs) {
  1890.                 return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
  1891.             }
  1892.  
  1893.             template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1894.             friend bool operator <= (Approx const& lhs, T const& rhs) {
  1895.                 return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
  1896.             }
  1897.  
  1898.             template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1899.             friend bool operator >= (T const& lhs, Approx const& rhs) {
  1900.                 return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
  1901.             }
  1902.  
  1903.             template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1904.             friend bool operator >= (Approx const& lhs, T const& rhs) {
  1905.                 return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
  1906.             }
  1907.  
  1908.             template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1909.             Approx& epsilon(T const& newEpsilon) {
  1910.                 double epsilonAsDouble = static_cast<double>(newEpsilon);
  1911.                 CATCH_ENFORCE(epsilonAsDouble >= 0 && epsilonAsDouble <= 1.0,
  1912.                               "Invalid Approx::epsilon: " << epsilonAsDouble
  1913.                               << ", Approx::epsilon has to be between 0 and 1");
  1914.                 m_epsilon = epsilonAsDouble;
  1915.                 return *this;
  1916.             }
  1917.  
  1918.             template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1919.             Approx& margin(T const& newMargin) {
  1920.                 double marginAsDouble = static_cast<double>(newMargin);
  1921.                 CATCH_ENFORCE(marginAsDouble >= 0,
  1922.                               "Invalid Approx::margin: " << marginAsDouble
  1923.                               << ", Approx::Margin has to be non-negative.");
  1924.                 m_margin = marginAsDouble;
  1925.                 return *this;
  1926.             }
  1927.  
  1928.             template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  1929.             Approx& scale(T const& newScale) {
  1930.                 m_scale = static_cast<double>(newScale);
  1931.                 return *this;
  1932.             }
  1933.  
  1934.             std::string toString() const;
  1935.  
  1936.         private:
  1937.             double m_epsilon;
  1938.             double m_margin;
  1939.             double m_scale;
  1940.             double m_value;
  1941.         };
  1942.     }
  1943.  
  1944.     template<>
  1945.     struct StringMaker<Catch::Detail::Approx> {
  1946.         static std::string convert(Catch::Detail::Approx const& value);
  1947.     };
  1948.  
  1949. } // end namespace Catch
  1950.  
  1951.   // end catch_approx.h
  1952.   // start catch_string_manip.h
  1953.  
  1954. #include <string>
  1955. #include <iosfwd>
  1956.  
  1957. namespace Catch {
  1958.  
  1959.     bool startsWith(std::string const& s, std::string const& prefix);
  1960.     bool startsWith(std::string const& s, char prefix);
  1961.     bool endsWith(std::string const& s, std::string const& suffix);
  1962.     bool endsWith(std::string const& s, char suffix);
  1963.     bool contains(std::string const& s, std::string const& infix);
  1964.     void toLowerInPlace(std::string& s);
  1965.     std::string toLower(std::string const& s);
  1966.     std::string trim(std::string const& str);
  1967.     bool replaceInPlace(std::string& str, std::string const& replaceThis, std::string const& withThis);
  1968.  
  1969.     struct pluralise {
  1970.         pluralise(std::size_t count, std::string const& label);
  1971.  
  1972.         friend std::ostream& operator << (std::ostream& os, pluralise const& pluraliser);
  1973.  
  1974.         std::size_t m_count;
  1975.         std::string m_label;
  1976.     };
  1977. }
  1978.  
  1979. // end catch_string_manip.h
  1980. #ifndef CATCH_CONFIG_DISABLE_MATCHERS
  1981. // start catch_capture_matchers.h
  1982.  
  1983. // start catch_matchers.h
  1984.  
  1985. #include <string>
  1986. #include <vector>
  1987.  
  1988. namespace Catch {
  1989.     namespace Matchers {
  1990.         namespace Impl {
  1991.  
  1992.             template<typename ArgT> struct MatchAllOf;
  1993.             template<typename ArgT> struct MatchAnyOf;
  1994.             template<typename ArgT> struct MatchNotOf;
  1995.  
  1996.             class MatcherUntypedBase {
  1997.             public:
  1998.                 MatcherUntypedBase() = default;
  1999.                 MatcherUntypedBase(MatcherUntypedBase const&) = default;
  2000.                 MatcherUntypedBase& operator = (MatcherUntypedBase const&) = delete;
  2001.                 std::string toString() const;
  2002.  
  2003.             protected:
  2004.                 virtual ~MatcherUntypedBase();
  2005.                 virtual std::string describe() const = 0;
  2006.                 mutable std::string m_cachedToString;
  2007.             };
  2008.  
  2009.             template<typename ObjectT>
  2010.             struct MatcherMethod {
  2011.                 virtual bool match(ObjectT const& arg) const = 0;
  2012.             };
  2013.             template<typename PtrT>
  2014.             struct MatcherMethod<PtrT*> {
  2015.                 virtual bool match(PtrT* arg) const = 0;
  2016.             };
  2017.  
  2018.             template<typename ObjectT, typename ComparatorT = ObjectT>
  2019.             struct MatcherBase : MatcherUntypedBase, MatcherMethod<ObjectT> {
  2020.  
  2021.                 MatchAllOf<ComparatorT> operator && (MatcherBase const& other) const;
  2022.                 MatchAnyOf<ComparatorT> operator || (MatcherBase const& other) const;
  2023.                 MatchNotOf<ComparatorT> operator ! () const;
  2024.             };
  2025.  
  2026.             template<typename ArgT>
  2027.             struct MatchAllOf : MatcherBase<ArgT> {
  2028.                 bool match(ArgT const& arg) const override {
  2029.                     for (auto matcher : m_matchers) {
  2030.                         if (!matcher->match(arg))
  2031.                             return false;
  2032.                     }
  2033.                     return true;
  2034.                 }
  2035.                 std::string describe() const override {
  2036.                     std::string description;
  2037.                     description.reserve(4 + m_matchers.size() * 32);
  2038.                     description += "( ";
  2039.                     bool first = true;
  2040.                     for (auto matcher : m_matchers) {
  2041.                         if (first)
  2042.                             first = false;
  2043.                         else
  2044.                             description += " and ";
  2045.                         description += matcher->toString();
  2046.                     }
  2047.                     description += " )";
  2048.                     return description;
  2049.                 }
  2050.  
  2051.                 MatchAllOf<ArgT>& operator && (MatcherBase<ArgT> const& other) {
  2052.                     m_matchers.push_back(&other);
  2053.                     return *this;
  2054.                 }
  2055.  
  2056.                 std::vector<MatcherBase<ArgT> const*> m_matchers;
  2057.             };
  2058.             template<typename ArgT>
  2059.             struct MatchAnyOf : MatcherBase<ArgT> {
  2060.  
  2061.                 bool match(ArgT const& arg) const override {
  2062.                     for (auto matcher : m_matchers) {
  2063.                         if (matcher->match(arg))
  2064.                             return true;
  2065.                     }
  2066.                     return false;
  2067.                 }
  2068.                 std::string describe() const override {
  2069.                     std::string description;
  2070.                     description.reserve(4 + m_matchers.size() * 32);
  2071.                     description += "( ";
  2072.                     bool first = true;
  2073.                     for (auto matcher : m_matchers) {
  2074.                         if (first)
  2075.                             first = false;
  2076.                         else
  2077.                             description += " or ";
  2078.                         description += matcher->toString();
  2079.                     }
  2080.                     description += " )";
  2081.                     return description;
  2082.                 }
  2083.  
  2084.                 MatchAnyOf<ArgT>& operator || (MatcherBase<ArgT> const& other) {
  2085.                     m_matchers.push_back(&other);
  2086.                     return *this;
  2087.                 }
  2088.  
  2089.                 std::vector<MatcherBase<ArgT> const*> m_matchers;
  2090.             };
  2091.  
  2092.             template<typename ArgT>
  2093.             struct MatchNotOf : MatcherBase<ArgT> {
  2094.  
  2095.                 MatchNotOf(MatcherBase<ArgT> const& underlyingMatcher) : m_underlyingMatcher(underlyingMatcher) {}
  2096.  
  2097.                 bool match(ArgT const& arg) const override {
  2098.                     return !m_underlyingMatcher.match(arg);
  2099.                 }
  2100.  
  2101.                 std::string describe() const override {
  2102.                     return "not " + m_underlyingMatcher.toString();
  2103.                 }
  2104.                 MatcherBase<ArgT> const& m_underlyingMatcher;
  2105.             };
  2106.  
  2107.             template<typename ObjectT, typename ComparatorT>
  2108.             MatchAllOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator && (MatcherBase const& other) const {
  2109.                 return MatchAllOf<ComparatorT>() && *this && other;
  2110.             }
  2111.             template<typename ObjectT, typename ComparatorT>
  2112.             MatchAnyOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator || (MatcherBase const& other) const {
  2113.                 return MatchAnyOf<ComparatorT>() || *this || other;
  2114.             }
  2115.             template<typename ObjectT, typename ComparatorT>
  2116.             MatchNotOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator ! () const {
  2117.                 return MatchNotOf<ComparatorT>(*this);
  2118.             }
  2119.  
  2120.         } // namespace Impl
  2121.  
  2122.     } // namespace Matchers
  2123.  
  2124.     using namespace Matchers;
  2125.     using Matchers::Impl::MatcherBase;
  2126.  
  2127. } // namespace Catch
  2128.  
  2129.   // end catch_matchers.h
  2130.   // start catch_matchers_string.h
  2131.  
  2132. #include <string>
  2133.  
  2134. namespace Catch {
  2135.     namespace Matchers {
  2136.  
  2137.         namespace StdString {
  2138.  
  2139.             struct CasedString {
  2140.                 CasedString(std::string const& str, CaseSensitive::Choice caseSensitivity);
  2141.                 std::string adjustString(std::string const& str) const;
  2142.                 std::string caseSensitivitySuffix() const;
  2143.  
  2144.                 CaseSensitive::Choice m_caseSensitivity;
  2145.                 std::string m_str;
  2146.             };
  2147.  
  2148.             struct StringMatcherBase : MatcherBase<std::string> {
  2149.                 StringMatcherBase(std::string const& operation, CasedString const& comparator);
  2150.                 std::string describe() const override;
  2151.  
  2152.                 CasedString m_comparator;
  2153.                 std::string m_operation;
  2154.             };
  2155.  
  2156.             struct EqualsMatcher : StringMatcherBase {
  2157.                 EqualsMatcher(CasedString const& comparator);
  2158.                 bool match(std::string const& source) const override;
  2159.             };
  2160.             struct ContainsMatcher : StringMatcherBase {
  2161.                 ContainsMatcher(CasedString const& comparator);
  2162.                 bool match(std::string const& source) const override;
  2163.             };
  2164.             struct StartsWithMatcher : StringMatcherBase {
  2165.                 StartsWithMatcher(CasedString const& comparator);
  2166.                 bool match(std::string const& source) const override;
  2167.             };
  2168.             struct EndsWithMatcher : StringMatcherBase {
  2169.                 EndsWithMatcher(CasedString const& comparator);
  2170.                 bool match(std::string const& source) const override;
  2171.             };
  2172.  
  2173.         } // namespace StdString
  2174.  
  2175.           // The following functions create the actual matcher objects.
  2176.           // This allows the types to be inferred
  2177.  
  2178.         StdString::EqualsMatcher Equals(std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
  2179.         StdString::ContainsMatcher Contains(std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
  2180.         StdString::EndsWithMatcher EndsWith(std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
  2181.         StdString::StartsWithMatcher StartsWith(std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
  2182.  
  2183.     } // namespace Matchers
  2184. } // namespace Catch
  2185.  
  2186.   // end catch_matchers_string.h
  2187.   // start catch_matchers_vector.h
  2188.  
  2189. namespace Catch {
  2190.     namespace Matchers {
  2191.  
  2192.         namespace Vector {
  2193.  
  2194.             template<typename T>
  2195.             struct ContainsElementMatcher : MatcherBase<std::vector<T>, T> {
  2196.  
  2197.                 ContainsElementMatcher(T const &comparator) : m_comparator(comparator) {}
  2198.  
  2199.                 bool match(std::vector<T> const &v) const override {
  2200.                     for (auto const& el : v) {
  2201.                         if (el == m_comparator) {
  2202.                             return true;
  2203.                         }
  2204.                     }
  2205.                     return false;
  2206.                 }
  2207.  
  2208.                 std::string describe() const override {
  2209.                     return "Contains: " + ::Catch::Detail::stringify(m_comparator);
  2210.                 }
  2211.  
  2212.                 T const& m_comparator;
  2213.             };
  2214.  
  2215.             template<typename T>
  2216.             struct ContainsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
  2217.  
  2218.                 ContainsMatcher(std::vector<T> const &comparator) : m_comparator(comparator) {}
  2219.  
  2220.                 bool match(std::vector<T> const &v) const override {
  2221.                     // !TBD: see note in EqualsMatcher
  2222.                     if (m_comparator.size() > v.size())
  2223.                         return false;
  2224.                     for (auto const& comparator : m_comparator) {
  2225.                         auto present = false;
  2226.                         for (const auto& el : v) {
  2227.                             if (el == comparator) {
  2228.                                 present = true;
  2229.                                 break;
  2230.                             }
  2231.                         }
  2232.                         if (!present) {
  2233.                             return false;
  2234.                         }
  2235.                     }
  2236.                     return true;
  2237.                 }
  2238.                 std::string describe() const override {
  2239.                     return "Contains: " + ::Catch::Detail::stringify(m_comparator);
  2240.                 }
  2241.  
  2242.                 std::vector<T> const& m_comparator;
  2243.             };
  2244.  
  2245.             template<typename T>
  2246.             struct EqualsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
  2247.  
  2248.                 EqualsMatcher(std::vector<T> const &comparator) : m_comparator(comparator) {}
  2249.  
  2250.                 bool match(std::vector<T> const &v) const override {
  2251.                     // !TBD: This currently works if all elements can be compared using !=
  2252.                     // - a more general approach would be via a compare template that defaults
  2253.                     // to using !=. but could be specialised for, e.g. std::vector<T> etc
  2254.                     // - then just call that directly
  2255.                     if (m_comparator.size() != v.size())
  2256.                         return false;
  2257.                     for (std::size_t i = 0; i < v.size(); ++i)
  2258.                         if (m_comparator[i] != v[i])
  2259.                             return false;
  2260.                     return true;
  2261.                 }
  2262.                 std::string describe() const override {
  2263.                     return "Equals: " + ::Catch::Detail::stringify(m_comparator);
  2264.                 }
  2265.                 std::vector<T> const& m_comparator;
  2266.             };
  2267.  
  2268.         } // namespace Vector
  2269.  
  2270.           // The following functions create the actual matcher objects.
  2271.           // This allows the types to be inferred
  2272.  
  2273.         template<typename T>
  2274.         Vector::ContainsMatcher<T> Contains(std::vector<T> const& comparator) {
  2275.             return Vector::ContainsMatcher<T>(comparator);
  2276.         }
  2277.  
  2278.         template<typename T>
  2279.         Vector::ContainsElementMatcher<T> VectorContains(T const& comparator) {
  2280.             return Vector::ContainsElementMatcher<T>(comparator);
  2281.         }
  2282.  
  2283.         template<typename T>
  2284.         Vector::EqualsMatcher<T> Equals(std::vector<T> const& comparator) {
  2285.             return Vector::EqualsMatcher<T>(comparator);
  2286.         }
  2287.  
  2288.     } // namespace Matchers
  2289. } // namespace Catch
  2290.  
  2291.   // end catch_matchers_vector.h
  2292. namespace Catch {
  2293.  
  2294.     template<typename ArgT, typename MatcherT>
  2295.     class MatchExpr : public ITransientExpression {
  2296.         ArgT const& m_arg;
  2297.         MatcherT m_matcher;
  2298.         StringRef m_matcherString;
  2299.         bool m_result;
  2300.     public:
  2301.         MatchExpr(ArgT const& arg, MatcherT const& matcher, StringRef matcherString)
  2302.             : m_arg(arg),
  2303.             m_matcher(matcher),
  2304.             m_matcherString(matcherString),
  2305.             m_result(matcher.match(arg)) {
  2306.         }
  2307.  
  2308.         auto isBinaryExpression() const -> bool  override { return true; }
  2309.         auto getResult() const -> bool override { return m_result; }
  2310.  
  2311.         void streamReconstructedExpression(std::ostream &os) const override {
  2312.             auto matcherAsString = m_matcher.toString();
  2313.             os << Catch::Detail::stringify(m_arg) << ' ';
  2314.             if (matcherAsString == Detail::unprintableString)
  2315.                 os << m_matcherString;
  2316.             else
  2317.                 os << matcherAsString;
  2318.         }
  2319.     };
  2320.  
  2321.     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
  2322.  
  2323.     void handleExceptionMatchExpr(AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString);
  2324.  
  2325.     template<typename ArgT, typename MatcherT>
  2326.     auto makeMatchExpr(ArgT const& arg, MatcherT const& matcher, StringRef matcherString) -> MatchExpr<ArgT, MatcherT> {
  2327.         return MatchExpr<ArgT, MatcherT>(arg, matcher, matcherString);
  2328.     }
  2329.  
  2330. } // namespace Catch
  2331.  
  2332.   ///////////////////////////////////////////////////////////////////////////////
  2333. #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
  2334.     do { \
  2335.         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  2336.         INTERNAL_CATCH_TRY( catchAssertionHandler ) { \
  2337.             catchAssertionHandler.handle( Catch::makeMatchExpr( arg, matcher, #matcher ) ); \
  2338.         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
  2339.         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2340.     } while( Catch::alwaysFalse() )
  2341.  
  2342.   ///////////////////////////////////////////////////////////////////////////////
  2343. #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
  2344.     do { \
  2345.         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  2346.         if( catchAssertionHandler.allowThrows() ) \
  2347.             try { \
  2348.                 static_cast<void>(__VA_ARGS__ ); \
  2349.                 catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \
  2350.             } \
  2351.             catch( exceptionType const& ex ) { \
  2352.                 catchAssertionHandler.handle( Catch::makeMatchExpr( ex, matcher, #matcher ) ); \
  2353.             } \
  2354.             catch( ... ) { \
  2355.                 catchAssertionHandler.useActiveException(); \
  2356.             } \
  2357.         else \
  2358.             catchAssertionHandler.handle( Catch::ResultWas::Ok ); \
  2359.         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2360.     } while( Catch::alwaysFalse() )
  2361.  
  2362.   // end catch_capture_matchers.h
  2363. #endif
  2364.  
  2365.   // These files are included here so the single_include script doesn't put them
  2366.   // in the conditionally compiled sections
  2367.   // start catch_test_case_info.h
  2368.  
  2369. #include <string>
  2370. #include <vector>
  2371. #include <memory>
  2372.  
  2373. #ifdef __clang__
  2374. #pragma clang diagnostic push
  2375. #pragma clang diagnostic ignored "-Wpadded"
  2376. #endif
  2377.  
  2378. namespace Catch {
  2379.  
  2380.     struct ITestInvoker;
  2381.  
  2382.     struct TestCaseInfo {
  2383.         enum SpecialProperties {
  2384.             None = 0,
  2385.             IsHidden = 1 << 1,
  2386.             ShouldFail = 1 << 2,
  2387.             MayFail = 1 << 3,
  2388.             Throws = 1 << 4,
  2389.             NonPortable = 1 << 5,
  2390.             Benchmark = 1 << 6
  2391.         };
  2392.  
  2393.         TestCaseInfo(std::string const& _name,
  2394.                      std::string const& _className,
  2395.                      std::string const& _description,
  2396.                      std::vector<std::string> const& _tags,
  2397.                      SourceLineInfo const& _lineInfo);
  2398.  
  2399.         friend void setTags(TestCaseInfo& testCaseInfo, std::vector<std::string> tags);
  2400.  
  2401.         bool isHidden() const;
  2402.         bool throws() const;
  2403.         bool okToFail() const;
  2404.         bool expectedToFail() const;
  2405.  
  2406.         std::string tagsAsString() const;
  2407.  
  2408.         std::string name;
  2409.         std::string className;
  2410.         std::string description;
  2411.         std::vector<std::string> tags;
  2412.         std::vector<std::string> lcaseTags;
  2413.         SourceLineInfo lineInfo;
  2414.         SpecialProperties properties;
  2415.     };
  2416.  
  2417.     class TestCase : public TestCaseInfo {
  2418.     public:
  2419.  
  2420.         TestCase(ITestInvoker* testCase, TestCaseInfo const& info);
  2421.  
  2422.         TestCase withName(std::string const& _newName) const;
  2423.  
  2424.         void invoke() const;
  2425.  
  2426.         TestCaseInfo const& getTestCaseInfo() const;
  2427.  
  2428.         bool operator == (TestCase const& other) const;
  2429.         bool operator < (TestCase const& other) const;
  2430.  
  2431.     private:
  2432.         std::shared_ptr<ITestInvoker> test;
  2433.     };
  2434.  
  2435.     TestCase makeTestCase(ITestInvoker* testCase,
  2436.                           std::string const& className,
  2437.                           std::string const& name,
  2438.                           std::string const& description,
  2439.                           SourceLineInfo const& lineInfo);
  2440. }
  2441.  
  2442. #ifdef __clang__
  2443. #pragma clang diagnostic pop
  2444. #endif
  2445.  
  2446. // end catch_test_case_info.h
  2447. // start catch_interfaces_runner.h
  2448.  
  2449. namespace Catch {
  2450.  
  2451.     struct IRunner {
  2452.         virtual ~IRunner();
  2453.         virtual bool aborting() const = 0;
  2454.     };
  2455. }
  2456.  
  2457. // end catch_interfaces_runner.h
  2458.  
  2459. #ifdef __OBJC__
  2460. // start catch_objc.hpp
  2461.  
  2462. #import <objc/runtime.h>
  2463.  
  2464. #include <string>
  2465.  
  2466. // NB. Any general catch headers included here must be included
  2467. // in catch.hpp first to make sure they are included by the single
  2468. // header for non obj-usage
  2469.  
  2470. ///////////////////////////////////////////////////////////////////////////////
  2471. // This protocol is really only here for (self) documenting purposes, since
  2472. // all its methods are optional.
  2473. @protocol OcFixture
  2474.  
  2475. @optional
  2476.  
  2477. - (void)setUp;
  2478. -(void)tearDown;
  2479.  
  2480. @end
  2481.  
  2482. namespace Catch {
  2483.  
  2484.     class OcMethod : public ITestInvoker {
  2485.  
  2486.     public:
  2487.         OcMethod(Class cls, SEL sel) : m_cls(cls), m_sel(sel) {}
  2488.  
  2489.         virtual void invoke() const {
  2490.             id obj = [[m_cls alloc] init];
  2491.  
  2492.             performOptionalSelector(obj, @selector(setUp)  );
  2493.             performOptionalSelector(obj, m_sel);
  2494.             performOptionalSelector(obj, @selector(tearDown)  );
  2495.  
  2496.             arcSafeRelease(obj);
  2497.         }
  2498.     private:
  2499.         virtual ~OcMethod() {}
  2500.  
  2501.         Class m_cls;
  2502.         SEL m_sel;
  2503.     };
  2504.  
  2505.     namespace Detail {
  2506.  
  2507.         inline std::string getAnnotation(Class cls,
  2508.                                          std::string const& annotationName,
  2509.                                          std::string const& testCaseName) {
  2510.             NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
  2511.                 SEL sel = NSSelectorFromString(selStr);
  2512.             arcSafeRelease(selStr);
  2513.             id value = performOptionalSelector(cls, sel);
  2514.             if (value)
  2515.                 return[(NSString*)value UTF8String];
  2516.             return "";
  2517.         }
  2518.     }
  2519.  
  2520.     inline std::size_t registerTestMethods() {
  2521.         std::size_t noTestMethods = 0;
  2522.         int noClasses = objc_getClassList(nullptr, 0);
  2523.  
  2524.         Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc(sizeof(Class) * noClasses);
  2525.         objc_getClassList(classes, noClasses);
  2526.  
  2527.         for (int c = 0; c < noClasses; c++) {
  2528.             Class cls = classes[c];
  2529.             {
  2530.                 u_int count;
  2531.                 Method* methods = class_copyMethodList(cls, &count);
  2532.                 for (u_int m = 0; m < count; m++) {
  2533.                     SEL selector = method_getName(methods[m]);
  2534.                     std::string methodName = sel_getName(selector);
  2535.                     if (startsWith(methodName, "Catch_TestCase_")) {
  2536.                         std::string testCaseName = methodName.substr(15);
  2537.                         std::string name = Detail::getAnnotation(cls, "Name", testCaseName);
  2538.                         std::string desc = Detail::getAnnotation(cls, "Description", testCaseName);
  2539.                         const char* className = class_getName(cls);
  2540.  
  2541.                         getMutableRegistryHub().registerTest(makeTestCase(new OcMethod(cls, selector), className, name.c_str(), desc.c_str(), SourceLineInfo("", 0)));
  2542.                         noTestMethods++;
  2543.                     }
  2544.                 }
  2545.                 free(methods);
  2546.             }
  2547.         }
  2548.         return noTestMethods;
  2549.     }
  2550.  
  2551. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  2552.  
  2553.     namespace Matchers {
  2554.         namespace Impl {
  2555.             namespace NSStringMatchers {
  2556.  
  2557.                 struct StringHolder : MatcherBase<NSString*> {
  2558.                     StringHolder(NSString* substr) : m_substr([substr copy]) {}
  2559.                     StringHolder(StringHolder const& other) : m_substr([other.m_substr copy]) {}
  2560.                     StringHolder() {
  2561.                         arcSafeRelease(m_substr);
  2562.                     }
  2563.  
  2564.                     bool match(NSString* arg) const override {
  2565.                         return false;
  2566.                     }
  2567.  
  2568.                     NSString* CATCH_ARC_STRONG m_substr;
  2569.                 };
  2570.  
  2571.                 struct Equals : StringHolder {
  2572.                     Equals(NSString* substr) : StringHolder(substr) {}
  2573.  
  2574.                     bool match(NSString* str) const override {
  2575.                         return  (str != nil || m_substr == nil) &&
  2576.                             [str isEqualToString : m_substr];
  2577.                     }
  2578.  
  2579.                     std::string describe() const override {
  2580.                         return "equals string: " + Catch::Detail::stringify(m_substr);
  2581.                     }
  2582.                 };
  2583.  
  2584.                 struct Contains : StringHolder {
  2585.                     Contains(NSString* substr) : StringHolder(substr) {}
  2586.  
  2587.                     bool match(NSString* str) const {
  2588.                         return  (str != nil || m_substr == nil) &&
  2589.                             [str rangeOfString : m_substr].location != NSNotFound;
  2590.                     }
  2591.  
  2592.                     std::string describe() const override {
  2593.                         return "contains string: " + Catch::Detail::stringify(m_substr);
  2594.                     }
  2595.                 };
  2596.  
  2597.                 struct StartsWith : StringHolder {
  2598.                     StartsWith(NSString* substr) : StringHolder(substr) {}
  2599.  
  2600.                     bool match(NSString* str) const override {
  2601.                         return  (str != nil || m_substr == nil) &&
  2602.                             [str rangeOfString : m_substr].location == 0;
  2603.                     }
  2604.  
  2605.                     std::string describe() const override {
  2606.                         return "starts with: " + Catch::Detail::stringify(m_substr);
  2607.                     }
  2608.                 };
  2609.                 struct EndsWith : StringHolder {
  2610.                     EndsWith(NSString* substr) : StringHolder(substr) {}
  2611.  
  2612.                     bool match(NSString* str) const override {
  2613.                         return  (str != nil || m_substr == nil) &&
  2614.                             [str rangeOfString : m_substr].location == [str length] - [m_substr length];
  2615.                     }
  2616.  
  2617.                     std::string describe() const override {
  2618.                         return "ends with: " + Catch::Detail::stringify(m_substr);
  2619.                     }
  2620.                 };
  2621.  
  2622.             } // namespace NSStringMatchers
  2623.         } // namespace Impl
  2624.  
  2625.         inline Impl::NSStringMatchers::Equals
  2626.             Equals(NSString* substr) { return Impl::NSStringMatchers::Equals(substr); }
  2627.  
  2628.         inline Impl::NSStringMatchers::Contains
  2629.             Contains(NSString* substr) { return Impl::NSStringMatchers::Contains(substr); }
  2630.  
  2631.         inline Impl::NSStringMatchers::StartsWith
  2632.             StartsWith(NSString* substr) { return Impl::NSStringMatchers::StartsWith(substr); }
  2633.  
  2634.         inline Impl::NSStringMatchers::EndsWith
  2635.             EndsWith(NSString* substr) { return Impl::NSStringMatchers::EndsWith(substr); }
  2636.  
  2637.     } // namespace Matchers
  2638.  
  2639.     using namespace Matchers;
  2640.  
  2641. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  2642.  
  2643. } // namespace Catch
  2644.  
  2645.   ///////////////////////////////////////////////////////////////////////////////
  2646. #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
  2647. #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
  2648. +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
  2649. { \
  2650. return @ name; \
  2651. } \
  2652. +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
  2653. { \
  2654. return @ desc; \
  2655. } \
  2656. -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
  2657.  
  2658. #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
  2659.  
  2660.   // end catch_objc.hpp
  2661. #endif
  2662.  
  2663. #ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
  2664.   // start catch_external_interfaces.h
  2665.  
  2666.   // start catch_reporter_bases.hpp
  2667.  
  2668.   // start catch_interfaces_reporter.h
  2669.  
  2670.   // start catch_config.hpp
  2671.  
  2672.   // start catch_test_spec_parser.h
  2673.  
  2674. #ifdef __clang__
  2675. #pragma clang diagnostic push
  2676. #pragma clang diagnostic ignored "-Wpadded"
  2677. #endif
  2678.  
  2679.   // start catch_test_spec.h
  2680.  
  2681. #ifdef __clang__
  2682. #pragma clang diagnostic push
  2683. #pragma clang diagnostic ignored "-Wpadded"
  2684. #endif
  2685.  
  2686.   // start catch_wildcard_pattern.h
  2687.  
  2688. namespace Catch {
  2689.     class WildcardPattern {
  2690.         enum WildcardPosition {
  2691.             NoWildcard = 0,
  2692.             WildcardAtStart = 1,
  2693.             WildcardAtEnd = 2,
  2694.             WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
  2695.         };
  2696.  
  2697.     public:
  2698.  
  2699.         WildcardPattern(std::string const& pattern, CaseSensitive::Choice caseSensitivity);
  2700.         virtual ~WildcardPattern() = default;
  2701.         virtual bool matches(std::string const& str) const;
  2702.  
  2703.     private:
  2704.         std::string adjustCase(std::string const& str) const;
  2705.         CaseSensitive::Choice m_caseSensitivity;
  2706.         WildcardPosition m_wildcard = NoWildcard;
  2707.         std::string m_pattern;
  2708.     };
  2709. }
  2710.  
  2711. // end catch_wildcard_pattern.h
  2712. #include <string>
  2713. #include <vector>
  2714. #include <memory>
  2715.  
  2716. namespace Catch {
  2717.  
  2718.     class TestSpec {
  2719.         struct Pattern {
  2720.             virtual ~Pattern();
  2721.             virtual bool matches(TestCaseInfo const& testCase) const = 0;
  2722.         };
  2723.         using PatternPtr = std::shared_ptr<Pattern>;
  2724.  
  2725.         class NamePattern : public Pattern {
  2726.         public:
  2727.             NamePattern(std::string const& name);
  2728.             virtual ~NamePattern();
  2729.             virtual bool matches(TestCaseInfo const& testCase) const override;
  2730.         private:
  2731.             WildcardPattern m_wildcardPattern;
  2732.         };
  2733.  
  2734.         class TagPattern : public Pattern {
  2735.         public:
  2736.             TagPattern(std::string const& tag);
  2737.             virtual ~TagPattern();
  2738.             virtual bool matches(TestCaseInfo const& testCase) const override;
  2739.         private:
  2740.             std::string m_tag;
  2741.         };
  2742.  
  2743.         class ExcludedPattern : public Pattern {
  2744.         public:
  2745.             ExcludedPattern(PatternPtr const& underlyingPattern);
  2746.             virtual ~ExcludedPattern();
  2747.             virtual bool matches(TestCaseInfo const& testCase) const override;
  2748.         private:
  2749.             PatternPtr m_underlyingPattern;
  2750.         };
  2751.  
  2752.         struct Filter {
  2753.             std::vector<PatternPtr> m_patterns;
  2754.  
  2755.             bool matches(TestCaseInfo const& testCase) const;
  2756.         };
  2757.  
  2758.     public:
  2759.         bool hasFilters() const;
  2760.         bool matches(TestCaseInfo const& testCase) const;
  2761.  
  2762.     private:
  2763.         std::vector<Filter> m_filters;
  2764.  
  2765.         friend class TestSpecParser;
  2766.     };
  2767. }
  2768.  
  2769. #ifdef __clang__
  2770. #pragma clang diagnostic pop
  2771. #endif
  2772.  
  2773. // end catch_test_spec.h
  2774. // start catch_interfaces_tag_alias_registry.h
  2775.  
  2776. #include <string>
  2777.  
  2778. namespace Catch {
  2779.  
  2780.     struct TagAlias;
  2781.  
  2782.     struct ITagAliasRegistry {
  2783.         virtual ~ITagAliasRegistry();
  2784.         // Nullptr if not present
  2785.         virtual TagAlias const* find(std::string const& alias) const = 0;
  2786.         virtual std::string expandAliases(std::string const& unexpandedTestSpec) const = 0;
  2787.  
  2788.         static ITagAliasRegistry const& get();
  2789.     };
  2790.  
  2791. } // end namespace Catch
  2792.  
  2793.   // end catch_interfaces_tag_alias_registry.h
  2794. namespace Catch {
  2795.  
  2796.     class TestSpecParser {
  2797.         enum Mode { None, Name, QuotedName, Tag, EscapedName };
  2798.         Mode m_mode = None;
  2799.         bool m_exclusion = false;
  2800.         std::size_t m_start = std::string::npos, m_pos = 0;
  2801.         std::string m_arg;
  2802.         std::vector<std::size_t> m_escapeChars;
  2803.         TestSpec::Filter m_currentFilter;
  2804.         TestSpec m_testSpec;
  2805.         ITagAliasRegistry const* m_tagAliases = nullptr;
  2806.  
  2807.     public:
  2808.         TestSpecParser(ITagAliasRegistry const& tagAliases);
  2809.  
  2810.         TestSpecParser& parse(std::string const& arg);
  2811.         TestSpec testSpec();
  2812.  
  2813.     private:
  2814.         void visitChar(char c);
  2815.         void startNewMode(Mode mode, std::size_t start);
  2816.         void escape();
  2817.         std::string subString() const;
  2818.  
  2819.         template<typename T>
  2820.         void addPattern() {
  2821.             std::string token = subString();
  2822.             for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
  2823.                 token = token.substr(0, m_escapeChars[i] - m_start - i) + token.substr(m_escapeChars[i] - m_start - i + 1);
  2824.             m_escapeChars.clear();
  2825.             if (startsWith(token, "exclude:")) {
  2826.                 m_exclusion = true;
  2827.                 token = token.substr(8);
  2828.             }
  2829.             if (!token.empty()) {
  2830.                 TestSpec::PatternPtr pattern = std::make_shared<T>(token);
  2831.                 if (m_exclusion)
  2832.                     pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
  2833.                 m_currentFilter.m_patterns.push_back(pattern);
  2834.             }
  2835.             m_exclusion = false;
  2836.             m_mode = None;
  2837.         }
  2838.  
  2839.         void addFilter();
  2840.     };
  2841.     TestSpec parseTestSpec(std::string const& arg);
  2842.  
  2843. } // namespace Catch
  2844.  
  2845. #ifdef __clang__
  2846. #pragma clang diagnostic pop
  2847. #endif
  2848.  
  2849.   // end catch_test_spec_parser.h
  2850.   // start catch_interfaces_config.h
  2851.  
  2852. #include <iosfwd>
  2853. #include <string>
  2854. #include <vector>
  2855. #include <memory>
  2856.  
  2857. namespace Catch {
  2858.  
  2859.     enum class Verbosity {
  2860.         Quiet = 0,
  2861.         Normal,
  2862.         High
  2863.     };
  2864.  
  2865.     struct WarnAbout {
  2866.         enum What {
  2867.             Nothing = 0x00,
  2868.             NoAssertions = 0x01
  2869.         };
  2870.     };
  2871.  
  2872.     struct ShowDurations {
  2873.         enum OrNot {
  2874.             DefaultForReporter,
  2875.             Always,
  2876.             Never
  2877.         };
  2878.     };
  2879.     struct RunTests {
  2880.         enum InWhatOrder {
  2881.             InDeclarationOrder,
  2882.             InLexicographicalOrder,
  2883.             InRandomOrder
  2884.         };
  2885.     };
  2886.     struct UseColour {
  2887.         enum YesOrNo {
  2888.             Auto,
  2889.             Yes,
  2890.             No
  2891.         };
  2892.     };
  2893.     struct WaitForKeypress {
  2894.         enum When {
  2895.             Never,
  2896.             BeforeStart = 1,
  2897.             BeforeExit = 2,
  2898.             BeforeStartAndExit = BeforeStart | BeforeExit
  2899.         };
  2900.     };
  2901.  
  2902.     class TestSpec;
  2903.  
  2904.     struct IConfig : NonCopyable {
  2905.  
  2906.         virtual ~IConfig();
  2907.  
  2908.         virtual bool allowThrows() const = 0;
  2909.         virtual std::ostream& stream() const = 0;
  2910.         virtual std::string name() const = 0;
  2911.         virtual bool includeSuccessfulResults() const = 0;
  2912.         virtual bool shouldDebugBreak() const = 0;
  2913.         virtual bool warnAboutMissingAssertions() const = 0;
  2914.         virtual int abortAfter() const = 0;
  2915.         virtual bool showInvisibles() const = 0;
  2916.         virtual ShowDurations::OrNot showDurations() const = 0;
  2917.         virtual TestSpec const& testSpec() const = 0;
  2918.         virtual RunTests::InWhatOrder runOrder() const = 0;
  2919.         virtual unsigned int rngSeed() const = 0;
  2920.         virtual int benchmarkResolutionMultiple() const = 0;
  2921.         virtual UseColour::YesOrNo useColour() const = 0;
  2922.         virtual std::vector<std::string> const& getSectionsToRun() const = 0;
  2923.         virtual Verbosity verbosity() const = 0;
  2924.     };
  2925.  
  2926.     using IConfigPtr = std::shared_ptr<IConfig const>;
  2927. }
  2928.  
  2929. // end catch_interfaces_config.h
  2930. // Libstdc++ doesn't like incomplete classes for unique_ptr
  2931. // start catch_stream.h
  2932.  
  2933. // start catch_streambuf.h
  2934.  
  2935. #include <streambuf>
  2936.  
  2937. namespace Catch {
  2938.  
  2939.     class StreamBufBase : public std::streambuf {
  2940.     public:
  2941.         virtual ~StreamBufBase();
  2942.     };
  2943. }
  2944.  
  2945. // end catch_streambuf.h
  2946. #include <streambuf>
  2947. #include <ostream>
  2948. #include <fstream>
  2949. #include <memory>
  2950.  
  2951. namespace Catch {
  2952.  
  2953.     std::ostream& cout();
  2954.     std::ostream& cerr();
  2955.     std::ostream& clog();
  2956.  
  2957.     struct IStream {
  2958.         virtual ~IStream();
  2959.         virtual std::ostream& stream() const = 0;
  2960.     };
  2961.  
  2962.     class FileStream : public IStream {
  2963.         mutable std::ofstream m_ofs;
  2964.     public:
  2965.         FileStream(std::string const& filename);
  2966.         ~FileStream() override = default;
  2967.     public: // IStream
  2968.         std::ostream& stream() const override;
  2969.     };
  2970.  
  2971.     class CoutStream : public IStream {
  2972.         mutable std::ostream m_os;
  2973.     public:
  2974.         CoutStream();
  2975.         ~CoutStream() override = default;
  2976.  
  2977.     public: // IStream
  2978.         std::ostream& stream() const override;
  2979.     };
  2980.  
  2981.     class DebugOutStream : public IStream {
  2982.         std::unique_ptr<StreamBufBase> m_streamBuf;
  2983.         mutable std::ostream m_os;
  2984.     public:
  2985.         DebugOutStream();
  2986.         ~DebugOutStream() override = default;
  2987.  
  2988.     public: // IStream
  2989.         std::ostream& stream() const override;
  2990.     };
  2991. }
  2992.  
  2993. // end catch_stream.h
  2994.  
  2995. #include <memory>
  2996. #include <vector>
  2997. #include <string>
  2998.  
  2999. #ifndef CATCH_CONFIG_CONSOLE_WIDTH
  3000. #define CATCH_CONFIG_CONSOLE_WIDTH 80
  3001. #endif
  3002.  
  3003. namespace Catch {
  3004.  
  3005.     struct IStream;
  3006.  
  3007.     struct ConfigData {
  3008.         bool listTests = false;
  3009.         bool listTags = false;
  3010.         bool listReporters = false;
  3011.         bool listTestNamesOnly = false;
  3012.  
  3013.         bool showSuccessfulTests = false;
  3014.         bool shouldDebugBreak = false;
  3015.         bool noThrow = false;
  3016.         bool showHelp = false;
  3017.         bool showInvisibles = false;
  3018.         bool filenamesAsTags = false;
  3019.         bool libIdentify = false;
  3020.  
  3021.         int abortAfter = -1;
  3022.         unsigned int rngSeed = 0;
  3023.         int benchmarkResolutionMultiple = 100;
  3024.  
  3025.         Verbosity verbosity = Verbosity::Normal;
  3026.         WarnAbout::What warnings = WarnAbout::Nothing;
  3027.         ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
  3028.         RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
  3029.         UseColour::YesOrNo useColour = UseColour::Auto;
  3030.         WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
  3031.  
  3032.         std::string outputFilename;
  3033.         std::string name;
  3034.         std::string processName;
  3035.  
  3036.         std::vector<std::string> reporterNames;
  3037.         std::vector<std::string> testsOrTags;
  3038.         std::vector<std::string> sectionsToRun;
  3039.     };
  3040.  
  3041.     class Config : public IConfig {
  3042.     public:
  3043.  
  3044.         Config() = default;
  3045.         Config(ConfigData const& data);
  3046.         virtual ~Config() = default;
  3047.  
  3048.         std::string const& getFilename() const;
  3049.  
  3050.         bool listTests() const;
  3051.         bool listTestNamesOnly() const;
  3052.         bool listTags() const;
  3053.         bool listReporters() const;
  3054.  
  3055.         std::string getProcessName() const;
  3056.  
  3057.         std::vector<std::string> const& getReporterNames() const;
  3058.         std::vector<std::string> const& getSectionsToRun() const override;
  3059.  
  3060.         virtual TestSpec const& testSpec() const override;
  3061.  
  3062.         bool showHelp() const;
  3063.  
  3064.         // IConfig interface
  3065.         bool allowThrows() const override;
  3066.         std::ostream& stream() const override;
  3067.         std::string name() const override;
  3068.         bool includeSuccessfulResults() const override;
  3069.         bool warnAboutMissingAssertions() const override;
  3070.         ShowDurations::OrNot showDurations() const override;
  3071.         RunTests::InWhatOrder runOrder() const override;
  3072.         unsigned int rngSeed() const override;
  3073.         int benchmarkResolutionMultiple() const override;
  3074.         UseColour::YesOrNo useColour() const override;
  3075.         bool shouldDebugBreak() const override;
  3076.         int abortAfter() const override;
  3077.         bool showInvisibles() const override;
  3078.         Verbosity verbosity() const override;
  3079.  
  3080.     private:
  3081.  
  3082.         IStream const* openStream();
  3083.         ConfigData m_data;
  3084.  
  3085.         std::unique_ptr<IStream const> m_stream;
  3086.         TestSpec m_testSpec;
  3087.     };
  3088.  
  3089. } // end namespace Catch
  3090.  
  3091.   // end catch_config.hpp
  3092.   // start catch_assertionresult.h
  3093.  
  3094. #include <string>
  3095.  
  3096. namespace Catch {
  3097.  
  3098.     struct AssertionResultData {
  3099.         AssertionResultData() = delete;
  3100.  
  3101.         AssertionResultData(ResultWas::OfType _resultType, LazyExpression const& _lazyExpression);
  3102.  
  3103.         std::string message;
  3104.         mutable std::string reconstructedExpression;
  3105.         LazyExpression lazyExpression;
  3106.         ResultWas::OfType resultType;
  3107.  
  3108.         std::string reconstructExpression() const;
  3109.     };
  3110.  
  3111.     class AssertionResult {
  3112.     public:
  3113.         AssertionResult() = delete;
  3114.         AssertionResult(AssertionInfo const& info, AssertionResultData const& data);
  3115.  
  3116.         bool isOk() const;
  3117.         bool succeeded() const;
  3118.         ResultWas::OfType getResultType() const;
  3119.         bool hasExpression() const;
  3120.         bool hasMessage() const;
  3121.         std::string getExpression() const;
  3122.         std::string getExpressionInMacro() const;
  3123.         bool hasExpandedExpression() const;
  3124.         std::string getExpandedExpression() const;
  3125.         std::string getMessage() const;
  3126.         SourceLineInfo getSourceInfo() const;
  3127.         std::string getTestMacroName() const;
  3128.  
  3129.         //protected:
  3130.         AssertionInfo m_info;
  3131.         AssertionResultData m_resultData;
  3132.     };
  3133.  
  3134. } // end namespace Catch
  3135.  
  3136.   // end catch_assertionresult.h
  3137.   // start catch_option.hpp
  3138.  
  3139. namespace Catch {
  3140.  
  3141.     // An optional type
  3142.     template<typename T>
  3143.     class Option {
  3144.     public:
  3145.         Option() : nullableValue(nullptr) {}
  3146.         Option(T const& _value)
  3147.             : nullableValue(new(storage) T(_value)) {
  3148.         }
  3149.         Option(Option const& _other)
  3150.             : nullableValue(_other ? new(storage) T(*_other) : nullptr) {
  3151.         }
  3152.  
  3153.         ~Option() {
  3154.             reset();
  3155.         }
  3156.  
  3157.         Option& operator= (Option const& _other) {
  3158.             if (&_other != this) {
  3159.                 reset();
  3160.                 if (_other)
  3161.                     nullableValue = new(storage) T(*_other);
  3162.             }
  3163.             return *this;
  3164.         }
  3165.         Option& operator = (T const& _value) {
  3166.             reset();
  3167.             nullableValue = new(storage) T(_value);
  3168.             return *this;
  3169.         }
  3170.  
  3171.         void reset() {
  3172.             if (nullableValue)
  3173.                 nullableValue->~T();
  3174.             nullableValue = nullptr;
  3175.         }
  3176.  
  3177.         T& operator*() { return *nullableValue; }
  3178.         T const& operator*() const { return *nullableValue; }
  3179.         T* operator->() { return nullableValue; }
  3180.         const T* operator->() const { return nullableValue; }
  3181.  
  3182.         T valueOr(T const& defaultValue) const {
  3183.             return nullableValue ? *nullableValue : defaultValue;
  3184.         }
  3185.  
  3186.         bool some() const { return nullableValue != nullptr; }
  3187.         bool none() const { return nullableValue == nullptr; }
  3188.  
  3189.         bool operator !() const { return nullableValue == nullptr; }
  3190.         explicit operator bool() const {
  3191.             return some();
  3192.         }
  3193.  
  3194.     private:
  3195.         T *nullableValue;
  3196.         alignas(alignof(T)) char storage[sizeof(T)];
  3197.     };
  3198.  
  3199. } // end namespace Catch
  3200.  
  3201.   // end catch_option.hpp
  3202. #include <string>
  3203. #include <iosfwd>
  3204. #include <map>
  3205. #include <set>
  3206. #include <memory>
  3207.  
  3208. namespace Catch {
  3209.  
  3210.     struct ReporterConfig {
  3211.         explicit ReporterConfig(IConfigPtr const& _fullConfig);
  3212.  
  3213.         ReporterConfig(IConfigPtr const& _fullConfig, std::ostream& _stream);
  3214.  
  3215.         std::ostream& stream() const;
  3216.         IConfigPtr fullConfig() const;
  3217.  
  3218.     private:
  3219.         std::ostream* m_stream;
  3220.         IConfigPtr m_fullConfig;
  3221.     };
  3222.  
  3223.     struct ReporterPreferences {
  3224.         bool shouldRedirectStdOut = false;
  3225.     };
  3226.  
  3227.     template<typename T>
  3228.     struct LazyStat : Option<T> {
  3229.         LazyStat& operator=(T const& _value) {
  3230.             Option<T>::operator=(_value);
  3231.             used = false;
  3232.             return *this;
  3233.         }
  3234.         void reset() {
  3235.             Option<T>::reset();
  3236.             used = false;
  3237.         }
  3238.         bool used = false;
  3239.     };
  3240.  
  3241.     struct TestRunInfo {
  3242.         TestRunInfo(std::string const& _name);
  3243.         std::string name;
  3244.     };
  3245.     struct GroupInfo {
  3246.         GroupInfo(std::string const& _name,
  3247.                   std::size_t _groupIndex,
  3248.                   std::size_t _groupsCount);
  3249.  
  3250.         std::string name;
  3251.         std::size_t groupIndex;
  3252.         std::size_t groupsCounts;
  3253.     };
  3254.  
  3255.     struct AssertionStats {
  3256.         AssertionStats(AssertionResult const& _assertionResult,
  3257.                        std::vector<MessageInfo> const& _infoMessages,
  3258.                        Totals const& _totals);
  3259.  
  3260.         AssertionStats(AssertionStats const&) = default;
  3261.         AssertionStats(AssertionStats &&) = default;
  3262.         AssertionStats& operator = (AssertionStats const&) = default;
  3263.         AssertionStats& operator = (AssertionStats &&) = default;
  3264.         virtual ~AssertionStats();
  3265.  
  3266.         AssertionResult assertionResult;
  3267.         std::vector<MessageInfo> infoMessages;
  3268.         Totals totals;
  3269.     };
  3270.  
  3271.     struct SectionStats {
  3272.         SectionStats(SectionInfo const& _sectionInfo,
  3273.                      Counts const& _assertions,
  3274.                      double _durationInSeconds,
  3275.                      bool _missingAssertions);
  3276.         SectionStats(SectionStats const&) = default;
  3277.         SectionStats(SectionStats &&) = default;
  3278.         SectionStats& operator = (SectionStats const&) = default;
  3279.         SectionStats& operator = (SectionStats &&) = default;
  3280.         virtual ~SectionStats();
  3281.  
  3282.         SectionInfo sectionInfo;
  3283.         Counts assertions;
  3284.         double durationInSeconds;
  3285.         bool missingAssertions;
  3286.     };
  3287.  
  3288.     struct TestCaseStats {
  3289.         TestCaseStats(TestCaseInfo const& _testInfo,
  3290.                       Totals const& _totals,
  3291.                       std::string const& _stdOut,
  3292.                       std::string const& _stdErr,
  3293.                       bool _aborting);
  3294.  
  3295.         TestCaseStats(TestCaseStats const&) = default;
  3296.         TestCaseStats(TestCaseStats &&) = default;
  3297.         TestCaseStats& operator = (TestCaseStats const&) = default;
  3298.         TestCaseStats& operator = (TestCaseStats &&) = default;
  3299.         virtual ~TestCaseStats();
  3300.  
  3301.         TestCaseInfo testInfo;
  3302.         Totals totals;
  3303.         std::string stdOut;
  3304.         std::string stdErr;
  3305.         bool aborting;
  3306.     };
  3307.  
  3308.     struct TestGroupStats {
  3309.         TestGroupStats(GroupInfo const& _groupInfo,
  3310.                        Totals const& _totals,
  3311.                        bool _aborting);
  3312.         TestGroupStats(GroupInfo const& _groupInfo);
  3313.  
  3314.         TestGroupStats(TestGroupStats const&) = default;
  3315.         TestGroupStats(TestGroupStats &&) = default;
  3316.         TestGroupStats& operator = (TestGroupStats const&) = default;
  3317.         TestGroupStats& operator = (TestGroupStats &&) = default;
  3318.         virtual ~TestGroupStats();
  3319.  
  3320.         GroupInfo groupInfo;
  3321.         Totals totals;
  3322.         bool aborting;
  3323.     };
  3324.  
  3325.     struct TestRunStats {
  3326.         TestRunStats(TestRunInfo const& _runInfo,
  3327.                      Totals const& _totals,
  3328.                      bool _aborting);
  3329.  
  3330.         TestRunStats(TestRunStats const&) = default;
  3331.         TestRunStats(TestRunStats &&) = default;
  3332.         TestRunStats& operator = (TestRunStats const&) = default;
  3333.         TestRunStats& operator = (TestRunStats &&) = default;
  3334.         virtual ~TestRunStats();
  3335.  
  3336.         TestRunInfo runInfo;
  3337.         Totals totals;
  3338.         bool aborting;
  3339.     };
  3340.  
  3341.     struct BenchmarkInfo {
  3342.         std::string name;
  3343.     };
  3344.     struct BenchmarkStats {
  3345.         BenchmarkInfo info;
  3346.         std::size_t iterations;
  3347.         uint64_t elapsedTimeInNanoseconds;
  3348.     };
  3349.  
  3350.     struct IStreamingReporter {
  3351.         virtual ~IStreamingReporter() = default;
  3352.  
  3353.         // Implementing class must also provide the following static methods:
  3354.         // static std::string getDescription();
  3355.         // static std::set<Verbosity> getSupportedVerbosities()
  3356.  
  3357.         virtual ReporterPreferences getPreferences() const = 0;
  3358.  
  3359.         virtual void noMatchingTestCases(std::string const& spec) = 0;
  3360.  
  3361.         virtual void testRunStarting(TestRunInfo const& testRunInfo) = 0;
  3362.         virtual void testGroupStarting(GroupInfo const& groupInfo) = 0;
  3363.  
  3364.         virtual void testCaseStarting(TestCaseInfo const& testInfo) = 0;
  3365.         virtual void sectionStarting(SectionInfo const& sectionInfo) = 0;
  3366.  
  3367.         // *** experimental ***
  3368.         virtual void benchmarkStarting(BenchmarkInfo const&) {}
  3369.  
  3370.         virtual void assertionStarting(AssertionInfo const& assertionInfo) = 0;
  3371.  
  3372.         // The return value indicates if the messages buffer should be cleared:
  3373.         virtual bool assertionEnded(AssertionStats const& assertionStats) = 0;
  3374.  
  3375.         // *** experimental ***
  3376.         virtual void benchmarkEnded(BenchmarkStats const&) {}
  3377.  
  3378.         virtual void sectionEnded(SectionStats const& sectionStats) = 0;
  3379.         virtual void testCaseEnded(TestCaseStats const& testCaseStats) = 0;
  3380.         virtual void testGroupEnded(TestGroupStats const& testGroupStats) = 0;
  3381.         virtual void testRunEnded(TestRunStats const& testRunStats) = 0;
  3382.  
  3383.         virtual void skipTest(TestCaseInfo const& testInfo) = 0;
  3384.  
  3385.         // Default empty implementation provided
  3386.         virtual void fatalErrorEncountered(StringRef name);
  3387.  
  3388.         virtual bool isMulti() const;
  3389.     };
  3390.     using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
  3391.  
  3392.     struct IReporterFactory {
  3393.         virtual ~IReporterFactory();
  3394.         virtual IStreamingReporterPtr create(ReporterConfig const& config) const = 0;
  3395.         virtual std::string getDescription() const = 0;
  3396.     };
  3397.     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
  3398.  
  3399.     struct IReporterRegistry {
  3400.         using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
  3401.         using Listeners = std::vector<IReporterFactoryPtr>;
  3402.  
  3403.         virtual ~IReporterRegistry();
  3404.         virtual IStreamingReporterPtr create(std::string const& name, IConfigPtr const& config) const = 0;
  3405.         virtual FactoryMap const& getFactories() const = 0;
  3406.         virtual Listeners const& getListeners() const = 0;
  3407.     };
  3408.  
  3409.     void addReporter(IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter);
  3410.  
  3411. } // end namespace Catch
  3412.  
  3413.   // end catch_interfaces_reporter.h
  3414. #include <algorithm>
  3415. #include <cstring>
  3416. #include <cfloat>
  3417. #include <cstdio>
  3418. #include <assert.h>
  3419. #include <memory>
  3420.  
  3421. namespace Catch {
  3422.     void prepareExpandedExpression(AssertionResult& result);
  3423.  
  3424.     // Returns double formatted as %.3f (format expected on output)
  3425.     std::string getFormattedDuration(double duration);
  3426.  
  3427.     template<typename DerivedT>
  3428.     struct StreamingReporterBase : IStreamingReporter {
  3429.  
  3430.         StreamingReporterBase(ReporterConfig const& _config)
  3431.             : m_config(_config.fullConfig()),
  3432.             stream(_config.stream()) {
  3433.             m_reporterPrefs.shouldRedirectStdOut = false;
  3434.             CATCH_ENFORCE(DerivedT::getSupportedVerbosities().count(m_config->verbosity()), "Verbosity level not supported by this reporter");
  3435.         }
  3436.  
  3437.         ReporterPreferences getPreferences() const override {
  3438.             return m_reporterPrefs;
  3439.         }
  3440.  
  3441.         static std::set<Verbosity> getSupportedVerbosities() {
  3442.             return{ Verbosity::Normal };
  3443.         }
  3444.  
  3445.         ~StreamingReporterBase() override = default;
  3446.  
  3447.         void noMatchingTestCases(std::string const&) override {}
  3448.  
  3449.         void testRunStarting(TestRunInfo const& _testRunInfo) override {
  3450.             currentTestRunInfo = _testRunInfo;
  3451.         }
  3452.         void testGroupStarting(GroupInfo const& _groupInfo) override {
  3453.             currentGroupInfo = _groupInfo;
  3454.         }
  3455.  
  3456.         void testCaseStarting(TestCaseInfo const& _testInfo) override {
  3457.             currentTestCaseInfo = _testInfo;
  3458.         }
  3459.         void sectionStarting(SectionInfo const& _sectionInfo) override {
  3460.             m_sectionStack.push_back(_sectionInfo);
  3461.         }
  3462.  
  3463.         void sectionEnded(SectionStats const& /* _sectionStats */) override {
  3464.             m_sectionStack.pop_back();
  3465.         }
  3466.         void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
  3467.             currentTestCaseInfo.reset();
  3468.         }
  3469.         void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
  3470.             currentGroupInfo.reset();
  3471.         }
  3472.         void testRunEnded(TestRunStats const& /* _testRunStats */) override {
  3473.             currentTestCaseInfo.reset();
  3474.             currentGroupInfo.reset();
  3475.             currentTestRunInfo.reset();
  3476.         }
  3477.  
  3478.         void skipTest(TestCaseInfo const&) override {
  3479.             // Don't do anything with this by default.
  3480.             // It can optionally be overridden in the derived class.
  3481.         }
  3482.  
  3483.         IConfigPtr m_config;
  3484.         std::ostream& stream;
  3485.  
  3486.         LazyStat<TestRunInfo> currentTestRunInfo;
  3487.         LazyStat<GroupInfo> currentGroupInfo;
  3488.         LazyStat<TestCaseInfo> currentTestCaseInfo;
  3489.  
  3490.         std::vector<SectionInfo> m_sectionStack;
  3491.         ReporterPreferences m_reporterPrefs;
  3492.     };
  3493.  
  3494.     template<typename DerivedT>
  3495.     struct CumulativeReporterBase : IStreamingReporter {
  3496.         template<typename T, typename ChildNodeT>
  3497.         struct Node {
  3498.             explicit Node(T const& _value) : value(_value) {}
  3499.             virtual ~Node() {}
  3500.  
  3501.             using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
  3502.             T value;
  3503.             ChildNodes children;
  3504.         };
  3505.         struct SectionNode {
  3506.             explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
  3507.             virtual ~SectionNode() = default;
  3508.  
  3509.             bool operator == (SectionNode const& other) const {
  3510.                 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
  3511.             }
  3512.             bool operator == (std::shared_ptr<SectionNode> const& other) const {
  3513.                 return operator==(*other);
  3514.             }
  3515.  
  3516.             SectionStats stats;
  3517.             using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
  3518.             using Assertions = std::vector<AssertionStats>;
  3519.             ChildSections childSections;
  3520.             Assertions assertions;
  3521.             std::string stdOut;
  3522.             std::string stdErr;
  3523.         };
  3524.  
  3525.         struct BySectionInfo {
  3526.             BySectionInfo(SectionInfo const& other) : m_other(other) {}
  3527.             BySectionInfo(BySectionInfo const& other) : m_other(other.m_other) {}
  3528.             bool operator() (std::shared_ptr<SectionNode> const& node) const {
  3529.                 return ((node->stats.sectionInfo.name == m_other.name) &&
  3530.                     (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
  3531.             }
  3532.             void operator=(BySectionInfo const&) = delete;
  3533.  
  3534.         private:
  3535.             SectionInfo const& m_other;
  3536.         };
  3537.  
  3538.         using TestCaseNode = Node<TestCaseStats, SectionNode>;
  3539.         using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
  3540.         using TestRunNode = Node<TestRunStats, TestGroupNode>;
  3541.  
  3542.         CumulativeReporterBase(ReporterConfig const& _config)
  3543.             : m_config(_config.fullConfig()),
  3544.             stream(_config.stream()) {
  3545.             m_reporterPrefs.shouldRedirectStdOut = false;
  3546.             CATCH_ENFORCE(DerivedT::getSupportedVerbosities().count(m_config->verbosity()), "Verbosity level not supported by this reporter");
  3547.         }
  3548.         ~CumulativeReporterBase() override = default;
  3549.  
  3550.         ReporterPreferences getPreferences() const override {
  3551.             return m_reporterPrefs;
  3552.         }
  3553.  
  3554.         static std::set<Verbosity> getSupportedVerbosities() {
  3555.             return{ Verbosity::Normal };
  3556.         }
  3557.  
  3558.         void testRunStarting(TestRunInfo const&) override {}
  3559.         void testGroupStarting(GroupInfo const&) override {}
  3560.  
  3561.         void testCaseStarting(TestCaseInfo const&) override {}
  3562.  
  3563.         void sectionStarting(SectionInfo const& sectionInfo) override {
  3564.             SectionStats incompleteStats(sectionInfo, Counts(), 0, false);
  3565.             std::shared_ptr<SectionNode> node;
  3566.             if (m_sectionStack.empty()) {
  3567.                 if (!m_rootSection)
  3568.                     m_rootSection = std::make_shared<SectionNode>(incompleteStats);
  3569.                 node = m_rootSection;
  3570.             } else {
  3571.                 SectionNode& parentNode = *m_sectionStack.back();
  3572.                 auto it =
  3573.                     std::find_if(parentNode.childSections.begin(),
  3574.                                  parentNode.childSections.end(),
  3575.                                  BySectionInfo(sectionInfo));
  3576.                 if (it == parentNode.childSections.end()) {
  3577.                     node = std::make_shared<SectionNode>(incompleteStats);
  3578.                     parentNode.childSections.push_back(node);
  3579.                 } else
  3580.                     node = *it;
  3581.             }
  3582.             m_sectionStack.push_back(node);
  3583.             m_deepestSection = std::move(node);
  3584.         }
  3585.  
  3586.         void assertionStarting(AssertionInfo const&) override {}
  3587.  
  3588.         bool assertionEnded(AssertionStats const& assertionStats) override {
  3589.             assert(!m_sectionStack.empty());
  3590.             // AssertionResult holds a pointer to a temporary DecomposedExpression,
  3591.             // which getExpandedExpression() calls to build the expression string.
  3592.             // Our section stack copy of the assertionResult will likely outlive the
  3593.             // temporary, so it must be expanded or discarded now to avoid calling
  3594.             // a destroyed object later.
  3595.             prepareExpandedExpression(const_cast<AssertionResult&>(assertionStats.assertionResult));
  3596.             SectionNode& sectionNode = *m_sectionStack.back();
  3597.             sectionNode.assertions.push_back(assertionStats);
  3598.             return true;
  3599.         }
  3600.         void sectionEnded(SectionStats const& sectionStats) override {
  3601.             assert(!m_sectionStack.empty());
  3602.             SectionNode& node = *m_sectionStack.back();
  3603.             node.stats = sectionStats;
  3604.             m_sectionStack.pop_back();
  3605.         }
  3606.         void testCaseEnded(TestCaseStats const& testCaseStats) override {
  3607.             auto node = std::make_shared<TestCaseNode>(testCaseStats);
  3608.             assert(m_sectionStack.size() == 0);
  3609.             node->children.push_back(m_rootSection);
  3610.             m_testCases.push_back(node);
  3611.             m_rootSection.reset();
  3612.  
  3613.             assert(m_deepestSection);
  3614.             m_deepestSection->stdOut = testCaseStats.stdOut;
  3615.             m_deepestSection->stdErr = testCaseStats.stdErr;
  3616.         }
  3617.         void testGroupEnded(TestGroupStats const& testGroupStats) override {
  3618.             auto node = std::make_shared<TestGroupNode>(testGroupStats);
  3619.             node->children.swap(m_testCases);
  3620.             m_testGroups.push_back(node);
  3621.         }
  3622.         void testRunEnded(TestRunStats const& testRunStats) override {
  3623.             auto node = std::make_shared<TestRunNode>(testRunStats);
  3624.             node->children.swap(m_testGroups);
  3625.             m_testRuns.push_back(node);
  3626.             testRunEndedCumulative();
  3627.         }
  3628.         virtual void testRunEndedCumulative() = 0;
  3629.  
  3630.         void skipTest(TestCaseInfo const&) override {}
  3631.  
  3632.         IConfigPtr m_config;
  3633.         std::ostream& stream;
  3634.         std::vector<AssertionStats> m_assertions;
  3635.         std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
  3636.         std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
  3637.         std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
  3638.  
  3639.         std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
  3640.  
  3641.         std::shared_ptr<SectionNode> m_rootSection;
  3642.         std::shared_ptr<SectionNode> m_deepestSection;
  3643.         std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
  3644.         ReporterPreferences m_reporterPrefs;
  3645.     };
  3646.  
  3647.     template<char C>
  3648.     char const* getLineOfChars() {
  3649.         static char line[CATCH_CONFIG_CONSOLE_WIDTH] = { 0 };
  3650.         if (!*line) {
  3651.             std::memset(line, C, CATCH_CONFIG_CONSOLE_WIDTH - 1);
  3652.             line[CATCH_CONFIG_CONSOLE_WIDTH - 1] = 0;
  3653.         }
  3654.         return line;
  3655.     }
  3656.  
  3657.     struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
  3658.         TestEventListenerBase(ReporterConfig const& _config);
  3659.  
  3660.         void assertionStarting(AssertionInfo const&) override;
  3661.         bool assertionEnded(AssertionStats const&) override;
  3662.     };
  3663.  
  3664. } // end namespace Catch
  3665.  
  3666.   // end catch_reporter_bases.hpp
  3667.   // start catch_console_colour.h
  3668.  
  3669. namespace Catch {
  3670.  
  3671.     struct Colour {
  3672.         enum Code {
  3673.             None = 0,
  3674.  
  3675.             White,
  3676.             Red,
  3677.             Green,
  3678.             Blue,
  3679.             Cyan,
  3680.             Yellow,
  3681.             Grey,
  3682.  
  3683.             Bright = 0x10,
  3684.  
  3685.             BrightRed = Bright | Red,
  3686.             BrightGreen = Bright | Green,
  3687.             LightGrey = Bright | Grey,
  3688.             BrightWhite = Bright | White,
  3689.  
  3690.             // By intention
  3691.             FileName = LightGrey,
  3692.             Warning = Yellow,
  3693.             ResultError = BrightRed,
  3694.             ResultSuccess = BrightGreen,
  3695.             ResultExpectedFailure = Warning,
  3696.  
  3697.             Error = BrightRed,
  3698.             Success = Green,
  3699.  
  3700.             OriginalExpression = Cyan,
  3701.             ReconstructedExpression = Yellow,
  3702.  
  3703.             SecondaryText = LightGrey,
  3704.             Headers = White
  3705.         };
  3706.  
  3707.         // Use constructed object for RAII guard
  3708.         Colour(Code _colourCode);
  3709.         Colour(Colour&& other) noexcept;
  3710.         Colour& operator=(Colour&& other) noexcept;
  3711.         ~Colour();
  3712.  
  3713.         // Use static method for one-shot changes
  3714.         static void use(Code _colourCode);
  3715.  
  3716.     private:
  3717.         bool m_moved = false;
  3718.     };
  3719.  
  3720.     std::ostream& operator << (std::ostream& os, Colour const&);
  3721.  
  3722. } // end namespace Catch
  3723.  
  3724.   // end catch_console_colour.h
  3725.   // start catch_reporter_registrars.hpp
  3726.  
  3727.  
  3728. namespace Catch {
  3729.  
  3730.     template<typename T>
  3731.     class ReporterRegistrar {
  3732.  
  3733.         class ReporterFactory : public IReporterFactory {
  3734.  
  3735.             virtual IStreamingReporterPtr create(ReporterConfig const& config) const override {
  3736.                 return std::unique_ptr<T>(new T(config));
  3737.             }
  3738.  
  3739.             virtual std::string getDescription() const override {
  3740.                 return T::getDescription();
  3741.             }
  3742.         };
  3743.  
  3744.     public:
  3745.  
  3746.         ReporterRegistrar(std::string const& name) {
  3747.             getMutableRegistryHub().registerReporter(name, std::make_shared<ReporterFactory>());
  3748.         }
  3749.     };
  3750.  
  3751.     template<typename T>
  3752.     class ListenerRegistrar {
  3753.  
  3754.         class ListenerFactory : public IReporterFactory {
  3755.  
  3756.             virtual IStreamingReporterPtr create(ReporterConfig const& config) const override {
  3757.                 return std::unique_ptr<T>(new T(config));
  3758.             }
  3759.             virtual std::string getDescription() const override {
  3760.                 return std::string();
  3761.             }
  3762.         };
  3763.  
  3764.     public:
  3765.  
  3766.         ListenerRegistrar() {
  3767.             getMutableRegistryHub().registerListener(std::make_shared<ListenerFactory>());
  3768.         }
  3769.     };
  3770. }
  3771.  
  3772. #if !defined(CATCH_CONFIG_DISABLE)
  3773.  
  3774. #define CATCH_REGISTER_REPORTER( name, reporterType ) \
  3775.     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \
  3776.     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
  3777.     CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  3778.  
  3779. #define CATCH_REGISTER_LISTENER( listenerType ) \
  3780.      CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS   \
  3781.      namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
  3782.      CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
  3783. #else // CATCH_CONFIG_DISABLE
  3784.  
  3785. #define CATCH_REGISTER_REPORTER(name, reporterType)
  3786. #define CATCH_REGISTER_LISTENER(listenerType)
  3787.  
  3788. #endif // CATCH_CONFIG_DISABLE
  3789.  
  3790. // end catch_reporter_registrars.hpp
  3791. // end catch_external_interfaces.h
  3792. #endif
  3793.  
  3794. #ifdef CATCH_IMPL
  3795. // start catch_impl.hpp
  3796.  
  3797. #ifdef __clang__
  3798. #pragma clang diagnostic push
  3799. #pragma clang diagnostic ignored "-Wweak-vtables"
  3800. #endif
  3801.  
  3802. // Keep these here for external reporters
  3803. // start catch_test_case_tracker.h
  3804.  
  3805. #include <string>
  3806. #include <vector>
  3807. #include <memory>
  3808.  
  3809. namespace Catch {
  3810.     namespace TestCaseTracking {
  3811.  
  3812.         struct NameAndLocation {
  3813.             std::string name;
  3814.             SourceLineInfo location;
  3815.  
  3816.             NameAndLocation(std::string const& _name, SourceLineInfo const& _location);
  3817.         };
  3818.  
  3819.         struct ITracker;
  3820.  
  3821.         using ITrackerPtr = std::shared_ptr<ITracker>;
  3822.  
  3823.         struct ITracker {
  3824.             virtual ~ITracker();
  3825.  
  3826.             // static queries
  3827.             virtual NameAndLocation const& nameAndLocation() const = 0;
  3828.  
  3829.             // dynamic queries
  3830.             virtual bool isComplete() const = 0; // Successfully completed or failed
  3831.             virtual bool isSuccessfullyCompleted() const = 0;
  3832.             virtual bool isOpen() const = 0; // Started but not complete
  3833.             virtual bool hasChildren() const = 0;
  3834.  
  3835.             virtual ITracker& parent() = 0;
  3836.  
  3837.             // actions
  3838.             virtual void close() = 0; // Successfully complete
  3839.             virtual void fail() = 0;
  3840.             virtual void markAsNeedingAnotherRun() = 0;
  3841.  
  3842.             virtual void addChild(ITrackerPtr const& child) = 0;
  3843.             virtual ITrackerPtr findChild(NameAndLocation const& nameAndLocation) = 0;
  3844.             virtual void openChild() = 0;
  3845.  
  3846.             // Debug/ checking
  3847.             virtual bool isSectionTracker() const = 0;
  3848.             virtual bool isIndexTracker() const = 0;
  3849.         };
  3850.  
  3851.         class TrackerContext {
  3852.  
  3853.             enum RunState {
  3854.                 NotStarted,
  3855.                 Executing,
  3856.                 CompletedCycle
  3857.             };
  3858.  
  3859.             ITrackerPtr m_rootTracker;
  3860.             ITracker* m_currentTracker = nullptr;
  3861.             RunState m_runState = NotStarted;
  3862.  
  3863.         public:
  3864.  
  3865.             static TrackerContext& instance();
  3866.  
  3867.             ITracker& startRun();
  3868.             void endRun();
  3869.  
  3870.             void startCycle();
  3871.             void completeCycle();
  3872.  
  3873.             bool completedCycle() const;
  3874.             ITracker& currentTracker();
  3875.             void setCurrentTracker(ITracker* tracker);
  3876.         };
  3877.  
  3878.         class TrackerBase : public ITracker {
  3879.         protected:
  3880.             enum CycleState {
  3881.                 NotStarted,
  3882.                 Executing,
  3883.                 ExecutingChildren,
  3884.                 NeedsAnotherRun,
  3885.                 CompletedSuccessfully,
  3886.                 Failed
  3887.             };
  3888.  
  3889.             class TrackerHasName {
  3890.                 NameAndLocation m_nameAndLocation;
  3891.             public:
  3892.                 TrackerHasName(NameAndLocation const& nameAndLocation);
  3893.                 bool operator ()(ITrackerPtr const& tracker) const;
  3894.             };
  3895.  
  3896.             using Children = std::vector<ITrackerPtr>;
  3897.             NameAndLocation m_nameAndLocation;
  3898.             TrackerContext& m_ctx;
  3899.             ITracker* m_parent;
  3900.             Children m_children;
  3901.             CycleState m_runState = NotStarted;
  3902.  
  3903.         public:
  3904.             TrackerBase(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent);
  3905.  
  3906.             NameAndLocation const& nameAndLocation() const override;
  3907.             bool isComplete() const override;
  3908.             bool isSuccessfullyCompleted() const override;
  3909.             bool isOpen() const override;
  3910.             bool hasChildren() const override;
  3911.  
  3912.             void addChild(ITrackerPtr const& child) override;
  3913.  
  3914.             ITrackerPtr findChild(NameAndLocation const& nameAndLocation) override;
  3915.             ITracker& parent() override;
  3916.  
  3917.             void openChild() override;
  3918.  
  3919.             bool isSectionTracker() const override;
  3920.             bool isIndexTracker() const override;
  3921.  
  3922.             void open();
  3923.  
  3924.             void close() override;
  3925.             void fail() override;
  3926.             void markAsNeedingAnotherRun() override;
  3927.  
  3928.         private:
  3929.             void moveToParent();
  3930.             void moveToThis();
  3931.         };
  3932.  
  3933.         class SectionTracker : public TrackerBase {
  3934.             std::vector<std::string> m_filters;
  3935.         public:
  3936.             SectionTracker(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent);
  3937.  
  3938.             bool isSectionTracker() const override;
  3939.  
  3940.             static SectionTracker& acquire(TrackerContext& ctx, NameAndLocation const& nameAndLocation);
  3941.  
  3942.             void tryOpen();
  3943.  
  3944.             void addInitialFilters(std::vector<std::string> const& filters);
  3945.             void addNextFilters(std::vector<std::string> const& filters);
  3946.         };
  3947.  
  3948.         class IndexTracker : public TrackerBase {
  3949.             int m_size;
  3950.             int m_index = -1;
  3951.         public:
  3952.             IndexTracker(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size);
  3953.  
  3954.             bool isIndexTracker() const override;
  3955.             void close() override;
  3956.  
  3957.             static IndexTracker& acquire(TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size);
  3958.  
  3959.             int index() const;
  3960.  
  3961.             void moveNext();
  3962.         };
  3963.  
  3964.     } // namespace TestCaseTracking
  3965.  
  3966.     using TestCaseTracking::ITracker;
  3967.     using TestCaseTracking::TrackerContext;
  3968.     using TestCaseTracking::SectionTracker;
  3969.     using TestCaseTracking::IndexTracker;
  3970.  
  3971. } // namespace Catch
  3972.  
  3973.   // end catch_test_case_tracker.h
  3974.  
  3975.   // start catch_leak_detector.h
  3976.  
  3977. namespace Catch {
  3978.  
  3979.     struct LeakDetector {
  3980.         LeakDetector();
  3981.     };
  3982.  
  3983. }
  3984. // end catch_leak_detector.h
  3985. // Cpp files will be included in the single-header file here
  3986. // start catch_approx.cpp
  3987.  
  3988. #include <cmath>
  3989. #include <limits>
  3990.  
  3991. namespace {
  3992.  
  3993.     // Performs equivalent check of std::fabs(lhs - rhs) <= margin
  3994.     // But without the subtraction to allow for INFINITY in comparison
  3995.     bool marginComparison(double lhs, double rhs, double margin) {
  3996.         return (lhs + margin >= rhs) && (rhs + margin >= lhs);
  3997.     }
  3998.  
  3999. }
  4000.  
  4001. namespace Catch {
  4002.     namespace Detail {
  4003.  
  4004.         Approx::Approx(double value)
  4005.             : m_epsilon(std::numeric_limits<float>::epsilon() * 100),
  4006.             m_margin(0.0),
  4007.             m_scale(0.0),
  4008.             m_value(value) {
  4009.         }
  4010.  
  4011.         Approx Approx::custom() {
  4012.             return Approx(0);
  4013.         }
  4014.  
  4015.         std::string Approx::toString() const {
  4016.             std::ostringstream oss;
  4017.             oss << "Approx( " << ::Catch::Detail::stringify(m_value) << " )";
  4018.             return oss.str();
  4019.         }
  4020.  
  4021.         bool Approx::equalityComparisonImpl(const double other) const {
  4022.             // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
  4023.             // Thanks to Richard Harris for his help refining the scaled margin value
  4024.             return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
  4025.         }
  4026.  
  4027.     } // end namespace Detail
  4028.  
  4029.     std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
  4030.         return value.toString();
  4031.     }
  4032.  
  4033. } // end namespace Catch
  4034.   // end catch_approx.cpp
  4035.   // start catch_assertionhandler.cpp
  4036.  
  4037.   // start catch_context.h
  4038.  
  4039. #include <memory>
  4040.  
  4041. namespace Catch {
  4042.  
  4043.     struct IResultCapture;
  4044.     struct IRunner;
  4045.     struct IConfig;
  4046.  
  4047.     using IConfigPtr = std::shared_ptr<IConfig const>;
  4048.  
  4049.     struct IContext {
  4050.         virtual ~IContext();
  4051.  
  4052.         virtual IResultCapture* getResultCapture() = 0;
  4053.         virtual IRunner* getRunner() = 0;
  4054.         virtual IConfigPtr getConfig() const = 0;
  4055.     };
  4056.  
  4057.     struct IMutableContext : IContext {
  4058.         virtual ~IMutableContext();
  4059.         virtual void setResultCapture(IResultCapture* resultCapture) = 0;
  4060.         virtual void setRunner(IRunner* runner) = 0;
  4061.         virtual void setConfig(IConfigPtr const& config) = 0;
  4062.     };
  4063.  
  4064.     IContext& getCurrentContext();
  4065.     IMutableContext& getCurrentMutableContext();
  4066.     void cleanUpContext();
  4067. }
  4068.  
  4069. // end catch_context.h
  4070. #include <cassert>
  4071.  
  4072. namespace Catch {
  4073.  
  4074.     auto operator <<(std::ostream& os, ITransientExpression const& expr) -> std::ostream& {
  4075.         expr.streamReconstructedExpression(os);
  4076.         return os;
  4077.     }
  4078.  
  4079.     LazyExpression::LazyExpression(bool isNegated)
  4080.         : m_isNegated(isNegated) {
  4081.     }
  4082.  
  4083.     LazyExpression::LazyExpression(LazyExpression const& other) : m_isNegated(other.m_isNegated) {}
  4084.  
  4085.     LazyExpression::operator bool() const {
  4086.         return m_transientExpression != nullptr;
  4087.     }
  4088.  
  4089.     auto operator << (std::ostream& os, LazyExpression const& lazyExpr) -> std::ostream& {
  4090.         if (lazyExpr.m_isNegated)
  4091.             os << "!";
  4092.  
  4093.         if (lazyExpr) {
  4094.             if (lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression())
  4095.                 os << "(" << *lazyExpr.m_transientExpression << ")";
  4096.             else
  4097.                 os << *lazyExpr.m_transientExpression;
  4098.         } else {
  4099.             os << "{** error - unchecked empty expression requested **}";
  4100.         }
  4101.         return os;
  4102.     }
  4103.  
  4104.     AssertionHandler::AssertionHandler
  4105.     (StringRef macroName,
  4106.      SourceLineInfo const& lineInfo,
  4107.      StringRef capturedExpression,
  4108.      ResultDisposition::Flags resultDisposition)
  4109.         : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition } {
  4110.         getCurrentContext().getResultCapture()->assertionStarting(m_assertionInfo);
  4111.     }
  4112.     AssertionHandler::~AssertionHandler() {
  4113.         if (m_inExceptionGuard) {
  4114.             handle(ResultWas::ThrewException, "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE");
  4115.             getCurrentContext().getResultCapture()->exceptionEarlyReported();
  4116.         }
  4117.     }
  4118.  
  4119.     void AssertionHandler::handle(ITransientExpression const& expr) {
  4120.  
  4121.         bool negated = isFalseTest(m_assertionInfo.resultDisposition);
  4122.         bool result = expr.getResult() != negated;
  4123.  
  4124.         handle(result ? ResultWas::Ok : ResultWas::ExpressionFailed, &expr, negated);
  4125.     }
  4126.     void AssertionHandler::handle(ResultWas::OfType resultType) {
  4127.         handle(resultType, nullptr, false);
  4128.     }
  4129.     void AssertionHandler::handle(ResultWas::OfType resultType, StringRef const& message) {
  4130.         AssertionResultData data(resultType, LazyExpression(false));
  4131.         data.message = message;
  4132.         handle(data, nullptr);
  4133.     }
  4134.     void AssertionHandler::handle(ResultWas::OfType resultType, ITransientExpression const* expr, bool negated) {
  4135.         AssertionResultData data(resultType, LazyExpression(negated));
  4136.         handle(data, expr);
  4137.     }
  4138.     void AssertionHandler::handle(AssertionResultData const& resultData, ITransientExpression const* expr) {
  4139.  
  4140.         getResultCapture().assertionRun();
  4141.  
  4142.         AssertionResult assertionResult{ m_assertionInfo, resultData };
  4143.         assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
  4144.  
  4145.         getResultCapture().assertionEnded(assertionResult);
  4146.  
  4147.         if (!assertionResult.isOk()) {
  4148.             m_shouldDebugBreak = getCurrentContext().getConfig()->shouldDebugBreak();
  4149.             m_shouldThrow =
  4150.                 getCurrentContext().getRunner()->aborting() ||
  4151.                 (m_assertionInfo.resultDisposition & ResultDisposition::Normal);
  4152.         }
  4153.     }
  4154.  
  4155.     auto AssertionHandler::allowThrows() const -> bool {
  4156.         return getCurrentContext().getConfig()->allowThrows();
  4157.     }
  4158.  
  4159.     auto AssertionHandler::shouldDebugBreak() const -> bool {
  4160.         return m_shouldDebugBreak;
  4161.     }
  4162.     void AssertionHandler::reactWithDebugBreak() const {
  4163.         if (m_shouldDebugBreak) {
  4164.             ///////////////////////////////////////////////////////////////////
  4165.             // To inspect the state during test, you need to go one level up the callstack
  4166.             // To go back to the test and change execution, jump over the reactWithoutDebugBreak() call
  4167.             ///////////////////////////////////////////////////////////////////
  4168.             CATCH_BREAK_INTO_DEBUGGER();
  4169.         }
  4170.         reactWithoutDebugBreak();
  4171.     }
  4172.     void AssertionHandler::reactWithoutDebugBreak() const {
  4173.         if (m_shouldThrow)
  4174.             throw Catch::TestFailureException();
  4175.     }
  4176.  
  4177.     void AssertionHandler::useActiveException() {
  4178.         handle(ResultWas::ThrewException, Catch::translateActiveException());
  4179.     }
  4180.  
  4181.     void AssertionHandler::setExceptionGuard() {
  4182.         assert(m_inExceptionGuard == false);
  4183.         m_inExceptionGuard = true;
  4184.     }
  4185.     void AssertionHandler::unsetExceptionGuard() {
  4186.         assert(m_inExceptionGuard == true);
  4187.         m_inExceptionGuard = false;
  4188.     }
  4189.  
  4190.     // This is the overload that takes a string and infers the Equals matcher from it
  4191.     // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
  4192.     void handleExceptionMatchExpr(AssertionHandler& handler, std::string const& str, StringRef matcherString) {
  4193.         handleExceptionMatchExpr(handler, Matchers::Equals(str), matcherString);
  4194.     }
  4195.  
  4196. } // namespace Catch
  4197.   // end catch_assertionhandler.cpp
  4198.   // start catch_assertionresult.cpp
  4199.  
  4200. namespace Catch {
  4201.     AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression) :
  4202.         lazyExpression(_lazyExpression),
  4203.         resultType(_resultType) {
  4204.     }
  4205.  
  4206.     std::string AssertionResultData::reconstructExpression() const {
  4207.  
  4208.         if (reconstructedExpression.empty()) {
  4209.             if (lazyExpression) {
  4210.                 // !TBD Use stringstream for now, but rework above to pass stream in
  4211.                 std::ostringstream oss;
  4212.                 oss << lazyExpression;
  4213.                 reconstructedExpression = oss.str();
  4214.             }
  4215.         }
  4216.         return reconstructedExpression;
  4217.     }
  4218.  
  4219.     AssertionResult::AssertionResult(AssertionInfo const& info, AssertionResultData const& data)
  4220.         : m_info(info),
  4221.         m_resultData(data) {
  4222.     }
  4223.  
  4224.     // Result was a success
  4225.     bool AssertionResult::succeeded() const {
  4226.         return Catch::isOk(m_resultData.resultType);
  4227.     }
  4228.  
  4229.     // Result was a success, or failure is suppressed
  4230.     bool AssertionResult::isOk() const {
  4231.         return Catch::isOk(m_resultData.resultType) || shouldSuppressFailure(m_info.resultDisposition);
  4232.     }
  4233.  
  4234.     ResultWas::OfType AssertionResult::getResultType() const {
  4235.         return m_resultData.resultType;
  4236.     }
  4237.  
  4238.     bool AssertionResult::hasExpression() const {
  4239.         return m_info.capturedExpression[0] != 0;
  4240.     }
  4241.  
  4242.     bool AssertionResult::hasMessage() const {
  4243.         return !m_resultData.message.empty();
  4244.     }
  4245.  
  4246.     std::string AssertionResult::getExpression() const {
  4247.         if (isFalseTest(m_info.resultDisposition))
  4248.             return "!(" + std::string(m_info.capturedExpression) + ")";
  4249.         else
  4250.             return m_info.capturedExpression;
  4251.     }
  4252.  
  4253.     std::string AssertionResult::getExpressionInMacro() const {
  4254.         std::string expr;
  4255.         if (m_info.macroName[0] == 0)
  4256.             expr = m_info.capturedExpression;
  4257.         else {
  4258.             expr.reserve(m_info.macroName.size() + m_info.capturedExpression.size() + 4);
  4259.             expr += m_info.macroName;
  4260.             expr += "( ";
  4261.             expr += m_info.capturedExpression;
  4262.             expr += " )";
  4263.         }
  4264.         return expr;
  4265.     }
  4266.  
  4267.     bool AssertionResult::hasExpandedExpression() const {
  4268.         return hasExpression() && getExpandedExpression() != getExpression();
  4269.     }
  4270.  
  4271.     std::string AssertionResult::getExpandedExpression() const {
  4272.         std::string expr = m_resultData.reconstructExpression();
  4273.         return expr.empty()
  4274.             ? getExpression()
  4275.             : expr;
  4276.     }
  4277.  
  4278.     std::string AssertionResult::getMessage() const {
  4279.         return m_resultData.message;
  4280.     }
  4281.     SourceLineInfo AssertionResult::getSourceInfo() const {
  4282.         return m_info.lineInfo;
  4283.     }
  4284.  
  4285.     std::string AssertionResult::getTestMacroName() const {
  4286.         return m_info.macroName;
  4287.     }
  4288.  
  4289. } // end namespace Catch
  4290.   // end catch_assertionresult.cpp
  4291.   // start catch_benchmark.cpp
  4292.  
  4293. namespace Catch {
  4294.  
  4295.     auto BenchmarkLooper::getResolution() -> uint64_t {
  4296.         return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple();
  4297.     }
  4298.  
  4299.     void BenchmarkLooper::reportStart() {
  4300.         getResultCapture().benchmarkStarting({ m_name });
  4301.     }
  4302.     auto BenchmarkLooper::needsMoreIterations() -> bool {
  4303.         auto elapsed = m_timer.getElapsedNanoseconds();
  4304.  
  4305.         // Exponentially increasing iterations until we're confident in our timer resolution
  4306.         if (elapsed < m_resolution) {
  4307.             m_iterationsToRun *= 10;
  4308.             return true;
  4309.         }
  4310.  
  4311.         getResultCapture().benchmarkEnded({ { m_name }, m_count, elapsed });
  4312.         return false;
  4313.     }
  4314.  
  4315. } // end namespace Catch
  4316.   // end catch_benchmark.cpp
  4317.   // start catch_capture_matchers.cpp
  4318.  
  4319. namespace Catch {
  4320.  
  4321.     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
  4322.  
  4323.     // This is the general overload that takes a any string matcher
  4324.     // There is another overload, in catch_assertinhandler.h/.cpp, that only takes a string and infers
  4325.     // the Equals matcher (so the header does not mention matchers)
  4326.     void handleExceptionMatchExpr(AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString) {
  4327.         std::string exceptionMessage = Catch::translateActiveException();
  4328.         MatchExpr<std::string, StringMatcher const&> expr(exceptionMessage, matcher, matcherString);
  4329.         handler.handle(expr);
  4330.     }
  4331.  
  4332. } // namespace Catch
  4333.   // end catch_capture_matchers.cpp
  4334.   // start catch_commandline.cpp
  4335.  
  4336.   // start catch_commandline.h
  4337.  
  4338.   // start catch_clara.h
  4339.  
  4340.   // Use Catch's value for console width (store Clara's off to the side, if present)
  4341. #ifdef CLARA_CONFIG_CONSOLE_WIDTH
  4342. #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  4343. #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  4344. #endif
  4345. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
  4346.  
  4347. #ifdef __clang__
  4348. #pragma clang diagnostic push
  4349. #pragma clang diagnostic ignored "-Wweak-vtables"
  4350. #pragma clang diagnostic ignored "-Wexit-time-destructors"
  4351. #pragma clang diagnostic ignored "-Wshadow"
  4352. #endif
  4353.  
  4354.   // start clara.hpp
  4355.   // v1.0-develop.2
  4356.   // See https://github.com/philsquared/Clara
  4357.  
  4358.  
  4359. #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
  4360. #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
  4361. #endif
  4362.  
  4363. #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  4364. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
  4365. #endif
  4366.  
  4367.   // ----------- #included from clara_textflow.hpp -----------
  4368.  
  4369.   // TextFlowCpp
  4370.   //
  4371.   // A single-header library for wrapping and laying out basic text, by Phil Nash
  4372.   //
  4373.   // This work is licensed under the BSD 2-Clause license.
  4374.   // See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause
  4375.   //
  4376.   // This project is hosted at https://github.com/philsquared/textflowcpp
  4377.  
  4378.  
  4379. #include <cassert>
  4380. #include <ostream>
  4381. #include <sstream>
  4382. #include <vector>
  4383.  
  4384. #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  4385. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
  4386. #endif
  4387.  
  4388. namespace Catch {
  4389.     namespace clara {
  4390.         namespace TextFlow {
  4391.  
  4392.             inline auto isWhitespace(char c) -> bool {
  4393.                 static std::string chars = " \t\n\r";
  4394.                 return chars.find(c) != std::string::npos;
  4395.             }
  4396.             inline auto isBreakableBefore(char c) -> bool {
  4397.                 static std::string chars = "[({<|";
  4398.                 return chars.find(c) != std::string::npos;
  4399.             }
  4400.             inline auto isBreakableAfter(char c) -> bool {
  4401.                 static std::string chars = "])}>.,:;*+-=&/\\";
  4402.                 return chars.find(c) != std::string::npos;
  4403.             }
  4404.  
  4405.             class Columns;
  4406.  
  4407.             class Column {
  4408.                 std::vector<std::string> m_strings;
  4409.                 size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
  4410.                 size_t m_indent = 0;
  4411.                 size_t m_initialIndent = std::string::npos;
  4412.  
  4413.             public:
  4414.                 class iterator {
  4415.                     friend Column;
  4416.  
  4417.                     Column const& m_column;
  4418.                     size_t m_stringIndex = 0;
  4419.                     size_t m_pos = 0;
  4420.  
  4421.                     size_t m_len = 0;
  4422.                     size_t m_end = 0;
  4423.                     bool m_suffix = false;
  4424.  
  4425.                     iterator(Column const& column, size_t stringIndex)
  4426.                         : m_column(column),
  4427.                         m_stringIndex(stringIndex) {
  4428.                     }
  4429.  
  4430.                     auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
  4431.  
  4432.                     auto isBoundary(size_t at) const -> bool {
  4433.                         assert(at > 0);
  4434.                         assert(at <= line().size());
  4435.  
  4436.                         return at == line().size() ||
  4437.                             (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
  4438.                             isBreakableBefore(line()[at]) ||
  4439.                             isBreakableAfter(line()[at - 1]);
  4440.                     }
  4441.  
  4442.                     void calcLength() {
  4443.                         assert(m_stringIndex < m_column.m_strings.size());
  4444.  
  4445.                         m_suffix = false;
  4446.                         auto width = m_column.m_width - indent();
  4447.                         m_end = m_pos;
  4448.                         while (m_end < line().size() && line()[m_end] != '\n')
  4449.                             ++m_end;
  4450.  
  4451.                         if (m_end < m_pos + width) {
  4452.                             m_len = m_end - m_pos;
  4453.                         } else {
  4454.                             size_t len = width;
  4455.                             while (len > 0 && !isBoundary(m_pos + len))
  4456.                                 --len;
  4457.                             while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
  4458.                                 --len;
  4459.  
  4460.                             if (len > 0) {
  4461.                                 m_len = len;
  4462.                             } else {
  4463.                                 m_suffix = true;
  4464.                                 m_len = width - 1;
  4465.                             }
  4466.                         }
  4467.                     }
  4468.  
  4469.                     auto indent() const -> size_t {
  4470.                         auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
  4471.                         return initial == std::string::npos ? m_column.m_indent : initial;
  4472.                     }
  4473.  
  4474.                     auto addIndentAndSuffix(std::string const &plain) const -> std::string {
  4475.                         return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
  4476.                     }
  4477.  
  4478.                 public:
  4479.                     explicit iterator(Column const& column) : m_column(column) {
  4480.                         assert(m_column.m_width > m_column.m_indent);
  4481.                         assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
  4482.                         calcLength();
  4483.                         if (m_len == 0)
  4484.                             m_stringIndex++; // Empty string
  4485.                     }
  4486.  
  4487.                     auto operator *() const -> std::string {
  4488.                         assert(m_stringIndex < m_column.m_strings.size());
  4489.                         assert(m_pos <= m_end);
  4490.                         if (m_pos + m_column.m_width < m_end)
  4491.                             return addIndentAndSuffix(line().substr(m_pos, m_len));
  4492.                         else
  4493.                             return addIndentAndSuffix(line().substr(m_pos, m_end - m_pos));
  4494.                     }
  4495.  
  4496.                     auto operator ++() -> iterator& {
  4497.                         m_pos += m_len;
  4498.                         if (m_pos < line().size() && line()[m_pos] == '\n')
  4499.                             m_pos += 1;
  4500.                         else
  4501.                             while (m_pos < line().size() && isWhitespace(line()[m_pos]))
  4502.                                 ++m_pos;
  4503.  
  4504.                         if (m_pos == line().size()) {
  4505.                             m_pos = 0;
  4506.                             ++m_stringIndex;
  4507.                         }
  4508.                         if (m_stringIndex < m_column.m_strings.size())
  4509.                             calcLength();
  4510.                         return *this;
  4511.                     }
  4512.                     auto operator ++(int) -> iterator {
  4513.                         iterator prev(*this);
  4514.                         operator++();
  4515.                         return prev;
  4516.                     }
  4517.  
  4518.                     auto operator ==(iterator const& other) const -> bool {
  4519.                         return
  4520.                             m_pos == other.m_pos &&
  4521.                             m_stringIndex == other.m_stringIndex &&
  4522.                             &m_column == &other.m_column;
  4523.                     }
  4524.                     auto operator !=(iterator const& other) const -> bool {
  4525.                         return !operator==(other);
  4526.                     }
  4527.                 };
  4528.                 using const_iterator = iterator;
  4529.  
  4530.                 explicit Column(std::string const& text) { m_strings.push_back(text); }
  4531.  
  4532.                 auto width(size_t newWidth) -> Column& {
  4533.                     assert(newWidth > 0);
  4534.                     m_width = newWidth;
  4535.                     return *this;
  4536.                 }
  4537.                 auto indent(size_t newIndent) -> Column& {
  4538.                     m_indent = newIndent;
  4539.                     return *this;
  4540.                 }
  4541.                 auto initialIndent(size_t newIndent) -> Column& {
  4542.                     m_initialIndent = newIndent;
  4543.                     return *this;
  4544.                 }
  4545.  
  4546.                 auto width() const -> size_t { return m_width; }
  4547.                 auto begin() const -> iterator { return iterator(*this); }
  4548.                 auto end() const -> iterator { return{ *this, m_strings.size() }; }
  4549.  
  4550.                 inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
  4551.                     bool first = true;
  4552.                     for (auto line : col) {
  4553.                         if (first)
  4554.                             first = false;
  4555.                         else
  4556.                             os << "\n";
  4557.                         os << line;
  4558.                     }
  4559.                     return os;
  4560.                 }
  4561.  
  4562.                 auto operator + (Column const& other)->Columns;
  4563.  
  4564.                 auto toString() const -> std::string {
  4565.                     std::ostringstream oss;
  4566.                     oss << *this;
  4567.                     return oss.str();
  4568.                 }
  4569.             };
  4570.  
  4571.             class Spacer : public Column {
  4572.  
  4573.             public:
  4574.                 explicit Spacer(size_t spaceWidth) : Column("") {
  4575.                     width(spaceWidth);
  4576.                 }
  4577.             };
  4578.  
  4579.             class Columns {
  4580.                 std::vector<Column> m_columns;
  4581.  
  4582.             public:
  4583.  
  4584.                 class iterator {
  4585.                     friend Columns;
  4586.                     struct EndTag {};
  4587.  
  4588.                     std::vector<Column> const& m_columns;
  4589.                     std::vector<Column::iterator> m_iterators;
  4590.                     size_t m_activeIterators;
  4591.  
  4592.                     iterator(Columns const& columns, EndTag)
  4593.                         : m_columns(columns.m_columns),
  4594.                         m_activeIterators(0) {
  4595.                         m_iterators.reserve(m_columns.size());
  4596.  
  4597.                         for (auto const& col : m_columns)
  4598.                             m_iterators.push_back(col.end());
  4599.                     }
  4600.  
  4601.                 public:
  4602.                     explicit iterator(Columns const& columns)
  4603.                         : m_columns(columns.m_columns),
  4604.                         m_activeIterators(m_columns.size()) {
  4605.                         m_iterators.reserve(m_columns.size());
  4606.  
  4607.                         for (auto const& col : m_columns)
  4608.                             m_iterators.push_back(col.begin());
  4609.                     }
  4610.  
  4611.                     auto operator ==(iterator const& other) const -> bool {
  4612.                         return m_iterators == other.m_iterators;
  4613.                     }
  4614.                     auto operator !=(iterator const& other) const -> bool {
  4615.                         return m_iterators != other.m_iterators;
  4616.                     }
  4617.                     auto operator *() const -> std::string {
  4618.                         std::string row, padding;
  4619.  
  4620.                         for (size_t i = 0; i < m_columns.size(); ++i) {
  4621.                             auto width = m_columns[i].width();
  4622.                             if (m_iterators[i] != m_columns[i].end()) {
  4623.                                 std::string col = *m_iterators[i];
  4624.                                 row += padding + col;
  4625.                                 if (col.size() < width)
  4626.                                     padding = std::string(width - col.size(), ' ');
  4627.                                 else
  4628.                                     padding = "";
  4629.                             } else {
  4630.                                 padding += std::string(width, ' ');
  4631.                             }
  4632.                         }
  4633.                         return row;
  4634.                     }
  4635.                     auto operator ++() -> iterator& {
  4636.                         for (size_t i = 0; i < m_columns.size(); ++i) {
  4637.                             if (m_iterators[i] != m_columns[i].end())
  4638.                                 ++m_iterators[i];
  4639.                         }
  4640.                         return *this;
  4641.                     }
  4642.                     auto operator ++(int) -> iterator {
  4643.                         iterator prev(*this);
  4644.                         operator++();
  4645.                         return prev;
  4646.                     }
  4647.                 };
  4648.                 using const_iterator = iterator;
  4649.  
  4650.                 auto begin() const -> iterator { return iterator(*this); }
  4651.                 auto end() const -> iterator { return{ *this, iterator::EndTag() }; }
  4652.  
  4653.                 auto operator += (Column const& col) -> Columns& {
  4654.                     m_columns.push_back(col);
  4655.                     return *this;
  4656.                 }
  4657.                 auto operator + (Column const& col) -> Columns {
  4658.                     Columns combined = *this;
  4659.                     combined += col;
  4660.                     return combined;
  4661.                 }
  4662.  
  4663.                 inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
  4664.  
  4665.                     bool first = true;
  4666.                     for (auto line : cols) {
  4667.                         if (first)
  4668.                             first = false;
  4669.                         else
  4670.                             os << "\n";
  4671.                         os << line;
  4672.                     }
  4673.                     return os;
  4674.                 }
  4675.  
  4676.                 auto toString() const -> std::string {
  4677.                     std::ostringstream oss;
  4678.                     oss << *this;
  4679.                     return oss.str();
  4680.                 }
  4681.             };
  4682.  
  4683.             inline auto Column::operator + (Column const& other) -> Columns {
  4684.                 Columns cols;
  4685.                 cols += *this;
  4686.                 cols += other;
  4687.                 return cols;
  4688.             }
  4689.         }
  4690.     }
  4691. } // namespace Catch::clara::TextFlow
  4692.  
  4693.   // ----------- end of #include from clara_textflow.hpp -----------
  4694.   // ........... back in clara.hpp
  4695.  
  4696. #include <memory>
  4697. #include <set>
  4698. #include <algorithm>
  4699.  
  4700. #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
  4701. #define CATCH_PLATFORM_WINDOWS
  4702. #endif
  4703.  
  4704. namespace Catch {
  4705.     namespace clara {
  4706.         namespace detail {
  4707.  
  4708.             // Traits for extracting arg and return type of lambdas (for single argument lambdas)
  4709.             template<typename L>
  4710.             struct UnaryLambdaTraits : UnaryLambdaTraits<decltype(&L::operator())> {};
  4711.  
  4712.             template<typename ClassT, typename ReturnT, typename... Args>
  4713.             struct UnaryLambdaTraits<ReturnT(ClassT::*)(Args...) const> {
  4714.                 static const bool isValid = false;
  4715.             };
  4716.  
  4717.             template<typename ClassT, typename ReturnT, typename ArgT>
  4718.             struct UnaryLambdaTraits<ReturnT(ClassT::*)(ArgT) const> {
  4719.                 static const bool isValid = true;
  4720.                 using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;;
  4721.                 using ReturnType = ReturnT;
  4722.             };
  4723.  
  4724.             class TokenStream;
  4725.  
  4726.             // Transport for raw args (copied from main args, or supplied via init list for testing)
  4727.             class Args {
  4728.                 friend TokenStream;
  4729.                 std::string m_exeName;
  4730.                 std::vector<std::string> m_args;
  4731.  
  4732.             public:
  4733.                 Args(int argc, char *argv[]) {
  4734.                     m_exeName = argv[0];
  4735.                     for (int i = 1; i < argc; ++i)
  4736.                         m_args.push_back(argv[i]);
  4737.                 }
  4738.  
  4739.                 Args(std::initializer_list<std::string> args)
  4740.                     : m_exeName(*args.begin()),
  4741.                     m_args(args.begin() + 1, args.end()) {
  4742.                 }
  4743.  
  4744.                 auto exeName() const -> std::string {
  4745.                     return m_exeName;
  4746.                 }
  4747.             };
  4748.  
  4749.             // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
  4750.             // may encode an option + its argument if the : or = form is used
  4751.             enum class TokenType {
  4752.                 Option, Argument
  4753.             };
  4754.             struct Token {
  4755.                 TokenType type;
  4756.                 std::string token;
  4757.             };
  4758.  
  4759.             inline auto isOptPrefix(char c) -> bool {
  4760.                 return c == '-'
  4761. #ifdef CATCH_PLATFORM_WINDOWS
  4762.                     || c == '/'
  4763. #endif
  4764.                     ;
  4765.             }
  4766.  
  4767.             // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
  4768.             class TokenStream {
  4769.                 using Iterator = std::vector<std::string>::const_iterator;
  4770.                 Iterator it;
  4771.                 Iterator itEnd;
  4772.                 std::vector<Token> m_tokenBuffer;
  4773.  
  4774.                 void loadBuffer() {
  4775.                     m_tokenBuffer.resize(0);
  4776.  
  4777.                     // Skip any empty strings
  4778.                     while (it != itEnd && it->empty())
  4779.                         ++it;
  4780.  
  4781.                     if (it != itEnd) {
  4782.                         auto const &next = *it;
  4783.                         if (isOptPrefix(next[0])) {
  4784.                             auto delimiterPos = next.find_first_of(" :=");
  4785.                             if (delimiterPos != std::string::npos) {
  4786.                                 m_tokenBuffer.push_back({ TokenType::Option, next.substr(0, delimiterPos) });
  4787.                                 m_tokenBuffer.push_back({ TokenType::Argument, next.substr(delimiterPos + 1) });
  4788.                             } else {
  4789.                                 if (next[1] != '-' && next.size() > 2) {
  4790.                                     std::string opt = "- ";
  4791.                                     for (size_t i = 1; i < next.size(); ++i) {
  4792.                                         opt[1] = next[i];
  4793.                                         m_tokenBuffer.push_back({ TokenType::Option, opt });
  4794.                                     }
  4795.                                 } else {
  4796.                                     m_tokenBuffer.push_back({ TokenType::Option, next });
  4797.                                 }
  4798.                             }
  4799.                         } else {
  4800.                             m_tokenBuffer.push_back({ TokenType::Argument, next });
  4801.                         }
  4802.                     }
  4803.                 }
  4804.  
  4805.             public:
  4806.                 explicit TokenStream(Args const &args) : TokenStream(args.m_args.begin(), args.m_args.end()) {}
  4807.  
  4808.                 TokenStream(Iterator it, Iterator itEnd) : it(it), itEnd(itEnd) {
  4809.                     loadBuffer();
  4810.                 }
  4811.  
  4812.                 explicit operator bool() const {
  4813.                     return !m_tokenBuffer.empty() || it != itEnd;
  4814.                 }
  4815.  
  4816.                 auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
  4817.  
  4818.                 auto operator*() const -> Token {
  4819.                     assert(!m_tokenBuffer.empty());
  4820.                     return m_tokenBuffer.front();
  4821.                 }
  4822.  
  4823.                 auto operator->() const -> Token const * {
  4824.                     assert(!m_tokenBuffer.empty());
  4825.                     return &m_tokenBuffer.front();
  4826.                 }
  4827.  
  4828.                 auto operator++() -> TokenStream & {
  4829.                     if (m_tokenBuffer.size() >= 2) {
  4830.                         m_tokenBuffer.erase(m_tokenBuffer.begin());
  4831.                     } else {
  4832.                         if (it != itEnd)
  4833.                             ++it;
  4834.                         loadBuffer();
  4835.                     }
  4836.                     return *this;
  4837.                 }
  4838.             };
  4839.  
  4840.             class ResultBase {
  4841.             public:
  4842.                 enum Type {
  4843.                     Ok, LogicError, RuntimeError
  4844.                 };
  4845.  
  4846.             protected:
  4847.                 ResultBase(Type type) : m_type(type) {}
  4848.                 virtual ~ResultBase() = default;
  4849.  
  4850.                 virtual void enforceOk() const = 0;
  4851.  
  4852.                 Type m_type;
  4853.             };
  4854.  
  4855.             template<typename T>
  4856.             class ResultValueBase : public ResultBase {
  4857.             public:
  4858.                 auto value() const -> T const & {
  4859.                     enforceOk();
  4860.                     return m_value;
  4861.                 }
  4862.  
  4863.             protected:
  4864.                 ResultValueBase(Type type) : ResultBase(type) {}
  4865.  
  4866.                 ResultValueBase(ResultValueBase const &other) : ResultBase(other) {
  4867.                     if (m_type == ResultBase::Ok)
  4868.                         new(&m_value) T(other.m_value);
  4869.                 }
  4870.  
  4871.                 ResultValueBase(Type, T const &value) : ResultBase(Ok) {
  4872.                     new(&m_value) T(value);
  4873.                 }
  4874.  
  4875.                 auto operator=(ResultValueBase const &other) -> ResultValueBase & {
  4876.                     if (m_type == ResultBase::Ok)
  4877.                         m_value.~T();
  4878.                     ResultBase::operator=(other);
  4879.                     if (m_type == ResultBase::Ok)
  4880.                         new(&m_value) T(other.m_value);
  4881.                     return *this;
  4882.                 }
  4883.  
  4884.                 ~ResultValueBase() {
  4885.                     if (m_type == Ok)
  4886.                         m_value.~T();
  4887.                 }
  4888.  
  4889.                 union {
  4890.                     T m_value;
  4891.                 };
  4892.             };
  4893.  
  4894.             template<>
  4895.             class ResultValueBase<void> : public ResultBase {
  4896.             protected:
  4897.                 using ResultBase::ResultBase;
  4898.             };
  4899.  
  4900.             template<typename T = void>
  4901.             class BasicResult : public ResultValueBase<T> {
  4902.             public:
  4903.                 template<typename U>
  4904.                 explicit BasicResult(BasicResult<U> const &other)
  4905.                     : ResultValueBase<T>(other.type()),
  4906.                     m_errorMessage(other.errorMessage()) {
  4907.                     assert(type() != ResultBase::Ok);
  4908.                 }
  4909.  
  4910.                 template<typename U>
  4911.                 static auto ok(U const &value) -> BasicResult { return{ ResultBase::Ok, value }; }
  4912.                 static auto ok() -> BasicResult { return{ ResultBase::Ok }; }
  4913.                 static auto logicError(std::string const &message) -> BasicResult { return{ ResultBase::LogicError, message }; }
  4914.                 static auto runtimeError(std::string const &message) -> BasicResult { return{ ResultBase::RuntimeError, message }; }
  4915.  
  4916.                 explicit operator bool() const { return m_type == ResultBase::Ok; }
  4917.                 auto type() const -> ResultBase::Type { return m_type; }
  4918.                 auto errorMessage() const -> std::string { return m_errorMessage; }
  4919.  
  4920.             protected:
  4921.                 virtual void enforceOk() const {
  4922.                     // !TBD: If no exceptions, std::terminate here or something
  4923.                     switch (m_type) {
  4924.                         case ResultBase::LogicError:
  4925.                             throw std::logic_error(m_errorMessage);
  4926.                         case ResultBase::RuntimeError:
  4927.                             throw std::runtime_error(m_errorMessage);
  4928.                         case ResultBase::Ok:
  4929.                             break;
  4930.                     }
  4931.                 }
  4932.  
  4933.                 std::string m_errorMessage; // Only populated if resultType is an error
  4934.  
  4935.                 BasicResult(ResultBase::Type type, std::string const &message)
  4936.                     : ResultValueBase<T>(type),
  4937.                     m_errorMessage(message) {
  4938.                     assert(m_type != ResultBase::Ok);
  4939.                 }
  4940.  
  4941.                 using ResultValueBase<T>::ResultValueBase;
  4942.                 using ResultBase::m_type;
  4943.             };
  4944.  
  4945.             enum class ParseResultType {
  4946.                 Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
  4947.             };
  4948.  
  4949.             class ParseState {
  4950.             public:
  4951.  
  4952.                 ParseState(ParseResultType type, TokenStream const &remainingTokens)
  4953.                     : m_type(type),
  4954.                     m_remainingTokens(remainingTokens) {
  4955.                 }
  4956.  
  4957.                 auto type() const -> ParseResultType { return m_type; }
  4958.                 auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
  4959.  
  4960.             private:
  4961.                 ParseResultType m_type;
  4962.                 TokenStream m_remainingTokens;
  4963.             };
  4964.  
  4965.             using Result = BasicResult<void>;
  4966.             using ParserResult = BasicResult<ParseResultType>;
  4967.             using InternalParseResult = BasicResult<ParseState>;
  4968.  
  4969.             struct HelpColumns {
  4970.                 std::string left;
  4971.                 std::string right;
  4972.             };
  4973.  
  4974.             template<typename T>
  4975.             inline auto convertInto(std::string const &source, T& target) -> ParserResult {
  4976.                 std::stringstream ss;
  4977.                 ss << source;
  4978.                 ss >> target;
  4979.                 if (ss.fail())
  4980.                     return ParserResult::runtimeError("Unable to convert '" + source + "' to destination type");
  4981.                 else
  4982.                     return ParserResult::ok(ParseResultType::Matched);
  4983.             }
  4984.             inline auto convertInto(std::string const &source, std::string& target) -> ParserResult {
  4985.                 target = source;
  4986.                 return ParserResult::ok(ParseResultType::Matched);
  4987.             }
  4988.             inline auto convertInto(std::string const &source, bool &target) -> ParserResult {
  4989.                 std::string srcLC = source;
  4990.                 std::transform(srcLC.begin(), srcLC.end(), srcLC.begin(), [](char c) { return static_cast<char>(::tolower(c)); });
  4991.                 if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
  4992.                     target = true;
  4993.                 else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
  4994.                     target = false;
  4995.                 else
  4996.                     return ParserResult::runtimeError("Expected a boolean value but did not recognise: '" + source + "'");
  4997.                 return ParserResult::ok(ParseResultType::Matched);
  4998.             }
  4999.  
  5000.             struct BoundRefBase {
  5001.                 BoundRefBase() = default;
  5002.                 BoundRefBase(BoundRefBase const &) = delete;
  5003.                 BoundRefBase(BoundRefBase &&) = delete;
  5004.                 BoundRefBase &operator=(BoundRefBase const &) = delete;
  5005.                 BoundRefBase &operator=(BoundRefBase &&) = delete;
  5006.  
  5007.                 virtual ~BoundRefBase() = default;
  5008.  
  5009.                 virtual auto isFlag() const -> bool = 0;
  5010.                 virtual auto isContainer() const -> bool { return false; }
  5011.                 virtual auto setValue(std::string const &arg)->ParserResult = 0;
  5012.                 virtual auto setFlag(bool flag)->ParserResult = 0;
  5013.             };
  5014.  
  5015.             struct BoundValueRefBase : BoundRefBase {
  5016.                 auto isFlag() const -> bool override { return false; }
  5017.  
  5018.                 auto setFlag(bool) -> ParserResult override {
  5019.                     return ParserResult::logicError("Flags can only be set on boolean fields");
  5020.                 }
  5021.             };
  5022.  
  5023.             struct BoundFlagRefBase : BoundRefBase {
  5024.                 auto isFlag() const -> bool override { return true; }
  5025.  
  5026.                 auto setValue(std::string const &arg) -> ParserResult override {
  5027.                     bool flag;
  5028.                     auto result = convertInto(arg, flag);
  5029.                     if (result)
  5030.                         setFlag(flag);
  5031.                     return result;
  5032.                 }
  5033.             };
  5034.  
  5035.             template<typename T>
  5036.             struct BoundRef : BoundValueRefBase {
  5037.                 T &m_ref;
  5038.  
  5039.                 explicit BoundRef(T &ref) : m_ref(ref) {}
  5040.  
  5041.                 auto setValue(std::string const &arg) -> ParserResult override {
  5042.                     return convertInto(arg, m_ref);
  5043.                 }
  5044.             };
  5045.  
  5046.             template<typename T>
  5047.             struct BoundRef<std::vector<T>> : BoundValueRefBase {
  5048.                 std::vector<T> &m_ref;
  5049.  
  5050.                 explicit BoundRef(std::vector<T> &ref) : m_ref(ref) {}
  5051.  
  5052.                 auto isContainer() const -> bool override { return true; }
  5053.  
  5054.                 auto setValue(std::string const &arg) -> ParserResult override {
  5055.                     T temp;
  5056.                     auto result = convertInto(arg, temp);
  5057.                     if (result)
  5058.                         m_ref.push_back(temp);
  5059.                     return result;
  5060.                 }
  5061.             };
  5062.  
  5063.             struct BoundFlagRef : BoundFlagRefBase {
  5064.                 bool &m_ref;
  5065.  
  5066.                 explicit BoundFlagRef(bool &ref) : m_ref(ref) {}
  5067.  
  5068.                 auto setFlag(bool flag) -> ParserResult override {
  5069.                     m_ref = flag;
  5070.                     return ParserResult::ok(ParseResultType::Matched);
  5071.                 }
  5072.             };
  5073.  
  5074.             template<typename ReturnType>
  5075.             struct LambdaInvoker {
  5076.                 static_assert(std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult");
  5077.  
  5078.                 template<typename L, typename ArgType>
  5079.                 static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult {
  5080.                     return lambda(arg);
  5081.                 }
  5082.             };
  5083.  
  5084.             template<>
  5085.             struct LambdaInvoker<void> {
  5086.                 template<typename L, typename ArgType>
  5087.                 static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult {
  5088.                     lambda(arg);
  5089.                     return ParserResult::ok(ParseResultType::Matched);
  5090.                 }
  5091.             };
  5092.  
  5093.             template<typename ArgType, typename L>
  5094.             inline auto invokeLambda(L const &lambda, std::string const &arg) -> ParserResult {
  5095.                 ArgType temp;
  5096.                 auto result = convertInto(arg, temp);
  5097.                 return !result
  5098.                     ? result
  5099.                     : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke(lambda, temp);
  5100.             };
  5101.  
  5102.             template<typename L>
  5103.             struct BoundLambda : BoundValueRefBase {
  5104.                 L m_lambda;
  5105.  
  5106.                 static_assert(UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument");
  5107.                 explicit BoundLambda(L const &lambda) : m_lambda(lambda) {}
  5108.  
  5109.                 auto setValue(std::string const &arg) -> ParserResult override {
  5110.                     return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>(m_lambda, arg);
  5111.                 }
  5112.             };
  5113.  
  5114.             template<typename L>
  5115.             struct BoundFlagLambda : BoundFlagRefBase {
  5116.                 L m_lambda;
  5117.  
  5118.                 static_assert(UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument");
  5119.                 static_assert(std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean");
  5120.  
  5121.                 explicit BoundFlagLambda(L const &lambda) : m_lambda(lambda) {}
  5122.  
  5123.                 auto setFlag(bool flag) -> ParserResult override {
  5124.                     return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke(m_lambda, flag);
  5125.                 }
  5126.             };
  5127.  
  5128.             enum class Optionality { Optional, Required };
  5129.  
  5130.             struct Parser;
  5131.  
  5132.             class ParserBase {
  5133.             public:
  5134.                 virtual ~ParserBase() = default;
  5135.                 virtual auto validate() const -> Result { return Result::ok(); }
  5136.                 virtual auto parse(std::string const& exeName, TokenStream const &tokens) const->InternalParseResult = 0;
  5137.                 virtual auto cardinality() const -> size_t { return 1; }
  5138.  
  5139.                 auto parse(Args const &args) const -> InternalParseResult {
  5140.                     return parse(args.exeName(), TokenStream(args));
  5141.                 }
  5142.             };
  5143.  
  5144.             template<typename DerivedT>
  5145.             class ComposableParserImpl : public ParserBase {
  5146.             public:
  5147.                 template<typename T>
  5148.                 auto operator|(T const &other) const->Parser;
  5149.             };
  5150.  
  5151.             // Common code and state for Args and Opts
  5152.             template<typename DerivedT>
  5153.             class ParserRefImpl : public ComposableParserImpl<DerivedT> {
  5154.             protected:
  5155.                 Optionality m_optionality = Optionality::Optional;
  5156.                 std::shared_ptr<BoundRefBase> m_ref;
  5157.                 std::string m_hint;
  5158.                 std::string m_description;
  5159.  
  5160.                 explicit ParserRefImpl(std::shared_ptr<BoundRefBase> const &ref) : m_ref(ref) {}
  5161.  
  5162.             public:
  5163.                 template<typename T>
  5164.                 ParserRefImpl(T &ref, std::string const &hint)
  5165.                     : m_ref(std::make_shared<BoundRef<T>>(ref)),
  5166.                     m_hint(hint) {
  5167.                 }
  5168.  
  5169.                 template<typename LambdaT>
  5170.                 ParserRefImpl(LambdaT const &ref, std::string const &hint)
  5171.                     : m_ref(std::make_shared<BoundLambda<LambdaT>>(ref)),
  5172.                     m_hint(hint) {
  5173.                 }
  5174.  
  5175.                 auto operator()(std::string const &description) -> DerivedT & {
  5176.                     m_description = description;
  5177.                     return static_cast<DerivedT &>(*this);
  5178.                 }
  5179.  
  5180.                 auto optional() -> DerivedT & {
  5181.                     m_optionality = Optionality::Optional;
  5182.                     return static_cast<DerivedT &>(*this);
  5183.                 };
  5184.  
  5185.                 auto required() -> DerivedT & {
  5186.                     m_optionality = Optionality::Required;
  5187.                     return static_cast<DerivedT &>(*this);
  5188.                 };
  5189.  
  5190.                 auto isOptional() const -> bool {
  5191.                     return m_optionality == Optionality::Optional;
  5192.                 }
  5193.  
  5194.                 auto cardinality() const -> size_t override {
  5195.                     if (m_ref->isContainer())
  5196.                         return 0;
  5197.                     else
  5198.                         return 1;
  5199.                 }
  5200.  
  5201.                 auto hint() const -> std::string { return m_hint; }
  5202.             };
  5203.  
  5204.             class ExeName : public ComposableParserImpl<ExeName> {
  5205.                 std::shared_ptr<std::string> m_name;
  5206.                 std::shared_ptr<BoundRefBase> m_ref;
  5207.  
  5208.                 template<typename LambdaT>
  5209.                 static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundRefBase> {
  5210.                     return std::make_shared<BoundLambda<LambdaT>>(lambda);
  5211.                 }
  5212.  
  5213.             public:
  5214.                 ExeName() : m_name(std::make_shared<std::string>("<executable>")) {}
  5215.  
  5216.                 explicit ExeName(std::string &ref) : ExeName() {
  5217.                     m_ref = std::make_shared<BoundRef<std::string>>(ref);
  5218.                 }
  5219.  
  5220.                 template<typename LambdaT>
  5221.                 explicit ExeName(LambdaT const& lambda) : ExeName() {
  5222.                     m_ref = std::make_shared<BoundLambda<LambdaT>>(lambda);
  5223.                 }
  5224.  
  5225.                 // The exe name is not parsed out of the normal tokens, but is handled specially
  5226.                 auto parse(std::string const&, TokenStream const &tokens) const -> InternalParseResult override {
  5227.                     return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
  5228.                 }
  5229.  
  5230.                 auto name() const -> std::string { return *m_name; }
  5231.                 auto set(std::string const& newName) -> ParserResult {
  5232.  
  5233.                     auto lastSlash = newName.find_last_of("\\/");
  5234.                     auto filename = (lastSlash == std::string::npos)
  5235.                         ? newName
  5236.                         : newName.substr(lastSlash + 1);
  5237.  
  5238.                     *m_name = filename;
  5239.                     if (m_ref)
  5240.                         return m_ref->setValue(filename);
  5241.                     else
  5242.                         return ParserResult::ok(ParseResultType::Matched);
  5243.                 }
  5244.             };
  5245.  
  5246.             class Arg : public ParserRefImpl<Arg> {
  5247.             public:
  5248.                 using ParserRefImpl::ParserRefImpl;
  5249.  
  5250.                 auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override {
  5251.                     auto validationResult = validate();
  5252.                     if (!validationResult)
  5253.                         return InternalParseResult(validationResult);
  5254.  
  5255.                     auto remainingTokens = tokens;
  5256.                     auto const &token = *remainingTokens;
  5257.                     if (token.type != TokenType::Argument)
  5258.                         return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens));
  5259.  
  5260.                     auto result = m_ref->setValue(remainingTokens->token);
  5261.                     if (!result)
  5262.                         return InternalParseResult(result);
  5263.                     else
  5264.                         return InternalParseResult::ok(ParseState(ParseResultType::Matched, ++remainingTokens));
  5265.                 }
  5266.             };
  5267.  
  5268.             inline auto normaliseOpt(std::string const &optName) -> std::string {
  5269. #ifdef CATCH_PLATFORM_WINDOWS
  5270.                 if (optName[0] == '/')
  5271.                     return "-" + optName.substr(1);
  5272.                 else
  5273. #endif
  5274.                     return optName;
  5275.             }
  5276.  
  5277.             class Opt : public ParserRefImpl<Opt> {
  5278.             protected:
  5279.                 std::vector<std::string> m_optNames;
  5280.  
  5281.             public:
  5282.                 template<typename LambdaT>
  5283.                 explicit Opt(LambdaT const &ref) : ParserRefImpl(std::make_shared<BoundFlagLambda<LambdaT>>(ref)) {}
  5284.  
  5285.                 explicit Opt(bool &ref) : ParserRefImpl(std::make_shared<BoundFlagRef>(ref)) {}
  5286.  
  5287.                 template<typename LambdaT>
  5288.                 Opt(LambdaT const &ref, std::string const &hint) : ParserRefImpl(ref, hint) {}
  5289.  
  5290.                 template<typename T>
  5291.                 Opt(T &ref, std::string const &hint) : ParserRefImpl(ref, hint) {}
  5292.  
  5293.                 auto operator[](std::string const &optName) -> Opt & {
  5294.                     m_optNames.push_back(optName);
  5295.                     return *this;
  5296.                 }
  5297.  
  5298.                 auto getHelpColumns() const -> std::vector<HelpColumns> {
  5299.                     std::ostringstream oss;
  5300.                     bool first = true;
  5301.                     for (auto const &opt : m_optNames) {
  5302.                         if (first)
  5303.                             first = false;
  5304.                         else
  5305.                             oss << ", ";
  5306.                         oss << opt;
  5307.                     }
  5308.                     if (!m_hint.empty())
  5309.                         oss << " <" << m_hint << ">";
  5310.                     return{ { oss.str(), m_description } };
  5311.                 }
  5312.  
  5313.                 auto isMatch(std::string const &optToken) const -> bool {
  5314.                     auto normalisedToken = normaliseOpt(optToken);
  5315.                     for (auto const &name : m_optNames) {
  5316.                         if (normaliseOpt(name) == normalisedToken)
  5317.                             return true;
  5318.                     }
  5319.                     return false;
  5320.                 }
  5321.  
  5322.                 using ParserBase::parse;
  5323.  
  5324.                 auto parse(std::string const&, TokenStream const &tokens) const -> InternalParseResult override {
  5325.                     auto validationResult = validate();
  5326.                     if (!validationResult)
  5327.                         return InternalParseResult(validationResult);
  5328.  
  5329.                     auto remainingTokens = tokens;
  5330.                     if (remainingTokens && remainingTokens->type == TokenType::Option) {
  5331.                         auto const &token = *remainingTokens;
  5332.                         if (isMatch(token.token)) {
  5333.                             if (m_ref->isFlag()) {
  5334.                                 auto result = m_ref->setFlag(true);
  5335.                                 if (!result)
  5336.                                     return InternalParseResult(result);
  5337.                                 if (result.value() == ParseResultType::ShortCircuitAll)
  5338.                                     return InternalParseResult::ok(ParseState(result.value(), remainingTokens));
  5339.                             } else {
  5340.                                 ++remainingTokens;
  5341.                                 if (!remainingTokens)
  5342.                                     return InternalParseResult::runtimeError("Expected argument following " + token.token);
  5343.                                 auto const &argToken = *remainingTokens;
  5344.                                 if (argToken.type != TokenType::Argument)
  5345.                                     return InternalParseResult::runtimeError("Expected argument following " + token.token);
  5346.                                 auto result = m_ref->setValue(argToken.token);
  5347.                                 if (!result)
  5348.                                     return InternalParseResult(result);
  5349.                                 if (result.value() == ParseResultType::ShortCircuitAll)
  5350.                                     return InternalParseResult::ok(ParseState(result.value(), remainingTokens));
  5351.                             }
  5352.                             return InternalParseResult::ok(ParseState(ParseResultType::Matched, ++remainingTokens));
  5353.                         }
  5354.                     }
  5355.                     return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens));
  5356.                 }
  5357.  
  5358.                 auto validate() const -> Result override {
  5359.                     if (m_optNames.empty())
  5360.                         return Result::logicError("No options supplied to Opt");
  5361.                     for (auto const &name : m_optNames) {
  5362.                         if (name.empty())
  5363.                             return Result::logicError("Option name cannot be empty");
  5364. #ifdef CATCH_PLATFORM_WINDOWS
  5365.                         if (name[0] != '-' && name[0] != '/')
  5366.                             return Result::logicError("Option name must begin with '-' or '/'");
  5367. #else
  5368.                         if (name[0] != '-')
  5369.                             return Result::logicError("Option name must begin with '-'");
  5370. #endif
  5371.                     }
  5372.                     return ParserRefImpl::validate();
  5373.                 }
  5374.             };
  5375.  
  5376.             struct Help : Opt {
  5377.                 Help(bool &showHelpFlag)
  5378.                     : Opt([&](bool flag) {
  5379.                     showHelpFlag = flag;
  5380.                     return ParserResult::ok(ParseResultType::ShortCircuitAll);
  5381.                 }) {
  5382.                     static_cast<Opt &>(*this)
  5383.                         ("display usage information")
  5384.                         ["-?"]["-h"]["--help"]
  5385.                         .optional();
  5386.                 }
  5387.             };
  5388.  
  5389.             struct Parser : ParserBase {
  5390.  
  5391.                 mutable ExeName m_exeName;
  5392.                 std::vector<Opt> m_options;
  5393.                 std::vector<Arg> m_args;
  5394.  
  5395.                 auto operator|=(ExeName const &exeName) -> Parser & {
  5396.                     m_exeName = exeName;
  5397.                     return *this;
  5398.                 }
  5399.  
  5400.                 auto operator|=(Arg const &arg) -> Parser & {
  5401.                     m_args.push_back(arg);
  5402.                     return *this;
  5403.                 }
  5404.  
  5405.                 auto operator|=(Opt const &opt) -> Parser & {
  5406.                     m_options.push_back(opt);
  5407.                     return *this;
  5408.                 }
  5409.  
  5410.                 auto operator|=(Parser const &other) -> Parser & {
  5411.                     m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
  5412.                     m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
  5413.                     return *this;
  5414.                 }
  5415.  
  5416.                 template<typename T>
  5417.                 auto operator|(T const &other) const -> Parser {
  5418.                     return Parser(*this) |= other;
  5419.                 }
  5420.  
  5421.                 auto getHelpColumns() const -> std::vector<HelpColumns> {
  5422.                     std::vector<HelpColumns> cols;
  5423.                     for (auto const &o : m_options) {
  5424.                         auto childCols = o.getHelpColumns();
  5425.                         cols.insert(cols.end(), childCols.begin(), childCols.end());
  5426.                     }
  5427.                     return cols;
  5428.                 }
  5429.  
  5430.                 void writeToStream(std::ostream &os) const {
  5431.                     if (!m_exeName.name().empty()) {
  5432.                         os << "usage:\n" << "  " << m_exeName.name() << " ";
  5433.                         bool required = true, first = true;
  5434.                         for (auto const &arg : m_args) {
  5435.                             if (first)
  5436.                                 first = false;
  5437.                             else
  5438.                                 os << " ";
  5439.                             if (arg.isOptional() && required) {
  5440.                                 os << "[";
  5441.                                 required = false;
  5442.                             }
  5443.                             os << "<" << arg.hint() << ">";
  5444.                             if (arg.cardinality() == 0)
  5445.                                 os << " ... ";
  5446.                         }
  5447.                         if (!required)
  5448.                             os << "]";
  5449.                         if (!m_options.empty())
  5450.                             os << " options";
  5451.                         os << "\n\nwhere options are:" << std::endl;
  5452.                     }
  5453.  
  5454.                     auto rows = getHelpColumns();
  5455.                     size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
  5456.                     size_t optWidth = 0;
  5457.                     for (auto const &cols : rows)
  5458.                         optWidth = (std::max)(optWidth, cols.left.size() + 2);
  5459.  
  5460.                     for (auto const &cols : rows) {
  5461.                         auto row =
  5462.                             TextFlow::Column(cols.left).width(optWidth).indent(2) +
  5463.                             TextFlow::Spacer(4) +
  5464.                             TextFlow::Column(cols.right).width(consoleWidth - 7 - optWidth);
  5465.                         os << row << std::endl;
  5466.                     }
  5467.                 }
  5468.  
  5469.                 friend auto operator<<(std::ostream &os, Parser const &parser) -> std::ostream& {
  5470.                     parser.writeToStream(os);
  5471.                     return os;
  5472.                 }
  5473.  
  5474.                 auto validate() const -> Result override {
  5475.                     for (auto const &opt : m_options) {
  5476.                         auto result = opt.validate();
  5477.                         if (!result)
  5478.                             return result;
  5479.                     }
  5480.                     for (auto const &arg : m_args) {
  5481.                         auto result = arg.validate();
  5482.                         if (!result)
  5483.                             return result;
  5484.                     }
  5485.                     return Result::ok();
  5486.                 }
  5487.  
  5488.                 using ParserBase::parse;
  5489.  
  5490.                 auto parse(std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult override {
  5491.  
  5492.                     struct ParserInfo {
  5493.                         ParserBase const* parser = nullptr;
  5494.                         size_t count = 0;
  5495.                     };
  5496.                     const size_t totalParsers = m_options.size() + m_args.size();
  5497.                     assert(totalParsers < 512);
  5498.                     // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
  5499.                     ParserInfo parseInfos[512];
  5500.  
  5501.                     {
  5502.                         size_t i = 0;
  5503.                         for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
  5504.                         for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
  5505.                     }
  5506.  
  5507.                     m_exeName.set(exeName);
  5508.  
  5509.                     auto result = InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
  5510.                     while (result.value().remainingTokens()) {
  5511.                         bool tokenParsed = false;
  5512.  
  5513.                         for (size_t i = 0; i < totalParsers; ++i) {
  5514.                             auto&  parseInfo = parseInfos[i];
  5515.                             if (parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality()) {
  5516.                                 result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
  5517.                                 if (!result)
  5518.                                     return result;
  5519.                                 if (result.value().type() != ParseResultType::NoMatch) {
  5520.                                     tokenParsed = true;
  5521.                                     ++parseInfo.count;
  5522.                                     break;
  5523.                                 }
  5524.                             }
  5525.                         }
  5526.  
  5527.                         if (result.value().type() == ParseResultType::ShortCircuitAll)
  5528.                             return result;
  5529.                         if (!tokenParsed)
  5530.                             return InternalParseResult::runtimeError("Unrecognised token: " + result.value().remainingTokens()->token);
  5531.                     }
  5532.                     // !TBD Check missing required options
  5533.                     return result;
  5534.                 }
  5535.             };
  5536.  
  5537.             template<typename DerivedT>
  5538.             template<typename T>
  5539.             auto ComposableParserImpl<DerivedT>::operator|(T const &other) const -> Parser {
  5540.                 return Parser() | static_cast<DerivedT const &>(*this) | other;
  5541.             }
  5542.         } // namespace detail
  5543.  
  5544.           // A Combined parser
  5545.         using detail::Parser;
  5546.  
  5547.         // A parser for options
  5548.         using detail::Opt;
  5549.  
  5550.         // A parser for arguments
  5551.         using detail::Arg;
  5552.  
  5553.         // Wrapper for argc, argv from main()
  5554.         using detail::Args;
  5555.  
  5556.         // Specifies the name of the executable
  5557.         using detail::ExeName;
  5558.  
  5559.         // Convenience wrapper for option parser that specifies the help option
  5560.         using detail::Help;
  5561.  
  5562.         // enum of result types from a parse
  5563.         using detail::ParseResultType;
  5564.  
  5565.         // Result type for parser operation
  5566.         using detail::ParserResult;
  5567.  
  5568.     }
  5569. } // namespace Catch::clara
  5570.  
  5571.   // end clara.hpp
  5572. #ifdef __clang__
  5573. #pragma clang diagnostic pop
  5574. #endif
  5575.  
  5576.   // Restore Clara's value for console width, if present
  5577. #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  5578. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  5579. #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  5580. #endif
  5581.  
  5582.   // end catch_clara.h
  5583. namespace Catch {
  5584.  
  5585.     clara::Parser makeCommandLineParser(ConfigData& config);
  5586.  
  5587. } // end namespace Catch
  5588.  
  5589.   // end catch_commandline.h
  5590. #include <fstream>
  5591. #include <ctime>
  5592.  
  5593. namespace Catch {
  5594.  
  5595.     clara::Parser makeCommandLineParser(ConfigData& config) {
  5596.  
  5597.         using namespace clara;
  5598.  
  5599.         auto const setWarning = [&](std::string const& warning) {
  5600.             if (warning != "NoAssertions")
  5601.                 return ParserResult::runtimeError("Unrecognised warning: '" + warning + "'");
  5602.             config.warnings = static_cast<WarnAbout::What>(config.warnings | WarnAbout::NoAssertions);
  5603.             return ParserResult::ok(ParseResultType::Matched);
  5604.         };
  5605.         auto const loadTestNamesFromFile = [&](std::string const& filename) {
  5606.             std::ifstream f(filename.c_str());
  5607.             if (!f.is_open())
  5608.                 return ParserResult::runtimeError("Unable to load input file: '" + filename + "'");
  5609.  
  5610.             std::string line;
  5611.             while (std::getline(f, line)) {
  5612.                 line = trim(line);
  5613.                 if (!line.empty() && !startsWith(line, '#')) {
  5614.                     if (!startsWith(line, '"'))
  5615.                         line = '"' + line + '"';
  5616.                     config.testsOrTags.push_back(line + ',');
  5617.                 }
  5618.             }
  5619.             return ParserResult::ok(ParseResultType::Matched);
  5620.         };
  5621.         auto const setTestOrder = [&](std::string const& order) {
  5622.             if (startsWith("declared", order))
  5623.                 config.runOrder = RunTests::InDeclarationOrder;
  5624.             else if (startsWith("lexical", order))
  5625.                 config.runOrder = RunTests::InLexicographicalOrder;
  5626.             else if (startsWith("random", order))
  5627.                 config.runOrder = RunTests::InRandomOrder;
  5628.             else
  5629.                 return clara::ParserResult::runtimeError("Unrecognised ordering: '" + order + "'");
  5630.             return ParserResult::ok(ParseResultType::Matched);
  5631.         };
  5632.         auto const setRngSeed = [&](std::string const& seed) {
  5633.             if (seed != "time")
  5634.                 return clara::detail::convertInto(seed, config.rngSeed);
  5635.             config.rngSeed = static_cast<unsigned int>(std::time(nullptr));
  5636.             return ParserResult::ok(ParseResultType::Matched);
  5637.         };
  5638.         auto const setColourUsage = [&](std::string const& useColour) {
  5639.             auto mode = toLower(useColour);
  5640.  
  5641.             if (mode == "yes")
  5642.                 config.useColour = UseColour::Yes;
  5643.             else if (mode == "no")
  5644.                 config.useColour = UseColour::No;
  5645.             else if (mode == "auto")
  5646.                 config.useColour = UseColour::Auto;
  5647.             else
  5648.                 return ParserResult::runtimeError("colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised");
  5649.             return ParserResult::ok(ParseResultType::Matched);
  5650.         };
  5651.         auto const setWaitForKeypress = [&](std::string const& keypress) {
  5652.             auto keypressLc = toLower(keypress);
  5653.             if (keypressLc == "start")
  5654.                 config.waitForKeypress = WaitForKeypress::BeforeStart;
  5655.             else if (keypressLc == "exit")
  5656.                 config.waitForKeypress = WaitForKeypress::BeforeExit;
  5657.             else if (keypressLc == "both")
  5658.                 config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
  5659.             else
  5660.                 return ParserResult::runtimeError("keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised");
  5661.             return ParserResult::ok(ParseResultType::Matched);
  5662.         };
  5663.         auto const setVerbosity = [&](std::string const& verbosity) {
  5664.             auto lcVerbosity = toLower(verbosity);
  5665.             if (lcVerbosity == "quiet")
  5666.                 config.verbosity = Verbosity::Quiet;
  5667.             else if (lcVerbosity == "normal")
  5668.                 config.verbosity = Verbosity::Normal;
  5669.             else if (lcVerbosity == "high")
  5670.                 config.verbosity = Verbosity::High;
  5671.             else
  5672.                 return ParserResult::runtimeError("Unrecognised verbosity, '" + verbosity + "'");
  5673.             return ParserResult::ok(ParseResultType::Matched);
  5674.         };
  5675.  
  5676.         auto cli
  5677.             = ExeName(config.processName)
  5678.             | Help(config.showHelp)
  5679.             | Opt(config.listTests)
  5680.             ["-l"]["--list-tests"]
  5681.             ("list all/matching test cases")
  5682.             | Opt(config.listTags)
  5683.             ["-t"]["--list-tags"]
  5684.             ("list all/matching tags")
  5685.             | Opt(config.showSuccessfulTests)
  5686.             ["-s"]["--success"]
  5687.             ("include successful tests in output")
  5688.             | Opt(config.shouldDebugBreak)
  5689.             ["-b"]["--break"]
  5690.             ("break into debugger on failure")
  5691.             | Opt(config.noThrow)
  5692.             ["-e"]["--nothrow"]
  5693.             ("skip exception tests")
  5694.             | Opt(config.showInvisibles)
  5695.             ["-i"]["--invisibles"]
  5696.             ("show invisibles (tabs, newlines)")
  5697.             | Opt(config.outputFilename, "filename")
  5698.             ["-o"]["--out"]
  5699.             ("output filename")
  5700.             | Opt(config.reporterNames, "name")
  5701.             ["-r"]["--reporter"]
  5702.             ("reporter to use (defaults to console)")
  5703.             | Opt(config.name, "name")
  5704.             ["-n"]["--name"]
  5705.             ("suite name")
  5706.             | Opt([&](bool) { config.abortAfter = 1; })
  5707.             ["-a"]["--abort"]
  5708.             ("abort at first failure")
  5709.             | Opt([&](int x) { config.abortAfter = x; }, "no. failures")
  5710.             ["-x"]["--abortx"]
  5711.             ("abort after x failures")
  5712.             | Opt(setWarning, "warning name")
  5713.             ["-w"]["--warn"]
  5714.             ("enable warnings")
  5715.             | Opt([&](bool flag) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no")
  5716.             ["-d"]["--durations"]
  5717.             ("show test durations")
  5718.             | Opt(loadTestNamesFromFile, "filename")
  5719.             ["-f"]["--input-file"]
  5720.             ("load test names to run from a file")
  5721.             | Opt(config.filenamesAsTags)
  5722.             ["-#"]["--filenames-as-tags"]
  5723.             ("adds a tag for the filename")
  5724.             | Opt(config.sectionsToRun, "section name")
  5725.             ["-c"]["--section"]
  5726.             ("specify section to run")
  5727.             | Opt(setVerbosity, "quiet|normal|high")
  5728.             ["-v"]["--verbosity"]
  5729.             ("set output verbosity")
  5730.             | Opt(config.listTestNamesOnly)
  5731.             ["--list-test-names-only"]
  5732.         ("list all/matching test cases names only")
  5733.             | Opt(config.listReporters)
  5734.             ["--list-reporters"]
  5735.         ("list all reporters")
  5736.             | Opt(setTestOrder, "decl|lex|rand")
  5737.             ["--order"]
  5738.         ("test case order (defaults to decl)")
  5739.             | Opt(setRngSeed, "'time'|number")
  5740.             ["--rng-seed"]
  5741.         ("set a specific seed for random numbers")
  5742.             | Opt(setColourUsage, "yes|no")
  5743.             ["--use-colour"]
  5744.         ("should output be colourised")
  5745.             | Opt(config.libIdentify)
  5746.             ["--libidentify"]
  5747.         ("report name and version according to libidentify standard")
  5748.             | Opt(setWaitForKeypress, "start|exit|both")
  5749.             ["--wait-for-keypress"]
  5750.         ("waits for a keypress before exiting")
  5751.             | Opt(config.benchmarkResolutionMultiple, "multiplier")
  5752.             ["--benchmark-resolution-multiple"]
  5753.         ("multiple of clock resolution to run benchmarks")
  5754.  
  5755.             | Arg(config.testsOrTags, "test name|pattern|tags")
  5756.             ("which test or tests to use");
  5757.  
  5758.         return cli;
  5759.     }
  5760.  
  5761. } // end namespace Catch
  5762.   // end catch_commandline.cpp
  5763.   // start catch_common.cpp
  5764.  
  5765. #include <cstring>
  5766. #include <ostream>
  5767.  
  5768. namespace Catch {
  5769.  
  5770.     SourceLineInfo::SourceLineInfo(char const* _file, std::size_t _line) noexcept
  5771.         :   file(_file),
  5772.         line(_line) {
  5773.     }
  5774.     bool SourceLineInfo::empty() const noexcept {
  5775.         return file[0] == '\0';
  5776.     }
  5777.     bool SourceLineInfo::operator == (SourceLineInfo const& other) const noexcept {
  5778.         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
  5779.     }
  5780.     bool SourceLineInfo::operator < (SourceLineInfo const& other) const noexcept {
  5781.         return line < other.line || (line == other.line && (std::strcmp(file, other.file) < 0));
  5782.     }
  5783.  
  5784.     std::ostream& operator << (std::ostream& os, SourceLineInfo const& info) {
  5785. #ifndef __GNUG__
  5786.         os << info.file << '(' << info.line << ')';
  5787. #else
  5788.         os << info.file << ':' << info.line;
  5789. #endif
  5790.         return os;
  5791.     }
  5792.  
  5793.     bool isTrue(bool value) { return value; }
  5794.     bool alwaysTrue() { return true; }
  5795.     bool alwaysFalse() { return false; }
  5796.  
  5797.     std::string StreamEndStop::operator+() const {
  5798.         return std::string();
  5799.     }
  5800.  
  5801.     NonCopyable::NonCopyable() = default;
  5802.     NonCopyable::~NonCopyable() = default;
  5803.  
  5804. }
  5805. // end catch_common.cpp
  5806. // start catch_config.cpp
  5807.  
  5808. namespace Catch {
  5809.  
  5810.     Config::Config(ConfigData const& data)
  5811.         : m_data(data),
  5812.         m_stream(openStream()) {
  5813.         if (!data.testsOrTags.empty()) {
  5814.             TestSpecParser parser(ITagAliasRegistry::get());
  5815.             for (auto const& testOrTags : data.testsOrTags)
  5816.                 parser.parse(testOrTags);
  5817.             m_testSpec = parser.testSpec();
  5818.         }
  5819.     }
  5820.  
  5821.     std::string const& Config::getFilename() const {
  5822.         return m_data.outputFilename;
  5823.     }
  5824.  
  5825.     bool Config::listTests() const { return m_data.listTests; }
  5826.     bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
  5827.     bool Config::listTags() const { return m_data.listTags; }
  5828.     bool Config::listReporters() const { return m_data.listReporters; }
  5829.  
  5830.     std::string Config::getProcessName() const { return m_data.processName; }
  5831.  
  5832.     std::vector<std::string> const& Config::getReporterNames() const { return m_data.reporterNames; }
  5833.     std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
  5834.  
  5835.     TestSpec const& Config::testSpec() const { return m_testSpec; }
  5836.  
  5837.     bool Config::showHelp() const { return m_data.showHelp; }
  5838.  
  5839.     // IConfig interface
  5840.     bool Config::allowThrows() const { return !m_data.noThrow; }
  5841.     std::ostream& Config::stream() const { return m_stream->stream(); }
  5842.     std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
  5843.     bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
  5844.     bool Config::warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
  5845.     ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
  5846.     RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
  5847.     unsigned int Config::rngSeed() const { return m_data.rngSeed; }
  5848.     int Config::benchmarkResolutionMultiple() const { return m_data.benchmarkResolutionMultiple; }
  5849.     UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
  5850.     bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
  5851.     int Config::abortAfter() const { return m_data.abortAfter; }
  5852.     bool Config::showInvisibles() const { return m_data.showInvisibles; }
  5853.     Verbosity Config::verbosity() const { return m_data.verbosity; }
  5854.  
  5855.     IStream const* Config::openStream() {
  5856.         if (m_data.outputFilename.empty())
  5857.             return new CoutStream();
  5858.         else if (m_data.outputFilename[0] == '%') {
  5859.             if (m_data.outputFilename == "%debug")
  5860.                 return new DebugOutStream();
  5861.             else
  5862.                 CATCH_ERROR("Unrecognised stream: '" << m_data.outputFilename << "'");
  5863.         } else
  5864.             return new FileStream(m_data.outputFilename);
  5865.     }
  5866.  
  5867. } // end namespace Catch
  5868.   // end catch_config.cpp
  5869.   // start catch_console_colour.cpp
  5870.  
  5871. #if defined(__clang__)
  5872. #    pragma clang diagnostic push
  5873. #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  5874. #endif
  5875.  
  5876.   // start catch_errno_guard.h
  5877.  
  5878. namespace Catch {
  5879.  
  5880.     class ErrnoGuard {
  5881.     public:
  5882.         ErrnoGuard();
  5883.         ~ErrnoGuard();
  5884.     private:
  5885.         int m_oldErrno;
  5886.     };
  5887.  
  5888. }
  5889.  
  5890. // end catch_errno_guard.h
  5891. // start catch_windows_h_proxy.h
  5892.  
  5893.  
  5894. #if defined(CATCH_PLATFORM_WINDOWS)
  5895.  
  5896. #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
  5897. #  define CATCH_DEFINED_NOMINMAX
  5898. #  define NOMINMAX
  5899. #endif
  5900. #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
  5901. #  define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
  5902. #  define WIN32_LEAN_AND_MEAN
  5903. #endif
  5904.  
  5905. #ifdef __AFXDLL
  5906. #include <AfxWin.h>
  5907. #else
  5908. #include <windows.h>
  5909. #endif
  5910.  
  5911. #ifdef CATCH_DEFINED_NOMINMAX
  5912. #  undef NOMINMAX
  5913. #endif
  5914. #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
  5915. #  undef WIN32_LEAN_AND_MEAN
  5916. #endif
  5917.  
  5918. #endif // defined(CATCH_PLATFORM_WINDOWS)
  5919.  
  5920. // end catch_windows_h_proxy.h
  5921. namespace Catch {
  5922.     namespace {
  5923.  
  5924.         struct IColourImpl {
  5925.             virtual ~IColourImpl() = default;
  5926.             virtual void use(Colour::Code _colourCode) = 0;
  5927.         };
  5928.  
  5929.         struct NoColourImpl : IColourImpl {
  5930.             void use(Colour::Code) {}
  5931.  
  5932.             static IColourImpl* instance() {
  5933.                 static NoColourImpl s_instance;
  5934.                 return &s_instance;
  5935.             }
  5936.         };
  5937.  
  5938.     } // anon namespace
  5939. } // namespace Catch
  5940.  
  5941. #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
  5942. #   ifdef CATCH_PLATFORM_WINDOWS
  5943. #       define CATCH_CONFIG_COLOUR_WINDOWS
  5944. #   else
  5945. #       define CATCH_CONFIG_COLOUR_ANSI
  5946. #   endif
  5947. #endif
  5948.  
  5949. #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
  5950.  
  5951. namespace Catch {
  5952.     namespace {
  5953.  
  5954.         class Win32ColourImpl : public IColourImpl {
  5955.         public:
  5956.             Win32ColourImpl() : stdoutHandle(GetStdHandle(STD_OUTPUT_HANDLE)) {
  5957.                 CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
  5958.                 GetConsoleScreenBufferInfo(stdoutHandle, &csbiInfo);
  5959.                 originalForegroundAttributes = csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY);
  5960.                 originalBackgroundAttributes = csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
  5961.             }
  5962.  
  5963.             virtual void use(Colour::Code _colourCode) override {
  5964.                 switch (_colourCode) {
  5965.                     case Colour::None:      return setTextAttribute(originalForegroundAttributes);
  5966.                     case Colour::White:     return setTextAttribute(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
  5967.                     case Colour::Red:       return setTextAttribute(FOREGROUND_RED);
  5968.                     case Colour::Green:     return setTextAttribute(FOREGROUND_GREEN);
  5969.                     case Colour::Blue:      return setTextAttribute(FOREGROUND_BLUE);
  5970.                     case Colour::Cyan:      return setTextAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN);
  5971.                     case Colour::Yellow:    return setTextAttribute(FOREGROUND_RED | FOREGROUND_GREEN);
  5972.                     case Colour::Grey:      return setTextAttribute(0);
  5973.  
  5974.                     case Colour::LightGrey:     return setTextAttribute(FOREGROUND_INTENSITY);
  5975.                     case Colour::BrightRed:     return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_RED);
  5976.                     case Colour::BrightGreen:   return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_GREEN);
  5977.                     case Colour::BrightWhite:   return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
  5978.  
  5979.                     case Colour::Bright: CATCH_INTERNAL_ERROR("not a colour");
  5980.                 }
  5981.             }
  5982.  
  5983.         private:
  5984.             void setTextAttribute(WORD _textAttribute) {
  5985.                 SetConsoleTextAttribute(stdoutHandle, _textAttribute | originalBackgroundAttributes);
  5986.             }
  5987.             HANDLE stdoutHandle;
  5988.             WORD originalForegroundAttributes;
  5989.             WORD originalBackgroundAttributes;
  5990.         };
  5991.  
  5992.         IColourImpl* platformColourInstance() {
  5993.             static Win32ColourImpl s_instance;
  5994.  
  5995.             IConfigPtr config = getCurrentContext().getConfig();
  5996.             UseColour::YesOrNo colourMode = config
  5997.                 ? config->useColour()
  5998.                 : UseColour::Auto;
  5999.             if (colourMode == UseColour::Auto)
  6000.                 colourMode = UseColour::Yes;
  6001.             return colourMode == UseColour::Yes
  6002.                 ? &s_instance
  6003.                 : NoColourImpl::instance();
  6004.         }
  6005.  
  6006.     } // end anon namespace
  6007. } // end namespace Catch
  6008.  
  6009. #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
  6010.  
  6011. #include <unistd.h>
  6012.  
  6013. namespace Catch {
  6014.     namespace {
  6015.  
  6016.         // use POSIX/ ANSI console terminal codes
  6017.         // Thanks to Adam Strzelecki for original contribution
  6018.         // (http://github.com/nanoant)
  6019.         // https://github.com/philsquared/Catch/pull/131
  6020.         class PosixColourImpl : public IColourImpl {
  6021.         public:
  6022.             virtual void use(Colour::Code _colourCode) override {
  6023.                 switch (_colourCode) {
  6024.                     case Colour::None:
  6025.                     case Colour::White:     return setColour("[0m");
  6026.                     case Colour::Red:       return setColour("[0;31m");
  6027.                     case Colour::Green:     return setColour("[0;32m");
  6028.                     case Colour::Blue:      return setColour("[0;34m");
  6029.                     case Colour::Cyan:      return setColour("[0;36m");
  6030.                     case Colour::Yellow:    return setColour("[0;33m");
  6031.                     case Colour::Grey:      return setColour("[1;30m");
  6032.  
  6033.                     case Colour::LightGrey:     return setColour("[0;37m");
  6034.                     case Colour::BrightRed:     return setColour("[1;31m");
  6035.                     case Colour::BrightGreen:   return setColour("[1;32m");
  6036.                     case Colour::BrightWhite:   return setColour("[1;37m");
  6037.  
  6038.                     case Colour::Bright: CATCH_INTERNAL_ERROR("not a colour");
  6039.                 }
  6040.             }
  6041.             static IColourImpl* instance() {
  6042.                 static PosixColourImpl s_instance;
  6043.                 return &s_instance;
  6044.             }
  6045.  
  6046.         private:
  6047.             void setColour(const char* _escapeCode) {
  6048.                 Catch::cout() << '\033' << _escapeCode;
  6049.             }
  6050.         };
  6051.  
  6052.         bool useColourOnPlatform() {
  6053.             return
  6054. #ifdef CATCH_PLATFORM_MAC
  6055.                 !isDebuggerActive() &&
  6056. #endif
  6057.                 isatty(STDOUT_FILENO);
  6058.         }
  6059.         IColourImpl* platformColourInstance() {
  6060.             ErrnoGuard guard;
  6061.             IConfigPtr config = getCurrentContext().getConfig();
  6062.             UseColour::YesOrNo colourMode = config
  6063.                 ? config->useColour()
  6064.                 : UseColour::Auto;
  6065.             if (colourMode == UseColour::Auto)
  6066.                 colourMode = useColourOnPlatform()
  6067.                 ? UseColour::Yes
  6068.                 : UseColour::No;
  6069.             return colourMode == UseColour::Yes
  6070.                 ? PosixColourImpl::instance()
  6071.                 : NoColourImpl::instance();
  6072.         }
  6073.  
  6074.     } // end anon namespace
  6075. } // end namespace Catch
  6076.  
  6077. #else  // not Windows or ANSI ///////////////////////////////////////////////
  6078.  
  6079. namespace Catch {
  6080.  
  6081.     static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
  6082.  
  6083. } // end namespace Catch
  6084.  
  6085. #endif // Windows/ ANSI/ None
  6086.  
  6087. namespace Catch {
  6088.  
  6089.     Colour::Colour(Code _colourCode) { use(_colourCode); }
  6090.     Colour::Colour(Colour&& rhs) noexcept {
  6091.         m_moved = rhs.m_moved;
  6092.         rhs.m_moved = true;
  6093.     }
  6094.     Colour& Colour::operator=(Colour&& rhs) noexcept {
  6095.         m_moved = rhs.m_moved;
  6096.         rhs.m_moved = true;
  6097.         return *this;
  6098.     }
  6099.  
  6100.     Colour::~Colour() { if (!m_moved) use(None); }
  6101.  
  6102.     void Colour::use(Code _colourCode) {
  6103.         static IColourImpl* impl = platformColourInstance();
  6104.         impl->use(_colourCode);
  6105.     }
  6106.  
  6107.     std::ostream& operator << (std::ostream& os, Colour const&) {
  6108.         return os;
  6109.     }
  6110.  
  6111. } // end namespace Catch
  6112.  
  6113. #if defined(__clang__)
  6114. #    pragma clang diagnostic pop
  6115. #endif
  6116.  
  6117.   // end catch_console_colour.cpp
  6118.   // start catch_context.cpp
  6119.  
  6120. namespace Catch {
  6121.  
  6122.     class Context : public IMutableContext, NonCopyable {
  6123.  
  6124.     public: // IContext
  6125.         virtual IResultCapture* getResultCapture() override {
  6126.             return m_resultCapture;
  6127.         }
  6128.         virtual IRunner* getRunner() override {
  6129.             return m_runner;
  6130.         }
  6131.  
  6132.         virtual IConfigPtr getConfig() const override {
  6133.             return m_config;
  6134.         }
  6135.  
  6136.         virtual ~Context() override;
  6137.  
  6138.     public: // IMutableContext
  6139.         virtual void setResultCapture(IResultCapture* resultCapture) override {
  6140.             m_resultCapture = resultCapture;
  6141.         }
  6142.         virtual void setRunner(IRunner* runner) override {
  6143.             m_runner = runner;
  6144.         }
  6145.         virtual void setConfig(IConfigPtr const& config) override {
  6146.             m_config = config;
  6147.         }
  6148.  
  6149.         friend IMutableContext& getCurrentMutableContext();
  6150.  
  6151.     private:
  6152.         IConfigPtr m_config;
  6153.         IRunner* m_runner = nullptr;
  6154.         IResultCapture* m_resultCapture = nullptr;
  6155.     };
  6156.  
  6157.     namespace {
  6158.         Context* currentContext = nullptr;
  6159.     }
  6160.     IMutableContext& getCurrentMutableContext() {
  6161.         if (!currentContext)
  6162.             currentContext = new Context();
  6163.         return *currentContext;
  6164.     }
  6165.     IContext& getCurrentContext() {
  6166.         return getCurrentMutableContext();
  6167.     }
  6168.  
  6169.     void cleanUpContext() {
  6170.         delete currentContext;
  6171.         currentContext = nullptr;
  6172.     }
  6173.     IContext::~IContext() = default;
  6174.     IMutableContext::~IMutableContext() = default;
  6175.     Context::~Context() = default;
  6176. }
  6177. // end catch_context.cpp
  6178. // start catch_debug_console.cpp
  6179.  
  6180. // start catch_debug_console.h
  6181.  
  6182. #include <string>
  6183.  
  6184. namespace Catch {
  6185.     void writeToDebugConsole(std::string const& text);
  6186. }
  6187.  
  6188. // end catch_debug_console.h
  6189. #ifdef CATCH_PLATFORM_WINDOWS
  6190.  
  6191. namespace Catch {
  6192.     void writeToDebugConsole(std::string const& text) {
  6193.         ::OutputDebugStringA(text.c_str());
  6194.     }
  6195. }
  6196. #else
  6197. namespace Catch {
  6198.     void writeToDebugConsole(std::string const& text) {
  6199.         // !TBD: Need a version for Mac/ XCode and other IDEs
  6200.         Catch::cout() << text;
  6201.     }
  6202. }
  6203. #endif // Platform
  6204. // end catch_debug_console.cpp
  6205. // start catch_debugger.cpp
  6206.  
  6207. #ifdef CATCH_PLATFORM_MAC
  6208.  
  6209. #include <assert.h>
  6210. #include <stdbool.h>
  6211. #include <sys/types.h>
  6212. #include <unistd.h>
  6213. #include <sys/sysctl.h>
  6214.  
  6215. namespace Catch {
  6216.  
  6217.     // The following function is taken directly from the following technical note:
  6218.     // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
  6219.  
  6220.     // Returns true if the current process is being debugged (either
  6221.     // running under the debugger or has a debugger attached post facto).
  6222.     bool isDebuggerActive() {
  6223.  
  6224.         int                 mib[4];
  6225.         struct kinfo_proc   info;
  6226.         std::size_t         size;
  6227.  
  6228.         // Initialize the flags so that, if sysctl fails for some bizarre
  6229.         // reason, we get a predictable result.
  6230.  
  6231.         info.kp_proc.p_flag = 0;
  6232.  
  6233.         // Initialize mib, which tells sysctl the info we want, in this case
  6234.         // we're looking for information about a specific process ID.
  6235.  
  6236.         mib[0] = CTL_KERN;
  6237.         mib[1] = KERN_PROC;
  6238.         mib[2] = KERN_PROC_PID;
  6239.         mib[3] = getpid();
  6240.  
  6241.         // Call sysctl.
  6242.  
  6243.         size = sizeof(info);
  6244.         if (sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0) {
  6245.             Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
  6246.             return false;
  6247.         }
  6248.  
  6249.         // We're being debugged if the P_TRACED flag is set.
  6250.  
  6251.         return ((info.kp_proc.p_flag & P_TRACED) != 0);
  6252.     }
  6253. } // namespace Catch
  6254.  
  6255. #elif defined(CATCH_PLATFORM_LINUX)
  6256. #include <fstream>
  6257. #include <string>
  6258.  
  6259. namespace Catch {
  6260.     // The standard POSIX way of detecting a debugger is to attempt to
  6261.     // ptrace() the process, but this needs to be done from a child and not
  6262.     // this process itself to still allow attaching to this process later
  6263.     // if wanted, so is rather heavy. Under Linux we have the PID of the
  6264.     // "debugger" (which doesn't need to be gdb, of course, it could also
  6265.     // be strace, for example) in /proc/$PID/status, so just get it from
  6266.     // there instead.
  6267.     bool isDebuggerActive() {
  6268.         // Libstdc++ has a bug, where std::ifstream sets errno to 0
  6269.         // This way our users can properly assert over errno values
  6270.         ErrnoGuard guard;
  6271.         std::ifstream in("/proc/self/status");
  6272.         for (std::string line; std::getline(in, line); ) {
  6273.             static const int PREFIX_LEN = 11;
  6274.             if (line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0) {
  6275.                 // We're traced if the PID is not 0 and no other PID starts
  6276.                 // with 0 digit, so it's enough to check for just a single
  6277.                 // character.
  6278.                 return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
  6279.             }
  6280.         }
  6281.  
  6282.         return false;
  6283.     }
  6284. } // namespace Catch
  6285. #elif defined(_MSC_VER)
  6286. extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  6287. namespace Catch {
  6288.     bool isDebuggerActive() {
  6289.         return IsDebuggerPresent() != 0;
  6290.     }
  6291. }
  6292. #elif defined(__MINGW32__)
  6293. extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  6294. namespace Catch {
  6295.     bool isDebuggerActive() {
  6296.         return IsDebuggerPresent() != 0;
  6297.     }
  6298. }
  6299. #else
  6300. namespace Catch {
  6301.     bool isDebuggerActive() { return false; }
  6302. }
  6303. #endif // Platform
  6304. // end catch_debugger.cpp
  6305. // start catch_decomposer.cpp
  6306.  
  6307. namespace Catch {
  6308.  
  6309.     ITransientExpression::~ITransientExpression() = default;
  6310.  
  6311.     void formatReconstructedExpression(std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs) {
  6312.         if (lhs.size() + rhs.size() < 40 &&
  6313.             lhs.find('\n') == std::string::npos &&
  6314.             rhs.find('\n') == std::string::npos)
  6315.             os << lhs << " " << op << " " << rhs;
  6316.         else
  6317.             os << lhs << "\n" << op << "\n" << rhs;
  6318.     }
  6319. }
  6320. // end catch_decomposer.cpp
  6321. // start catch_errno_guard.cpp
  6322.  
  6323. #include <cerrno>
  6324.  
  6325. namespace Catch {
  6326.     ErrnoGuard::ErrnoGuard() :m_oldErrno(errno) {}
  6327.     ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
  6328. }
  6329. // end catch_errno_guard.cpp
  6330. // start catch_exception_translator_registry.cpp
  6331.  
  6332. // start catch_exception_translator_registry.h
  6333.  
  6334. #include <vector>
  6335. #include <string>
  6336. #include <memory>
  6337.  
  6338. namespace Catch {
  6339.  
  6340.     class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
  6341.     public:
  6342.         ~ExceptionTranslatorRegistry();
  6343.         virtual void registerTranslator(const IExceptionTranslator* translator);
  6344.         virtual std::string translateActiveException() const override;
  6345.         std::string tryTranslators() const;
  6346.  
  6347.     private:
  6348.         std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
  6349.     };
  6350. }
  6351.  
  6352. // end catch_exception_translator_registry.h
  6353. #ifdef __OBJC__
  6354. #import "Foundation/Foundation.h"
  6355. #endif
  6356.  
  6357. namespace Catch {
  6358.  
  6359.     ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
  6360.     }
  6361.  
  6362.     void ExceptionTranslatorRegistry::registerTranslator(const IExceptionTranslator* translator) {
  6363.         m_translators.push_back(std::unique_ptr<const IExceptionTranslator>(translator));
  6364.     }
  6365.  
  6366.     std::string ExceptionTranslatorRegistry::translateActiveException() const {
  6367.         try {
  6368. #ifdef __OBJC__
  6369.             // In Objective-C try objective-c exceptions first
  6370.             @try {
  6371.                 return tryTranslators();
  6372.             }
  6373.             @catch (NSException *exception) {
  6374.                 return Catch::Detail::stringify([exception description]);
  6375.             }
  6376. #else
  6377.             return tryTranslators();
  6378. #endif
  6379.         } catch (TestFailureException&) {
  6380.             std::rethrow_exception(std::current_exception());
  6381.         } catch (std::exception& ex) {
  6382.             return ex.what();
  6383.         } catch (std::string& msg) {
  6384.             return msg;
  6385.         } catch (const char* msg) {
  6386.             return msg;
  6387.         } catch (...) {
  6388.             return "Unknown exception";
  6389.         }
  6390.     }
  6391.  
  6392.     std::string ExceptionTranslatorRegistry::tryTranslators() const {
  6393.         if (m_translators.empty())
  6394.             std::rethrow_exception(std::current_exception());
  6395.         else
  6396.             return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
  6397.     }
  6398. }
  6399. // end catch_exception_translator_registry.cpp
  6400. // start catch_fatal_condition.cpp
  6401.  
  6402. // start catch_fatal_condition.h
  6403.  
  6404. #include <string>
  6405.  
  6406. #if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
  6407.  
  6408. #  if !defined ( CATCH_CONFIG_WINDOWS_SEH )
  6409.  
  6410. namespace Catch {
  6411.     struct FatalConditionHandler {
  6412.         void reset();
  6413.     };
  6414. }
  6415.  
  6416. #  else // CATCH_CONFIG_WINDOWS_SEH is defined
  6417.  
  6418. namespace Catch {
  6419.  
  6420.     struct FatalConditionHandler {
  6421.  
  6422.         static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
  6423.         FatalConditionHandler();
  6424.         static void reset();
  6425.         ~FatalConditionHandler();
  6426.  
  6427.     private:
  6428.         static bool isSet;
  6429.         static ULONG guaranteeSize;
  6430.         static PVOID exceptionHandlerHandle;
  6431.     };
  6432.  
  6433. } // namespace Catch
  6434.  
  6435. #  endif // CATCH_CONFIG_WINDOWS_SEH
  6436.  
  6437. #else // Not Windows - assumed to be POSIX compatible //////////////////////////
  6438.  
  6439. #  if !defined(CATCH_CONFIG_POSIX_SIGNALS)
  6440.  
  6441. namespace Catch {
  6442.     struct FatalConditionHandler {
  6443.         void reset();
  6444.     };
  6445. }
  6446.  
  6447. #  else // CATCH_CONFIG_POSIX_SIGNALS is defined
  6448.  
  6449. #include <signal.h>
  6450.  
  6451. namespace Catch {
  6452.  
  6453.     struct FatalConditionHandler {
  6454.  
  6455.         static bool isSet;
  6456.         static struct sigaction oldSigActions[];// [sizeof(signalDefs) / sizeof(SignalDefs)];
  6457.         static stack_t oldSigStack;
  6458.         static char altStackMem[];
  6459.  
  6460.         static void handleSignal(int sig);
  6461.  
  6462.         FatalConditionHandler();
  6463.         ~FatalConditionHandler();
  6464.         static void reset();
  6465.     };
  6466.  
  6467. } // namespace Catch
  6468.  
  6469. #  endif // CATCH_CONFIG_POSIX_SIGNALS
  6470.  
  6471. #endif // not Windows
  6472.  
  6473.   // end catch_fatal_condition.h
  6474. namespace {
  6475.     // Report the error condition
  6476.     void reportFatal(char const * const message) {
  6477.         Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition(message);
  6478.     }
  6479. }
  6480.  
  6481. #if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
  6482.  
  6483. #  if !defined ( CATCH_CONFIG_WINDOWS_SEH )
  6484.  
  6485. namespace Catch {
  6486.     void FatalConditionHandler::reset() {}
  6487. }
  6488.  
  6489. #  else // CATCH_CONFIG_WINDOWS_SEH is defined
  6490.  
  6491. namespace Catch {
  6492.     struct SignalDefs { DWORD id; const char* name; };
  6493.  
  6494.     // There is no 1-1 mapping between signals and windows exceptions.
  6495.     // Windows can easily distinguish between SO and SigSegV,
  6496.     // but SigInt, SigTerm, etc are handled differently.
  6497.     static SignalDefs signalDefs[] = {
  6498.         { EXCEPTION_ILLEGAL_INSTRUCTION,  "SIGILL - Illegal instruction signal" },
  6499.         { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
  6500.         { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
  6501.         { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
  6502.     };
  6503.  
  6504.     LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
  6505.         for (auto const& def : signalDefs) {
  6506.             if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
  6507.                 reportFatal(def.name);
  6508.             }
  6509.         }
  6510.         // If its not an exception we care about, pass it along.
  6511.         // This stops us from eating debugger breaks etc.
  6512.         return EXCEPTION_CONTINUE_SEARCH;
  6513.     }
  6514.  
  6515.     FatalConditionHandler::FatalConditionHandler() {
  6516.         isSet = true;
  6517.         // 32k seems enough for Catch to handle stack overflow,
  6518.         // but the value was found experimentally, so there is no strong guarantee
  6519.         guaranteeSize = 32 * 1024;
  6520.         exceptionHandlerHandle = nullptr;
  6521.         // Register as first handler in current chain
  6522.         exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
  6523.         // Pass in guarantee size to be filled
  6524.         SetThreadStackGuarantee(&guaranteeSize);
  6525.     }
  6526.  
  6527.     void FatalConditionHandler::reset() {
  6528.         if (isSet) {
  6529.             // Unregister handler and restore the old guarantee
  6530.             RemoveVectoredExceptionHandler(exceptionHandlerHandle);
  6531.             SetThreadStackGuarantee(&guaranteeSize);
  6532.             exceptionHandlerHandle = nullptr;
  6533.             isSet = false;
  6534.         }
  6535.     }
  6536.  
  6537.     FatalConditionHandler::~FatalConditionHandler() {
  6538.         reset();
  6539.     }
  6540.  
  6541.     bool FatalConditionHandler::isSet = false;
  6542.     ULONG FatalConditionHandler::guaranteeSize = 0;
  6543.     PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
  6544.  
  6545. } // namespace Catch
  6546.  
  6547. #  endif // CATCH_CONFIG_WINDOWS_SEH
  6548.  
  6549. #else // Not Windows - assumed to be POSIX compatible //////////////////////////
  6550.  
  6551. #  if !defined(CATCH_CONFIG_POSIX_SIGNALS)
  6552.  
  6553. namespace Catch {
  6554.     void FatalConditionHandler::reset() {}
  6555. }
  6556.  
  6557. #  else // CATCH_CONFIG_POSIX_SIGNALS is defined
  6558.  
  6559. #include <signal.h>
  6560.  
  6561. namespace Catch {
  6562.  
  6563.     struct SignalDefs {
  6564.         int id;
  6565.         const char* name;
  6566.     };
  6567.     static SignalDefs signalDefs[] = {
  6568.         { SIGINT,  "SIGINT - Terminal interrupt signal" },
  6569.         { SIGILL,  "SIGILL - Illegal instruction signal" },
  6570.         { SIGFPE,  "SIGFPE - Floating point error signal" },
  6571.         { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
  6572.         { SIGTERM, "SIGTERM - Termination request signal" },
  6573.         { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
  6574.     };
  6575.  
  6576.     void FatalConditionHandler::handleSignal(int sig) {
  6577.         char const * name = "<unknown signal>";
  6578.         for (auto const& def : signalDefs) {
  6579.             if (sig == def.id) {
  6580.                 name = def.name;
  6581.                 break;
  6582.             }
  6583.         }
  6584.         reset();
  6585.         reportFatal(name);
  6586.         raise(sig);
  6587.     }
  6588.  
  6589.     FatalConditionHandler::FatalConditionHandler() {
  6590.         isSet = true;
  6591.         stack_t sigStack;
  6592.         sigStack.ss_sp = altStackMem;
  6593.         sigStack.ss_size = SIGSTKSZ;
  6594.         sigStack.ss_flags = 0;
  6595.         sigaltstack(&sigStack, &oldSigStack);
  6596.         struct sigaction sa = {};
  6597.  
  6598.         sa.sa_handler = handleSignal;
  6599.         sa.sa_flags = SA_ONSTACK;
  6600.         for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
  6601.             sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
  6602.         }
  6603.     }
  6604.  
  6605.     FatalConditionHandler::~FatalConditionHandler() {
  6606.         reset();
  6607.     }
  6608.  
  6609.     void FatalConditionHandler::reset() {
  6610.         if (isSet) {
  6611.             // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
  6612.             for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
  6613.                 sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
  6614.             }
  6615.             // Return the old stack
  6616.             sigaltstack(&oldSigStack, nullptr);
  6617.             isSet = false;
  6618.         }
  6619.     }
  6620.  
  6621.     bool FatalConditionHandler::isSet = false;
  6622.     struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)] = {};
  6623.     stack_t FatalConditionHandler::oldSigStack = {};
  6624.     char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
  6625.  
  6626. } // namespace Catch
  6627.  
  6628. #  endif // CATCH_CONFIG_POSIX_SIGNALS
  6629.  
  6630. #endif // not Windows
  6631.   // end catch_fatal_condition.cpp
  6632.   // start catch_interfaces_capture.cpp
  6633.  
  6634. namespace Catch {
  6635.     IResultCapture::~IResultCapture() = default;
  6636. }
  6637. // end catch_interfaces_capture.cpp
  6638. // start catch_interfaces_config.cpp
  6639.  
  6640. namespace Catch {
  6641.     IConfig::~IConfig() = default;
  6642. }
  6643. // end catch_interfaces_config.cpp
  6644. // start catch_interfaces_exception.cpp
  6645.  
  6646. namespace Catch {
  6647.     IExceptionTranslator::~IExceptionTranslator() = default;
  6648.     IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
  6649. }
  6650. // end catch_interfaces_exception.cpp
  6651. // start catch_interfaces_registry_hub.cpp
  6652.  
  6653. namespace Catch {
  6654.     IRegistryHub::~IRegistryHub() = default;
  6655.     IMutableRegistryHub::~IMutableRegistryHub() = default;
  6656. }
  6657. // end catch_interfaces_registry_hub.cpp
  6658. // start catch_interfaces_reporter.cpp
  6659.  
  6660. // start catch_reporter_multi.h
  6661.  
  6662. namespace Catch {
  6663.  
  6664.     class MultipleReporters : public IStreamingReporter {
  6665.         using Reporters = std::vector<IStreamingReporterPtr>;
  6666.         Reporters m_reporters;
  6667.  
  6668.     public:
  6669.         void add(IStreamingReporterPtr&& reporter);
  6670.  
  6671.     public: // IStreamingReporter
  6672.  
  6673.         ReporterPreferences getPreferences() const override;
  6674.  
  6675.         void noMatchingTestCases(std::string const& spec) override;
  6676.  
  6677.         static std::set<Verbosity> getSupportedVerbosities();
  6678.  
  6679.         void benchmarkStarting(BenchmarkInfo const& benchmarkInfo) override;
  6680.         void benchmarkEnded(BenchmarkStats const& benchmarkStats) override;
  6681.  
  6682.         void testRunStarting(TestRunInfo const& testRunInfo) override;
  6683.         void testGroupStarting(GroupInfo const& groupInfo) override;
  6684.         void testCaseStarting(TestCaseInfo const& testInfo) override;
  6685.         void sectionStarting(SectionInfo const& sectionInfo) override;
  6686.         void assertionStarting(AssertionInfo const& assertionInfo) override;
  6687.  
  6688.         // The return value indicates if the messages buffer should be cleared:
  6689.         bool assertionEnded(AssertionStats const& assertionStats) override;
  6690.         void sectionEnded(SectionStats const& sectionStats) override;
  6691.         void testCaseEnded(TestCaseStats const& testCaseStats) override;
  6692.         void testGroupEnded(TestGroupStats const& testGroupStats) override;
  6693.         void testRunEnded(TestRunStats const& testRunStats) override;
  6694.  
  6695.         void skipTest(TestCaseInfo const& testInfo) override;
  6696.         bool isMulti() const override;
  6697.  
  6698.     };
  6699.  
  6700. } // end namespace Catch
  6701.  
  6702.   // end catch_reporter_multi.h
  6703. namespace Catch {
  6704.  
  6705.     ReporterConfig::ReporterConfig(IConfigPtr const& _fullConfig)
  6706.         : m_stream(&_fullConfig->stream()), m_fullConfig(_fullConfig) {}
  6707.  
  6708.     ReporterConfig::ReporterConfig(IConfigPtr const& _fullConfig, std::ostream& _stream)
  6709.         : m_stream(&_stream), m_fullConfig(_fullConfig) {}
  6710.  
  6711.     std::ostream& ReporterConfig::stream() const { return *m_stream; }
  6712.     IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
  6713.  
  6714.     TestRunInfo::TestRunInfo(std::string const& _name) : name(_name) {}
  6715.  
  6716.     GroupInfo::GroupInfo(std::string const& _name,
  6717.                          std::size_t _groupIndex,
  6718.                          std::size_t _groupsCount)
  6719.         : name(_name),
  6720.         groupIndex(_groupIndex),
  6721.         groupsCounts(_groupsCount) {
  6722.     }
  6723.  
  6724.     AssertionStats::AssertionStats(AssertionResult const& _assertionResult,
  6725.                                    std::vector<MessageInfo> const& _infoMessages,
  6726.                                    Totals const& _totals)
  6727.         : assertionResult(_assertionResult),
  6728.         infoMessages(_infoMessages),
  6729.         totals(_totals) {
  6730.         assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
  6731.  
  6732.         if (assertionResult.hasMessage()) {
  6733.             // Copy message into messages list.
  6734.             // !TBD This should have been done earlier, somewhere
  6735.             MessageBuilder builder(assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType());
  6736.             builder << assertionResult.getMessage();
  6737.             builder.m_info.message = builder.m_stream.str();
  6738.  
  6739.             infoMessages.push_back(builder.m_info);
  6740.         }
  6741.     }
  6742.  
  6743.     AssertionStats::~AssertionStats() = default;
  6744.  
  6745.     SectionStats::SectionStats(SectionInfo const& _sectionInfo,
  6746.                                Counts const& _assertions,
  6747.                                double _durationInSeconds,
  6748.                                bool _missingAssertions)
  6749.         : sectionInfo(_sectionInfo),
  6750.         assertions(_assertions),
  6751.         durationInSeconds(_durationInSeconds),
  6752.         missingAssertions(_missingAssertions) {
  6753.     }
  6754.  
  6755.     SectionStats::~SectionStats() = default;
  6756.  
  6757.     TestCaseStats::TestCaseStats(TestCaseInfo const& _testInfo,
  6758.                                  Totals const& _totals,
  6759.                                  std::string const& _stdOut,
  6760.                                  std::string const& _stdErr,
  6761.                                  bool _aborting)
  6762.         : testInfo(_testInfo),
  6763.         totals(_totals),
  6764.         stdOut(_stdOut),
  6765.         stdErr(_stdErr),
  6766.         aborting(_aborting) {
  6767.     }
  6768.  
  6769.     TestCaseStats::~TestCaseStats() = default;
  6770.  
  6771.     TestGroupStats::TestGroupStats(GroupInfo const& _groupInfo,
  6772.                                    Totals const& _totals,
  6773.                                    bool _aborting)
  6774.         : groupInfo(_groupInfo),
  6775.         totals(_totals),
  6776.         aborting(_aborting) {
  6777.     }
  6778.  
  6779.     TestGroupStats::TestGroupStats(GroupInfo const& _groupInfo)
  6780.         : groupInfo(_groupInfo),
  6781.         aborting(false) {
  6782.     }
  6783.  
  6784.     TestGroupStats::~TestGroupStats() = default;
  6785.  
  6786.     TestRunStats::TestRunStats(TestRunInfo const& _runInfo,
  6787.                                Totals const& _totals,
  6788.                                bool _aborting)
  6789.         : runInfo(_runInfo),
  6790.         totals(_totals),
  6791.         aborting(_aborting) {
  6792.     }
  6793.  
  6794.     TestRunStats::~TestRunStats() = default;
  6795.  
  6796.     void IStreamingReporter::fatalErrorEncountered(StringRef) {}
  6797.     bool IStreamingReporter::isMulti() const { return false; }
  6798.  
  6799.     IReporterFactory::~IReporterFactory() = default;
  6800.     IReporterRegistry::~IReporterRegistry() = default;
  6801.  
  6802.     void addReporter(IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter) {
  6803.  
  6804.         if (!existingReporter) {
  6805.             existingReporter = std::move(additionalReporter);
  6806.             return;
  6807.         }
  6808.  
  6809.         MultipleReporters* multi = nullptr;
  6810.  
  6811.         if (existingReporter->isMulti()) {
  6812.             multi = static_cast<MultipleReporters*>(existingReporter.get());
  6813.         } else {
  6814.             auto newMulti = std::unique_ptr<MultipleReporters>(new MultipleReporters);
  6815.             newMulti->add(std::move(existingReporter));
  6816.             multi = newMulti.get();
  6817.             existingReporter = std::move(newMulti);
  6818.         }
  6819.         multi->add(std::move(additionalReporter));
  6820.     }
  6821.  
  6822. } // end namespace Catch
  6823.   // end catch_interfaces_reporter.cpp
  6824.   // start catch_interfaces_runner.cpp
  6825.  
  6826. namespace Catch {
  6827.     IRunner::~IRunner() = default;
  6828. }
  6829. // end catch_interfaces_runner.cpp
  6830. // start catch_interfaces_testcase.cpp
  6831.  
  6832. namespace Catch {
  6833.     ITestInvoker::~ITestInvoker() = default;
  6834.     ITestCaseRegistry::~ITestCaseRegistry() = default;
  6835. }
  6836. // end catch_interfaces_testcase.cpp
  6837. // start catch_leak_detector.cpp
  6838.  
  6839. namespace Catch {
  6840.  
  6841. #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
  6842. #include <crtdbg.h>
  6843.  
  6844.     LeakDetector::LeakDetector() {
  6845.         int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  6846.         flag |= _CRTDBG_LEAK_CHECK_DF;
  6847.         flag |= _CRTDBG_ALLOC_MEM_DF;
  6848.         _CrtSetDbgFlag(flag);
  6849.         _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
  6850.         _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  6851.         // Change this to leaking allocation's number to break there
  6852.         _CrtSetBreakAlloc(-1);
  6853.     }
  6854.  
  6855. #else
  6856.  
  6857.     LeakDetector::LeakDetector() {}
  6858.  
  6859. #endif
  6860.  
  6861. }
  6862. // end catch_leak_detector.cpp
  6863. // start catch_list.cpp
  6864.  
  6865. // start catch_list.h
  6866.  
  6867. #include <set>
  6868.  
  6869. namespace Catch {
  6870.  
  6871.     std::size_t listTests(Config const& config);
  6872.  
  6873.     std::size_t listTestsNamesOnly(Config const& config);
  6874.  
  6875.     struct TagInfo {
  6876.         void add(std::string const& spelling);
  6877.         std::string all() const;
  6878.  
  6879.         std::set<std::string> spellings;
  6880.         std::size_t count = 0;
  6881.     };
  6882.  
  6883.     std::size_t listTags(Config const& config);
  6884.  
  6885.     std::size_t listReporters(Config const& /*config*/);
  6886.  
  6887.     Option<std::size_t> list(Config const& config);
  6888.  
  6889. } // end namespace Catch
  6890.  
  6891.   // end catch_list.h
  6892.   // start catch_text.h
  6893.  
  6894. namespace Catch {
  6895.     using namespace clara::TextFlow;
  6896. }
  6897.  
  6898. // end catch_text.h
  6899. #include <limits>
  6900. #include <algorithm>
  6901. #include <iomanip>
  6902.  
  6903. namespace Catch {
  6904.  
  6905.     std::size_t listTests(Config const& config) {
  6906.         TestSpec testSpec = config.testSpec();
  6907.         if (config.testSpec().hasFilters())
  6908.             Catch::cout() << "Matching test cases:\n";
  6909.         else {
  6910.             Catch::cout() << "All available test cases:\n";
  6911.             testSpec = TestSpecParser(ITagAliasRegistry::get()).parse("*").testSpec();
  6912.         }
  6913.  
  6914.         auto matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config);
  6915.         for (auto const& testCaseInfo : matchedTestCases) {
  6916.             Colour::Code colour = testCaseInfo.isHidden()
  6917.                 ? Colour::SecondaryText
  6918.                 : Colour::None;
  6919.             Colour colourGuard(colour);
  6920.  
  6921.             Catch::cout() << Column(testCaseInfo.name).initialIndent(2).indent(4) << "\n";
  6922.             if (config.verbosity() >= Verbosity::High) {
  6923.                 Catch::cout() << Column(Catch::Detail::stringify(testCaseInfo.lineInfo)).indent(4) << std::endl;
  6924.                 std::string description = testCaseInfo.description;
  6925.                 if (description.empty())
  6926.                     description = "(NO DESCRIPTION)";
  6927.                 Catch::cout() << Column(description).indent(4) << std::endl;
  6928.             }
  6929.             if (!testCaseInfo.tags.empty())
  6930.                 Catch::cout() << Column(testCaseInfo.tagsAsString()).indent(6) << "\n";
  6931.         }
  6932.  
  6933.         if (!config.testSpec().hasFilters())
  6934.             Catch::cout() << pluralise(matchedTestCases.size(), "test case") << '\n' << std::endl;
  6935.         else
  6936.             Catch::cout() << pluralise(matchedTestCases.size(), "matching test case") << '\n' << std::endl;
  6937.         return matchedTestCases.size();
  6938.     }
  6939.  
  6940.     std::size_t listTestsNamesOnly(Config const& config) {
  6941.         TestSpec testSpec = config.testSpec();
  6942.         if (!config.testSpec().hasFilters())
  6943.             testSpec = TestSpecParser(ITagAliasRegistry::get()).parse("*").testSpec();
  6944.         std::size_t matchedTests = 0;
  6945.         std::vector<TestCase> matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config);
  6946.         for (auto const& testCaseInfo : matchedTestCases) {
  6947.             matchedTests++;
  6948.             if (startsWith(testCaseInfo.name, '#'))
  6949.                 Catch::cout() << '"' << testCaseInfo.name << '"';
  6950.             else
  6951.                 Catch::cout() << testCaseInfo.name;
  6952.             if (config.verbosity() >= Verbosity::High)
  6953.                 Catch::cout() << "\t@" << testCaseInfo.lineInfo;
  6954.             Catch::cout() << std::endl;
  6955.         }
  6956.         return matchedTests;
  6957.     }
  6958.  
  6959.     void TagInfo::add(std::string const& spelling) {
  6960.         ++count;
  6961.         spellings.insert(spelling);
  6962.     }
  6963.  
  6964.     std::string TagInfo::all() const {
  6965.         std::string out;
  6966.         for (auto const& spelling : spellings)
  6967.             out += "[" + spelling + "]";
  6968.         return out;
  6969.     }
  6970.  
  6971.     std::size_t listTags(Config const& config) {
  6972.         TestSpec testSpec = config.testSpec();
  6973.         if (config.testSpec().hasFilters())
  6974.             Catch::cout() << "Tags for matching test cases:\n";
  6975.         else {
  6976.             Catch::cout() << "All available tags:\n";
  6977.             testSpec = TestSpecParser(ITagAliasRegistry::get()).parse("*").testSpec();
  6978.         }
  6979.  
  6980.         std::map<std::string, TagInfo> tagCounts;
  6981.  
  6982.         std::vector<TestCase> matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config);
  6983.         for (auto const& testCase : matchedTestCases) {
  6984.             for (auto const& tagName : testCase.getTestCaseInfo().tags) {
  6985.                 std::string lcaseTagName = toLower(tagName);
  6986.                 auto countIt = tagCounts.find(lcaseTagName);
  6987.                 if (countIt == tagCounts.end())
  6988.                     countIt = tagCounts.insert(std::make_pair(lcaseTagName, TagInfo())).first;
  6989.                 countIt->second.add(tagName);
  6990.             }
  6991.         }
  6992.  
  6993.         for (auto const& tagCount : tagCounts) {
  6994.             std::ostringstream oss;
  6995.             oss << "  " << std::setw(2) << tagCount.second.count << "  ";
  6996.             auto wrapper = Column(tagCount.second.all())
  6997.                 .initialIndent(0)
  6998.                 .indent(oss.str().size())
  6999.                 .width(CATCH_CONFIG_CONSOLE_WIDTH - 10);
  7000.             Catch::cout() << oss.str() << wrapper << '\n';
  7001.         }
  7002.         Catch::cout() << pluralise(tagCounts.size(), "tag") << '\n' << std::endl;
  7003.         return tagCounts.size();
  7004.     }
  7005.  
  7006.     std::size_t listReporters(Config const& /*config*/) {
  7007.         Catch::cout() << "Available reporters:\n";
  7008.         IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
  7009.         std::size_t maxNameLen = 0;
  7010.         for (auto const& factoryKvp : factories)
  7011.             maxNameLen = (std::max)(maxNameLen, factoryKvp.first.size());
  7012.  
  7013.         for (auto const& factoryKvp : factories) {
  7014.             Catch::cout()
  7015.                 << Column(factoryKvp.first + ":")
  7016.                 .indent(2)
  7017.                 .width(5 + maxNameLen)
  7018.                 + Column(factoryKvp.second->getDescription())
  7019.                 .initialIndent(0)
  7020.                 .indent(2)
  7021.                 .width(CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen - 8)
  7022.                 << "\n";
  7023.         }
  7024.         Catch::cout() << std::endl;
  7025.         return factories.size();
  7026.     }
  7027.  
  7028.     Option<std::size_t> list(Config const& config) {
  7029.         Option<std::size_t> listedCount;
  7030.         if (config.listTests())
  7031.             listedCount = listedCount.valueOr(0) + listTests(config);
  7032.         if (config.listTestNamesOnly())
  7033.             listedCount = listedCount.valueOr(0) + listTestsNamesOnly(config);
  7034.         if (config.listTags())
  7035.             listedCount = listedCount.valueOr(0) + listTags(config);
  7036.         if (config.listReporters())
  7037.             listedCount = listedCount.valueOr(0) + listReporters(config);
  7038.         return listedCount;
  7039.     }
  7040.  
  7041. } // end namespace Catch
  7042.   // end catch_list.cpp
  7043.   // start catch_matchers.cpp
  7044.  
  7045. namespace Catch {
  7046.     namespace Matchers {
  7047.         namespace Impl {
  7048.  
  7049.             std::string MatcherUntypedBase::toString() const {
  7050.                 if (m_cachedToString.empty())
  7051.                     m_cachedToString = describe();
  7052.                 return m_cachedToString;
  7053.             }
  7054.  
  7055.             MatcherUntypedBase::~MatcherUntypedBase() = default;
  7056.  
  7057.         } // namespace Impl
  7058.     } // namespace Matchers
  7059.  
  7060.     using namespace Matchers;
  7061.     using Matchers::Impl::MatcherBase;
  7062.  
  7063. } // namespace Catch
  7064.   // end catch_matchers.cpp
  7065.   // start catch_matchers_string.cpp
  7066.  
  7067. namespace Catch {
  7068.     namespace Matchers {
  7069.  
  7070.         namespace StdString {
  7071.  
  7072.             CasedString::CasedString(std::string const& str, CaseSensitive::Choice caseSensitivity)
  7073.                 : m_caseSensitivity(caseSensitivity),
  7074.                 m_str(adjustString(str)) {
  7075.             }
  7076.             std::string CasedString::adjustString(std::string const& str) const {
  7077.                 return m_caseSensitivity == CaseSensitive::No
  7078.                     ? toLower(str)
  7079.                     : str;
  7080.             }
  7081.             std::string CasedString::caseSensitivitySuffix() const {
  7082.                 return m_caseSensitivity == CaseSensitive::No
  7083.                     ? " (case insensitive)"
  7084.                     : std::string();
  7085.             }
  7086.  
  7087.             StringMatcherBase::StringMatcherBase(std::string const& operation, CasedString const& comparator)
  7088.                 : m_comparator(comparator),
  7089.                 m_operation(operation) {
  7090.             }
  7091.  
  7092.             std::string StringMatcherBase::describe() const {
  7093.                 std::string description;
  7094.                 description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
  7095.                                     m_comparator.caseSensitivitySuffix().size());
  7096.                 description += m_operation;
  7097.                 description += ": \"";
  7098.                 description += m_comparator.m_str;
  7099.                 description += "\"";
  7100.                 description += m_comparator.caseSensitivitySuffix();
  7101.                 return description;
  7102.             }
  7103.  
  7104.             EqualsMatcher::EqualsMatcher(CasedString const& comparator) : StringMatcherBase("equals", comparator) {}
  7105.  
  7106.             bool EqualsMatcher::match(std::string const& source) const {
  7107.                 return m_comparator.adjustString(source) == m_comparator.m_str;
  7108.             }
  7109.  
  7110.             ContainsMatcher::ContainsMatcher(CasedString const& comparator) : StringMatcherBase("contains", comparator) {}
  7111.  
  7112.             bool ContainsMatcher::match(std::string const& source) const {
  7113.                 return contains(m_comparator.adjustString(source), m_comparator.m_str);
  7114.             }
  7115.  
  7116.             StartsWithMatcher::StartsWithMatcher(CasedString const& comparator) : StringMatcherBase("starts with", comparator) {}
  7117.  
  7118.             bool StartsWithMatcher::match(std::string const& source) const {
  7119.                 return startsWith(m_comparator.adjustString(source), m_comparator.m_str);
  7120.             }
  7121.  
  7122.             EndsWithMatcher::EndsWithMatcher(CasedString const& comparator) : StringMatcherBase("ends with", comparator) {}
  7123.  
  7124.             bool EndsWithMatcher::match(std::string const& source) const {
  7125.                 return endsWith(m_comparator.adjustString(source), m_comparator.m_str);
  7126.             }
  7127.  
  7128.         } // namespace StdString
  7129.  
  7130.         StdString::EqualsMatcher Equals(std::string const& str, CaseSensitive::Choice caseSensitivity) {
  7131.             return StdString::EqualsMatcher(StdString::CasedString(str, caseSensitivity));
  7132.         }
  7133.         StdString::ContainsMatcher Contains(std::string const& str, CaseSensitive::Choice caseSensitivity) {
  7134.             return StdString::ContainsMatcher(StdString::CasedString(str, caseSensitivity));
  7135.         }
  7136.         StdString::EndsWithMatcher EndsWith(std::string const& str, CaseSensitive::Choice caseSensitivity) {
  7137.             return StdString::EndsWithMatcher(StdString::CasedString(str, caseSensitivity));
  7138.         }
  7139.         StdString::StartsWithMatcher StartsWith(std::string const& str, CaseSensitive::Choice caseSensitivity) {
  7140.             return StdString::StartsWithMatcher(StdString::CasedString(str, caseSensitivity));
  7141.         }
  7142.  
  7143.     } // namespace Matchers
  7144. } // namespace Catch
  7145.   // end catch_matchers_string.cpp
  7146.   // start catch_message.cpp
  7147.  
  7148. namespace Catch {
  7149.  
  7150.     MessageInfo::MessageInfo(std::string const& _macroName,
  7151.                              SourceLineInfo const& _lineInfo,
  7152.                              ResultWas::OfType _type)
  7153.         : macroName(_macroName),
  7154.         lineInfo(_lineInfo),
  7155.         type(_type),
  7156.         sequence(++globalCount) {
  7157.     }
  7158.  
  7159.     bool MessageInfo::operator==(MessageInfo const& other) const {
  7160.         return sequence == other.sequence;
  7161.     }
  7162.  
  7163.     bool MessageInfo::operator<(MessageInfo const& other) const {
  7164.         return sequence < other.sequence;
  7165.     }
  7166.  
  7167.     // This may need protecting if threading support is added
  7168.     unsigned int MessageInfo::globalCount = 0;
  7169.  
  7170.     ////////////////////////////////////////////////////////////////////////////
  7171.  
  7172.     Catch::MessageBuilder::MessageBuilder(std::string const& macroName,
  7173.                                           SourceLineInfo const& lineInfo,
  7174.                                           ResultWas::OfType type)
  7175.         :m_info(macroName, lineInfo, type) {
  7176.     }
  7177.  
  7178.     ////////////////////////////////////////////////////////////////////////////
  7179.  
  7180.     ScopedMessage::ScopedMessage(MessageBuilder const& builder)
  7181.         : m_info(builder.m_info) {
  7182.         m_info.message = builder.m_stream.str();
  7183.         getResultCapture().pushScopedMessage(m_info);
  7184.     }
  7185.  
  7186.     ScopedMessage::~ScopedMessage() {
  7187.         if (!std::uncaught_exception()) {
  7188.             getResultCapture().popScopedMessage(m_info);
  7189.         }
  7190.     }
  7191.  
  7192. } // end namespace Catch
  7193.   // end catch_message.cpp
  7194.   // start catch_random_number_generator.cpp
  7195.  
  7196.   // start catch_random_number_generator.h
  7197.  
  7198. #include <algorithm>
  7199.  
  7200. namespace Catch {
  7201.  
  7202.     struct IConfig;
  7203.  
  7204.     void seedRng(IConfig const& config);
  7205.  
  7206.     unsigned int rngSeed();
  7207.  
  7208.     struct RandomNumberGenerator {
  7209.         using result_type = unsigned int;
  7210.  
  7211.         static constexpr result_type(min)() { return 0; }
  7212.         static constexpr result_type(max)() { return 1000000; }
  7213.  
  7214.         result_type operator()(result_type n) const;
  7215.         result_type operator()() const;
  7216.  
  7217.         template<typename V>
  7218.         static void shuffle(V& vector) {
  7219.             RandomNumberGenerator rng;
  7220.             std::shuffle(vector.begin(), vector.end(), rng);
  7221.         }
  7222.     };
  7223.  
  7224. }
  7225.  
  7226. // end catch_random_number_generator.h
  7227. #include <cstdlib>
  7228.  
  7229. namespace Catch {
  7230.  
  7231.     void seedRng(IConfig const& config) {
  7232.         if (config.rngSeed() != 0)
  7233.             std::srand(config.rngSeed());
  7234.     }
  7235.     unsigned int rngSeed() {
  7236.         return getCurrentContext().getConfig()->rngSeed();
  7237.     }
  7238.  
  7239.     RandomNumberGenerator::result_type RandomNumberGenerator::operator()(result_type n) const {
  7240.         return std::rand() % n;
  7241.     }
  7242.     RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
  7243.         return std::rand() % (max)();
  7244.     }
  7245.  
  7246. }
  7247. // end catch_random_number_generator.cpp
  7248. // start catch_registry_hub.cpp
  7249.  
  7250. // start catch_test_case_registry_impl.h
  7251.  
  7252. #include <vector>
  7253. #include <set>
  7254. #include <algorithm>
  7255. #include <ios>
  7256.  
  7257. namespace Catch {
  7258.  
  7259.     class TestCase;
  7260.     struct IConfig;
  7261.  
  7262.     std::vector<TestCase> sortTests(IConfig const& config, std::vector<TestCase> const& unsortedTestCases);
  7263.     bool matchTest(TestCase const& testCase, TestSpec const& testSpec, IConfig const& config);
  7264.  
  7265.     void enforceNoDuplicateTestCases(std::vector<TestCase> const& functions);
  7266.  
  7267.     std::vector<TestCase> filterTests(std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config);
  7268.     std::vector<TestCase> const& getAllTestCasesSorted(IConfig const& config);
  7269.  
  7270.     class TestRegistry : public ITestCaseRegistry {
  7271.     public:
  7272.         virtual ~TestRegistry() = default;
  7273.  
  7274.         virtual void registerTest(TestCase const& testCase);
  7275.  
  7276.         std::vector<TestCase> const& getAllTests() const override;
  7277.         std::vector<TestCase> const& getAllTestsSorted(IConfig const& config) const override;
  7278.  
  7279.     private:
  7280.         std::vector<TestCase> m_functions;
  7281.         mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
  7282.         mutable std::vector<TestCase> m_sortedFunctions;
  7283.         std::size_t m_unnamedCount = 0;
  7284.         std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
  7285.     };
  7286.  
  7287.     ///////////////////////////////////////////////////////////////////////////
  7288.  
  7289.     class TestInvokerAsFunction : public ITestInvoker {
  7290.         void(*m_testAsFunction)();
  7291.     public:
  7292.         TestInvokerAsFunction(void(*testAsFunction)()) noexcept;
  7293.  
  7294.         void invoke() const override;
  7295.     };
  7296.  
  7297.     std::string extractClassName(std::string const& classOrQualifiedMethodName);
  7298.  
  7299.     ///////////////////////////////////////////////////////////////////////////
  7300.  
  7301. } // end namespace Catch
  7302.  
  7303.   // end catch_test_case_registry_impl.h
  7304.   // start catch_reporter_registry.h
  7305.  
  7306. #include <map>
  7307.  
  7308. namespace Catch {
  7309.  
  7310.     class ReporterRegistry : public IReporterRegistry {
  7311.  
  7312.     public:
  7313.  
  7314.         ~ReporterRegistry() override;
  7315.  
  7316.         IStreamingReporterPtr create(std::string const& name, IConfigPtr const& config) const override;
  7317.  
  7318.         void registerReporter(std::string const& name, IReporterFactoryPtr const& factory);
  7319.         void registerListener(IReporterFactoryPtr const& factory);
  7320.  
  7321.         FactoryMap const& getFactories() const override;
  7322.         Listeners const& getListeners() const override;
  7323.  
  7324.     private:
  7325.         FactoryMap m_factories;
  7326.         Listeners m_listeners;
  7327.     };
  7328. }
  7329.  
  7330. // end catch_reporter_registry.h
  7331. // start catch_tag_alias_registry.h
  7332.  
  7333. // start catch_tag_alias.h
  7334.  
  7335. #include <string>
  7336.  
  7337. namespace Catch {
  7338.  
  7339.     struct TagAlias {
  7340.         TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
  7341.  
  7342.         std::string tag;
  7343.         SourceLineInfo lineInfo;
  7344.     };
  7345.  
  7346. } // end namespace Catch
  7347.  
  7348.   // end catch_tag_alias.h
  7349. #include <map>
  7350.  
  7351. namespace Catch {
  7352.  
  7353.     class TagAliasRegistry : public ITagAliasRegistry {
  7354.     public:
  7355.         ~TagAliasRegistry() override;
  7356.         TagAlias const* find(std::string const& alias) const override;
  7357.         std::string expandAliases(std::string const& unexpandedTestSpec) const override;
  7358.         void add(std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo);
  7359.  
  7360.     private:
  7361.         std::map<std::string, TagAlias> m_registry;
  7362.     };
  7363.  
  7364. } // end namespace Catch
  7365.  
  7366.   // end catch_tag_alias_registry.h
  7367.   // start catch_startup_exception_registry.h
  7368.  
  7369. #include <vector>
  7370. #include <exception>
  7371.  
  7372. namespace Catch {
  7373.  
  7374.     class StartupExceptionRegistry {
  7375.     public:
  7376.         void add(std::exception_ptr const& exception) noexcept;
  7377.         std::vector<std::exception_ptr> const& getExceptions() const noexcept;
  7378.     private:
  7379.         std::vector<std::exception_ptr> m_exceptions;
  7380.     };
  7381.  
  7382. } // end namespace Catch
  7383.  
  7384.   // end catch_startup_exception_registry.h
  7385. namespace Catch {
  7386.  
  7387.     namespace {
  7388.  
  7389.         class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
  7390.             private NonCopyable {
  7391.  
  7392.         public: // IRegistryHub
  7393.             RegistryHub() = default;
  7394.             IReporterRegistry const& getReporterRegistry() const override {
  7395.                 return m_reporterRegistry;
  7396.             }
  7397.             ITestCaseRegistry const& getTestCaseRegistry() const override {
  7398.                 return m_testCaseRegistry;
  7399.             }
  7400.             IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() override {
  7401.                 return m_exceptionTranslatorRegistry;
  7402.             }
  7403.             ITagAliasRegistry const& getTagAliasRegistry() const override {
  7404.                 return m_tagAliasRegistry;
  7405.             }
  7406.             StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
  7407.                 return m_exceptionRegistry;
  7408.             }
  7409.  
  7410.         public: // IMutableRegistryHub
  7411.             void registerReporter(std::string const& name, IReporterFactoryPtr const& factory) override {
  7412.                 m_reporterRegistry.registerReporter(name, factory);
  7413.             }
  7414.             void registerListener(IReporterFactoryPtr const& factory) override {
  7415.                 m_reporterRegistry.registerListener(factory);
  7416.             }
  7417.             void registerTest(TestCase const& testInfo) override {
  7418.                 m_testCaseRegistry.registerTest(testInfo);
  7419.             }
  7420.             void registerTranslator(const IExceptionTranslator* translator) override {
  7421.                 m_exceptionTranslatorRegistry.registerTranslator(translator);
  7422.             }
  7423.             void registerTagAlias(std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo) override {
  7424.                 m_tagAliasRegistry.add(alias, tag, lineInfo);
  7425.             }
  7426.             void registerStartupException() noexcept override {
  7427.                 m_exceptionRegistry.add(std::current_exception());
  7428.             }
  7429.  
  7430.         private:
  7431.             TestRegistry m_testCaseRegistry;
  7432.             ReporterRegistry m_reporterRegistry;
  7433.             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
  7434.             TagAliasRegistry m_tagAliasRegistry;
  7435.             StartupExceptionRegistry m_exceptionRegistry;
  7436.         };
  7437.  
  7438.         // Single, global, instance
  7439.         RegistryHub*& getTheRegistryHub() {
  7440.             static RegistryHub* theRegistryHub = nullptr;
  7441.             if (!theRegistryHub)
  7442.                 theRegistryHub = new RegistryHub();
  7443.             return theRegistryHub;
  7444.         }
  7445.     }
  7446.  
  7447.     IRegistryHub& getRegistryHub() {
  7448.         return *getTheRegistryHub();
  7449.     }
  7450.     IMutableRegistryHub& getMutableRegistryHub() {
  7451.         return *getTheRegistryHub();
  7452.     }
  7453.     void cleanUp() {
  7454.         delete getTheRegistryHub();
  7455.         getTheRegistryHub() = nullptr;
  7456.         cleanUpContext();
  7457.     }
  7458.     std::string translateActiveException() {
  7459.         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
  7460.     }
  7461.  
  7462. } // end namespace Catch
  7463.   // end catch_registry_hub.cpp
  7464.   // start catch_reporter_registry.cpp
  7465.  
  7466. namespace Catch {
  7467.  
  7468.     ReporterRegistry::~ReporterRegistry() = default;
  7469.  
  7470.     IStreamingReporterPtr ReporterRegistry::create(std::string const& name, IConfigPtr const& config) const {
  7471.         auto it = m_factories.find(name);
  7472.         if (it == m_factories.end())
  7473.             return nullptr;
  7474.         return it->second->create(ReporterConfig(config));
  7475.     }
  7476.  
  7477.     void ReporterRegistry::registerReporter(std::string const& name, IReporterFactoryPtr const& factory) {
  7478.         m_factories.emplace(name, factory);
  7479.     }
  7480.     void ReporterRegistry::registerListener(IReporterFactoryPtr const& factory) {
  7481.         m_listeners.push_back(factory);
  7482.     }
  7483.  
  7484.     IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
  7485.         return m_factories;
  7486.     }
  7487.     IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
  7488.         return m_listeners;
  7489.     }
  7490.  
  7491. }
  7492. // end catch_reporter_registry.cpp
  7493. // start catch_result_type.cpp
  7494.  
  7495. namespace Catch {
  7496.  
  7497.     bool isOk(ResultWas::OfType resultType) {
  7498.         return (resultType & ResultWas::FailureBit) == 0;
  7499.     }
  7500.     bool isJustInfo(int flags) {
  7501.         return flags == ResultWas::Info;
  7502.     }
  7503.  
  7504.     ResultDisposition::Flags operator | (ResultDisposition::Flags lhs, ResultDisposition::Flags rhs) {
  7505.         return static_cast<ResultDisposition::Flags>(static_cast<int>(lhs) | static_cast<int>(rhs));
  7506.     }
  7507.  
  7508.     bool shouldContinueOnFailure(int flags) { return (flags & ResultDisposition::ContinueOnFailure) != 0; }
  7509.     bool isFalseTest(int flags) { return (flags & ResultDisposition::FalseTest) != 0; }
  7510.     bool shouldSuppressFailure(int flags) { return (flags & ResultDisposition::SuppressFail) != 0; }
  7511.  
  7512. } // end namespace Catch
  7513.   // end catch_result_type.cpp
  7514.   // start catch_run_context.cpp
  7515.   // start catch_run_context.h
  7516.  
  7517. #include <string>
  7518.  
  7519. namespace Catch {
  7520.  
  7521.     struct IMutableContext;
  7522.  
  7523.     class StreamRedirect {
  7524.  
  7525.     public:
  7526.         StreamRedirect(std::ostream& stream, std::string& targetString);
  7527.  
  7528.         ~StreamRedirect();
  7529.  
  7530.     private:
  7531.         std::ostream& m_stream;
  7532.         std::streambuf* m_prevBuf;
  7533.         std::ostringstream m_oss;
  7534.         std::string& m_targetString;
  7535.     };
  7536.  
  7537.     // StdErr has two constituent streams in C++, std::cerr and std::clog
  7538.     // This means that we need to redirect 2 streams into 1 to keep proper
  7539.     // order of writes and cannot use StreamRedirect on its own
  7540.     class StdErrRedirect {
  7541.     public:
  7542.         StdErrRedirect(std::string& targetString);
  7543.         ~StdErrRedirect();
  7544.     private:
  7545.         std::streambuf* m_cerrBuf;
  7546.         std::streambuf* m_clogBuf;
  7547.         std::ostringstream m_oss;
  7548.         std::string& m_targetString;
  7549.     };
  7550.  
  7551.     ///////////////////////////////////////////////////////////////////////////
  7552.  
  7553.     class RunContext : public IResultCapture, public IRunner {
  7554.  
  7555.     public:
  7556.         RunContext(RunContext const&) = delete;
  7557.         RunContext& operator =(RunContext const&) = delete;
  7558.  
  7559.         explicit RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter);
  7560.  
  7561.         virtual ~RunContext();
  7562.  
  7563.         void testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount);
  7564.         void testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount);
  7565.  
  7566.         Totals runTest(TestCase const& testCase);
  7567.  
  7568.         IConfigPtr config() const;
  7569.         IStreamingReporter& reporter() const;
  7570.  
  7571.     private: // IResultCapture
  7572.  
  7573.         void assertionStarting(AssertionInfo const& info) override;
  7574.         void assertionEnded(AssertionResult const& result) override;
  7575.  
  7576.         bool sectionStarted(SectionInfo const& sectionInfo, Counts& assertions) override;
  7577.         bool testForMissingAssertions(Counts& assertions);
  7578.  
  7579.         void sectionEnded(SectionEndInfo const& endInfo) override;
  7580.         void sectionEndedEarly(SectionEndInfo const& endInfo) override;
  7581.  
  7582.         void benchmarkStarting(BenchmarkInfo const& info) override;
  7583.         void benchmarkEnded(BenchmarkStats const& stats) override;
  7584.  
  7585.         void pushScopedMessage(MessageInfo const& message) override;
  7586.         void popScopedMessage(MessageInfo const& message) override;
  7587.  
  7588.         std::string getCurrentTestName() const override;
  7589.  
  7590.         const AssertionResult* getLastResult() const override;
  7591.  
  7592.         void exceptionEarlyReported() override;
  7593.  
  7594.         void handleFatalErrorCondition(StringRef message) override;
  7595.  
  7596.         bool lastAssertionPassed() override;
  7597.  
  7598.         void assertionPassed() override;
  7599.  
  7600.         void assertionRun() override;
  7601.  
  7602.     public:
  7603.         // !TBD We need to do this another way!
  7604.         bool aborting() const override;
  7605.  
  7606.     private:
  7607.  
  7608.         void runCurrentTest(std::string& redirectedCout, std::string& redirectedCerr);
  7609.         void invokeActiveTestCase();
  7610.  
  7611.     private:
  7612.  
  7613.         void handleUnfinishedSections();
  7614.  
  7615.         TestRunInfo m_runInfo;
  7616.         IMutableContext& m_context;
  7617.         TestCase const* m_activeTestCase = nullptr;
  7618.         ITracker* m_testCaseTracker;
  7619.         Option<AssertionResult> m_lastResult;
  7620.  
  7621.         IConfigPtr m_config;
  7622.         Totals m_totals;
  7623.         IStreamingReporterPtr m_reporter;
  7624.         std::vector<MessageInfo> m_messages;
  7625.         AssertionInfo m_lastAssertionInfo;
  7626.         std::vector<SectionEndInfo> m_unfinishedSections;
  7627.         std::vector<ITracker*> m_activeSections;
  7628.         TrackerContext m_trackerContext;
  7629.         std::size_t m_prevPassed = 0;
  7630.         bool m_shouldReportUnexpected = true;
  7631.     };
  7632.  
  7633.     IResultCapture& getResultCapture();
  7634.  
  7635. } // end namespace Catch
  7636.  
  7637.   // end catch_run_context.h
  7638.  
  7639. #include <cassert>
  7640. #include <algorithm>
  7641.  
  7642. namespace Catch {
  7643.  
  7644.     StreamRedirect::StreamRedirect(std::ostream& stream, std::string& targetString)
  7645.         : m_stream(stream),
  7646.         m_prevBuf(stream.rdbuf()),
  7647.         m_targetString(targetString) {
  7648.         stream.rdbuf(m_oss.rdbuf());
  7649.     }
  7650.  
  7651.     StreamRedirect::~StreamRedirect() {
  7652.         m_targetString += m_oss.str();
  7653.         m_stream.rdbuf(m_prevBuf);
  7654.     }
  7655.  
  7656.     StdErrRedirect::StdErrRedirect(std::string & targetString)
  7657.         :m_cerrBuf(cerr().rdbuf()), m_clogBuf(clog().rdbuf()),
  7658.         m_targetString(targetString) {
  7659.         cerr().rdbuf(m_oss.rdbuf());
  7660.         clog().rdbuf(m_oss.rdbuf());
  7661.     }
  7662.  
  7663.     StdErrRedirect::~StdErrRedirect() {
  7664.         m_targetString += m_oss.str();
  7665.         cerr().rdbuf(m_cerrBuf);
  7666.         clog().rdbuf(m_clogBuf);
  7667.     }
  7668.  
  7669.     RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
  7670.         : m_runInfo(_config->name()),
  7671.         m_context(getCurrentMutableContext()),
  7672.         m_config(_config),
  7673.         m_reporter(std::move(reporter)),
  7674.         m_lastAssertionInfo{ "", SourceLineInfo("",0), "", ResultDisposition::Normal } {
  7675.         m_context.setRunner(this);
  7676.         m_context.setConfig(m_config);
  7677.         m_context.setResultCapture(this);
  7678.         m_reporter->testRunStarting(m_runInfo);
  7679.     }
  7680.  
  7681.     RunContext::~RunContext() {
  7682.         m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
  7683.     }
  7684.  
  7685.     void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
  7686.         m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
  7687.     }
  7688.  
  7689.     void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
  7690.         m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
  7691.     }
  7692.  
  7693.     Totals RunContext::runTest(TestCase const& testCase) {
  7694.         Totals prevTotals = m_totals;
  7695.  
  7696.         std::string redirectedCout;
  7697.         std::string redirectedCerr;
  7698.  
  7699.         TestCaseInfo testInfo = testCase.getTestCaseInfo();
  7700.  
  7701.         m_reporter->testCaseStarting(testInfo);
  7702.  
  7703.         m_activeTestCase = &testCase;
  7704.  
  7705.         ITracker& rootTracker = m_trackerContext.startRun();
  7706.         assert(rootTracker.isSectionTracker());
  7707.         static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
  7708.         do {
  7709.             m_trackerContext.startCycle();
  7710.             m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
  7711.             runCurrentTest(redirectedCout, redirectedCerr);
  7712.         } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
  7713.  
  7714.         Totals deltaTotals = m_totals.delta(prevTotals);
  7715.         if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
  7716.             deltaTotals.assertions.failed++;
  7717.             deltaTotals.testCases.passed--;
  7718.             deltaTotals.testCases.failed++;
  7719.         }
  7720.         m_totals.testCases += deltaTotals.testCases;
  7721.         m_reporter->testCaseEnded(TestCaseStats(testInfo,
  7722.                                                 deltaTotals,
  7723.                                                 redirectedCout,
  7724.                                                 redirectedCerr,
  7725.                                                 aborting()));
  7726.  
  7727.         m_activeTestCase = nullptr;
  7728.         m_testCaseTracker = nullptr;
  7729.  
  7730.         return deltaTotals;
  7731.     }
  7732.  
  7733.     IConfigPtr RunContext::config() const {
  7734.         return m_config;
  7735.     }
  7736.  
  7737.     IStreamingReporter& RunContext::reporter() const {
  7738.         return *m_reporter;
  7739.     }
  7740.  
  7741.     void RunContext::assertionStarting(AssertionInfo const& info) {
  7742.         m_reporter->assertionStarting(info);
  7743.     }
  7744.     void RunContext::assertionEnded(AssertionResult const & result) {
  7745.         if (result.getResultType() == ResultWas::Ok) {
  7746.             m_totals.assertions.passed++;
  7747.         } else if (!result.isOk()) {
  7748.             if (m_activeTestCase->getTestCaseInfo().okToFail())
  7749.                 m_totals.assertions.failedButOk++;
  7750.             else
  7751.                 m_totals.assertions.failed++;
  7752.         }
  7753.  
  7754.         // We have no use for the return value (whether messages should be cleared), because messages were made scoped
  7755.         // and should be let to clear themselves out.
  7756.         static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
  7757.  
  7758.         // Reset working state
  7759.         m_lastAssertionInfo = { "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}", m_lastAssertionInfo.resultDisposition };
  7760.         m_lastResult = result;
  7761.     }
  7762.  
  7763.     bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
  7764.         ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
  7765.         if (!sectionTracker.isOpen())
  7766.             return false;
  7767.         m_activeSections.push_back(&sectionTracker);
  7768.  
  7769.         m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
  7770.  
  7771.         m_reporter->sectionStarting(sectionInfo);
  7772.  
  7773.         assertions = m_totals.assertions;
  7774.  
  7775.         return true;
  7776.     }
  7777.  
  7778.     bool RunContext::testForMissingAssertions(Counts& assertions) {
  7779.         if (assertions.total() != 0)
  7780.             return false;
  7781.         if (!m_config->warnAboutMissingAssertions())
  7782.             return false;
  7783.         if (m_trackerContext.currentTracker().hasChildren())
  7784.             return false;
  7785.         m_totals.assertions.failed++;
  7786.         assertions.failed++;
  7787.         return true;
  7788.     }
  7789.  
  7790.     void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
  7791.         Counts assertions = m_totals.assertions - endInfo.prevAssertions;
  7792.         bool missingAssertions = testForMissingAssertions(assertions);
  7793.  
  7794.         if (!m_activeSections.empty()) {
  7795.             m_activeSections.back()->close();
  7796.             m_activeSections.pop_back();
  7797.         }
  7798.  
  7799.         m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
  7800.         m_messages.clear();
  7801.     }
  7802.  
  7803.     void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
  7804.         if (m_unfinishedSections.empty())
  7805.             m_activeSections.back()->fail();
  7806.         else
  7807.             m_activeSections.back()->close();
  7808.         m_activeSections.pop_back();
  7809.  
  7810.         m_unfinishedSections.push_back(endInfo);
  7811.     }
  7812.     void RunContext::benchmarkStarting(BenchmarkInfo const& info) {
  7813.         m_reporter->benchmarkStarting(info);
  7814.     }
  7815.     void RunContext::benchmarkEnded(BenchmarkStats const& stats) {
  7816.         m_reporter->benchmarkEnded(stats);
  7817.     }
  7818.  
  7819.     void RunContext::pushScopedMessage(MessageInfo const & message) {
  7820.         m_messages.push_back(message);
  7821.     }
  7822.  
  7823.     void RunContext::popScopedMessage(MessageInfo const & message) {
  7824.         m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
  7825.     }
  7826.  
  7827.     std::string RunContext::getCurrentTestName() const {
  7828.         return m_activeTestCase
  7829.             ? m_activeTestCase->getTestCaseInfo().name
  7830.             : std::string();
  7831.     }
  7832.  
  7833.     const AssertionResult * RunContext::getLastResult() const {
  7834.         return &(*m_lastResult);
  7835.     }
  7836.  
  7837.     void RunContext::exceptionEarlyReported() {
  7838.         m_shouldReportUnexpected = false;
  7839.     }
  7840.  
  7841.     void RunContext::handleFatalErrorCondition(StringRef message) {
  7842.         // First notify reporter that bad things happened
  7843.         m_reporter->fatalErrorEncountered(message);
  7844.  
  7845.         // Don't rebuild the result -- the stringification itself can cause more fatal errors
  7846.         // Instead, fake a result data.
  7847.         AssertionResultData tempResult(ResultWas::FatalErrorCondition, { false });
  7848.         tempResult.message = message;
  7849.         AssertionResult result(m_lastAssertionInfo, tempResult);
  7850.  
  7851.         getResultCapture().assertionEnded(result);
  7852.  
  7853.         handleUnfinishedSections();
  7854.  
  7855.         // Recreate section for test case (as we will lose the one that was in scope)
  7856.         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  7857.         SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
  7858.  
  7859.         Counts assertions;
  7860.         assertions.failed = 1;
  7861.         SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
  7862.         m_reporter->sectionEnded(testCaseSectionStats);
  7863.  
  7864.         auto const& testInfo = m_activeTestCase->getTestCaseInfo();
  7865.  
  7866.         Totals deltaTotals;
  7867.         deltaTotals.testCases.failed = 1;
  7868.         deltaTotals.assertions.failed = 1;
  7869.         m_reporter->testCaseEnded(TestCaseStats(testInfo,
  7870.                                                 deltaTotals,
  7871.                                                 std::string(),
  7872.                                                 std::string(),
  7873.                                                 false));
  7874.         m_totals.testCases.failed++;
  7875.         testGroupEnded(std::string(), m_totals, 1, 1);
  7876.         m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
  7877.     }
  7878.  
  7879.     bool RunContext::lastAssertionPassed() {
  7880.         return m_totals.assertions.passed == (m_prevPassed + 1);
  7881.     }
  7882.  
  7883.     void RunContext::assertionPassed() {
  7884.         ++m_totals.assertions.passed;
  7885.         m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}";
  7886.         m_lastAssertionInfo.macroName = "";
  7887.     }
  7888.  
  7889.     void RunContext::assertionRun() {
  7890.         m_prevPassed = m_totals.assertions.passed;
  7891.     }
  7892.  
  7893.     bool RunContext::aborting() const {
  7894.         return m_totals.assertions.failed == static_cast<std::size_t>(m_config->abortAfter());
  7895.     }
  7896.  
  7897.     void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
  7898.         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  7899.         SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
  7900.         m_reporter->sectionStarting(testCaseSection);
  7901.         Counts prevAssertions = m_totals.assertions;
  7902.         double duration = 0;
  7903.         m_shouldReportUnexpected = true;
  7904.         try {
  7905.             m_lastAssertionInfo = { "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal };
  7906.             seedRng(*m_config);
  7907.  
  7908.             Timer timer;
  7909.             timer.start();
  7910.             if (m_reporter->getPreferences().shouldRedirectStdOut) {
  7911.                 StreamRedirect coutRedir(cout(), redirectedCout);
  7912.                 StdErrRedirect errRedir(redirectedCerr);
  7913.                 invokeActiveTestCase();
  7914.             } else {
  7915.                 invokeActiveTestCase();
  7916.             }
  7917.             duration = timer.getElapsedSeconds();
  7918.         } catch (TestFailureException&) {
  7919.             // This just means the test was aborted due to failure
  7920.         } catch (...) {
  7921.             // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
  7922.             // are reported without translation at the point of origin.
  7923.             if (m_shouldReportUnexpected) {
  7924.                 AssertionHandler
  7925.                 (m_lastAssertionInfo.macroName,
  7926.                  m_lastAssertionInfo.lineInfo,
  7927.                  m_lastAssertionInfo.capturedExpression,
  7928.                  m_lastAssertionInfo.resultDisposition).useActiveException();
  7929.             }
  7930.         }
  7931.         m_testCaseTracker->close();
  7932.         handleUnfinishedSections();
  7933.         m_messages.clear();
  7934.  
  7935.         Counts assertions = m_totals.assertions - prevAssertions;
  7936.         bool missingAssertions = testForMissingAssertions(assertions);
  7937.         SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
  7938.         m_reporter->sectionEnded(testCaseSectionStats);
  7939.     }
  7940.  
  7941.     void RunContext::invokeActiveTestCase() {
  7942.         FatalConditionHandler fatalConditionHandler; // Handle signals
  7943.         m_activeTestCase->invoke();
  7944.         fatalConditionHandler.reset();
  7945.     }
  7946.  
  7947.     void RunContext::handleUnfinishedSections() {
  7948.         // If sections ended prematurely due to an exception we stored their
  7949.         // infos here so we can tear them down outside the unwind process.
  7950.         for (auto it = m_unfinishedSections.rbegin(),
  7951.              itEnd = m_unfinishedSections.rend();
  7952.              it != itEnd;
  7953.              ++it)
  7954.             sectionEnded(*it);
  7955.         m_unfinishedSections.clear();
  7956.     }
  7957.  
  7958.     IResultCapture& getResultCapture() {
  7959.         if (auto* capture = getCurrentContext().getResultCapture())
  7960.             return *capture;
  7961.         else
  7962.             CATCH_INTERNAL_ERROR("No result capture instance");
  7963.     }
  7964. }
  7965. // end catch_run_context.cpp
  7966. // start catch_section.cpp
  7967.  
  7968. namespace Catch {
  7969.  
  7970.     Section::Section(SectionInfo const& info)
  7971.         : m_info(info),
  7972.         m_sectionIncluded(getResultCapture().sectionStarted(m_info, m_assertions)) {
  7973.         m_timer.start();
  7974.     }
  7975.  
  7976. #if defined(_MSC_VER)
  7977. #pragma warning(push)
  7978. #pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
  7979. #endif
  7980.     Section::~Section() {
  7981.         if (m_sectionIncluded) {
  7982.             SectionEndInfo endInfo(m_info, m_assertions, m_timer.getElapsedSeconds());
  7983.             if (std::uncaught_exception())
  7984.                 getResultCapture().sectionEndedEarly(endInfo);
  7985.             else
  7986.                 getResultCapture().sectionEnded(endInfo);
  7987.         }
  7988.     }
  7989. #if defined(_MSC_VER)
  7990. #pragma warning(pop)
  7991. #endif
  7992.  
  7993.     // This indicates whether the section should be executed or not
  7994.     Section::operator bool() const {
  7995.         return m_sectionIncluded;
  7996.     }
  7997.  
  7998. } // end namespace Catch
  7999.   // end catch_section.cpp
  8000.   // start catch_section_info.cpp
  8001.  
  8002. namespace Catch {
  8003.  
  8004.     SectionInfo::SectionInfo
  8005.     (SourceLineInfo const& _lineInfo,
  8006.      std::string const& _name,
  8007.      std::string const& _description)
  8008.         : name(_name),
  8009.         description(_description),
  8010.         lineInfo(_lineInfo) {
  8011.     }
  8012.  
  8013.     SectionEndInfo::SectionEndInfo(SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds)
  8014.         : sectionInfo(_sectionInfo), prevAssertions(_prevAssertions), durationInSeconds(_durationInSeconds) {
  8015.     }
  8016.  
  8017. } // end namespace Catch
  8018.   // end catch_section_info.cpp
  8019.   // start catch_session.cpp
  8020.  
  8021.   // start catch_session.h
  8022.  
  8023. #include <memory>
  8024.  
  8025. namespace Catch {
  8026.  
  8027.     class Session : NonCopyable {
  8028.     public:
  8029.  
  8030.         Session();
  8031.         ~Session() override;
  8032.  
  8033.         void showHelp() const;
  8034.         void libIdentify();
  8035.  
  8036.         int applyCommandLine(int argc, char* argv[]);
  8037.  
  8038.         void useConfigData(ConfigData const& configData);
  8039.  
  8040.         int run(int argc, char* argv[]);
  8041. #if defined(WIN32) && defined(UNICODE)
  8042.         int run(int argc, wchar_t* const argv[]);
  8043. #endif
  8044.         int run();
  8045.  
  8046.         clara::Parser const& cli() const;
  8047.         void cli(clara::Parser const& newParser);
  8048.         ConfigData& configData();
  8049.         Config& config();
  8050.     private:
  8051.         int runInternal();
  8052.  
  8053.         clara::Parser m_cli;
  8054.         ConfigData m_configData;
  8055.         std::shared_ptr<Config> m_config;
  8056.         bool m_startupExceptions = false;
  8057.     };
  8058.  
  8059. } // end namespace Catch
  8060.  
  8061.   // end catch_session.h
  8062.   // start catch_version.h
  8063.  
  8064. #include <iosfwd>
  8065.  
  8066. namespace Catch {
  8067.  
  8068.     // Versioning information
  8069.     struct Version {
  8070.         Version(Version const&) = delete;
  8071.         Version& operator=(Version const&) = delete;
  8072.         Version(unsigned int _majorVersion,
  8073.                 unsigned int _minorVersion,
  8074.                 unsigned int _patchNumber,
  8075.                 char const * const _branchName,
  8076.                 unsigned int _buildNumber);
  8077.  
  8078.         unsigned int const majorVersion;
  8079.         unsigned int const minorVersion;
  8080.         unsigned int const patchNumber;
  8081.  
  8082.         // buildNumber is only used if branchName is not null
  8083.         char const * const branchName;
  8084.         unsigned int const buildNumber;
  8085.  
  8086.         friend std::ostream& operator << (std::ostream& os, Version const& version);
  8087.     };
  8088.  
  8089.     Version const& libraryVersion();
  8090. }
  8091.  
  8092. // end catch_version.h
  8093. #include <cstdlib>
  8094. #include <iomanip>
  8095.  
  8096. namespace {
  8097.     const int MaxExitCode = 255;
  8098.     using Catch::IStreamingReporterPtr;
  8099.     using Catch::IConfigPtr;
  8100.     using Catch::Config;
  8101.  
  8102.     IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
  8103.         auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
  8104.         CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
  8105.  
  8106.         return reporter;
  8107.     }
  8108.  
  8109. #ifndef CATCH_CONFIG_DEFAULT_REPORTER
  8110. #define CATCH_CONFIG_DEFAULT_REPORTER "console"
  8111. #endif
  8112.  
  8113.     IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
  8114.         auto const& reporterNames = config->getReporterNames();
  8115.         if (reporterNames.empty())
  8116.             return createReporter(CATCH_CONFIG_DEFAULT_REPORTER, config);
  8117.  
  8118.         IStreamingReporterPtr reporter;
  8119.         for (auto const& name : reporterNames)
  8120.             addReporter(reporter, createReporter(name, config));
  8121.         return reporter;
  8122.     }
  8123.  
  8124. #undef CATCH_CONFIG_DEFAULT_REPORTER
  8125.  
  8126.     void addListeners(IStreamingReporterPtr& reporters, IConfigPtr const& config) {
  8127.         auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
  8128.         for (auto const& listener : listeners)
  8129.             addReporter(reporters, listener->create(Catch::ReporterConfig(config)));
  8130.     }
  8131.  
  8132.     Catch::Totals runTests(std::shared_ptr<Config> const& config) {
  8133.         using namespace Catch;
  8134.         IStreamingReporterPtr reporter = makeReporter(config);
  8135.         addListeners(reporter, config);
  8136.  
  8137.         RunContext context(config, std::move(reporter));
  8138.  
  8139.         Totals totals;
  8140.  
  8141.         context.testGroupStarting(config->name(), 1, 1);
  8142.  
  8143.         TestSpec testSpec = config->testSpec();
  8144.         if (!testSpec.hasFilters())
  8145.             testSpec = TestSpecParser(ITagAliasRegistry::get()).parse("~[.]").testSpec(); // All not hidden tests
  8146.  
  8147.         auto const& allTestCases = getAllTestCasesSorted(*config);
  8148.         for (auto const& testCase : allTestCases) {
  8149.             if (!context.aborting() && matchTest(testCase, testSpec, *config))
  8150.                 totals += context.runTest(testCase);
  8151.             else
  8152.                 context.reporter().skipTest(testCase);
  8153.         }
  8154.  
  8155.         context.testGroupEnded(config->name(), totals, 1, 1);
  8156.         return totals;
  8157.     }
  8158.  
  8159.     void applyFilenamesAsTags(Catch::IConfig const& config) {
  8160.         using namespace Catch;
  8161.         auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
  8162.         for (auto& testCase : tests) {
  8163.             auto tags = testCase.tags;
  8164.  
  8165.             std::string filename = testCase.lineInfo.file;
  8166.             auto lastSlash = filename.find_last_of("\\/");
  8167.             if (lastSlash != std::string::npos) {
  8168.                 filename.erase(0, lastSlash);
  8169.                 filename[0] = '#';
  8170.             }
  8171.  
  8172.             auto lastDot = filename.find_last_of('.');
  8173.             if (lastDot != std::string::npos) {
  8174.                 filename.erase(lastDot);
  8175.             }
  8176.  
  8177.             tags.push_back(std::move(filename));
  8178.             setTags(testCase, tags);
  8179.         }
  8180.     }
  8181.  
  8182. }
  8183.  
  8184. namespace Catch {
  8185.  
  8186.     Session::Session() {
  8187.         static bool alreadyInstantiated = false;
  8188.         if (alreadyInstantiated) {
  8189.             try { CATCH_INTERNAL_ERROR("Only one instance of Catch::Session can ever be used"); } catch (...) { getMutableRegistryHub().registerStartupException(); }
  8190.         }
  8191.  
  8192.         const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
  8193.         if (!exceptions.empty()) {
  8194.             m_startupExceptions = true;
  8195.             Colour colourGuard(Colour::Red);
  8196.             Catch::cerr() << "Errors occured during startup!" << '\n';
  8197.             // iterate over all exceptions and notify user
  8198.             for (const auto& ex_ptr : exceptions) {
  8199.                 try {
  8200.                     std::rethrow_exception(ex_ptr);
  8201.                 } catch (std::exception const& ex) {
  8202.                     Catch::cerr() << Column(ex.what()).indent(2) << '\n';
  8203.                 }
  8204.             }
  8205.         }
  8206.  
  8207.         alreadyInstantiated = true;
  8208.         m_cli = makeCommandLineParser(m_configData);
  8209.     }
  8210.     Session::~Session() {
  8211.         Catch::cleanUp();
  8212.     }
  8213.  
  8214.     void Session::showHelp() const {
  8215.         Catch::cout()
  8216.             << "\nCatch v" << libraryVersion() << "\n"
  8217.             << m_cli << std::endl
  8218.             << "For more detailed usage please see the project docs\n" << std::endl;
  8219.     }
  8220.     void Session::libIdentify() {
  8221.         Catch::cout()
  8222.             << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
  8223.             << std::left << std::setw(16) << "category: " << "testframework\n"
  8224.             << std::left << std::setw(16) << "framework: " << "Catch Test\n"
  8225.             << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
  8226.     }
  8227.  
  8228.     int Session::applyCommandLine(int argc, char* argv[]) {
  8229.         if (m_startupExceptions)
  8230.             return 1;
  8231.  
  8232.         auto result = m_cli.parse(clara::Args(argc, argv));
  8233.         if (!result) {
  8234.             Catch::cerr()
  8235.                 << Colour(Colour::Red)
  8236.                 << "\nError(s) in input:\n"
  8237.                 << Column(result.errorMessage()).indent(2)
  8238.                 << "\n\n";
  8239.             Catch::cerr() << "Run with -? for usage\n" << std::endl;
  8240.             return MaxExitCode;
  8241.         }
  8242.  
  8243.         if (m_configData.showHelp)
  8244.             showHelp();
  8245.         if (m_configData.libIdentify)
  8246.             libIdentify();
  8247.         m_config.reset();
  8248.         return 0;
  8249.     }
  8250.  
  8251.     void Session::useConfigData(ConfigData const& configData) {
  8252.         m_configData = configData;
  8253.         m_config.reset();
  8254.     }
  8255.  
  8256.     int Session::run(int argc, char* argv[]) {
  8257.         if (m_startupExceptions)
  8258.             return 1;
  8259.         int returnCode = applyCommandLine(argc, argv);
  8260.         if (returnCode == 0)
  8261.             returnCode = run();
  8262.         return returnCode;
  8263.     }
  8264.  
  8265. #if defined(WIN32) && defined(UNICODE)
  8266.     int Session::run(int argc, wchar_t* const argv[]) {
  8267.  
  8268.         char **utf8Argv = new char *[argc];
  8269.  
  8270.         for (int i = 0; i < argc; ++i) {
  8271.             int bufSize = WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL);
  8272.  
  8273.             utf8Argv[i] = new char[bufSize];
  8274.  
  8275.             WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL);
  8276.         }
  8277.  
  8278.         int returnCode = run(argc, utf8Argv);
  8279.  
  8280.         for (int i = 0; i < argc; ++i)
  8281.             delete[] utf8Argv[i];
  8282.  
  8283.         delete[] utf8Argv;
  8284.  
  8285.         return returnCode;
  8286.     }
  8287. #endif
  8288.     int Session::run() {
  8289.         if ((m_configData.waitForKeypress & WaitForKeypress::BeforeStart) != 0) {
  8290.             Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
  8291.             static_cast<void>(std::getchar());
  8292.         }
  8293.         int exitCode = runInternal();
  8294.         if ((m_configData.waitForKeypress & WaitForKeypress::BeforeExit) != 0) {
  8295.             Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
  8296.             static_cast<void>(std::getchar());
  8297.         }
  8298.         return exitCode;
  8299.     }
  8300.  
  8301.     clara::Parser const& Session::cli() const {
  8302.         return m_cli;
  8303.     }
  8304.     void Session::cli(clara::Parser const& newParser) {
  8305.         m_cli = newParser;
  8306.     }
  8307.     ConfigData& Session::configData() {
  8308.         return m_configData;
  8309.     }
  8310.     Config& Session::config() {
  8311.         if (!m_config)
  8312.             m_config = std::make_shared<Config>(m_configData);
  8313.         return *m_config;
  8314.     }
  8315.  
  8316.     int Session::runInternal() {
  8317.         if (m_startupExceptions)
  8318.             return 1;
  8319.  
  8320.         if (m_configData.showHelp || m_configData.libIdentify)
  8321.             return 0;
  8322.  
  8323.         try {
  8324.             config(); // Force config to be constructed
  8325.  
  8326.             seedRng(*m_config);
  8327.  
  8328.             if (m_configData.filenamesAsTags)
  8329.                 applyFilenamesAsTags(*m_config);
  8330.  
  8331.             // Handle list request
  8332.             if (Option<std::size_t> listed = list(config()))
  8333.                 return static_cast<int>(*listed);
  8334.  
  8335.             return (std::min)(MaxExitCode, static_cast<int>(runTests(m_config).assertions.failed));
  8336.         } catch (std::exception& ex) {
  8337.             Catch::cerr() << ex.what() << std::endl;
  8338.             return MaxExitCode;
  8339.         }
  8340.     }
  8341.  
  8342. } // end namespace Catch
  8343.   // end catch_session.cpp
  8344.   // start catch_startup_exception_registry.cpp
  8345.  
  8346. namespace Catch {
  8347.     void StartupExceptionRegistry::add(std::exception_ptr const& exception) noexcept {
  8348.         try {
  8349.             m_exceptions.push_back(exception);
  8350.         } catch (...) {
  8351.             // If we run out of memory during start-up there's really not a lot more we can do about it
  8352.             std::terminate();
  8353.         }
  8354.     }
  8355.  
  8356.     std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
  8357.         return m_exceptions;
  8358.     }
  8359.  
  8360. } // end namespace Catch
  8361.   // end catch_startup_exception_registry.cpp
  8362.   // start catch_stream.cpp
  8363.  
  8364. #include <stdexcept>
  8365. #include <cstdio>
  8366. #include <iostream>
  8367.  
  8368. namespace Catch {
  8369.  
  8370.     template<typename WriterF, std::size_t bufferSize = 256>
  8371.     class StreamBufImpl : public StreamBufBase {
  8372.         char data[bufferSize];
  8373.         WriterF m_writer;
  8374.  
  8375.     public:
  8376.         StreamBufImpl() {
  8377.             setp(data, data + sizeof(data));
  8378.         }
  8379.  
  8380.         ~StreamBufImpl() noexcept {
  8381.             StreamBufImpl::sync();
  8382.         }
  8383.  
  8384.     private:
  8385.         int overflow(int c) override {
  8386.             sync();
  8387.  
  8388.             if (c != EOF) {
  8389.                 if (pbase() == epptr())
  8390.                     m_writer(std::string(1, static_cast<char>(c)));
  8391.                 else
  8392.                     sputc(static_cast<char>(c));
  8393.             }
  8394.             return 0;
  8395.         }
  8396.  
  8397.         int sync() override {
  8398.             if (pbase() != pptr()) {
  8399.                 m_writer(std::string(pbase(), static_cast<std::string::size_type>(pptr() - pbase())));
  8400.                 setp(pbase(), epptr());
  8401.             }
  8402.             return 0;
  8403.         }
  8404.     };
  8405.  
  8406.     ///////////////////////////////////////////////////////////////////////////
  8407.  
  8408.     Catch::IStream::~IStream() = default;
  8409.  
  8410.     FileStream::FileStream(std::string const& filename) {
  8411.         m_ofs.open(filename.c_str());
  8412.         CATCH_ENFORCE(!m_ofs.fail(), "Unable to open file: '" << filename << "'");
  8413.     }
  8414.  
  8415.     std::ostream& FileStream::stream() const {
  8416.         return m_ofs;
  8417.     }
  8418.  
  8419.     struct OutputDebugWriter {
  8420.  
  8421.         void operator()(std::string const&str) {
  8422.             writeToDebugConsole(str);
  8423.         }
  8424.     };
  8425.  
  8426.     DebugOutStream::DebugOutStream()
  8427.         : m_streamBuf(new StreamBufImpl<OutputDebugWriter>()),
  8428.         m_os(m_streamBuf.get()) {
  8429.     }
  8430.  
  8431.     std::ostream& DebugOutStream::stream() const {
  8432.         return m_os;
  8433.     }
  8434.  
  8435.     // Store the streambuf from cout up-front because
  8436.     // cout may get redirected when running tests
  8437.     CoutStream::CoutStream()
  8438.         : m_os(Catch::cout().rdbuf()) {
  8439.     }
  8440.  
  8441.     std::ostream& CoutStream::stream() const {
  8442.         return m_os;
  8443.     }
  8444.  
  8445. #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
  8446.     std::ostream& cout() {
  8447.         return std::cout;
  8448.     }
  8449.     std::ostream& cerr() {
  8450.         return std::cerr;
  8451.     }
  8452.     std::ostream& clog() {
  8453.         return std::clog;
  8454.     }
  8455. #endif
  8456. }
  8457. // end catch_stream.cpp
  8458. // start catch_streambuf.cpp
  8459.  
  8460. namespace Catch {
  8461.     StreamBufBase::~StreamBufBase() = default;
  8462. }
  8463. // end catch_streambuf.cpp
  8464. // start catch_string_manip.cpp
  8465.  
  8466. #include <algorithm>
  8467. #include <ostream>
  8468. #include <cstring>
  8469. #include <cctype>
  8470.  
  8471. namespace Catch {
  8472.  
  8473.     bool startsWith(std::string const& s, std::string const& prefix) {
  8474.         return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
  8475.     }
  8476.     bool startsWith(std::string const& s, char prefix) {
  8477.         return !s.empty() && s[0] == prefix;
  8478.     }
  8479.     bool endsWith(std::string const& s, std::string const& suffix) {
  8480.         return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
  8481.     }
  8482.     bool endsWith(std::string const& s, char suffix) {
  8483.         return !s.empty() && s[s.size() - 1] == suffix;
  8484.     }
  8485.     bool contains(std::string const& s, std::string const& infix) {
  8486.         return s.find(infix) != std::string::npos;
  8487.     }
  8488.     char toLowerCh(char c) {
  8489.         return static_cast<char>(std::tolower(c));
  8490.     }
  8491.     void toLowerInPlace(std::string& s) {
  8492.         std::transform(s.begin(), s.end(), s.begin(), toLowerCh);
  8493.     }
  8494.     std::string toLower(std::string const& s) {
  8495.         std::string lc = s;
  8496.         toLowerInPlace(lc);
  8497.         return lc;
  8498.     }
  8499.     std::string trim(std::string const& str) {
  8500.         static char const* whitespaceChars = "\n\r\t ";
  8501.         std::string::size_type start = str.find_first_not_of(whitespaceChars);
  8502.         std::string::size_type end = str.find_last_not_of(whitespaceChars);
  8503.  
  8504.         return start != std::string::npos ? str.substr(start, 1 + end - start) : std::string();
  8505.     }
  8506.  
  8507.     bool replaceInPlace(std::string& str, std::string const& replaceThis, std::string const& withThis) {
  8508.         bool replaced = false;
  8509.         std::size_t i = str.find(replaceThis);
  8510.         while (i != std::string::npos) {
  8511.             replaced = true;
  8512.             str = str.substr(0, i) + withThis + str.substr(i + replaceThis.size());
  8513.             if (i < str.size() - withThis.size())
  8514.                 i = str.find(replaceThis, i + withThis.size());
  8515.             else
  8516.                 i = std::string::npos;
  8517.         }
  8518.         return replaced;
  8519.     }
  8520.  
  8521.     pluralise::pluralise(std::size_t count, std::string const& label)
  8522.         : m_count(count),
  8523.         m_label(label) {
  8524.     }
  8525.  
  8526.     std::ostream& operator << (std::ostream& os, pluralise const& pluraliser) {
  8527.         os << pluraliser.m_count << ' ' << pluraliser.m_label;
  8528.         if (pluraliser.m_count != 1)
  8529.             os << 's';
  8530.         return os;
  8531.     }
  8532.  
  8533. }
  8534. // end catch_string_manip.cpp
  8535. // start catch_stringref.cpp
  8536.  
  8537. #if defined(__clang__)
  8538. #    pragma clang diagnostic push
  8539. #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  8540. #endif
  8541.  
  8542. #include <ostream>
  8543. #include <cassert>
  8544. #include <cstring>
  8545.  
  8546. namespace Catch {
  8547.  
  8548.     auto getEmptyStringRef() -> StringRef {
  8549.         static StringRef s_emptyStringRef("");
  8550.         return s_emptyStringRef;
  8551.     }
  8552.  
  8553.     StringRef::StringRef() noexcept
  8554.         :   StringRef(getEmptyStringRef()) {
  8555.     }
  8556.  
  8557.     StringRef::StringRef(StringRef const& other) noexcept
  8558.         : m_start(other.m_start),
  8559.         m_size(other.m_size) {
  8560.     }
  8561.  
  8562.     StringRef::StringRef(StringRef&& other) noexcept
  8563.         : m_start(other.m_start),
  8564.         m_size(other.m_size),
  8565.         m_data(other.m_data) {
  8566.         other.m_data = nullptr;
  8567.     }
  8568.  
  8569.     StringRef::StringRef(char const* rawChars) noexcept
  8570.         :   m_start(rawChars),
  8571.         m_size(static_cast<size_type>(std::strlen(rawChars))) {
  8572.         assert(rawChars != nullptr);
  8573.     }
  8574.  
  8575.     StringRef::StringRef(char const* rawChars, size_type size) noexcept
  8576.         : m_start(rawChars),
  8577.         m_size(size) {
  8578.         size_type rawSize = rawChars == nullptr ? 0 : static_cast<size_type>(std::strlen(rawChars));
  8579.         if (rawSize < size)
  8580.             m_size = rawSize;
  8581.     }
  8582.  
  8583.     StringRef::StringRef(std::string const& stdString) noexcept
  8584.         :   m_start(stdString.c_str()),
  8585.         m_size(stdString.size()) {
  8586.     }
  8587.  
  8588.     StringRef::~StringRef() noexcept {
  8589.         delete[] m_data;
  8590.     }
  8591.  
  8592.     auto StringRef::operator = (StringRef other) noexcept -> StringRef& {
  8593.         swap(other);
  8594.         return *this;
  8595.     }
  8596.     StringRef::operator std::string() const {
  8597.         return std::string(m_start, m_size);
  8598.     }
  8599.  
  8600.     void StringRef::swap(StringRef& other) noexcept {
  8601.         std::swap(m_start, other.m_start);
  8602.         std::swap(m_size, other.m_size);
  8603.         std::swap(m_data, other.m_data);
  8604.     }
  8605.  
  8606.     auto StringRef::c_str() const -> char const* {
  8607.         if (isSubstring())
  8608.             const_cast<StringRef*>(this)->takeOwnership();
  8609.         return m_start;
  8610.     }
  8611.     auto StringRef::data() const noexcept -> char const* {
  8612.         return m_start;
  8613.     }
  8614.  
  8615.     auto StringRef::isOwned() const noexcept -> bool {
  8616.         return m_data != nullptr;
  8617.     }
  8618.     auto StringRef::isSubstring() const noexcept -> bool {
  8619.         return m_start[m_size] != '\0';
  8620.     }
  8621.  
  8622.     void StringRef::takeOwnership() {
  8623.         if (!isOwned()) {
  8624.             m_data = new char[m_size + 1];
  8625.             memcpy(m_data, m_start, m_size);
  8626.             m_data[m_size] = '\0';
  8627.             m_start = m_data;
  8628.         }
  8629.     }
  8630.     auto StringRef::substr(size_type start, size_type size) const noexcept -> StringRef {
  8631.         if (start < m_size)
  8632.             return StringRef(m_start + start, size);
  8633.         else
  8634.             return StringRef();
  8635.     }
  8636.     auto StringRef::operator == (StringRef const& other) const noexcept -> bool {
  8637.         return
  8638.             size() == other.size() &&
  8639.             (std::strncmp(m_start, other.m_start, size()) == 0);
  8640.     }
  8641.     auto StringRef::operator != (StringRef const& other) const noexcept -> bool {
  8642.         return !operator==(other);
  8643.     }
  8644.  
  8645.     auto StringRef::operator[](size_type index) const noexcept -> char {
  8646.         return m_start[index];
  8647.     }
  8648.  
  8649.     auto StringRef::empty() const noexcept -> bool {
  8650.         return m_size == 0;
  8651.     }
  8652.  
  8653.     auto StringRef::size() const noexcept -> size_type {
  8654.         return m_size;
  8655.     }
  8656.     auto StringRef::numberOfCharacters() const noexcept -> size_type {
  8657.         size_type noChars = m_size;
  8658.         // Make adjustments for uft encodings
  8659.         for (size_type i = 0; i < m_size; ++i) {
  8660.             char c = m_start[i];
  8661.             if ((c & 0b11000000) == 0b11000000) {
  8662.                 if ((c & 0b11100000) == 0b11000000)
  8663.                     noChars--;
  8664.                 else if ((c & 0b11110000) == 0b11100000)
  8665.                     noChars -= 2;
  8666.                 else if ((c & 0b11111000) == 0b11110000)
  8667.                     noChars -= 3;
  8668.             }
  8669.         }
  8670.         return noChars;
  8671.     }
  8672.  
  8673.     auto operator + (StringRef const& lhs, StringRef const& rhs) -> std::string {
  8674.         std::string str;
  8675.         str.reserve(lhs.size() + rhs.size());
  8676.         str += lhs;
  8677.         str += rhs;
  8678.         return str;
  8679.     }
  8680.     auto operator + (StringRef const& lhs, const char* rhs) -> std::string {
  8681.         return std::string(lhs) + std::string(rhs);
  8682.     }
  8683.     auto operator + (char const* lhs, StringRef const& rhs) -> std::string {
  8684.         return std::string(lhs) + std::string(rhs);
  8685.     }
  8686.  
  8687.     auto operator << (std::ostream& os, StringRef const& str) -> std::ostream& {
  8688.         return os << str.c_str();
  8689.     }
  8690.  
  8691. } // namespace Catch
  8692.  
  8693. #if defined(__clang__)
  8694. #    pragma clang diagnostic pop
  8695. #endif
  8696.   // end catch_stringref.cpp
  8697.   // start catch_tag_alias.cpp
  8698.  
  8699. namespace Catch {
  8700.     TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo) : tag(_tag), lineInfo(_lineInfo) {}
  8701. }
  8702. // end catch_tag_alias.cpp
  8703. // start catch_tag_alias_autoregistrar.cpp
  8704.  
  8705. namespace Catch {
  8706.  
  8707.     RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
  8708.         try {
  8709.             getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
  8710.         } catch (...) {
  8711.             // Do not throw when constructing global objects, instead register the exception to be processed later
  8712.             getMutableRegistryHub().registerStartupException();
  8713.         }
  8714.     }
  8715.  
  8716. }
  8717. // end catch_tag_alias_autoregistrar.cpp
  8718. // start catch_tag_alias_registry.cpp
  8719.  
  8720. namespace Catch {
  8721.  
  8722.     TagAliasRegistry::~TagAliasRegistry() {}
  8723.  
  8724.     TagAlias const* TagAliasRegistry::find(std::string const& alias) const {
  8725.         auto it = m_registry.find(alias);
  8726.         if (it != m_registry.end())
  8727.             return &(it->second);
  8728.         else
  8729.             return nullptr;
  8730.     }
  8731.  
  8732.     std::string TagAliasRegistry::expandAliases(std::string const& unexpandedTestSpec) const {
  8733.         std::string expandedTestSpec = unexpandedTestSpec;
  8734.         for (auto const& registryKvp : m_registry) {
  8735.             std::size_t pos = expandedTestSpec.find(registryKvp.first);
  8736.             if (pos != std::string::npos) {
  8737.                 expandedTestSpec = expandedTestSpec.substr(0, pos) +
  8738.                     registryKvp.second.tag +
  8739.                     expandedTestSpec.substr(pos + registryKvp.first.size());
  8740.             }
  8741.         }
  8742.         return expandedTestSpec;
  8743.     }
  8744.  
  8745.     void TagAliasRegistry::add(std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo) {
  8746.         CATCH_ENFORCE(startsWith(alias, "[@") && endsWith(alias, ']'),
  8747.                       "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo);
  8748.  
  8749.         CATCH_ENFORCE(m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
  8750.                       "error: tag alias, '" << alias << "' already registered.\n"
  8751.                       << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
  8752.                       << "\tRedefined at: " << lineInfo);
  8753.     }
  8754.  
  8755.     ITagAliasRegistry::~ITagAliasRegistry() {}
  8756.  
  8757.     ITagAliasRegistry const& ITagAliasRegistry::get() {
  8758.         return getRegistryHub().getTagAliasRegistry();
  8759.     }
  8760.  
  8761. } // end namespace Catch
  8762.   // end catch_tag_alias_registry.cpp
  8763.   // start catch_test_case_info.cpp
  8764.  
  8765. #include <cctype>
  8766. #include <exception>
  8767. #include <algorithm>
  8768.  
  8769. namespace Catch {
  8770.  
  8771.     TestCaseInfo::SpecialProperties parseSpecialTag(std::string const& tag) {
  8772.         if (startsWith(tag, '.') ||
  8773.             tag == "!hide")
  8774.             return TestCaseInfo::IsHidden;
  8775.         else if (tag == "!throws")
  8776.             return TestCaseInfo::Throws;
  8777.         else if (tag == "!shouldfail")
  8778.             return TestCaseInfo::ShouldFail;
  8779.         else if (tag == "!mayfail")
  8780.             return TestCaseInfo::MayFail;
  8781.         else if (tag == "!nonportable")
  8782.             return TestCaseInfo::NonPortable;
  8783.         else if (tag == "!benchmark")
  8784.             return static_cast<TestCaseInfo::SpecialProperties>(TestCaseInfo::Benchmark | TestCaseInfo::IsHidden);
  8785.         else
  8786.             return TestCaseInfo::None;
  8787.     }
  8788.     bool isReservedTag(std::string const& tag) {
  8789.         return parseSpecialTag(tag) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum(tag[0]);
  8790.     }
  8791.     void enforceNotReservedTag(std::string const& tag, SourceLineInfo const& _lineInfo) {
  8792.         CATCH_ENFORCE(!isReservedTag(tag),
  8793.                       "Tag name: [" << tag << "] is not allowed.\n"
  8794.                       << "Tag names starting with non alpha-numeric characters are reserved\n"
  8795.                       << _lineInfo);
  8796.     }
  8797.  
  8798.     TestCase makeTestCase(ITestInvoker* _testCase,
  8799.                           std::string const& _className,
  8800.                           std::string const& _name,
  8801.                           std::string const& _descOrTags,
  8802.                           SourceLineInfo const& _lineInfo) {
  8803.         bool isHidden = false;
  8804.  
  8805.         // Parse out tags
  8806.         std::vector<std::string> tags;
  8807.         std::string desc, tag;
  8808.         bool inTag = false;
  8809.         for (char c : _descOrTags) {
  8810.             if (!inTag) {
  8811.                 if (c == '[')
  8812.                     inTag = true;
  8813.                 else
  8814.                     desc += c;
  8815.             } else {
  8816.                 if (c == ']') {
  8817.                     TestCaseInfo::SpecialProperties prop = parseSpecialTag(tag);
  8818.                     if ((prop & TestCaseInfo::IsHidden) != 0)
  8819.                         isHidden = true;
  8820.                     else if (prop == TestCaseInfo::None)
  8821.                         enforceNotReservedTag(tag, _lineInfo);
  8822.  
  8823.                     tags.push_back(tag);
  8824.                     tag.clear();
  8825.                     inTag = false;
  8826.                 } else
  8827.                     tag += c;
  8828.             }
  8829.         }
  8830.         if (isHidden) {
  8831.             tags.push_back(".");
  8832.         }
  8833.  
  8834.         TestCaseInfo info(_name, _className, desc, tags, _lineInfo);
  8835.         return TestCase(_testCase, info);
  8836.     }
  8837.  
  8838.     void setTags(TestCaseInfo& testCaseInfo, std::vector<std::string> tags) {
  8839.         std::sort(begin(tags), end(tags));
  8840.         tags.erase(std::unique(begin(tags), end(tags)), end(tags));
  8841.         testCaseInfo.lcaseTags.clear();
  8842.  
  8843.         for (auto const& tag : tags) {
  8844.             std::string lcaseTag = toLower(tag);
  8845.             testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>(testCaseInfo.properties | parseSpecialTag(lcaseTag));
  8846.             testCaseInfo.lcaseTags.push_back(lcaseTag);
  8847.         }
  8848.         testCaseInfo.tags = std::move(tags);
  8849.     }
  8850.  
  8851.     TestCaseInfo::TestCaseInfo(std::string const& _name,
  8852.                                std::string const& _className,
  8853.                                std::string const& _description,
  8854.                                std::vector<std::string> const& _tags,
  8855.                                SourceLineInfo const& _lineInfo)
  8856.         : name(_name),
  8857.         className(_className),
  8858.         description(_description),
  8859.         lineInfo(_lineInfo),
  8860.         properties(None) {
  8861.         setTags(*this, _tags);
  8862.     }
  8863.  
  8864.     bool TestCaseInfo::isHidden() const {
  8865.         return (properties & IsHidden) != 0;
  8866.     }
  8867.     bool TestCaseInfo::throws() const {
  8868.         return (properties & Throws) != 0;
  8869.     }
  8870.     bool TestCaseInfo::okToFail() const {
  8871.         return (properties & (ShouldFail | MayFail)) != 0;
  8872.     }
  8873.     bool TestCaseInfo::expectedToFail() const {
  8874.         return (properties & (ShouldFail)) != 0;
  8875.     }
  8876.  
  8877.     std::string TestCaseInfo::tagsAsString() const {
  8878.         std::string ret;
  8879.         // '[' and ']' per tag
  8880.         std::size_t full_size = 2 * tags.size();
  8881.         for (const auto& tag : tags) {
  8882.             full_size += tag.size();
  8883.         }
  8884.         ret.reserve(full_size);
  8885.         for (const auto& tag : tags) {
  8886.             ret.push_back('[');
  8887.             ret.append(tag);
  8888.             ret.push_back(']');
  8889.         }
  8890.  
  8891.         return ret;
  8892.     }
  8893.  
  8894.     TestCase::TestCase(ITestInvoker* testCase, TestCaseInfo const& info) : TestCaseInfo(info), test(testCase) {}
  8895.  
  8896.     TestCase TestCase::withName(std::string const& _newName) const {
  8897.         TestCase other(*this);
  8898.         other.name = _newName;
  8899.         return other;
  8900.     }
  8901.  
  8902.     void TestCase::invoke() const {
  8903.         test->invoke();
  8904.     }
  8905.  
  8906.     bool TestCase::operator == (TestCase const& other) const {
  8907.         return  test.get() == other.test.get() &&
  8908.             name == other.name &&
  8909.             className == other.className;
  8910.     }
  8911.  
  8912.     bool TestCase::operator < (TestCase const& other) const {
  8913.         return name < other.name;
  8914.     }
  8915.  
  8916.     TestCaseInfo const& TestCase::getTestCaseInfo() const {
  8917.         return *this;
  8918.     }
  8919.  
  8920. } // end namespace Catch
  8921.   // end catch_test_case_info.cpp
  8922.   // start catch_test_case_registry_impl.cpp
  8923.  
  8924. #include <sstream>
  8925.  
  8926. namespace Catch {
  8927.  
  8928.     std::vector<TestCase> sortTests(IConfig const& config, std::vector<TestCase> const& unsortedTestCases) {
  8929.  
  8930.         std::vector<TestCase> sorted = unsortedTestCases;
  8931.  
  8932.         switch (config.runOrder()) {
  8933.             case RunTests::InLexicographicalOrder:
  8934.                 std::sort(sorted.begin(), sorted.end());
  8935.                 break;
  8936.             case RunTests::InRandomOrder:
  8937.                 seedRng(config);
  8938.                 RandomNumberGenerator::shuffle(sorted);
  8939.                 break;
  8940.             case RunTests::InDeclarationOrder:
  8941.                 // already in declaration order
  8942.                 break;
  8943.         }
  8944.         return sorted;
  8945.     }
  8946.     bool matchTest(TestCase const& testCase, TestSpec const& testSpec, IConfig const& config) {
  8947.         return testSpec.matches(testCase) && (config.allowThrows() || !testCase.throws());
  8948.     }
  8949.  
  8950.     void enforceNoDuplicateTestCases(std::vector<TestCase> const& functions) {
  8951.         std::set<TestCase> seenFunctions;
  8952.         for (auto const& function : functions) {
  8953.             auto prev = seenFunctions.insert(function);
  8954.             CATCH_ENFORCE(prev.second,
  8955.                           "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
  8956.                           << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
  8957.                           << "\tRedefined at " << function.getTestCaseInfo().lineInfo);
  8958.         }
  8959.     }
  8960.  
  8961.     std::vector<TestCase> filterTests(std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config) {
  8962.         std::vector<TestCase> filtered;
  8963.         filtered.reserve(testCases.size());
  8964.         for (auto const& testCase : testCases)
  8965.             if (matchTest(testCase, testSpec, config))
  8966.                 filtered.push_back(testCase);
  8967.         return filtered;
  8968.     }
  8969.     std::vector<TestCase> const& getAllTestCasesSorted(IConfig const& config) {
  8970.         return getRegistryHub().getTestCaseRegistry().getAllTestsSorted(config);
  8971.     }
  8972.  
  8973.     void TestRegistry::registerTest(TestCase const& testCase) {
  8974.         std::string name = testCase.getTestCaseInfo().name;
  8975.         if (name.empty()) {
  8976.             std::ostringstream oss;
  8977.             oss << "Anonymous test case " << ++m_unnamedCount;
  8978.             return registerTest(testCase.withName(oss.str()));
  8979.         }
  8980.         m_functions.push_back(testCase);
  8981.     }
  8982.  
  8983.     std::vector<TestCase> const& TestRegistry::getAllTests() const {
  8984.         return m_functions;
  8985.     }
  8986.     std::vector<TestCase> const& TestRegistry::getAllTestsSorted(IConfig const& config) const {
  8987.         if (m_sortedFunctions.empty())
  8988.             enforceNoDuplicateTestCases(m_functions);
  8989.  
  8990.         if (m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty()) {
  8991.             m_sortedFunctions = sortTests(config, m_functions);
  8992.             m_currentSortOrder = config.runOrder();
  8993.         }
  8994.         return m_sortedFunctions;
  8995.     }
  8996.  
  8997.     ///////////////////////////////////////////////////////////////////////////
  8998.     TestInvokerAsFunction::TestInvokerAsFunction(void(*testAsFunction)()) noexcept : m_testAsFunction(testAsFunction) {}
  8999.  
  9000.     void TestInvokerAsFunction::invoke() const {
  9001.         m_testAsFunction();
  9002.     }
  9003.  
  9004.     std::string extractClassName(std::string const& classOrQualifiedMethodName) {
  9005.         std::string className = classOrQualifiedMethodName;
  9006.         if (startsWith(className, '&')) {
  9007.             std::size_t lastColons = className.rfind("::");
  9008.             std::size_t penultimateColons = className.rfind("::", lastColons - 1);
  9009.             if (penultimateColons == std::string::npos)
  9010.                 penultimateColons = 1;
  9011.             className = className.substr(penultimateColons, lastColons - penultimateColons);
  9012.         }
  9013.         return className;
  9014.     }
  9015.  
  9016. } // end namespace Catch
  9017.   // end catch_test_case_registry_impl.cpp
  9018.   // start catch_test_case_tracker.cpp
  9019.  
  9020. #include <algorithm>
  9021. #include <assert.h>
  9022. #include <stdexcept>
  9023. #include <memory>
  9024.  
  9025. #if defined(__clang__)
  9026. #    pragma clang diagnostic push
  9027. #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  9028. #endif
  9029.  
  9030. namespace Catch {
  9031.     namespace TestCaseTracking {
  9032.  
  9033.         NameAndLocation::NameAndLocation(std::string const& _name, SourceLineInfo const& _location)
  9034.             : name(_name),
  9035.             location(_location) {
  9036.         }
  9037.  
  9038.         ITracker::~ITracker() = default;
  9039.  
  9040.         TrackerContext& TrackerContext::instance() {
  9041.             static TrackerContext s_instance;
  9042.             return s_instance;
  9043.         }
  9044.  
  9045.         ITracker& TrackerContext::startRun() {
  9046.             m_rootTracker = std::make_shared<SectionTracker>(NameAndLocation("{root}", CATCH_INTERNAL_LINEINFO), *this, nullptr);
  9047.             m_currentTracker = nullptr;
  9048.             m_runState = Executing;
  9049.             return *m_rootTracker;
  9050.         }
  9051.  
  9052.         void TrackerContext::endRun() {
  9053.             m_rootTracker.reset();
  9054.             m_currentTracker = nullptr;
  9055.             m_runState = NotStarted;
  9056.         }
  9057.  
  9058.         void TrackerContext::startCycle() {
  9059.             m_currentTracker = m_rootTracker.get();
  9060.             m_runState = Executing;
  9061.         }
  9062.         void TrackerContext::completeCycle() {
  9063.             m_runState = CompletedCycle;
  9064.         }
  9065.  
  9066.         bool TrackerContext::completedCycle() const {
  9067.             return m_runState == CompletedCycle;
  9068.         }
  9069.         ITracker& TrackerContext::currentTracker() {
  9070.             return *m_currentTracker;
  9071.         }
  9072.         void TrackerContext::setCurrentTracker(ITracker* tracker) {
  9073.             m_currentTracker = tracker;
  9074.         }
  9075.  
  9076.         TrackerBase::TrackerHasName::TrackerHasName(NameAndLocation const& nameAndLocation) : m_nameAndLocation(nameAndLocation) {}
  9077.         bool TrackerBase::TrackerHasName::operator ()(ITrackerPtr const& tracker) const {
  9078.             return
  9079.                 tracker->nameAndLocation().name == m_nameAndLocation.name &&
  9080.                 tracker->nameAndLocation().location == m_nameAndLocation.location;
  9081.         }
  9082.  
  9083.         TrackerBase::TrackerBase(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent)
  9084.             : m_nameAndLocation(nameAndLocation),
  9085.             m_ctx(ctx),
  9086.             m_parent(parent) {
  9087.         }
  9088.  
  9089.         NameAndLocation const& TrackerBase::nameAndLocation() const {
  9090.             return m_nameAndLocation;
  9091.         }
  9092.         bool TrackerBase::isComplete() const {
  9093.             return m_runState == CompletedSuccessfully || m_runState == Failed;
  9094.         }
  9095.         bool TrackerBase::isSuccessfullyCompleted() const {
  9096.             return m_runState == CompletedSuccessfully;
  9097.         }
  9098.         bool TrackerBase::isOpen() const {
  9099.             return m_runState != NotStarted && !isComplete();
  9100.         }
  9101.         bool TrackerBase::hasChildren() const {
  9102.             return !m_children.empty();
  9103.         }
  9104.  
  9105.         void TrackerBase::addChild(ITrackerPtr const& child) {
  9106.             m_children.push_back(child);
  9107.         }
  9108.  
  9109.         ITrackerPtr TrackerBase::findChild(NameAndLocation const& nameAndLocation) {
  9110.             auto it = std::find_if(m_children.begin(), m_children.end(), TrackerHasName(nameAndLocation));
  9111.             return(it != m_children.end())
  9112.                 ? *it
  9113.                 : nullptr;
  9114.         }
  9115.         ITracker& TrackerBase::parent() {
  9116.             assert(m_parent); // Should always be non-null except for root
  9117.             return *m_parent;
  9118.         }
  9119.  
  9120.         void TrackerBase::openChild() {
  9121.             if (m_runState != ExecutingChildren) {
  9122.                 m_runState = ExecutingChildren;
  9123.                 if (m_parent)
  9124.                     m_parent->openChild();
  9125.             }
  9126.         }
  9127.  
  9128.         bool TrackerBase::isSectionTracker() const { return false; }
  9129.         bool TrackerBase::isIndexTracker() const { return false; }
  9130.  
  9131.         void TrackerBase::open() {
  9132.             m_runState = Executing;
  9133.             moveToThis();
  9134.             if (m_parent)
  9135.                 m_parent->openChild();
  9136.         }
  9137.  
  9138.         void TrackerBase::close() {
  9139.  
  9140.             // Close any still open children (e.g. generators)
  9141.             while (&m_ctx.currentTracker() != this)
  9142.                 m_ctx.currentTracker().close();
  9143.  
  9144.             switch (m_runState) {
  9145.                 case NeedsAnotherRun:
  9146.                     break;
  9147.  
  9148.                 case Executing:
  9149.                     m_runState = CompletedSuccessfully;
  9150.                     break;
  9151.                 case ExecutingChildren:
  9152.                     if (m_children.empty() || m_children.back()->isComplete())
  9153.                         m_runState = CompletedSuccessfully;
  9154.                     break;
  9155.  
  9156.                 case NotStarted:
  9157.                 case CompletedSuccessfully:
  9158.                 case Failed:
  9159.                     CATCH_INTERNAL_ERROR("Illogical state: " << m_runState);
  9160.  
  9161.                 default:
  9162.                     CATCH_INTERNAL_ERROR("Unknown state: " << m_runState);
  9163.             }
  9164.             moveToParent();
  9165.             m_ctx.completeCycle();
  9166.         }
  9167.         void TrackerBase::fail() {
  9168.             m_runState = Failed;
  9169.             if (m_parent)
  9170.                 m_parent->markAsNeedingAnotherRun();
  9171.             moveToParent();
  9172.             m_ctx.completeCycle();
  9173.         }
  9174.         void TrackerBase::markAsNeedingAnotherRun() {
  9175.             m_runState = NeedsAnotherRun;
  9176.         }
  9177.  
  9178.         void TrackerBase::moveToParent() {
  9179.             assert(m_parent);
  9180.             m_ctx.setCurrentTracker(m_parent);
  9181.         }
  9182.         void TrackerBase::moveToThis() {
  9183.             m_ctx.setCurrentTracker(this);
  9184.         }
  9185.  
  9186.         SectionTracker::SectionTracker(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent)
  9187.             : TrackerBase(nameAndLocation, ctx, parent) {
  9188.             if (parent) {
  9189.                 while (!parent->isSectionTracker())
  9190.                     parent = &parent->parent();
  9191.  
  9192.                 SectionTracker& parentSection = static_cast<SectionTracker&>(*parent);
  9193.                 addNextFilters(parentSection.m_filters);
  9194.             }
  9195.         }
  9196.  
  9197.         bool SectionTracker::isSectionTracker() const { return true; }
  9198.  
  9199.         SectionTracker& SectionTracker::acquire(TrackerContext& ctx, NameAndLocation const& nameAndLocation) {
  9200.             std::shared_ptr<SectionTracker> section;
  9201.  
  9202.             ITracker& currentTracker = ctx.currentTracker();
  9203.             if (ITrackerPtr childTracker = currentTracker.findChild(nameAndLocation)) {
  9204.                 assert(childTracker);
  9205.                 assert(childTracker->isSectionTracker());
  9206.                 section = std::static_pointer_cast<SectionTracker>(childTracker);
  9207.             } else {
  9208.                 section = std::make_shared<SectionTracker>(nameAndLocation, ctx, &currentTracker);
  9209.                 currentTracker.addChild(section);
  9210.             }
  9211.             if (!ctx.completedCycle())
  9212.                 section->tryOpen();
  9213.             return *section;
  9214.         }
  9215.  
  9216.         void SectionTracker::tryOpen() {
  9217.             if (!isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name))
  9218.                 open();
  9219.         }
  9220.  
  9221.         void SectionTracker::addInitialFilters(std::vector<std::string> const& filters) {
  9222.             if (!filters.empty()) {
  9223.                 m_filters.push_back(""); // Root - should never be consulted
  9224.                 m_filters.push_back(""); // Test Case - not a section filter
  9225.                 m_filters.insert(m_filters.end(), filters.begin(), filters.end());
  9226.             }
  9227.         }
  9228.         void SectionTracker::addNextFilters(std::vector<std::string> const& filters) {
  9229.             if (filters.size() > 1)
  9230.                 m_filters.insert(m_filters.end(), ++filters.begin(), filters.end());
  9231.         }
  9232.  
  9233.         IndexTracker::IndexTracker(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size)
  9234.             : TrackerBase(nameAndLocation, ctx, parent),
  9235.             m_size(size) {
  9236.         }
  9237.  
  9238.         bool IndexTracker::isIndexTracker() const { return true; }
  9239.  
  9240.         IndexTracker& IndexTracker::acquire(TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size) {
  9241.             std::shared_ptr<IndexTracker> tracker;
  9242.  
  9243.             ITracker& currentTracker = ctx.currentTracker();
  9244.             if (ITrackerPtr childTracker = currentTracker.findChild(nameAndLocation)) {
  9245.                 assert(childTracker);
  9246.                 assert(childTracker->isIndexTracker());
  9247.                 tracker = std::static_pointer_cast<IndexTracker>(childTracker);
  9248.             } else {
  9249.                 tracker = std::make_shared<IndexTracker>(nameAndLocation, ctx, &currentTracker, size);
  9250.                 currentTracker.addChild(tracker);
  9251.             }
  9252.  
  9253.             if (!ctx.completedCycle() && !tracker->isComplete()) {
  9254.                 if (tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun)
  9255.                     tracker->moveNext();
  9256.                 tracker->open();
  9257.             }
  9258.  
  9259.             return *tracker;
  9260.         }
  9261.  
  9262.         int IndexTracker::index() const { return m_index; }
  9263.  
  9264.         void IndexTracker::moveNext() {
  9265.             m_index++;
  9266.             m_children.clear();
  9267.         }
  9268.  
  9269.         void IndexTracker::close() {
  9270.             TrackerBase::close();
  9271.             if (m_runState == CompletedSuccessfully && m_index < m_size - 1)
  9272.                 m_runState = Executing;
  9273.         }
  9274.  
  9275.     } // namespace TestCaseTracking
  9276.  
  9277.     using TestCaseTracking::ITracker;
  9278.     using TestCaseTracking::TrackerContext;
  9279.     using TestCaseTracking::SectionTracker;
  9280.     using TestCaseTracking::IndexTracker;
  9281.  
  9282. } // namespace Catch
  9283.  
  9284. #if defined(__clang__)
  9285. #    pragma clang diagnostic pop
  9286. #endif
  9287.   // end catch_test_case_tracker.cpp
  9288.   // start catch_test_registry.cpp
  9289.  
  9290. namespace Catch {
  9291.  
  9292.     auto makeTestInvoker(void(*testAsFunction)()) noexcept -> ITestInvoker* {
  9293.         return new(std::nothrow) TestInvokerAsFunction(testAsFunction);
  9294.     }
  9295.  
  9296.     NameAndTags::NameAndTags(StringRef name_, StringRef tags_) noexcept : name(name_), tags(tags_) {}
  9297.  
  9298.     AutoReg::AutoReg(ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef classOrMethod, NameAndTags const& nameAndTags) noexcept {
  9299.         try {
  9300.             getMutableRegistryHub()
  9301.                 .registerTest(
  9302.                     makeTestCase(
  9303.                         invoker,
  9304.                         extractClassName(classOrMethod),
  9305.                         nameAndTags.name,
  9306.                         nameAndTags.tags,
  9307.                         lineInfo));
  9308.         } catch (...) {
  9309.             // Do not throw when constructing global objects, instead register the exception to be processed later
  9310.             getMutableRegistryHub().registerStartupException();
  9311.         }
  9312.     }
  9313.  
  9314.     AutoReg::~AutoReg() = default;
  9315. }
  9316. // end catch_test_registry.cpp
  9317. // start catch_test_spec.cpp
  9318.  
  9319. #include <algorithm>
  9320. #include <string>
  9321. #include <vector>
  9322. #include <memory>
  9323.  
  9324. namespace Catch {
  9325.  
  9326.     TestSpec::Pattern::~Pattern() = default;
  9327.     TestSpec::NamePattern::~NamePattern() = default;
  9328.     TestSpec::TagPattern::~TagPattern() = default;
  9329.     TestSpec::ExcludedPattern::~ExcludedPattern() = default;
  9330.  
  9331.     TestSpec::NamePattern::NamePattern(std::string const& name)
  9332.         : m_wildcardPattern(toLower(name), CaseSensitive::No) {
  9333.     }
  9334.     bool TestSpec::NamePattern::matches(TestCaseInfo const& testCase) const {
  9335.         return m_wildcardPattern.matches(toLower(testCase.name));
  9336.     }
  9337.  
  9338.     TestSpec::TagPattern::TagPattern(std::string const& tag) : m_tag(toLower(tag)) {}
  9339.     bool TestSpec::TagPattern::matches(TestCaseInfo const& testCase) const {
  9340.         return std::find(begin(testCase.lcaseTags),
  9341.                          end(testCase.lcaseTags),
  9342.                          m_tag) != end(testCase.lcaseTags);
  9343.     }
  9344.  
  9345.     TestSpec::ExcludedPattern::ExcludedPattern(PatternPtr const& underlyingPattern) : m_underlyingPattern(underlyingPattern) {}
  9346.     bool TestSpec::ExcludedPattern::matches(TestCaseInfo const& testCase) const { return !m_underlyingPattern->matches(testCase); }
  9347.  
  9348.     bool TestSpec::Filter::matches(TestCaseInfo const& testCase) const {
  9349.         // All patterns in a filter must match for the filter to be a match
  9350.         for (auto const& pattern : m_patterns) {
  9351.             if (!pattern->matches(testCase))
  9352.                 return false;
  9353.         }
  9354.         return true;
  9355.     }
  9356.  
  9357.     bool TestSpec::hasFilters() const {
  9358.         return !m_filters.empty();
  9359.     }
  9360.     bool TestSpec::matches(TestCaseInfo const& testCase) const {
  9361.         // A TestSpec matches if any filter matches
  9362.         for (auto const& filter : m_filters)
  9363.             if (filter.matches(testCase))
  9364.                 return true;
  9365.         return false;
  9366.     }
  9367. }
  9368. // end catch_test_spec.cpp
  9369. // start catch_test_spec_parser.cpp
  9370.  
  9371. namespace Catch {
  9372.  
  9373.     TestSpecParser::TestSpecParser(ITagAliasRegistry const& tagAliases) : m_tagAliases(&tagAliases) {}
  9374.  
  9375.     TestSpecParser& TestSpecParser::parse(std::string const& arg) {
  9376.         m_mode = None;
  9377.         m_exclusion = false;
  9378.         m_start = std::string::npos;
  9379.         m_arg = m_tagAliases->expandAliases(arg);
  9380.         m_escapeChars.clear();
  9381.         for (m_pos = 0; m_pos < m_arg.size(); ++m_pos)
  9382.             visitChar(m_arg[m_pos]);
  9383.         if (m_mode == Name)
  9384.             addPattern<TestSpec::NamePattern>();
  9385.         return *this;
  9386.     }
  9387.     TestSpec TestSpecParser::testSpec() {
  9388.         addFilter();
  9389.         return m_testSpec;
  9390.     }
  9391.  
  9392.     void TestSpecParser::visitChar(char c) {
  9393.         if (m_mode == None) {
  9394.             switch (c) {
  9395.                 case ' ': return;
  9396.                 case '~': m_exclusion = true; return;
  9397.                 case '[': return startNewMode(Tag, ++m_pos);
  9398.                 case '"': return startNewMode(QuotedName, ++m_pos);
  9399.                 case '\\': return escape();
  9400.                 default: startNewMode(Name, m_pos); break;
  9401.             }
  9402.         }
  9403.         if (m_mode == Name) {
  9404.             if (c == ',') {
  9405.                 addPattern<TestSpec::NamePattern>();
  9406.                 addFilter();
  9407.             } else if (c == '[') {
  9408.                 if (subString() == "exclude:")
  9409.                     m_exclusion = true;
  9410.                 else
  9411.                     addPattern<TestSpec::NamePattern>();
  9412.                 startNewMode(Tag, ++m_pos);
  9413.             } else if (c == '\\')
  9414.                 escape();
  9415.         } else if (m_mode == EscapedName)
  9416.             m_mode = Name;
  9417.         else if (m_mode == QuotedName && c == '"')
  9418.             addPattern<TestSpec::NamePattern>();
  9419.         else if (m_mode == Tag && c == ']')
  9420.             addPattern<TestSpec::TagPattern>();
  9421.     }
  9422.     void TestSpecParser::startNewMode(Mode mode, std::size_t start) {
  9423.         m_mode = mode;
  9424.         m_start = start;
  9425.     }
  9426.     void TestSpecParser::escape() {
  9427.         if (m_mode == None)
  9428.             m_start = m_pos;
  9429.         m_mode = EscapedName;
  9430.         m_escapeChars.push_back(m_pos);
  9431.     }
  9432.     std::string TestSpecParser::subString() const { return m_arg.substr(m_start, m_pos - m_start); }
  9433.  
  9434.     void TestSpecParser::addFilter() {
  9435.         if (!m_currentFilter.m_patterns.empty()) {
  9436.             m_testSpec.m_filters.push_back(m_currentFilter);
  9437.             m_currentFilter = TestSpec::Filter();
  9438.         }
  9439.     }
  9440.  
  9441.     TestSpec parseTestSpec(std::string const& arg) {
  9442.         return TestSpecParser(ITagAliasRegistry::get()).parse(arg).testSpec();
  9443.     }
  9444.  
  9445. } // namespace Catch
  9446.   // end catch_test_spec_parser.cpp
  9447.   // start catch_timer.cpp
  9448.  
  9449. #include <chrono>
  9450.  
  9451. namespace Catch {
  9452.  
  9453.     auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
  9454.         return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
  9455.     }
  9456.  
  9457.     auto estimateClockResolution() -> uint64_t {
  9458.         uint64_t sum = 0;
  9459.         static const uint64_t iterations = 1000000;
  9460.  
  9461.         for (std::size_t i = 0; i < iterations; ++i) {
  9462.  
  9463.             uint64_t ticks;
  9464.             uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
  9465.             do {
  9466.                 ticks = getCurrentNanosecondsSinceEpoch();
  9467.             } while (ticks == baseTicks);
  9468.  
  9469.             auto delta = ticks - baseTicks;
  9470.             sum += delta;
  9471.         }
  9472.  
  9473.         // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
  9474.         // - and potentially do more iterations if there's a high variance.
  9475.         return sum / iterations;
  9476.     }
  9477.     auto getEstimatedClockResolution() -> uint64_t {
  9478.         static auto s_resolution = estimateClockResolution();
  9479.         return s_resolution;
  9480.     }
  9481.  
  9482.     void Timer::start() {
  9483.         m_nanoseconds = getCurrentNanosecondsSinceEpoch();
  9484.     }
  9485.     auto Timer::getElapsedNanoseconds() const -> unsigned int {
  9486.         return static_cast<unsigned int>(getCurrentNanosecondsSinceEpoch() - m_nanoseconds);
  9487.     }
  9488.     auto Timer::getElapsedMicroseconds() const -> unsigned int {
  9489.         return static_cast<unsigned int>(getElapsedNanoseconds() / 1000);
  9490.     }
  9491.     auto Timer::getElapsedMilliseconds() const -> unsigned int {
  9492.         return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);
  9493.     }
  9494.     auto Timer::getElapsedSeconds() const -> double {
  9495.         return getElapsedMicroseconds() / 1000000.0;
  9496.     }
  9497.  
  9498. } // namespace Catch
  9499.   // end catch_timer.cpp
  9500.   // start catch_tostring.cpp
  9501.  
  9502. #if defined(__clang__)
  9503. #    pragma clang diagnostic push
  9504. #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  9505. #    pragma clang diagnostic ignored "-Wglobal-constructors"
  9506. #endif
  9507.  
  9508. #include <iomanip>
  9509.  
  9510. namespace Catch {
  9511.  
  9512.     namespace Detail {
  9513.  
  9514.         const std::string unprintableString = "{?}";
  9515.  
  9516.         namespace {
  9517.             const int hexThreshold = 255;
  9518.  
  9519.             struct Endianness {
  9520.                 enum Arch { Big, Little };
  9521.  
  9522.                 static Arch which() {
  9523.                     union _ {
  9524.                         int asInt;
  9525.                         char asChar[sizeof(int)];
  9526.                     } u;
  9527.  
  9528.                     u.asInt = 1;
  9529.                     return (u.asChar[sizeof(int) - 1] == 1) ? Big : Little;
  9530.                 }
  9531.             };
  9532.         }
  9533.  
  9534.         std::string rawMemoryToString(const void *object, std::size_t size) {
  9535.             // Reverse order for little endian architectures
  9536.             int i = 0, end = static_cast<int>(size), inc = 1;
  9537.             if (Endianness::which() == Endianness::Little) {
  9538.                 i = end - 1;
  9539.                 end = inc = -1;
  9540.             }
  9541.  
  9542.             unsigned char const *bytes = static_cast<unsigned char const *>(object);
  9543.             std::ostringstream os;
  9544.             os << "0x" << std::setfill('0') << std::hex;
  9545.             for (; i != end; i += inc)
  9546.                 os << std::setw(2) << static_cast<unsigned>(bytes[i]);
  9547.             return os.str();
  9548.         }
  9549.     }
  9550.  
  9551.     template<typename T>
  9552.     std::string fpToString(T value, int precision) {
  9553.         std::ostringstream oss;
  9554.         oss << std::setprecision(precision)
  9555.             << std::fixed
  9556.             << value;
  9557.         std::string d = oss.str();
  9558.         std::size_t i = d.find_last_not_of('0');
  9559.         if (i != std::string::npos && i != d.size() - 1) {
  9560.             if (d[i] == '.')
  9561.                 i++;
  9562.             d = d.substr(0, i + 1);
  9563.         }
  9564.         return d;
  9565.     }
  9566.  
  9567.     //// ======================================================= ////
  9568.     //
  9569.     //   Out-of-line defs for full specialization of StringMaker
  9570.     //
  9571.     //// ======================================================= ////
  9572.  
  9573.     std::string StringMaker<std::string>::convert(const std::string& str) {
  9574.         if (!getCurrentContext().getConfig()->showInvisibles()) {
  9575.             return '"' + str + '"';
  9576.         }
  9577.  
  9578.         std::string s("\"");
  9579.         for (char c : str) {
  9580.             switch (c) {
  9581.                 case '\n':
  9582.                     s.append("\\n");
  9583.                     break;
  9584.                 case '\t':
  9585.                     s.append("\\t");
  9586.                     break;
  9587.                 default:
  9588.                     s.push_back(c);
  9589.                     break;
  9590.             }
  9591.         }
  9592.         s.append("\"");
  9593.         return s;
  9594.     }
  9595.  
  9596.     std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
  9597.         std::string s;
  9598.         s.reserve(wstr.size());
  9599.         for (auto c : wstr) {
  9600.             s += (c <= 0xff) ? static_cast<char>(c) : '?';
  9601.         }
  9602.         return ::Catch::Detail::stringify(s);
  9603.     }
  9604.  
  9605.     std::string StringMaker<char const*>::convert(char const* str) {
  9606.         if (str) {
  9607.             return ::Catch::Detail::stringify(std::string{ str });
  9608.         } else {
  9609.             return{ "{null string}" };
  9610.         }
  9611.     }
  9612.     std::string StringMaker<char*>::convert(char* str) {
  9613.         if (str) {
  9614.             return ::Catch::Detail::stringify(std::string{ str });
  9615.         } else {
  9616.             return{ "{null string}" };
  9617.         }
  9618.     }
  9619.     std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
  9620.         if (str) {
  9621.             return ::Catch::Detail::stringify(std::wstring{ str });
  9622.         } else {
  9623.             return{ "{null string}" };
  9624.         }
  9625.     }
  9626.     std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
  9627.         if (str) {
  9628.             return ::Catch::Detail::stringify(std::wstring{ str });
  9629.         } else {
  9630.             return{ "{null string}" };
  9631.         }
  9632.     }
  9633.  
  9634.     std::string StringMaker<int>::convert(int value) {
  9635.         return ::Catch::Detail::stringify(static_cast<long long>(value));
  9636.     }
  9637.     std::string StringMaker<long>::convert(long value) {
  9638.         return ::Catch::Detail::stringify(static_cast<long long>(value));
  9639.     }
  9640.     std::string StringMaker<long long>::convert(long long value) {
  9641.         std::ostringstream oss;
  9642.         oss << value;
  9643.         if (value > Detail::hexThreshold) {
  9644.             oss << " (0x" << std::hex << value << ')';
  9645.         }
  9646.         return oss.str();
  9647.     }
  9648.  
  9649.     std::string StringMaker<unsigned int>::convert(unsigned int value) {
  9650.         return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  9651.     }
  9652.     std::string StringMaker<unsigned long>::convert(unsigned long value) {
  9653.         return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  9654.     }
  9655.     std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
  9656.         std::ostringstream oss;
  9657.         oss << value;
  9658.         if (value > Detail::hexThreshold) {
  9659.             oss << " (0x" << std::hex << value << ')';
  9660.         }
  9661.         return oss.str();
  9662.     }
  9663.  
  9664.     std::string StringMaker<bool>::convert(bool b) {
  9665.         return b ? "true" : "false";
  9666.     }
  9667.  
  9668.     std::string StringMaker<char>::convert(char value) {
  9669.         if (value == '\r') {
  9670.             return "'\\r'";
  9671.         } else if (value == '\f') {
  9672.             return "'\\f'";
  9673.         } else if (value == '\n') {
  9674.             return "'\\n'";
  9675.         } else if (value == '\t') {
  9676.             return "'\\t'";
  9677.         } else if ('\0' <= value && value < ' ') {
  9678.             return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
  9679.         } else {
  9680.             char chstr[] = "' '";
  9681.             chstr[1] = value;
  9682.             return chstr;
  9683.         }
  9684.     }
  9685.     std::string StringMaker<signed char>::convert(signed char c) {
  9686.         return ::Catch::Detail::stringify(static_cast<char>(c));
  9687.     }
  9688.     std::string StringMaker<unsigned char>::convert(unsigned char c) {
  9689.         return ::Catch::Detail::stringify(static_cast<char>(c));
  9690.     }
  9691.  
  9692.     std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
  9693.         return "nullptr";
  9694.     }
  9695.  
  9696.     std::string StringMaker<float>::convert(float value) {
  9697.         return fpToString(value, 5) + 'f';
  9698.     }
  9699.     std::string StringMaker<double>::convert(double value) {
  9700.         return fpToString(value, 10);
  9701.     }
  9702.  
  9703. } // end namespace Catch
  9704.  
  9705. #if defined(__clang__)
  9706. #    pragma clang diagnostic pop
  9707. #endif
  9708.  
  9709.   // end catch_tostring.cpp
  9710.   // start catch_totals.cpp
  9711.  
  9712. namespace Catch {
  9713.  
  9714.     Counts Counts::operator - (Counts const& other) const {
  9715.         Counts diff;
  9716.         diff.passed = passed - other.passed;
  9717.         diff.failed = failed - other.failed;
  9718.         diff.failedButOk = failedButOk - other.failedButOk;
  9719.         return diff;
  9720.     }
  9721.  
  9722.     Counts& Counts::operator += (Counts const& other) {
  9723.         passed += other.passed;
  9724.         failed += other.failed;
  9725.         failedButOk += other.failedButOk;
  9726.         return *this;
  9727.     }
  9728.  
  9729.     std::size_t Counts::total() const {
  9730.         return passed + failed + failedButOk;
  9731.     }
  9732.     bool Counts::allPassed() const {
  9733.         return failed == 0 && failedButOk == 0;
  9734.     }
  9735.     bool Counts::allOk() const {
  9736.         return failed == 0;
  9737.     }
  9738.  
  9739.     Totals Totals::operator - (Totals const& other) const {
  9740.         Totals diff;
  9741.         diff.assertions = assertions - other.assertions;
  9742.         diff.testCases = testCases - other.testCases;
  9743.         return diff;
  9744.     }
  9745.  
  9746.     Totals& Totals::operator += (Totals const& other) {
  9747.         assertions += other.assertions;
  9748.         testCases += other.testCases;
  9749.         return *this;
  9750.     }
  9751.  
  9752.     Totals Totals::delta(Totals const& prevTotals) const {
  9753.         Totals diff = *this - prevTotals;
  9754.         if (diff.assertions.failed > 0)
  9755.             ++diff.testCases.failed;
  9756.         else if (diff.assertions.failedButOk > 0)
  9757.             ++diff.testCases.failedButOk;
  9758.         else
  9759.             ++diff.testCases.passed;
  9760.         return diff;
  9761.     }
  9762.  
  9763. }
  9764. // end catch_totals.cpp
  9765. // start catch_version.cpp
  9766.  
  9767. #include <ostream>
  9768.  
  9769. namespace Catch {
  9770.  
  9771.     Version::Version
  9772.     (unsigned int _majorVersion,
  9773.      unsigned int _minorVersion,
  9774.      unsigned int _patchNumber,
  9775.      char const * const _branchName,
  9776.      unsigned int _buildNumber)
  9777.         : majorVersion(_majorVersion),
  9778.         minorVersion(_minorVersion),
  9779.         patchNumber(_patchNumber),
  9780.         branchName(_branchName),
  9781.         buildNumber(_buildNumber) {
  9782.     }
  9783.  
  9784.     std::ostream& operator << (std::ostream& os, Version const& version) {
  9785.         os << version.majorVersion << '.'
  9786.             << version.minorVersion << '.'
  9787.             << version.patchNumber;
  9788.         // branchName is never null -> 0th char is \0 if it is empty
  9789.         if (version.branchName[0]) {
  9790.             os << '-' << version.branchName
  9791.                 << '.' << version.buildNumber;
  9792.         }
  9793.         return os;
  9794.     }
  9795.  
  9796.     Version const& libraryVersion() {
  9797.         static Version version(2, 0, 1, "", 0);
  9798.         return version;
  9799.     }
  9800.  
  9801. }
  9802. // end catch_version.cpp
  9803. // start catch_wildcard_pattern.cpp
  9804.  
  9805. namespace Catch {
  9806.  
  9807.     WildcardPattern::WildcardPattern(std::string const& pattern,
  9808.                                      CaseSensitive::Choice caseSensitivity)
  9809.         : m_caseSensitivity(caseSensitivity),
  9810.         m_pattern(adjustCase(pattern)) {
  9811.         if (startsWith(m_pattern, '*')) {
  9812.             m_pattern = m_pattern.substr(1);
  9813.             m_wildcard = WildcardAtStart;
  9814.         }
  9815.         if (endsWith(m_pattern, '*')) {
  9816.             m_pattern = m_pattern.substr(0, m_pattern.size() - 1);
  9817.             m_wildcard = static_cast<WildcardPosition>(m_wildcard | WildcardAtEnd);
  9818.         }
  9819.     }
  9820.  
  9821.     bool WildcardPattern::matches(std::string const& str) const {
  9822.         switch (m_wildcard) {
  9823.             case NoWildcard:
  9824.                 return m_pattern == adjustCase(str);
  9825.             case WildcardAtStart:
  9826.                 return endsWith(adjustCase(str), m_pattern);
  9827.             case WildcardAtEnd:
  9828.                 return startsWith(adjustCase(str), m_pattern);
  9829.             case WildcardAtBothEnds:
  9830.                 return contains(adjustCase(str), m_pattern);
  9831.             default:
  9832.                 CATCH_INTERNAL_ERROR("Unknown enum");
  9833.         }
  9834.     }
  9835.  
  9836.     std::string WildcardPattern::adjustCase(std::string const& str) const {
  9837.         return m_caseSensitivity == CaseSensitive::No ? toLower(str) : str;
  9838.     }
  9839. }
  9840. // end catch_wildcard_pattern.cpp
  9841. // start catch_xmlwriter.cpp
  9842.  
  9843. // start catch_xmlwriter.h
  9844.  
  9845. #include <sstream>
  9846. #include <vector>
  9847.  
  9848. namespace Catch {
  9849.  
  9850.     class XmlEncode {
  9851.     public:
  9852.         enum ForWhat { ForTextNodes, ForAttributes };
  9853.  
  9854.         XmlEncode(std::string const& str, ForWhat forWhat = ForTextNodes);
  9855.  
  9856.         void encodeTo(std::ostream& os) const;
  9857.  
  9858.         friend std::ostream& operator << (std::ostream& os, XmlEncode const& xmlEncode);
  9859.  
  9860.     private:
  9861.         std::string m_str;
  9862.         ForWhat m_forWhat;
  9863.     };
  9864.  
  9865.     class XmlWriter {
  9866.     public:
  9867.  
  9868.         class ScopedElement {
  9869.         public:
  9870.             ScopedElement(XmlWriter* writer);
  9871.  
  9872.             ScopedElement(ScopedElement&& other) noexcept;
  9873.             ScopedElement& operator=(ScopedElement&& other) noexcept;
  9874.  
  9875.             ~ScopedElement();
  9876.  
  9877.             ScopedElement& writeText(std::string const& text, bool indent = true);
  9878.  
  9879.             template<typename T>
  9880.             ScopedElement& writeAttribute(std::string const& name, T const& attribute) {
  9881.                 m_writer->writeAttribute(name, attribute);
  9882.                 return *this;
  9883.             }
  9884.  
  9885.         private:
  9886.             mutable XmlWriter* m_writer = nullptr;
  9887.         };
  9888.  
  9889.         XmlWriter(std::ostream& os = Catch::cout());
  9890.         ~XmlWriter();
  9891.  
  9892.         XmlWriter(XmlWriter const&) = delete;
  9893.         XmlWriter& operator=(XmlWriter const&) = delete;
  9894.  
  9895.         XmlWriter& startElement(std::string const& name);
  9896.  
  9897.         ScopedElement scopedElement(std::string const& name);
  9898.  
  9899.         XmlWriter& endElement();
  9900.  
  9901.         XmlWriter& writeAttribute(std::string const& name, std::string const& attribute);
  9902.  
  9903.         XmlWriter& writeAttribute(std::string const& name, bool attribute);
  9904.  
  9905.         template<typename T>
  9906.         XmlWriter& writeAttribute(std::string const& name, T const& attribute) {
  9907.             m_oss.clear();
  9908.             m_oss.str(std::string());
  9909.             m_oss << attribute;
  9910.             return writeAttribute(name, m_oss.str());
  9911.         }
  9912.  
  9913.         XmlWriter& writeText(std::string const& text, bool indent = true);
  9914.  
  9915.         XmlWriter& writeComment(std::string const& text);
  9916.  
  9917.         void writeStylesheetRef(std::string const& url);
  9918.  
  9919.         XmlWriter& writeBlankLine();
  9920.  
  9921.         void ensureTagClosed();
  9922.  
  9923.     private:
  9924.  
  9925.         void writeDeclaration();
  9926.  
  9927.         void newlineIfNecessary();
  9928.  
  9929.         bool m_tagIsOpen = false;
  9930.         bool m_needsNewline = false;
  9931.         std::vector<std::string> m_tags;
  9932.         std::string m_indent;
  9933.         std::ostream& m_os;
  9934.         std::ostringstream m_oss;
  9935.     };
  9936.  
  9937. }
  9938.  
  9939. // end catch_xmlwriter.h
  9940. #include <iomanip>
  9941.  
  9942. namespace Catch {
  9943.  
  9944.     XmlEncode::XmlEncode(std::string const& str, ForWhat forWhat)
  9945.         : m_str(str),
  9946.         m_forWhat(forWhat) {
  9947.     }
  9948.  
  9949.     void XmlEncode::encodeTo(std::ostream& os) const {
  9950.  
  9951.         // Apostrophe escaping not necessary if we always use " to write attributes
  9952.         // (see: http://www.w3.org/TR/xml/#syntax)
  9953.  
  9954.         for (std::size_t i = 0; i < m_str.size(); ++i) {
  9955.             char c = m_str[i];
  9956.             switch (c) {
  9957.                 case '<':   os << "&lt;"; break;
  9958.                 case '&':   os << "&amp;"; break;
  9959.  
  9960.                 case '>':
  9961.                     // See: http://www.w3.org/TR/xml/#syntax
  9962.                     if (i > 2 && m_str[i - 1] == ']' && m_str[i - 2] == ']')
  9963.                         os << "&gt;";
  9964.                     else
  9965.                         os << c;
  9966.                     break;
  9967.  
  9968.                 case '\"':
  9969.                     if (m_forWhat == ForAttributes)
  9970.                         os << "&quot;";
  9971.                     else
  9972.                         os << c;
  9973.                     break;
  9974.  
  9975.                 default:
  9976.                     // Escape control chars - based on contribution by @espenalb in PR #465 and
  9977.                     // by @mrpi PR #588
  9978.                     if ((c >= 0 && c < '\x09') || (c > '\x0D' && c < '\x20') || c == '\x7F') {
  9979.                         // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
  9980.                         os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
  9981.                             << static_cast<int>(c);
  9982.                     } else
  9983.                         os << c;
  9984.             }
  9985.         }
  9986.     }
  9987.  
  9988.     std::ostream& operator << (std::ostream& os, XmlEncode const& xmlEncode) {
  9989.         xmlEncode.encodeTo(os);
  9990.         return os;
  9991.     }
  9992.  
  9993.     XmlWriter::ScopedElement::ScopedElement(XmlWriter* writer)
  9994.         : m_writer(writer) {
  9995.     }
  9996.  
  9997.     XmlWriter::ScopedElement::ScopedElement(ScopedElement&& other) noexcept
  9998.         : m_writer(other.m_writer) {
  9999.         other.m_writer = nullptr;
  10000.     }
  10001.     XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=(ScopedElement&& other) noexcept {
  10002.         if (m_writer) {
  10003.             m_writer->endElement();
  10004.         }
  10005.         m_writer = other.m_writer;
  10006.         other.m_writer = nullptr;
  10007.         return *this;
  10008.     }
  10009.  
  10010.     XmlWriter::ScopedElement::~ScopedElement() {
  10011.         if (m_writer)
  10012.             m_writer->endElement();
  10013.     }
  10014.  
  10015.     XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText(std::string const& text, bool indent) {
  10016.         m_writer->writeText(text, indent);
  10017.         return *this;
  10018.     }
  10019.  
  10020.     XmlWriter::XmlWriter(std::ostream& os) : m_os(os) {
  10021.         writeDeclaration();
  10022.     }
  10023.  
  10024.     XmlWriter::~XmlWriter() {
  10025.         while (!m_tags.empty())
  10026.             endElement();
  10027.     }
  10028.  
  10029.     XmlWriter& XmlWriter::startElement(std::string const& name) {
  10030.         ensureTagClosed();
  10031.         newlineIfNecessary();
  10032.         m_os << m_indent << '<' << name;
  10033.         m_tags.push_back(name);
  10034.         m_indent += "  ";
  10035.         m_tagIsOpen = true;
  10036.         return *this;
  10037.     }
  10038.  
  10039.     XmlWriter::ScopedElement XmlWriter::scopedElement(std::string const& name) {
  10040.         ScopedElement scoped(this);
  10041.         startElement(name);
  10042.         return scoped;
  10043.     }
  10044.  
  10045.     XmlWriter& XmlWriter::endElement() {
  10046.         newlineIfNecessary();
  10047.         m_indent = m_indent.substr(0, m_indent.size() - 2);
  10048.         if (m_tagIsOpen) {
  10049.             m_os << "/>";
  10050.             m_tagIsOpen = false;
  10051.         } else {
  10052.             m_os << m_indent << "</" << m_tags.back() << ">";
  10053.         }
  10054.         m_os << std::endl;
  10055.         m_tags.pop_back();
  10056.         return *this;
  10057.     }
  10058.  
  10059.     XmlWriter& XmlWriter::writeAttribute(std::string const& name, std::string const& attribute) {
  10060.         if (!name.empty() && !attribute.empty())
  10061.             m_os << ' ' << name << "=\"" << XmlEncode(attribute, XmlEncode::ForAttributes) << '"';
  10062.         return *this;
  10063.     }
  10064.  
  10065.     XmlWriter& XmlWriter::writeAttribute(std::string const& name, bool attribute) {
  10066.         m_os << ' ' << name << "=\"" << (attribute ? "true" : "false") << '"';
  10067.         return *this;
  10068.     }
  10069.  
  10070.     XmlWriter& XmlWriter::writeText(std::string const& text, bool indent) {
  10071.         if (!text.empty()) {
  10072.             bool tagWasOpen = m_tagIsOpen;
  10073.             ensureTagClosed();
  10074.             if (tagWasOpen && indent)
  10075.                 m_os << m_indent;
  10076.             m_os << XmlEncode(text);
  10077.             m_needsNewline = true;
  10078.         }
  10079.         return *this;
  10080.     }
  10081.  
  10082.     XmlWriter& XmlWriter::writeComment(std::string const& text) {
  10083.         ensureTagClosed();
  10084.         m_os << m_indent << "<!--" << text << "-->";
  10085.         m_needsNewline = true;
  10086.         return *this;
  10087.     }
  10088.  
  10089.     void XmlWriter::writeStylesheetRef(std::string const& url) {
  10090.         m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
  10091.     }
  10092.  
  10093.     XmlWriter& XmlWriter::writeBlankLine() {
  10094.         ensureTagClosed();
  10095.         m_os << '\n';
  10096.         return *this;
  10097.     }
  10098.  
  10099.     void XmlWriter::ensureTagClosed() {
  10100.         if (m_tagIsOpen) {
  10101.             m_os << ">" << std::endl;
  10102.             m_tagIsOpen = false;
  10103.         }
  10104.     }
  10105.  
  10106.     void XmlWriter::writeDeclaration() {
  10107.         m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  10108.     }
  10109.  
  10110.     void XmlWriter::newlineIfNecessary() {
  10111.         if (m_needsNewline) {
  10112.             m_os << std::endl;
  10113.             m_needsNewline = false;
  10114.         }
  10115.     }
  10116. }
  10117. // end catch_xmlwriter.cpp
  10118. // start catch_reporter_bases.cpp
  10119.  
  10120. #include <cstring>
  10121. #include <cfloat>
  10122. #include <cstdio>
  10123. #include <assert.h>
  10124. #include <memory>
  10125.  
  10126. namespace Catch {
  10127.     void prepareExpandedExpression(AssertionResult& result) {
  10128.         result.getExpandedExpression();
  10129.     }
  10130.  
  10131.     // Because formatting using c++ streams is stateful, drop down to C is required
  10132.     // Alternatively we could use stringstream, but its performance is... not good.
  10133.     std::string getFormattedDuration(double duration) {
  10134.         // Max exponent + 1 is required to represent the whole part
  10135.         // + 1 for decimal point
  10136.         // + 3 for the 3 decimal places
  10137.         // + 1 for null terminator
  10138.         const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
  10139.         char buffer[maxDoubleSize];
  10140.  
  10141.         // Save previous errno, to prevent sprintf from overwriting it
  10142.         ErrnoGuard guard;
  10143. #ifdef _MSC_VER
  10144.         sprintf_s(buffer, "%.3f", duration);
  10145. #else
  10146.         sprintf(buffer, "%.3f", duration);
  10147. #endif
  10148.         return std::string(buffer);
  10149.     }
  10150.  
  10151.     TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
  10152.         :StreamingReporterBase(_config) {}
  10153.  
  10154.     void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
  10155.  
  10156.     bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
  10157.         return false;
  10158.     }
  10159.  
  10160. } // end namespace Catch
  10161.   // end catch_reporter_bases.cpp
  10162.   // start catch_reporter_compact.cpp
  10163.  
  10164. namespace {
  10165.  
  10166. #ifdef CATCH_PLATFORM_MAC
  10167.     const char* failedString() { return "FAILED"; }
  10168.     const char* passedString() { return "PASSED"; }
  10169. #else
  10170.     const char* failedString() { return "failed"; }
  10171.     const char* passedString() { return "passed"; }
  10172. #endif
  10173.  
  10174.     // Colour::LightGrey
  10175.     Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
  10176.  
  10177.     std::string bothOrAll(std::size_t count) {
  10178.         return count == 1 ? std::string() :
  10179.             count == 2 ? "both " : "all ";
  10180.     }
  10181. }
  10182.  
  10183. namespace Catch {
  10184.  
  10185.     struct CompactReporter : StreamingReporterBase<CompactReporter> {
  10186.  
  10187.         using StreamingReporterBase::StreamingReporterBase;
  10188.  
  10189.         ~CompactReporter() override;
  10190.  
  10191.         static std::string getDescription() {
  10192.             return "Reports test results on a single line, suitable for IDEs";
  10193.         }
  10194.  
  10195.         ReporterPreferences getPreferences() const override {
  10196.             ReporterPreferences prefs;
  10197.             prefs.shouldRedirectStdOut = false;
  10198.             return prefs;
  10199.         }
  10200.  
  10201.         void noMatchingTestCases(std::string const& spec) override {
  10202.             stream << "No test cases matched '" << spec << '\'' << std::endl;
  10203.         }
  10204.  
  10205.         void assertionStarting(AssertionInfo const&) override {}
  10206.  
  10207.         bool assertionEnded(AssertionStats const& _assertionStats) override {
  10208.             AssertionResult const& result = _assertionStats.assertionResult;
  10209.  
  10210.             bool printInfoMessages = true;
  10211.  
  10212.             // Drop out if result was successful and we're not printing those
  10213.             if (!m_config->includeSuccessfulResults() && result.isOk()) {
  10214.                 if (result.getResultType() != ResultWas::Warning)
  10215.                     return false;
  10216.                 printInfoMessages = false;
  10217.             }
  10218.  
  10219.             AssertionPrinter printer(stream, _assertionStats, printInfoMessages);
  10220.             printer.print();
  10221.  
  10222.             stream << std::endl;
  10223.             return true;
  10224.         }
  10225.  
  10226.         void sectionEnded(SectionStats const& _sectionStats) override {
  10227.             if (m_config->showDurations() == ShowDurations::Always) {
  10228.                 stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  10229.             }
  10230.         }
  10231.  
  10232.         void testRunEnded(TestRunStats const& _testRunStats) override {
  10233.             printTotals(_testRunStats.totals);
  10234.             stream << '\n' << std::endl;
  10235.             StreamingReporterBase::testRunEnded(_testRunStats);
  10236.         }
  10237.  
  10238.     private:
  10239.         class AssertionPrinter {
  10240.         public:
  10241.             AssertionPrinter& operator= (AssertionPrinter const&) = delete;
  10242.             AssertionPrinter(AssertionPrinter const&) = delete;
  10243.             AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
  10244.                 : stream(_stream)
  10245.                 , result(_stats.assertionResult)
  10246.                 , messages(_stats.infoMessages)
  10247.                 , itMessage(_stats.infoMessages.begin())
  10248.                 , printInfoMessages(_printInfoMessages) {
  10249.             }
  10250.  
  10251.             void print() {
  10252.                 printSourceInfo();
  10253.  
  10254.                 itMessage = messages.begin();
  10255.  
  10256.                 switch (result.getResultType()) {
  10257.                     case ResultWas::Ok:
  10258.                         printResultType(Colour::ResultSuccess, passedString());
  10259.                         printOriginalExpression();
  10260.                         printReconstructedExpression();
  10261.                         if (!result.hasExpression())
  10262.                             printRemainingMessages(Colour::None);
  10263.                         else
  10264.                             printRemainingMessages();
  10265.                         break;
  10266.                     case ResultWas::ExpressionFailed:
  10267.                         if (result.isOk())
  10268.                             printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
  10269.                         else
  10270.                             printResultType(Colour::Error, failedString());
  10271.                         printOriginalExpression();
  10272.                         printReconstructedExpression();
  10273.                         printRemainingMessages();
  10274.                         break;
  10275.                     case ResultWas::ThrewException:
  10276.                         printResultType(Colour::Error, failedString());
  10277.                         printIssue("unexpected exception with message:");
  10278.                         printMessage();
  10279.                         printExpressionWas();
  10280.                         printRemainingMessages();
  10281.                         break;
  10282.                     case ResultWas::FatalErrorCondition:
  10283.                         printResultType(Colour::Error, failedString());
  10284.                         printIssue("fatal error condition with message:");
  10285.                         printMessage();
  10286.                         printExpressionWas();
  10287.                         printRemainingMessages();
  10288.                         break;
  10289.                     case ResultWas::DidntThrowException:
  10290.                         printResultType(Colour::Error, failedString());
  10291.                         printIssue("expected exception, got none");
  10292.                         printExpressionWas();
  10293.                         printRemainingMessages();
  10294.                         break;
  10295.                     case ResultWas::Info:
  10296.                         printResultType(Colour::None, "info");
  10297.                         printMessage();
  10298.                         printRemainingMessages();
  10299.                         break;
  10300.                     case ResultWas::Warning:
  10301.                         printResultType(Colour::None, "warning");
  10302.                         printMessage();
  10303.                         printRemainingMessages();
  10304.                         break;
  10305.                     case ResultWas::ExplicitFailure:
  10306.                         printResultType(Colour::Error, failedString());
  10307.                         printIssue("explicitly");
  10308.                         printRemainingMessages(Colour::None);
  10309.                         break;
  10310.                         // These cases are here to prevent compiler warnings
  10311.                     case ResultWas::Unknown:
  10312.                     case ResultWas::FailureBit:
  10313.                     case ResultWas::Exception:
  10314.                         printResultType(Colour::Error, "** internal error **");
  10315.                         break;
  10316.                 }
  10317.             }
  10318.  
  10319.         private:
  10320.             void printSourceInfo() const {
  10321.                 Colour colourGuard(Colour::FileName);
  10322.                 stream << result.getSourceInfo() << ':';
  10323.             }
  10324.  
  10325.             void printResultType(Colour::Code colour, std::string const& passOrFail) const {
  10326.                 if (!passOrFail.empty()) {
  10327.                     {
  10328.                         Colour colourGuard(colour);
  10329.                         stream << ' ' << passOrFail;
  10330.                     }
  10331.                     stream << ':';
  10332.                 }
  10333.             }
  10334.  
  10335.             void printIssue(std::string const& issue) const {
  10336.                 stream << ' ' << issue;
  10337.             }
  10338.  
  10339.             void printExpressionWas() {
  10340.                 if (result.hasExpression()) {
  10341.                     stream << ';';
  10342.                     {
  10343.                         Colour colour(dimColour());
  10344.                         stream << " expression was:";
  10345.                     }
  10346.                     printOriginalExpression();
  10347.                 }
  10348.             }
  10349.  
  10350.             void printOriginalExpression() const {
  10351.                 if (result.hasExpression()) {
  10352.                     stream << ' ' << result.getExpression();
  10353.                 }
  10354.             }
  10355.  
  10356.             void printReconstructedExpression() const {
  10357.                 if (result.hasExpandedExpression()) {
  10358.                     {
  10359.                         Colour colour(dimColour());
  10360.                         stream << " for: ";
  10361.                     }
  10362.                     stream << result.getExpandedExpression();
  10363.                 }
  10364.             }
  10365.  
  10366.             void printMessage() {
  10367.                 if (itMessage != messages.end()) {
  10368.                     stream << " '" << itMessage->message << '\'';
  10369.                     ++itMessage;
  10370.                 }
  10371.             }
  10372.  
  10373.             void printRemainingMessages(Colour::Code colour = dimColour()) {
  10374.                 if (itMessage == messages.end())
  10375.                     return;
  10376.  
  10377.                 // using messages.end() directly yields (or auto) compilation error:
  10378.                 std::vector<MessageInfo>::const_iterator itEnd = messages.end();
  10379.                 const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
  10380.  
  10381.                 {
  10382.                     Colour colourGuard(colour);
  10383.                     stream << " with " << pluralise(N, "message") << ':';
  10384.                 }
  10385.  
  10386.                 for (; itMessage != itEnd; ) {
  10387.                     // If this assertion is a warning ignore any INFO messages
  10388.                     if (printInfoMessages || itMessage->type != ResultWas::Info) {
  10389.                         stream << " '" << itMessage->message << '\'';
  10390.                         if (++itMessage != itEnd) {
  10391.                             Colour colourGuard(dimColour());
  10392.                             stream << " and";
  10393.                         }
  10394.                     }
  10395.                 }
  10396.             }
  10397.  
  10398.         private:
  10399.             std::ostream& stream;
  10400.             AssertionResult const& result;
  10401.             std::vector<MessageInfo> messages;
  10402.             std::vector<MessageInfo>::const_iterator itMessage;
  10403.             bool printInfoMessages;
  10404.         };
  10405.  
  10406.         // Colour, message variants:
  10407.         // - white: No tests ran.
  10408.         // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
  10409.         // - white: Passed [both/all] N test cases (no assertions).
  10410.         // -   red: Failed N tests cases, failed M assertions.
  10411.         // - green: Passed [both/all] N tests cases with M assertions.
  10412.  
  10413.         void printTotals(const Totals& totals) const {
  10414.             if (totals.testCases.total() == 0) {
  10415.                 stream << "No tests ran.";
  10416.             } else if (totals.testCases.failed == totals.testCases.total()) {
  10417.                 Colour colour(Colour::ResultError);
  10418.                 const std::string qualify_assertions_failed =
  10419.                     totals.assertions.failed == totals.assertions.total() ?
  10420.                     bothOrAll(totals.assertions.failed) : std::string();
  10421.                 stream <<
  10422.                     "Failed " << bothOrAll(totals.testCases.failed)
  10423.                     << pluralise(totals.testCases.failed, "test case") << ", "
  10424.                     "failed " << qualify_assertions_failed <<
  10425.                     pluralise(totals.assertions.failed, "assertion") << '.';
  10426.             } else if (totals.assertions.total() == 0) {
  10427.                 stream <<
  10428.                     "Passed " << bothOrAll(totals.testCases.total())
  10429.                     << pluralise(totals.testCases.total(), "test case")
  10430.                     << " (no assertions).";
  10431.             } else if (totals.assertions.failed) {
  10432.                 Colour colour(Colour::ResultError);
  10433.                 stream <<
  10434.                     "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
  10435.                     "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
  10436.             } else {
  10437.                 Colour colour(Colour::ResultSuccess);
  10438.                 stream <<
  10439.                     "Passed " << bothOrAll(totals.testCases.passed)
  10440.                     << pluralise(totals.testCases.passed, "test case") <<
  10441.                     " with " << pluralise(totals.assertions.passed, "assertion") << '.';
  10442.             }
  10443.         }
  10444.     };
  10445.  
  10446.     CompactReporter::~CompactReporter() {}
  10447.  
  10448.     CATCH_REGISTER_REPORTER("compact", CompactReporter)
  10449.  
  10450. } // end namespace Catch
  10451.   // end catch_reporter_compact.cpp
  10452.   // start catch_reporter_console.cpp
  10453.  
  10454. #include <cfloat>
  10455. #include <cstdio>
  10456.  
  10457. #if defined(_MSC_VER)
  10458. #pragma warning(push)
  10459. #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  10460.   // Note that 4062 (not all labels are handled
  10461.   // and default is missing) is enabled
  10462. #endif
  10463.  
  10464. namespace Catch {
  10465.  
  10466.     namespace {
  10467.         std::size_t makeRatio(std::size_t number, std::size_t total) {
  10468.             std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
  10469.             return (ratio == 0 && number > 0) ? 1 : ratio;
  10470.         }
  10471.  
  10472.         std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
  10473.             if (i > j && i > k)
  10474.                 return i;
  10475.             else if (j > k)
  10476.                 return j;
  10477.             else
  10478.                 return k;
  10479.         }
  10480.  
  10481.         struct ColumnInfo {
  10482.             enum Justification { Left, Right };
  10483.             std::string name;
  10484.             int width;
  10485.             Justification justification;
  10486.         };
  10487.         struct ColumnBreak {};
  10488.         struct RowBreak {};
  10489.  
  10490.         class TablePrinter {
  10491.             std::ostream& m_os;
  10492.             std::vector<ColumnInfo> m_columnInfos;
  10493.             std::ostringstream m_oss;
  10494.             int m_currentColumn = -1;
  10495.             bool m_isOpen = false;
  10496.  
  10497.         public:
  10498.             TablePrinter(std::ostream& os, std::vector<ColumnInfo> const& columnInfos)
  10499.                 : m_os(os),
  10500.                 m_columnInfos(columnInfos) {
  10501.             }
  10502.  
  10503.             auto columnInfos() const -> std::vector<ColumnInfo> const& {
  10504.                 return m_columnInfos;
  10505.             }
  10506.  
  10507.             void open() {
  10508.                 if (!m_isOpen) {
  10509.                     m_isOpen = true;
  10510.                     *this << RowBreak();
  10511.                     for (auto const& info : m_columnInfos)
  10512.                         *this << info.name << ColumnBreak();
  10513.                     *this << RowBreak();
  10514.                     m_os << Catch::getLineOfChars<'-'>() << "\n";
  10515.                 }
  10516.             }
  10517.             void close() {
  10518.                 if (m_isOpen) {
  10519.                     *this << RowBreak();
  10520.                     m_os << std::endl;
  10521.                     m_isOpen = false;
  10522.                 }
  10523.             }
  10524.  
  10525.             template<typename T>
  10526.             friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
  10527.                 tp.m_oss << value;
  10528.                 return tp;
  10529.             }
  10530.  
  10531.             friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
  10532.                 auto colStr = tp.m_oss.str();
  10533.                 // This takes account of utf8 encodings
  10534.                 auto strSize = Catch::StringRef(colStr).numberOfCharacters();
  10535.                 tp.m_oss.str("");
  10536.                 tp.open();
  10537.                 if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
  10538.                     tp.m_currentColumn = -1;
  10539.                     tp.m_os << "\n";
  10540.                 }
  10541.                 tp.m_currentColumn++;
  10542.  
  10543.                 auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
  10544.                 auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width))
  10545.                     ? std::string(colInfo.width - (strSize + 2), ' ')
  10546.                     : std::string();
  10547.                 if (colInfo.justification == ColumnInfo::Left)
  10548.                     tp.m_os << colStr << padding << " ";
  10549.                 else
  10550.                     tp.m_os << padding << colStr << " ";
  10551.                 return tp;
  10552.             }
  10553.  
  10554.             friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
  10555.                 if (tp.m_currentColumn > 0) {
  10556.                     tp.m_os << "\n";
  10557.                     tp.m_currentColumn = -1;
  10558.                 }
  10559.                 return tp;
  10560.             }
  10561.         };
  10562.  
  10563.         class Duration {
  10564.             enum class Unit {
  10565.                 Auto,
  10566.                 Nanoseconds,
  10567.                 Microseconds,
  10568.                 Milliseconds,
  10569.                 Seconds,
  10570.                 Minutes
  10571.             };
  10572.             static const uint64_t s_nanosecondsInAMicrosecond = 1000;
  10573.             static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
  10574.             static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
  10575.             static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
  10576.  
  10577.             uint64_t m_inNanoseconds;
  10578.             Unit m_units;
  10579.  
  10580.         public:
  10581.             Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
  10582.                 : m_inNanoseconds(inNanoseconds),
  10583.                 m_units(units) {
  10584.                 if (m_units == Unit::Auto) {
  10585.                     if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
  10586.                         m_units = Unit::Nanoseconds;
  10587.                     else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
  10588.                         m_units = Unit::Microseconds;
  10589.                     else if (m_inNanoseconds < s_nanosecondsInASecond)
  10590.                         m_units = Unit::Milliseconds;
  10591.                     else if (m_inNanoseconds < s_nanosecondsInAMinute)
  10592.                         m_units = Unit::Seconds;
  10593.                     else
  10594.                         m_units = Unit::Minutes;
  10595.                 }
  10596.  
  10597.             }
  10598.  
  10599.             auto value() const -> double {
  10600.                 switch (m_units) {
  10601.                     case Unit::Microseconds:
  10602.                         return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
  10603.                     case Unit::Milliseconds:
  10604.                         return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
  10605.                     case Unit::Seconds:
  10606.                         return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
  10607.                     case Unit::Minutes:
  10608.                         return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
  10609.                     default:
  10610.                         return static_cast<double>(m_inNanoseconds);
  10611.                 }
  10612.             }
  10613.             auto unitsAsString() const -> std::string {
  10614.                 switch (m_units) {
  10615.                     case Unit::Nanoseconds:
  10616.                         return "ns";
  10617.                     case Unit::Microseconds:
  10618.                         return "µs";
  10619.                     case Unit::Milliseconds:
  10620.                         return "ms";
  10621.                     case Unit::Seconds:
  10622.                         return "s";
  10623.                     case Unit::Minutes:
  10624.                         return "m";
  10625.                     default:
  10626.                         return "** internal error **";
  10627.                 }
  10628.  
  10629.             }
  10630.             friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
  10631.                 return os << duration.value() << " " << duration.unitsAsString();
  10632.             }
  10633.         };
  10634.     } // end anon namespace
  10635.  
  10636.     struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
  10637.         TablePrinter m_tablePrinter;
  10638.  
  10639.         ConsoleReporter(ReporterConfig const& config)
  10640.             : StreamingReporterBase(config),
  10641.             m_tablePrinter(config.stream(),
  10642.             {
  10643.                 { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
  10644.                 { "iters", 8, ColumnInfo::Right },
  10645.                 { "elapsed ns", 14, ColumnInfo::Right },
  10646.                 { "average", 14, ColumnInfo::Right }
  10647.             }) {
  10648.         }
  10649.         ~ConsoleReporter() override;
  10650.         static std::string getDescription() {
  10651.             return "Reports test results as plain lines of text";
  10652.         }
  10653.  
  10654.         void noMatchingTestCases(std::string const& spec) override {
  10655.             stream << "No test cases matched '" << spec << '\'' << std::endl;
  10656.         }
  10657.  
  10658.         void assertionStarting(AssertionInfo const&) override {
  10659.         }
  10660.  
  10661.         bool assertionEnded(AssertionStats const& _assertionStats) override {
  10662.             AssertionResult const& result = _assertionStats.assertionResult;
  10663.  
  10664.             bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  10665.  
  10666.             // Drop out if result was successful but we're not printing them.
  10667.             if (!includeResults && result.getResultType() != ResultWas::Warning)
  10668.                 return false;
  10669.  
  10670.             lazyPrint();
  10671.  
  10672.             AssertionPrinter printer(stream, _assertionStats, includeResults);
  10673.             printer.print();
  10674.             stream << std::endl;
  10675.             return true;
  10676.         }
  10677.  
  10678.         void sectionStarting(SectionInfo const& _sectionInfo) override {
  10679.             m_headerPrinted = false;
  10680.             StreamingReporterBase::sectionStarting(_sectionInfo);
  10681.         }
  10682.         void sectionEnded(SectionStats const& _sectionStats) override {
  10683.             m_tablePrinter.close();
  10684.             if (_sectionStats.missingAssertions) {
  10685.                 lazyPrint();
  10686.                 Colour colour(Colour::ResultError);
  10687.                 if (m_sectionStack.size() > 1)
  10688.                     stream << "\nNo assertions in section";
  10689.                 else
  10690.                     stream << "\nNo assertions in test case";
  10691.                 stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
  10692.             }
  10693.             if (m_config->showDurations() == ShowDurations::Always) {
  10694.                 stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  10695.             }
  10696.             if (m_headerPrinted) {
  10697.                 m_headerPrinted = false;
  10698.             }
  10699.             StreamingReporterBase::sectionEnded(_sectionStats);
  10700.         }
  10701.  
  10702.         void benchmarkStarting(BenchmarkInfo const& info) override {
  10703.             lazyPrintWithoutClosingBenchmarkTable();
  10704.  
  10705.             auto nameCol = Column(info.name).width(m_tablePrinter.columnInfos()[0].width - 2);
  10706.  
  10707.             bool firstLine = true;
  10708.             for (auto line : nameCol) {
  10709.                 if (!firstLine)
  10710.                     m_tablePrinter << ColumnBreak() << ColumnBreak() << ColumnBreak();
  10711.                 else
  10712.                     firstLine = false;
  10713.  
  10714.                 m_tablePrinter << line << ColumnBreak();
  10715.             }
  10716.         }
  10717.         void benchmarkEnded(BenchmarkStats const& stats) override {
  10718.             Duration average(stats.elapsedTimeInNanoseconds / stats.iterations);
  10719.             m_tablePrinter
  10720.                 << stats.iterations << ColumnBreak()
  10721.                 << stats.elapsedTimeInNanoseconds << ColumnBreak()
  10722.                 << average << ColumnBreak();
  10723.         }
  10724.  
  10725.         void testCaseEnded(TestCaseStats const& _testCaseStats) override {
  10726.             m_tablePrinter.close();
  10727.             StreamingReporterBase::testCaseEnded(_testCaseStats);
  10728.             m_headerPrinted = false;
  10729.         }
  10730.         void testGroupEnded(TestGroupStats const& _testGroupStats) override {
  10731.             if (currentGroupInfo.used) {
  10732.                 printSummaryDivider();
  10733.                 stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
  10734.                 printTotals(_testGroupStats.totals);
  10735.                 stream << '\n' << std::endl;
  10736.             }
  10737.             StreamingReporterBase::testGroupEnded(_testGroupStats);
  10738.         }
  10739.         void testRunEnded(TestRunStats const& _testRunStats) override {
  10740.             printTotalsDivider(_testRunStats.totals);
  10741.             printTotals(_testRunStats.totals);
  10742.             stream << std::endl;
  10743.             StreamingReporterBase::testRunEnded(_testRunStats);
  10744.         }
  10745.  
  10746.     private:
  10747.  
  10748.         class AssertionPrinter {
  10749.         public:
  10750.             AssertionPrinter& operator= (AssertionPrinter const&) = delete;
  10751.             AssertionPrinter(AssertionPrinter const&) = delete;
  10752.             AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
  10753.                 : stream(_stream),
  10754.                 stats(_stats),
  10755.                 result(_stats.assertionResult),
  10756.                 colour(Colour::None),
  10757.                 message(result.getMessage()),
  10758.                 messages(_stats.infoMessages),
  10759.                 printInfoMessages(_printInfoMessages) {
  10760.                 switch (result.getResultType()) {
  10761.                     case ResultWas::Ok:
  10762.                         colour = Colour::Success;
  10763.                         passOrFail = "PASSED";
  10764.                         //if( result.hasMessage() )
  10765.                         if (_stats.infoMessages.size() == 1)
  10766.                             messageLabel = "with message";
  10767.                         if (_stats.infoMessages.size() > 1)
  10768.                             messageLabel = "with messages";
  10769.                         break;
  10770.                     case ResultWas::ExpressionFailed:
  10771.                         if (result.isOk()) {
  10772.                             colour = Colour::Success;
  10773.                             passOrFail = "FAILED - but was ok";
  10774.                         } else {
  10775.                             colour = Colour::Error;
  10776.                             passOrFail = "FAILED";
  10777.                         }
  10778.                         if (_stats.infoMessages.size() == 1)
  10779.                             messageLabel = "with message";
  10780.                         if (_stats.infoMessages.size() > 1)
  10781.                             messageLabel = "with messages";
  10782.                         break;
  10783.                     case ResultWas::ThrewException:
  10784.                         colour = Colour::Error;
  10785.                         passOrFail = "FAILED";
  10786.                         messageLabel = "due to unexpected exception with ";
  10787.                         if (_stats.infoMessages.size() == 1)
  10788.                             messageLabel += "message";
  10789.                         if (_stats.infoMessages.size() > 1)
  10790.                             messageLabel += "messages";
  10791.                         break;
  10792.                     case ResultWas::FatalErrorCondition:
  10793.                         colour = Colour::Error;
  10794.                         passOrFail = "FAILED";
  10795.                         messageLabel = "due to a fatal error condition";
  10796.                         break;
  10797.                     case ResultWas::DidntThrowException:
  10798.                         colour = Colour::Error;
  10799.                         passOrFail = "FAILED";
  10800.                         messageLabel = "because no exception was thrown where one was expected";
  10801.                         break;
  10802.                     case ResultWas::Info:
  10803.                         messageLabel = "info";
  10804.                         break;
  10805.                     case ResultWas::Warning:
  10806.                         messageLabel = "warning";
  10807.                         break;
  10808.                     case ResultWas::ExplicitFailure:
  10809.                         passOrFail = "FAILED";
  10810.                         colour = Colour::Error;
  10811.                         if (_stats.infoMessages.size() == 1)
  10812.                             messageLabel = "explicitly with message";
  10813.                         if (_stats.infoMessages.size() > 1)
  10814.                             messageLabel = "explicitly with messages";
  10815.                         break;
  10816.                         // These cases are here to prevent compiler warnings
  10817.                     case ResultWas::Unknown:
  10818.                     case ResultWas::FailureBit:
  10819.                     case ResultWas::Exception:
  10820.                         passOrFail = "** internal error **";
  10821.                         colour = Colour::Error;
  10822.                         break;
  10823.                 }
  10824.             }
  10825.  
  10826.             void print() const {
  10827.                 printSourceInfo();
  10828.                 if (stats.totals.assertions.total() > 0) {
  10829.                     if (result.isOk())
  10830.                         stream << '\n';
  10831.                     printResultType();
  10832.                     printOriginalExpression();
  10833.                     printReconstructedExpression();
  10834.                 } else {
  10835.                     stream << '\n';
  10836.                 }
  10837.                 printMessage();
  10838.             }
  10839.  
  10840.         private:
  10841.             void printResultType() const {
  10842.                 if (!passOrFail.empty()) {
  10843.                     Colour colourGuard(colour);
  10844.                     stream << passOrFail << ":\n";
  10845.                 }
  10846.             }
  10847.             void printOriginalExpression() const {
  10848.                 if (result.hasExpression()) {
  10849.                     Colour colourGuard(Colour::OriginalExpression);
  10850.                     stream << "  ";
  10851.                     stream << result.getExpressionInMacro();
  10852.                     stream << '\n';
  10853.                 }
  10854.             }
  10855.             void printReconstructedExpression() const {
  10856.                 if (result.hasExpandedExpression()) {
  10857.                     stream << "with expansion:\n";
  10858.                     Colour colourGuard(Colour::ReconstructedExpression);
  10859.                     stream << Column(result.getExpandedExpression()).indent(2) << '\n';
  10860.                 }
  10861.             }
  10862.             void printMessage() const {
  10863.                 if (!messageLabel.empty())
  10864.                     stream << messageLabel << ':' << '\n';
  10865.                 for (auto const& msg : messages) {
  10866.                     // If this assertion is a warning ignore any INFO messages
  10867.                     if (printInfoMessages || msg.type != ResultWas::Info)
  10868.                         stream << Column(msg.message).indent(2) << '\n';
  10869.                 }
  10870.             }
  10871.             void printSourceInfo() const {
  10872.                 Colour colourGuard(Colour::FileName);
  10873.                 stream << result.getSourceInfo() << ": ";
  10874.             }
  10875.  
  10876.             std::ostream& stream;
  10877.             AssertionStats const& stats;
  10878.             AssertionResult const& result;
  10879.             Colour::Code colour;
  10880.             std::string passOrFail;
  10881.             std::string messageLabel;
  10882.             std::string message;
  10883.             std::vector<MessageInfo> messages;
  10884.             bool printInfoMessages;
  10885.         };
  10886.  
  10887.         void lazyPrint() {
  10888.  
  10889.             m_tablePrinter.close();
  10890.             lazyPrintWithoutClosingBenchmarkTable();
  10891.         }
  10892.  
  10893.         void lazyPrintWithoutClosingBenchmarkTable() {
  10894.  
  10895.             if (!currentTestRunInfo.used)
  10896.                 lazyPrintRunInfo();
  10897.             if (!currentGroupInfo.used)
  10898.                 lazyPrintGroupInfo();
  10899.  
  10900.             if (!m_headerPrinted) {
  10901.                 printTestCaseAndSectionHeader();
  10902.                 m_headerPrinted = true;
  10903.             }
  10904.         }
  10905.         void lazyPrintRunInfo() {
  10906.             stream << '\n' << getLineOfChars<'~'>() << '\n';
  10907.             Colour colour(Colour::SecondaryText);
  10908.             stream << currentTestRunInfo->name
  10909.                 << " is a Catch v" << libraryVersion() << " host application.\n"
  10910.                 << "Run with -? for options\n\n";
  10911.  
  10912.             if (m_config->rngSeed() != 0)
  10913.                 stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
  10914.  
  10915.             currentTestRunInfo.used = true;
  10916.         }
  10917.         void lazyPrintGroupInfo() {
  10918.             if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
  10919.                 printClosedHeader("Group: " + currentGroupInfo->name);
  10920.                 currentGroupInfo.used = true;
  10921.             }
  10922.         }
  10923.         void printTestCaseAndSectionHeader() {
  10924.             assert(!m_sectionStack.empty());
  10925.             printOpenHeader(currentTestCaseInfo->name);
  10926.  
  10927.             if (m_sectionStack.size() > 1) {
  10928.                 Colour colourGuard(Colour::Headers);
  10929.  
  10930.                 auto
  10931.                     it = m_sectionStack.begin() + 1, // Skip first section (test case)
  10932.                     itEnd = m_sectionStack.end();
  10933.                 for (; it != itEnd; ++it)
  10934.                     printHeaderString(it->name, 2);
  10935.             }
  10936.  
  10937.             SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
  10938.  
  10939.             if (!lineInfo.empty()) {
  10940.                 stream << getLineOfChars<'-'>() << '\n';
  10941.                 Colour colourGuard(Colour::FileName);
  10942.                 stream << lineInfo << '\n';
  10943.             }
  10944.             stream << getLineOfChars<'.'>() << '\n' << std::endl;
  10945.         }
  10946.  
  10947.         void printClosedHeader(std::string const& _name) {
  10948.             printOpenHeader(_name);
  10949.             stream << getLineOfChars<'.'>() << '\n';
  10950.         }
  10951.         void printOpenHeader(std::string const& _name) {
  10952.             stream << getLineOfChars<'-'>() << '\n';
  10953.             {
  10954.                 Colour colourGuard(Colour::Headers);
  10955.                 printHeaderString(_name);
  10956.             }
  10957.         }
  10958.  
  10959.         // if string has a : in first line will set indent to follow it on
  10960.         // subsequent lines
  10961.         void printHeaderString(std::string const& _string, std::size_t indent = 0) {
  10962.             std::size_t i = _string.find(": ");
  10963.             if (i != std::string::npos)
  10964.                 i += 2;
  10965.             else
  10966.                 i = 0;
  10967.             stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
  10968.         }
  10969.  
  10970.         struct SummaryColumn {
  10971.  
  10972.             SummaryColumn(std::string const& _label, Colour::Code _colour)
  10973.                 : label(_label),
  10974.                 colour(_colour) {
  10975.             }
  10976.             SummaryColumn addRow(std::size_t count) {
  10977.                 std::ostringstream oss;
  10978.                 oss << count;
  10979.                 std::string row = oss.str();
  10980.                 for (auto& oldRow : rows) {
  10981.                     while (oldRow.size() < row.size())
  10982.                         oldRow = ' ' + oldRow;
  10983.                     while (oldRow.size() > row.size())
  10984.                         row = ' ' + row;
  10985.                 }
  10986.                 rows.push_back(row);
  10987.                 return *this;
  10988.             }
  10989.  
  10990.             std::string label;
  10991.             Colour::Code colour;
  10992.             std::vector<std::string> rows;
  10993.  
  10994.         };
  10995.  
  10996.         void printTotals(Totals const& totals) {
  10997.             if (totals.testCases.total() == 0) {
  10998.                 stream << Colour(Colour::Warning) << "No tests ran\n";
  10999.             } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
  11000.                 stream << Colour(Colour::ResultSuccess) << "All tests passed";
  11001.                 stream << " ("
  11002.                     << pluralise(totals.assertions.passed, "assertion") << " in "
  11003.                     << pluralise(totals.testCases.passed, "test case") << ')'
  11004.                     << '\n';
  11005.             } else {
  11006.  
  11007.                 std::vector<SummaryColumn> columns;
  11008.                 columns.push_back(SummaryColumn("", Colour::None)
  11009.                                   .addRow(totals.testCases.total())
  11010.                                   .addRow(totals.assertions.total()));
  11011.                 columns.push_back(SummaryColumn("passed", Colour::Success)
  11012.                                   .addRow(totals.testCases.passed)
  11013.                                   .addRow(totals.assertions.passed));
  11014.                 columns.push_back(SummaryColumn("failed", Colour::ResultError)
  11015.                                   .addRow(totals.testCases.failed)
  11016.                                   .addRow(totals.assertions.failed));
  11017.                 columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
  11018.                                   .addRow(totals.testCases.failedButOk)
  11019.                                   .addRow(totals.assertions.failedButOk));
  11020.  
  11021.                 printSummaryRow("test cases", columns, 0);
  11022.                 printSummaryRow("assertions", columns, 1);
  11023.             }
  11024.             system("pause");
  11025.         }
  11026.         void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
  11027.             for (auto col : cols) {
  11028.                 std::string value = col.rows[row];
  11029.                 if (col.label.empty()) {
  11030.                     stream << label << ": ";
  11031.                     if (value != "0")
  11032.                         stream << value;
  11033.                     else
  11034.                         stream << Colour(Colour::Warning) << "- none -";
  11035.                 } else if (value != "0") {
  11036.                     stream << Colour(Colour::LightGrey) << " | ";
  11037.                     stream << Colour(col.colour)
  11038.                         << value << ' ' << col.label;
  11039.                 }
  11040.             }
  11041.             stream << '\n';
  11042.         }
  11043.  
  11044.         void printTotalsDivider(Totals const& totals) {
  11045.             if (totals.testCases.total() > 0) {
  11046.                 std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
  11047.                 std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
  11048.                 std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
  11049.                 while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
  11050.                     findMax(failedRatio, failedButOkRatio, passedRatio)++;
  11051.                 while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
  11052.                     findMax(failedRatio, failedButOkRatio, passedRatio)--;
  11053.  
  11054.                 stream << Colour(Colour::Error) << std::string(failedRatio, '=');
  11055.                 stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
  11056.                 if (totals.testCases.allPassed())
  11057.                     stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
  11058.                 else
  11059.                     stream << Colour(Colour::Success) << std::string(passedRatio, '=');
  11060.             } else {
  11061.                 stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
  11062.             }
  11063.             stream << '\n';
  11064.         }
  11065.         void printSummaryDivider() {
  11066.             stream << getLineOfChars<'-'>() << '\n';
  11067.         }
  11068.  
  11069.     private:
  11070.         bool m_headerPrinted = false;
  11071.     };
  11072.  
  11073.     CATCH_REGISTER_REPORTER("console", ConsoleReporter)
  11074.  
  11075.         ConsoleReporter::~ConsoleReporter() {}
  11076.  
  11077. } // end namespace Catch
  11078.  
  11079. #if defined(_MSC_VER)
  11080. #pragma warning(pop)
  11081. #endif
  11082.   // end catch_reporter_console.cpp
  11083.   // start catch_reporter_junit.cpp
  11084.  
  11085. #include <assert.h>
  11086.  
  11087. #include <ctime>
  11088. #include <algorithm>
  11089.  
  11090. namespace Catch {
  11091.  
  11092.     namespace {
  11093.         std::string getCurrentTimestamp() {
  11094.             // Beware, this is not reentrant because of backward compatibility issues
  11095.             // Also, UTC only, again because of backward compatibility (%z is C++11)
  11096.             time_t rawtime;
  11097.             std::time(&rawtime);
  11098.             auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  11099.  
  11100. #ifdef _MSC_VER
  11101.             std::tm timeInfo = {};
  11102.             gmtime_s(&timeInfo, &rawtime);
  11103. #else
  11104.             std::tm* timeInfo;
  11105.             timeInfo = std::gmtime(&rawtime);
  11106. #endif
  11107.  
  11108.             char timeStamp[timeStampSize];
  11109.             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
  11110.  
  11111. #ifdef _MSC_VER
  11112.             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  11113. #else
  11114.             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
  11115. #endif
  11116.             return std::string(timeStamp);
  11117.         }
  11118.  
  11119.         std::string fileNameTag(const std::vector<std::string> &tags) {
  11120.             auto it = std::find_if(begin(tags),
  11121.                                    end(tags),
  11122.                                    [](std::string const& tag) {return tag.front() == '#'; });
  11123.             if (it != tags.end())
  11124.                 return it->substr(1);
  11125.             return std::string();
  11126.         }
  11127.     }
  11128.  
  11129.     class JunitReporter : public CumulativeReporterBase<JunitReporter> {
  11130.     public:
  11131.         JunitReporter(ReporterConfig const& _config)
  11132.             : CumulativeReporterBase(_config),
  11133.             xml(_config.stream()) {
  11134.             m_reporterPrefs.shouldRedirectStdOut = true;
  11135.         }
  11136.  
  11137.         ~JunitReporter() override;
  11138.  
  11139.         static std::string getDescription() {
  11140.             return "Reports test results in an XML format that looks like Ant's junitreport target";
  11141.         }
  11142.  
  11143.         void noMatchingTestCases(std::string const& /*spec*/) override {}
  11144.  
  11145.         void testRunStarting(TestRunInfo const& runInfo) override {
  11146.             CumulativeReporterBase::testRunStarting(runInfo);
  11147.             xml.startElement("testsuites");
  11148.         }
  11149.  
  11150.         void testGroupStarting(GroupInfo const& groupInfo) override {
  11151.             suiteTimer.start();
  11152.             stdOutForSuite.str("");
  11153.             stdErrForSuite.str("");
  11154.             unexpectedExceptions = 0;
  11155.             CumulativeReporterBase::testGroupStarting(groupInfo);
  11156.         }
  11157.  
  11158.         void testCaseStarting(TestCaseInfo const& testCaseInfo) override {
  11159.             m_okToFail = testCaseInfo.okToFail();
  11160.         }
  11161.         bool assertionEnded(AssertionStats const& assertionStats) override {
  11162.             if (assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail)
  11163.                 unexpectedExceptions++;
  11164.             return CumulativeReporterBase::assertionEnded(assertionStats);
  11165.         }
  11166.  
  11167.         void testCaseEnded(TestCaseStats const& testCaseStats) override {
  11168.             stdOutForSuite << testCaseStats.stdOut;
  11169.             stdErrForSuite << testCaseStats.stdErr;
  11170.             CumulativeReporterBase::testCaseEnded(testCaseStats);
  11171.         }
  11172.  
  11173.         void testGroupEnded(TestGroupStats const& testGroupStats) override {
  11174.             double suiteTime = suiteTimer.getElapsedSeconds();
  11175.             CumulativeReporterBase::testGroupEnded(testGroupStats);
  11176.             writeGroup(*m_testGroups.back(), suiteTime);
  11177.         }
  11178.  
  11179.         void testRunEndedCumulative() override {
  11180.             xml.endElement();
  11181.         }
  11182.  
  11183.         void writeGroup(TestGroupNode const& groupNode, double suiteTime) {
  11184.             XmlWriter::ScopedElement e = xml.scopedElement("testsuite");
  11185.             TestGroupStats const& stats = groupNode.value;
  11186.             xml.writeAttribute("name", stats.groupInfo.name);
  11187.             xml.writeAttribute("errors", unexpectedExceptions);
  11188.             xml.writeAttribute("failures", stats.totals.assertions.failed - unexpectedExceptions);
  11189.             xml.writeAttribute("tests", stats.totals.assertions.total());
  11190.             xml.writeAttribute("hostname", "tbd"); // !TBD
  11191.             if (m_config->showDurations() == ShowDurations::Never)
  11192.                 xml.writeAttribute("time", "");
  11193.             else
  11194.                 xml.writeAttribute("time", suiteTime);
  11195.             xml.writeAttribute("timestamp", getCurrentTimestamp());
  11196.  
  11197.             // Write test cases
  11198.             for (auto const& child : groupNode.children)
  11199.                 writeTestCase(*child);
  11200.  
  11201.             xml.scopedElement("system-out").writeText(trim(stdOutForSuite.str()), false);
  11202.             xml.scopedElement("system-err").writeText(trim(stdErrForSuite.str()), false);
  11203.         }
  11204.  
  11205.         void writeTestCase(TestCaseNode const& testCaseNode) {
  11206.             TestCaseStats const& stats = testCaseNode.value;
  11207.  
  11208.             // All test cases have exactly one section - which represents the
  11209.             // test case itself. That section may have 0-n nested sections
  11210.             assert(testCaseNode.children.size() == 1);
  11211.             SectionNode const& rootSection = *testCaseNode.children.front();
  11212.  
  11213.             std::string className = stats.testInfo.className;
  11214.  
  11215.             if (className.empty()) {
  11216.                 className = fileNameTag(stats.testInfo.tags);
  11217.                 if (className.empty())
  11218.                     className = "global";
  11219.             }
  11220.  
  11221.             if (!m_config->name().empty())
  11222.                 className = m_config->name() + "." + className;
  11223.  
  11224.             writeSection(className, "", rootSection);
  11225.         }
  11226.  
  11227.         void writeSection(std::string const& className,
  11228.                           std::string const& rootName,
  11229.                           SectionNode const& sectionNode) {
  11230.             std::string name = trim(sectionNode.stats.sectionInfo.name);
  11231.             if (!rootName.empty())
  11232.                 name = rootName + '/' + name;
  11233.  
  11234.             if (!sectionNode.assertions.empty() ||
  11235.                 !sectionNode.stdOut.empty() ||
  11236.                 !sectionNode.stdErr.empty()) {
  11237.                 XmlWriter::ScopedElement e = xml.scopedElement("testcase");
  11238.                 if (className.empty()) {
  11239.                     xml.writeAttribute("classname", name);
  11240.                     xml.writeAttribute("name", "root");
  11241.                 } else {
  11242.                     xml.writeAttribute("classname", className);
  11243.                     xml.writeAttribute("name", name);
  11244.                 }
  11245.                 xml.writeAttribute("time", ::Catch::Detail::stringify(sectionNode.stats.durationInSeconds));
  11246.  
  11247.                 writeAssertions(sectionNode);
  11248.  
  11249.                 if (!sectionNode.stdOut.empty())
  11250.                     xml.scopedElement("system-out").writeText(trim(sectionNode.stdOut), false);
  11251.                 if (!sectionNode.stdErr.empty())
  11252.                     xml.scopedElement("system-err").writeText(trim(sectionNode.stdErr), false);
  11253.             }
  11254.             for (auto const& childNode : sectionNode.childSections)
  11255.                 if (className.empty())
  11256.                     writeSection(name, "", *childNode);
  11257.                 else
  11258.                     writeSection(className, name, *childNode);
  11259.         }
  11260.  
  11261.         void writeAssertions(SectionNode const& sectionNode) {
  11262.             for (auto const& assertion : sectionNode.assertions)
  11263.                 writeAssertion(assertion);
  11264.         }
  11265.         void writeAssertion(AssertionStats const& stats) {
  11266.             AssertionResult const& result = stats.assertionResult;
  11267.             if (!result.isOk()) {
  11268.                 std::string elementName;
  11269.                 switch (result.getResultType()) {
  11270.                     case ResultWas::ThrewException:
  11271.                     case ResultWas::FatalErrorCondition:
  11272.                         elementName = "error";
  11273.                         break;
  11274.                     case ResultWas::ExplicitFailure:
  11275.                         elementName = "failure";
  11276.                         break;
  11277.                     case ResultWas::ExpressionFailed:
  11278.                         elementName = "failure";
  11279.                         break;
  11280.                     case ResultWas::DidntThrowException:
  11281.                         elementName = "failure";
  11282.                         break;
  11283.  
  11284.                         // We should never see these here:
  11285.                     case ResultWas::Info:
  11286.                     case ResultWas::Warning:
  11287.                     case ResultWas::Ok:
  11288.                     case ResultWas::Unknown:
  11289.                     case ResultWas::FailureBit:
  11290.                     case ResultWas::Exception:
  11291.                         elementName = "internalError";
  11292.                         break;
  11293.                 }
  11294.  
  11295.                 XmlWriter::ScopedElement e = xml.scopedElement(elementName);
  11296.  
  11297.                 xml.writeAttribute("message", result.getExpandedExpression());
  11298.                 xml.writeAttribute("type", result.getTestMacroName());
  11299.  
  11300.                 std::ostringstream oss;
  11301.                 if (!result.getMessage().empty())
  11302.                     oss << result.getMessage() << '\n';
  11303.                 for (auto const& msg : stats.infoMessages)
  11304.                     if (msg.type == ResultWas::Info)
  11305.                         oss << msg.message << '\n';
  11306.  
  11307.                 oss << "at " << result.getSourceInfo();
  11308.                 xml.writeText(oss.str(), false);
  11309.             }
  11310.         }
  11311.  
  11312.         XmlWriter xml;
  11313.         Timer suiteTimer;
  11314.         std::ostringstream stdOutForSuite;
  11315.         std::ostringstream stdErrForSuite;
  11316.         unsigned int unexpectedExceptions = 0;
  11317.         bool m_okToFail = false;
  11318.     };
  11319.  
  11320.     JunitReporter::~JunitReporter() {}
  11321.     CATCH_REGISTER_REPORTER("junit", JunitReporter)
  11322.  
  11323. } // end namespace Catch
  11324.   // end catch_reporter_junit.cpp
  11325.   // start catch_reporter_multi.cpp
  11326.  
  11327. namespace Catch {
  11328.  
  11329.     void MultipleReporters::add(IStreamingReporterPtr&& reporter) {
  11330.         m_reporters.push_back(std::move(reporter));
  11331.     }
  11332.  
  11333.     ReporterPreferences MultipleReporters::getPreferences() const {
  11334.         return m_reporters[0]->getPreferences();
  11335.     }
  11336.  
  11337.     std::set<Verbosity> MultipleReporters::getSupportedVerbosities() {
  11338.         return std::set<Verbosity>{ };
  11339.     }
  11340.  
  11341.     void MultipleReporters::noMatchingTestCases(std::string const& spec) {
  11342.         for (auto const& reporter : m_reporters)
  11343.             reporter->noMatchingTestCases(spec);
  11344.     }
  11345.  
  11346.     void MultipleReporters::benchmarkStarting(BenchmarkInfo const& benchmarkInfo) {
  11347.         for (auto const& reporter : m_reporters)
  11348.             reporter->benchmarkStarting(benchmarkInfo);
  11349.     }
  11350.     void MultipleReporters::benchmarkEnded(BenchmarkStats const& benchmarkStats) {
  11351.         for (auto const& reporter : m_reporters)
  11352.             reporter->benchmarkEnded(benchmarkStats);
  11353.     }
  11354.  
  11355.     void MultipleReporters::testRunStarting(TestRunInfo const& testRunInfo) {
  11356.         for (auto const& reporter : m_reporters)
  11357.             reporter->testRunStarting(testRunInfo);
  11358.     }
  11359.  
  11360.     void MultipleReporters::testGroupStarting(GroupInfo const& groupInfo) {
  11361.         for (auto const& reporter : m_reporters)
  11362.             reporter->testGroupStarting(groupInfo);
  11363.     }
  11364.  
  11365.     void MultipleReporters::testCaseStarting(TestCaseInfo const& testInfo) {
  11366.         for (auto const& reporter : m_reporters)
  11367.             reporter->testCaseStarting(testInfo);
  11368.     }
  11369.  
  11370.     void MultipleReporters::sectionStarting(SectionInfo const& sectionInfo) {
  11371.         for (auto const& reporter : m_reporters)
  11372.             reporter->sectionStarting(sectionInfo);
  11373.     }
  11374.  
  11375.     void MultipleReporters::assertionStarting(AssertionInfo const& assertionInfo) {
  11376.         for (auto const& reporter : m_reporters)
  11377.             reporter->assertionStarting(assertionInfo);
  11378.     }
  11379.  
  11380.     // The return value indicates if the messages buffer should be cleared:
  11381.     bool MultipleReporters::assertionEnded(AssertionStats const& assertionStats) {
  11382.         bool clearBuffer = false;
  11383.         for (auto const& reporter : m_reporters)
  11384.             clearBuffer |= reporter->assertionEnded(assertionStats);
  11385.         return clearBuffer;
  11386.     }
  11387.  
  11388.     void MultipleReporters::sectionEnded(SectionStats const& sectionStats) {
  11389.         for (auto const& reporter : m_reporters)
  11390.             reporter->sectionEnded(sectionStats);
  11391.     }
  11392.  
  11393.     void MultipleReporters::testCaseEnded(TestCaseStats const& testCaseStats) {
  11394.         for (auto const& reporter : m_reporters)
  11395.             reporter->testCaseEnded(testCaseStats);
  11396.     }
  11397.  
  11398.     void MultipleReporters::testGroupEnded(TestGroupStats const& testGroupStats) {
  11399.         for (auto const& reporter : m_reporters)
  11400.             reporter->testGroupEnded(testGroupStats);
  11401.     }
  11402.  
  11403.     void MultipleReporters::testRunEnded(TestRunStats const& testRunStats) {
  11404.         for (auto const& reporter : m_reporters)
  11405.             reporter->testRunEnded(testRunStats);
  11406.     }
  11407.  
  11408.     void MultipleReporters::skipTest(TestCaseInfo const& testInfo) {
  11409.         for (auto const& reporter : m_reporters)
  11410.             reporter->skipTest(testInfo);
  11411.     }
  11412.  
  11413.     bool MultipleReporters::isMulti() const {
  11414.         return true;
  11415.     }
  11416.  
  11417. } // end namespace Catch
  11418.   // end catch_reporter_multi.cpp
  11419.   // start catch_reporter_xml.cpp
  11420.  
  11421. #if defined(_MSC_VER)
  11422. #pragma warning(push)
  11423. #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  11424.   // Note that 4062 (not all labels are handled
  11425.   // and default is missing) is enabled
  11426. #endif
  11427.  
  11428. namespace Catch {
  11429.     class XmlReporter : public StreamingReporterBase<XmlReporter> {
  11430.     public:
  11431.         XmlReporter(ReporterConfig const& _config)
  11432.             : StreamingReporterBase(_config),
  11433.             m_xml(_config.stream()) {
  11434.             m_reporterPrefs.shouldRedirectStdOut = true;
  11435.         }
  11436.  
  11437.         ~XmlReporter() override;
  11438.  
  11439.         static std::string getDescription() {
  11440.             return "Reports test results as an XML document";
  11441.         }
  11442.  
  11443.         virtual std::string getStylesheetRef() const {
  11444.             return std::string();
  11445.         }
  11446.  
  11447.         void writeSourceInfo(SourceLineInfo const& sourceInfo) {
  11448.             m_xml
  11449.                 .writeAttribute("filename", sourceInfo.file)
  11450.                 .writeAttribute("line", sourceInfo.line);
  11451.         }
  11452.  
  11453.     public: // StreamingReporterBase
  11454.  
  11455.         void noMatchingTestCases(std::string const& s) override {
  11456.             StreamingReporterBase::noMatchingTestCases(s);
  11457.         }
  11458.  
  11459.         void testRunStarting(TestRunInfo const& testInfo) override {
  11460.             StreamingReporterBase::testRunStarting(testInfo);
  11461.             std::string stylesheetRef = getStylesheetRef();
  11462.             if (!stylesheetRef.empty())
  11463.                 m_xml.writeStylesheetRef(stylesheetRef);
  11464.             m_xml.startElement("Catch");
  11465.             if (!m_config->name().empty())
  11466.                 m_xml.writeAttribute("name", m_config->name());
  11467.         }
  11468.  
  11469.         void testGroupStarting(GroupInfo const& groupInfo) override {
  11470.             StreamingReporterBase::testGroupStarting(groupInfo);
  11471.             m_xml.startElement("Group")
  11472.                 .writeAttribute("name", groupInfo.name);
  11473.         }
  11474.  
  11475.         void testCaseStarting(TestCaseInfo const& testInfo) override {
  11476.             StreamingReporterBase::testCaseStarting(testInfo);
  11477.             m_xml.startElement("TestCase")
  11478.                 .writeAttribute("name", trim(testInfo.name))
  11479.                 .writeAttribute("description", testInfo.description)
  11480.                 .writeAttribute("tags", testInfo.tagsAsString());
  11481.  
  11482.             writeSourceInfo(testInfo.lineInfo);
  11483.  
  11484.             if (m_config->showDurations() == ShowDurations::Always)
  11485.                 m_testCaseTimer.start();
  11486.             m_xml.ensureTagClosed();
  11487.         }
  11488.  
  11489.         void sectionStarting(SectionInfo const& sectionInfo) override {
  11490.             StreamingReporterBase::sectionStarting(sectionInfo);
  11491.             if (m_sectionDepth++ > 0) {
  11492.                 m_xml.startElement("Section")
  11493.                     .writeAttribute("name", trim(sectionInfo.name))
  11494.                     .writeAttribute("description", sectionInfo.description);
  11495.                 writeSourceInfo(sectionInfo.lineInfo);
  11496.                 m_xml.ensureTagClosed();
  11497.             }
  11498.         }
  11499.  
  11500.         void assertionStarting(AssertionInfo const&) override {}
  11501.  
  11502.         bool assertionEnded(AssertionStats const& assertionStats) override {
  11503.  
  11504.             AssertionResult const& result = assertionStats.assertionResult;
  11505.  
  11506.             bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  11507.  
  11508.             if (includeResults) {
  11509.                 // Print any info messages in <Info> tags.
  11510.                 for (auto const& msg : assertionStats.infoMessages) {
  11511.                     if (msg.type == ResultWas::Info) {
  11512.                         m_xml.scopedElement("Info")
  11513.                             .writeText(msg.message);
  11514.                     } else if (msg.type == ResultWas::Warning) {
  11515.                         m_xml.scopedElement("Warning")
  11516.                             .writeText(msg.message);
  11517.                     }
  11518.                 }
  11519.             }
  11520.  
  11521.             // Drop out if result was successful but we're not printing them.
  11522.             if (!includeResults && result.getResultType() != ResultWas::Warning)
  11523.                 return true;
  11524.  
  11525.             // Print the expression if there is one.
  11526.             if (result.hasExpression()) {
  11527.                 m_xml.startElement("Expression")
  11528.                     .writeAttribute("success", result.succeeded())
  11529.                     .writeAttribute("type", result.getTestMacroName());
  11530.  
  11531.                 writeSourceInfo(result.getSourceInfo());
  11532.  
  11533.                 m_xml.scopedElement("Original")
  11534.                     .writeText(result.getExpression());
  11535.                 m_xml.scopedElement("Expanded")
  11536.                     .writeText(result.getExpandedExpression());
  11537.             }
  11538.  
  11539.             // And... Print a result applicable to each result type.
  11540.             switch (result.getResultType()) {
  11541.                 case ResultWas::ThrewException:
  11542.                     m_xml.startElement("Exception");
  11543.                     writeSourceInfo(result.getSourceInfo());
  11544.                     m_xml.writeText(result.getMessage());
  11545.                     m_xml.endElement();
  11546.                     break;
  11547.                 case ResultWas::FatalErrorCondition:
  11548.                     m_xml.startElement("FatalErrorCondition");
  11549.                     writeSourceInfo(result.getSourceInfo());
  11550.                     m_xml.writeText(result.getMessage());
  11551.                     m_xml.endElement();
  11552.                     break;
  11553.                 case ResultWas::Info:
  11554.                     m_xml.scopedElement("Info")
  11555.                         .writeText(result.getMessage());
  11556.                     break;
  11557.                 case ResultWas::Warning:
  11558.                     // Warning will already have been written
  11559.                     break;
  11560.                 case ResultWas::ExplicitFailure:
  11561.                     m_xml.startElement("Failure");
  11562.                     writeSourceInfo(result.getSourceInfo());
  11563.                     m_xml.writeText(result.getMessage());
  11564.                     m_xml.endElement();
  11565.                     break;
  11566.                 default:
  11567.                     break;
  11568.             }
  11569.  
  11570.             if (result.hasExpression())
  11571.                 m_xml.endElement();
  11572.  
  11573.             return true;
  11574.         }
  11575.  
  11576.         void sectionEnded(SectionStats const& sectionStats) override {
  11577.             StreamingReporterBase::sectionEnded(sectionStats);
  11578.             if (--m_sectionDepth > 0) {
  11579.                 XmlWriter::ScopedElement e = m_xml.scopedElement("OverallResults");
  11580.                 e.writeAttribute("successes", sectionStats.assertions.passed);
  11581.                 e.writeAttribute("failures", sectionStats.assertions.failed);
  11582.                 e.writeAttribute("expectedFailures", sectionStats.assertions.failedButOk);
  11583.  
  11584.                 if (m_config->showDurations() == ShowDurations::Always)
  11585.                     e.writeAttribute("durationInSeconds", sectionStats.durationInSeconds);
  11586.  
  11587.                 m_xml.endElement();
  11588.             }
  11589.         }
  11590.  
  11591.         void testCaseEnded(TestCaseStats const& testCaseStats) override {
  11592.             StreamingReporterBase::testCaseEnded(testCaseStats);
  11593.             XmlWriter::ScopedElement e = m_xml.scopedElement("OverallResult");
  11594.             e.writeAttribute("success", testCaseStats.totals.assertions.allOk());
  11595.  
  11596.             if (m_config->showDurations() == ShowDurations::Always)
  11597.                 e.writeAttribute("durationInSeconds", m_testCaseTimer.getElapsedSeconds());
  11598.  
  11599.             if (!testCaseStats.stdOut.empty())
  11600.                 m_xml.scopedElement("StdOut").writeText(trim(testCaseStats.stdOut), false);
  11601.             if (!testCaseStats.stdErr.empty())
  11602.                 m_xml.scopedElement("StdErr").writeText(trim(testCaseStats.stdErr), false);
  11603.  
  11604.             m_xml.endElement();
  11605.         }
  11606.  
  11607.         void testGroupEnded(TestGroupStats const& testGroupStats) override {
  11608.             StreamingReporterBase::testGroupEnded(testGroupStats);
  11609.             // TODO: Check testGroupStats.aborting and act accordingly.
  11610.             m_xml.scopedElement("OverallResults")
  11611.                 .writeAttribute("successes", testGroupStats.totals.assertions.passed)
  11612.                 .writeAttribute("failures", testGroupStats.totals.assertions.failed)
  11613.                 .writeAttribute("expectedFailures", testGroupStats.totals.assertions.failedButOk);
  11614.             m_xml.endElement();
  11615.         }
  11616.  
  11617.         void testRunEnded(TestRunStats const& testRunStats) override {
  11618.             StreamingReporterBase::testRunEnded(testRunStats);
  11619.             m_xml.scopedElement("OverallResults")
  11620.                 .writeAttribute("successes", testRunStats.totals.assertions.passed)
  11621.                 .writeAttribute("failures", testRunStats.totals.assertions.failed)
  11622.                 .writeAttribute("expectedFailures", testRunStats.totals.assertions.failedButOk);
  11623.             m_xml.endElement();
  11624.         }
  11625.  
  11626.     private:
  11627.         Timer m_testCaseTimer;
  11628.         XmlWriter m_xml;
  11629.         int m_sectionDepth = 0;
  11630.     };
  11631.  
  11632.     XmlReporter::~XmlReporter() {}
  11633.     CATCH_REGISTER_REPORTER("xml", XmlReporter)
  11634.  
  11635. } // end namespace Catch
  11636.  
  11637. #if defined(_MSC_VER)
  11638. #pragma warning(pop)
  11639. #endif
  11640.   // end catch_reporter_xml.cpp
  11641.  
  11642. namespace Catch {
  11643.     LeakDetector leakDetector;
  11644. }
  11645.  
  11646. #ifdef __clang__
  11647. #pragma clang diagnostic pop
  11648. #endif
  11649.  
  11650. // end catch_impl.hpp
  11651. #endif
  11652.  
  11653. #ifdef CATCH_CONFIG_MAIN
  11654. // start catch_default_main.hpp
  11655.  
  11656. #ifndef __OBJC__
  11657.  
  11658. #if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
  11659. // Standard C/C++ Win32 Unicode wmain entry point
  11660. extern "C" int wmain(int argc, wchar_t * argv[], wchar_t *[]) {
  11661. #else
  11662. // Standard C/C++ main entry point
  11663. int main(int argc, char * argv[]) {
  11664. #endif
  11665.  
  11666.     return Catch::Session().run(argc, argv);
  11667. }
  11668.  
  11669. #else // __OBJC__
  11670.  
  11671. // Objective-C entry point
  11672. int main(int argc, char * const argv[]) {
  11673. #if !CATCH_ARC_ENABLED
  11674.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  11675. #endif
  11676.  
  11677.     Catch::registerTestMethods();
  11678.     int result = Catch::Session().run(argc, (char**)argv);
  11679.  
  11680. #if !CATCH_ARC_ENABLED
  11681.     [pool drain];
  11682. #endif
  11683.  
  11684.     return result;
  11685. }
  11686.  
  11687. #endif // __OBJC__
  11688.  
  11689. // end catch_default_main.hpp
  11690. #endif
  11691.  
  11692. #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
  11693. #  undef CLARA_CONFIG_MAIN
  11694. #endif
  11695.  
  11696. #if !defined(CATCH_CONFIG_DISABLE)
  11697. //////
  11698. // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  11699. #ifdef CATCH_CONFIG_PREFIX_ALL
  11700.  
  11701. #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  11702. #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  11703.  
  11704. #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", __VA_ARGS__ )
  11705. #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  11706. #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  11707. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  11708. #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  11709. #endif// CATCH_CONFIG_DISABLE_MATCHERS
  11710. #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  11711.  
  11712. #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  11713. #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  11714. #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  11715. #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  11716. #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  11717.  
  11718. #define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", __VA_ARGS__ )
  11719. #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  11720. #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  11721. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  11722. #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  11723. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  11724. #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  11725.  
  11726. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  11727. #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  11728.  
  11729. #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  11730. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  11731.  
  11732. #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
  11733. #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  11734. #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
  11735.  
  11736. #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  11737. #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  11738. #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  11739. #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  11740. #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  11741. #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  11742. #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  11743. #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  11744.  
  11745. #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  11746.  
  11747. // "BDD-style" convenience wrappers
  11748. #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
  11749. #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  11750. #define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc )
  11751. #define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc )
  11752. #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc )
  11753. #define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc )
  11754. #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc )
  11755.  
  11756. // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  11757. #else
  11758.  
  11759. #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__  )
  11760. #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  11761.  
  11762. #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  11763. #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  11764. #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  11765. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  11766. #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  11767. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  11768. #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  11769.  
  11770. #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  11771. #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  11772. #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  11773. #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  11774. #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  11775.  
  11776. #define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  11777. #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  11778. #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  11779. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  11780. #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  11781. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  11782. #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  11783.  
  11784. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  11785. #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  11786.  
  11787. #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  11788. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  11789.  
  11790. #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
  11791. #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  11792. #define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
  11793.  
  11794. #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  11795. #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  11796. #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  11797. #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  11798. #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  11799. #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  11800. #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  11801. #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  11802. #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  11803.  
  11804. #endif
  11805.  
  11806. #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
  11807.  
  11808. // "BDD-style" convenience wrappers
  11809. #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
  11810. #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  11811.  
  11812. #define GIVEN( desc )    SECTION( std::string("   Given: ") + desc )
  11813. #define WHEN( desc )     SECTION( std::string("    When: ") + desc )
  11814. #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc )
  11815. #define THEN( desc )     SECTION( std::string("    Then: ") + desc )
  11816. #define AND_THEN( desc ) SECTION( std::string("     And: ") + desc )
  11817.  
  11818. using Catch::Detail::Approx;
  11819.  
  11820. #else
  11821. //////
  11822. // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  11823. #ifdef CATCH_CONFIG_PREFIX_ALL
  11824.  
  11825. #define CATCH_REQUIRE( ... )        (void)(0)
  11826. #define CATCH_REQUIRE_FALSE( ... )  (void)(0)
  11827.  
  11828. #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
  11829. #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  11830. #define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0)
  11831. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  11832. #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  11833. #endif// CATCH_CONFIG_DISABLE_MATCHERS
  11834. #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
  11835.  
  11836. #define CATCH_CHECK( ... )         (void)(0)
  11837. #define CATCH_CHECK_FALSE( ... )   (void)(0)
  11838. #define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__)
  11839. #define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__))
  11840. #define CATCH_CHECK_NOFAIL( ... )  (void)(0)
  11841.  
  11842. #define CATCH_CHECK_THROWS( ... )  (void)(0)
  11843. #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  11844. #define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0)
  11845. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  11846. #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  11847. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  11848. #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
  11849.  
  11850. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  11851. #define CATCH_CHECK_THAT( arg, matcher )   (void)(0)
  11852.  
  11853. #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
  11854. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  11855.  
  11856. #define CATCH_INFO( msg )    (void)(0)
  11857. #define CATCH_WARN( msg )    (void)(0)
  11858. #define CATCH_CAPTURE( msg ) (void)(0)
  11859.  
  11860. #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  11861. #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  11862. #define CATCH_METHOD_AS_TEST_CASE( method, ... )
  11863. #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
  11864. #define CATCH_SECTION( ... )
  11865. #define CATCH_FAIL( ... ) (void)(0)
  11866. #define CATCH_FAIL_CHECK( ... ) (void)(0)
  11867. #define CATCH_SUCCEED( ... ) (void)(0)
  11868.  
  11869. #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  11870.  
  11871. // "BDD-style" convenience wrappers
  11872. #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  11873. #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 )
  11874. #define CATCH_GIVEN( desc )
  11875. #define CATCH_WHEN( desc )
  11876. #define CATCH_AND_WHEN( desc )
  11877. #define CATCH_THEN( desc )
  11878. #define CATCH_AND_THEN( desc )
  11879.  
  11880. // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  11881. #else
  11882.  
  11883. #define REQUIRE( ... )       (void)(0)
  11884. #define REQUIRE_FALSE( ... ) (void)(0)
  11885.  
  11886. #define REQUIRE_THROWS( ... ) (void)(0)
  11887. #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  11888. #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
  11889. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  11890. #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  11891. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  11892. #define REQUIRE_NOTHROW( ... ) (void)(0)
  11893.  
  11894. #define CHECK( ... ) (void)(0)
  11895. #define CHECK_FALSE( ... ) (void)(0)
  11896. #define CHECKED_IF( ... ) if (__VA_ARGS__)
  11897. #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
  11898. #define CHECK_NOFAIL( ... ) (void)(0)
  11899.  
  11900. #define CHECK_THROWS( ... )  (void)(0)
  11901. #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  11902. #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
  11903. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  11904. #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  11905. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  11906. #define CHECK_NOTHROW( ... ) (void)(0)
  11907.  
  11908. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  11909. #define CHECK_THAT( arg, matcher ) (void)(0)
  11910.  
  11911. #define REQUIRE_THAT( arg, matcher ) (void)(0)
  11912. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  11913.  
  11914. #define INFO( msg ) (void)(0)
  11915. #define WARN( msg ) (void)(0)
  11916. #define CAPTURE( msg ) (void)(0)
  11917.  
  11918. #define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  11919. #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  11920. #define METHOD_AS_TEST_CASE( method, ... )
  11921. #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
  11922. #define SECTION( ... )
  11923. #define FAIL( ... ) (void)(0)
  11924. #define FAIL_CHECK( ... ) (void)(0)
  11925. #define SUCCEED( ... ) (void)(0)
  11926. #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  11927.  
  11928. #endif
  11929.  
  11930. #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
  11931.  
  11932. // "BDD-style" convenience wrappers
  11933. #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
  11934. #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
  11935.  
  11936. #define GIVEN( desc )
  11937. #define WHEN( desc )
  11938. #define AND_WHEN( desc )
  11939. #define THEN( desc )
  11940. #define AND_THEN( desc )
  11941.  
  11942. using Catch::Detail::Approx;
  11943.  
  11944. #endif
  11945.  
  11946. // start catch_reenable_warnings.h
  11947.  
  11948.  
  11949. #ifdef __clang__
  11950. #    ifdef __ICC // icpc defines the __clang__ macro
  11951. #        pragma warning(pop)
  11952. #    else
  11953. #        pragma clang diagnostic pop
  11954. #    endif
  11955. #elif defined __GNUC__
  11956. #    pragma GCC diagnostic pop
  11957. #endif
  11958.  
  11959. // end catch_reenable_warnings.h
  11960. // end catch.hpp
  11961. #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
Advertisement
Comments
  • User was banned
Add Comment
Please, Sign In to add comment