text: /*
   *  Catch v2.2.2
   *  Generated: 2018-04-06 12:05:03.186665
   *  ----------------------------------------------------------
   *  This file has been merged from multiple headers. Please don't edit it directly
   *  Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved.
   *
   *  Distributed under the Boost Software License, Version 1.0. (See accompanying
   *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
   */
  #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
  #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
  
  
  
   // start catch.hpp
  
  #define CATCH_VERSION_MAJOR 2
  #define CATCH_VERSION_MINOR 2
  #define CATCH_VERSION_PATCH 2
  
  
  #ifdef __clang__
  #    pragma clang system_header
  #elif defined __GNUC__
  #    pragma GCC system_header
  #endif
  
  // start catch_suppress_warnings.h
  
  #ifdef __clang__
  #   ifdef __ICC // icpc defines the __clang__ macro
  #       pragma warning(push)
  #       pragma warning(disable: 161 1682)
  #   else // __ICC
  #       pragma clang diagnostic ignored "-Wunused-variable"
  #       pragma clang diagnostic push
  #       pragma clang diagnostic ignored "-Wpadded"
  #       pragma clang diagnostic ignored "-Wswitch-enum"
  #       pragma clang diagnostic ignored "-Wcovered-switch-default"
  #    endif
  #elif defined __GNUC__
  #    pragma GCC diagnostic ignored "-Wparentheses"
  #    pragma GCC diagnostic push
  #    pragma GCC diagnostic ignored "-Wunused-variable"
  #    pragma GCC diagnostic ignored "-Wpadded"
  #endif
  // end catch_suppress_warnings.h
  #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
  #  define CATCH_IMPL
  #  define CATCH_CONFIG_ALL_PARTS
  #endif
  
  // In the impl file, we want to have access to all parts of the headers
  // Can also be used to sanely support PCHs
  #if defined(CATCH_CONFIG_ALL_PARTS)
  #  define CATCH_CONFIG_EXTERNAL_INTERFACES
  #  if defined(CATCH_CONFIG_DISABLE_MATCHERS)
  #    undef CATCH_CONFIG_DISABLE_MATCHERS
  #  endif
  #  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  #endif
  
  #if !defined(CATCH_CONFIG_IMPL_ONLY)
  // start catch_platform.h
  
  #ifdef __APPLE__
  # include <TargetConditionals.h>
  # if TARGET_OS_OSX == 1
  #  define CATCH_PLATFORM_MAC
  # elif TARGET_OS_IPHONE == 1
  #  define CATCH_PLATFORM_IPHONE
  # endif
  
  #elif defined(linux) || defined(__linux) || defined(__linux__)
  #  define CATCH_PLATFORM_LINUX
  
  #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
  #  define CATCH_PLATFORM_WINDOWS
  #endif
  
  // end catch_platform.h
  
  #ifdef CATCH_IMPL
  #  ifndef CLARA_CONFIG_MAIN
  #    define CLARA_CONFIG_MAIN_NOT_DEFINED
  #    define CLARA_CONFIG_MAIN
  #  endif
  #endif
  
  // start catch_user_interfaces.h
  
  namespace Catch {
  	unsigned int rngSeed();
  }
  
  // end catch_user_interfaces.h
  // start catch_tag_alias_autoregistrar.h
  
  // start catch_common.h
  
  // start catch_compiler_capabilities.h
  
  // Detect a number of compiler features - by compiler
  // The following features are defined:
  //
  // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
  // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
  // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
  // ****************
  // Note to maintainers: if new toggles are added please document them
  // in configuration.md, too
  // ****************
  
  // In general each macro has a _NO_<feature name> form
  // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
  // Many features, at point of detection, define an _INTERNAL_ macro, so they
  // can be combined, en-mass, with the _NO_ forms later.
  
  #ifdef __cplusplus
  
  #  if __cplusplus >= 201402L
  #    define CATCH_CPP14_OR_GREATER
  #  endif
  
  #  if __cplusplus >= 201703L
  #    define CATCH_CPP17_OR_GREATER
  #  endif
  
  #endif
  
  #if defined(CATCH_CPP17_OR_GREATER)
  #  define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  #endif
  
  #ifdef __clang__
  
  #       define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
              _Pragma( "clang diagnostic push" ) \
              _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
              _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
  #       define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
              _Pragma( "clang diagnostic pop" )
  
  #       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
              _Pragma( "clang diagnostic push" ) \
              _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
  #       define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
              _Pragma( "clang diagnostic pop" )
  
  #endif // __clang__
  
  ////////////////////////////////////////////////////////////////////////////////
  // Assume that non-Windows platforms support posix signals by default
  #if !defined(CATCH_PLATFORM_WINDOWS)
  #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
  #endif
  
  ////////////////////////////////////////////////////////////////////////////////
  // We know some environments not to support full POSIX signals
  #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
  #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  #endif
  
  #ifdef __OS400__
  #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  #       define CATCH_CONFIG_COLOUR_NONE
  #endif
  
  ////////////////////////////////////////////////////////////////////////////////
  // Cygwin
  #ifdef __CYGWIN__
  
  // Required for some versions of Cygwin to declare gettimeofday
  // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
  #   define _BSD_SOURCE
  
  #endif // __CYGWIN__
  
  ////////////////////////////////////////////////////////////////////////////////
  // Visual C++
  #ifdef _MSC_VER
  
  #  if _MSC_VER >= 1900 // Visual Studio 2015 or newer
  #    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  #  endif
  
  // Universal Windows platform does not support SEH
  // Or console colours (or console at all...)
  #  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
  #    define CATCH_CONFIG_COLOUR_NONE
  #  else
  #    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
  #  endif
  
  #endif // _MSC_VER
  
  ////////////////////////////////////////////////////////////////////////////////
  
  // DJGPP
  #ifdef __DJGPP__
  #  define CATCH_INTERNAL_CONFIG_NO_WCHAR
  #endif // __DJGPP__
  
  ////////////////////////////////////////////////////////////////////////////////
  
  // Use of __COUNTER__ is suppressed during code analysis in
  // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
  // handled by it.
  // Otherwise all supported compilers support COUNTER macro,
  // but user still might want to turn it off
  #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
  #define CATCH_INTERNAL_CONFIG_COUNTER
  #endif
  
  #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
  #   define CATCH_CONFIG_COUNTER
  #endif
  #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
  #   define CATCH_CONFIG_WINDOWS_SEH
  #endif
  // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
  #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
  #   define CATCH_CONFIG_POSIX_SIGNALS
  #endif
  // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
  #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
  #   define CATCH_CONFIG_WCHAR
  #endif
  
  #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
  #  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  #endif
  
  #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
  #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
  #   define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
  #endif
  #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
  #   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
  #   define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  #endif
  
  // end catch_compiler_capabilities.h
  #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
  #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
  #ifdef CATCH_CONFIG_COUNTER
  #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
  #else
  #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
  #endif
  
  #include <iosfwd>
  #include <string>
  #include <cstdint>
  
  namespace Catch {
  
  	struct CaseSensitive {
  		enum Choice {
  			Yes,
  			No
  		};
  	};
  
  	class NonCopyable {
  		NonCopyable(NonCopyable const&) = delete;
  		NonCopyable(NonCopyable &&) = delete;
  		NonCopyable& operator = (NonCopyable const&) = delete;
  		NonCopyable& operator = (NonCopyable &&) = delete;
  
  	protected:
  		NonCopyable();
  		virtual ~NonCopyable();
  	};
  
  	struct SourceLineInfo {
  
  		SourceLineInfo() = delete;
  		SourceLineInfo(char const* _file, std::size_t _line) noexcept
  			: file(_file),
  			line(_line)
  		{}
  
  		SourceLineInfo(SourceLineInfo const& other) = default;
  		SourceLineInfo(SourceLineInfo &&) = default;
  		SourceLineInfo& operator = (SourceLineInfo const&) = default;
  		SourceLineInfo& operator = (SourceLineInfo &&) = default;
  
  		bool empty() const noexcept;
  		bool operator == (SourceLineInfo const& other) const noexcept;
  		bool operator < (SourceLineInfo const& other) const noexcept;
  
  		char const* file;
  		std::size_t line;
  	};
  
  	std::ostream& operator << (std::ostream& os, SourceLineInfo const& info);
  
  	// Use this in variadic streaming macros to allow
  	//    >> +StreamEndStop
  	// as well as
  	//    >> stuff +StreamEndStop
  	struct StreamEndStop {
  		std::string operator+() const;
  	};
  	template<typename T>
  	T const& operator + (T const& value, StreamEndStop) {
  		return value;
  	}
  }
  
  #define CATCH_INTERNAL_LINEINFO \
      ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
  
  // end catch_common.h
  namespace Catch {
  
  	struct RegistrarForTagAliases {
  		RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo);
  	};
  
  } // end namespace Catch
  
  #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
      CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
      namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
      CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  
  // end catch_tag_alias_autoregistrar.h
  // start catch_test_registry.h
  
  // start catch_interfaces_testcase.h
  
  #include <vector>
  #include <memory>
  
  namespace Catch {
  
  	class TestSpec;
  
  	struct ITestInvoker {
  		virtual void invoke() const = 0;
  		virtual ~ITestInvoker();
  	};
  
  	using ITestCasePtr = std::shared_ptr<ITestInvoker>;
  
  	class TestCase;
  	struct IConfig;
  
  	struct ITestCaseRegistry {
  		virtual ~ITestCaseRegistry();
  		virtual std::vector<TestCase> const& getAllTests() const = 0;
  		virtual std::vector<TestCase> const& getAllTestsSorted(IConfig const& config) const = 0;
  	};
  
  	bool matchTest(TestCase const& testCase, TestSpec const& testSpec, IConfig const& config);
  	std::vector<TestCase> filterTests(std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config);
  	std::vector<TestCase> const& getAllTestCasesSorted(IConfig const& config);
  
  }
  
  // end catch_interfaces_testcase.h
  // start catch_stringref.h
  
  #include <cstddef>
  #include <string>
  #include <iosfwd>
  
  namespace Catch {
  
  	class StringData;
  
  	/// A non-owning string class (similar to the forthcoming std::string_view)
  	/// Note that, because a StringRef may be a substring of another string,
  	/// it may not be null terminated. c_str() must return a null terminated
  	/// string, however, and so the StringRef will internally take ownership
  	/// (taking a copy), if necessary. In theory this ownership is not externally
  	/// visible - but it does mean (substring) StringRefs should not be shared between
  	/// threads.
  	class StringRef {
  	public:
  		using size_type = std::size_t;
  
  	private:
  		friend struct StringRefTestAccess;
  
  		char const* m_start;
  		size_type m_size;
  
  		char* m_data = nullptr;
  
  		void takeOwnership();
  
  		static constexpr char const* const s_empty = "";
  
  	public: // construction/ assignment
  		StringRef() noexcept
  			: StringRef(s_empty, 0)
  		{}
  
  		StringRef(StringRef const& other) noexcept
  			: m_start(other.m_start),
  			m_size(other.m_size)
  		{}
  
  		StringRef(StringRef&& other) noexcept
  			: m_start(other.m_start),
  			m_size(other.m_size),
  			m_data(other.m_data)
  		{
  			other.m_data = nullptr;
  		}
  
  		StringRef(char const* rawChars) noexcept;
  
  		StringRef(char const* rawChars, size_type size) noexcept
  			: m_start(rawChars),
  			m_size(size)
  		{}
  
  		StringRef(std::string const& stdString) noexcept
  			: m_start(stdString.c_str()),
  			m_size(stdString.size())
  		{}
  
  		~StringRef() noexcept {
  			delete[] m_data;
  		}
  
  		auto operator = (StringRef const &other) noexcept -> StringRef& {
  			delete[] m_data;
  			m_data = nullptr;
  			m_start = other.m_start;
  			m_size = other.m_size;
  			return *this;
  		}
  
  		operator std::string() const;
  
  		void swap(StringRef& other) noexcept;
  
  	public: // operators
  		auto operator == (StringRef const& other) const noexcept -> bool;
  		auto operator != (StringRef const& other) const noexcept -> bool;
  
  		auto operator[] (size_type index) const noexcept -> char;
  
  	public: // named queries
  		auto empty() const noexcept -> bool {
  			return m_size == 0;
  		}
  		auto size() const noexcept -> size_type {
  			return m_size;
  		}
  
  		auto numberOfCharacters() const noexcept->size_type;
  		auto c_str() const -> char const*;
  
  	public: // substrings and searches
  		auto substr(size_type start, size_type size) const noexcept->StringRef;
  
  		// Returns the current start pointer.
  		// Note that the pointer can change when if the StringRef is a substring
  		auto currentData() const noexcept -> char const*;
  
  	private: // ownership queries - may not be consistent between calls
  		auto isOwned() const noexcept -> bool;
  		auto isSubstring() const noexcept -> bool;
  	};
  
  	auto operator + (StringRef const& lhs, StringRef const& rhs)->std::string;
  	auto operator + (StringRef const& lhs, char const* rhs)->std::string;
  	auto operator + (char const* lhs, StringRef const& rhs)->std::string;
  
  	auto operator += (std::string& lhs, StringRef const& sr)->std::string&;
  	auto operator << (std::ostream& os, StringRef const& sr)->std::ostream&;
  
  	inline auto operator "" _sr(char const* rawChars, std::size_t size) noexcept -> StringRef {
  		return StringRef(rawChars, size);
  	}
  
  } // namespace Catch
  
  // end catch_stringref.h
  namespace Catch {
  
  	template<typename C>
  	class TestInvokerAsMethod : public ITestInvoker {
  		void (C::*m_testAsMethod)();
  	public:
  		TestInvokerAsMethod(void (C::*testAsMethod)()) noexcept : m_testAsMethod(testAsMethod) {}
  
  		void invoke() const override {
  			C obj;
  			(obj.*m_testAsMethod)();
  		}
  	};
  
  	auto makeTestInvoker(void(*testAsFunction)()) noexcept->ITestInvoker*;
  
  	template<typename C>
  	auto makeTestInvoker(void (C::*testAsMethod)()) noexcept -> ITestInvoker* {
  		return new(std::nothrow) TestInvokerAsMethod<C>(testAsMethod);
  	}
  
  	struct NameAndTags {
  		NameAndTags(StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef()) noexcept;
  		StringRef name;
  		StringRef tags;
  	};
  
  	struct AutoReg : NonCopyable {
  		AutoReg(ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags) noexcept;
  		~AutoReg();
  	};
  
  } // end namespace Catch
  
  #if defined(CATCH_CONFIG_DISABLE)
  #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
          static void TestName()
  #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
          namespace{                        \
              struct TestName : ClassName { \
                  void test();              \
              };                            \
          }                                 \
          void TestName::test()
  
  #endif
  
  	///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
          static void TestName(); \
          CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
          namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
          CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
          static void TestName()
  #define INTERNAL_CATCH_TESTCASE( ... ) \
          INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
  
  	///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
          CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
          namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
          CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  
  	///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
          CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
          namespace{ \
              struct TestName : ClassName{ \
                  void test(); \
              }; \
              Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
          } \
          CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
          void TestName::test()
  #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
          INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
  
  	///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
          CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
          Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
          CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  
  // end catch_test_registry.h
  // start catch_capture.hpp
  
  // start catch_assertionhandler.h
  
  // start catch_assertioninfo.h
  
  // start catch_result_type.h
  
  namespace Catch {
  
  	// ResultWas::OfType enum
  	struct ResultWas {
  		enum OfType {
  			Unknown = -1,
  			Ok = 0,
  			Info = 1,
  			Warning = 2,
  
  			FailureBit = 0x10,
  
  			ExpressionFailed = FailureBit | 1,
  			ExplicitFailure = FailureBit | 2,
  
  			Exception = 0x100 | FailureBit,
  
  			ThrewException = Exception | 1,
  			DidntThrowException = Exception | 2,
  
  			FatalErrorCondition = 0x200 | FailureBit
  
  		};
  	};
  
  	bool isOk(ResultWas::OfType resultType);
  	bool isJustInfo(int flags);
  
  	// ResultDisposition::Flags enum
  	struct ResultDisposition {
  		enum Flags {
  			Normal = 0x01,
  
  			ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
  			FalseTest = 0x04,           // Prefix expression with !
  			SuppressFail = 0x08         // Failures are reported but do not fail the test
  		};
  	};
  
  	ResultDisposition::Flags operator | (ResultDisposition::Flags lhs, ResultDisposition::Flags rhs);
  
  	bool shouldContinueOnFailure(int flags);
  	inline bool isFalseTest(int flags) { return (flags & ResultDisposition::FalseTest) != 0; }
  	bool shouldSuppressFailure(int flags);
  
  } // end namespace Catch
  
  // end catch_result_type.h
  namespace Catch {
  
  	struct AssertionInfo
  	{
  		StringRef macroName;
  		SourceLineInfo lineInfo;
  		StringRef capturedExpression;
  		ResultDisposition::Flags resultDisposition;
  
  		// We want to delete this constructor but a compiler bug in 4.8 means
  		// the struct is then treated as non-aggregate
  		//AssertionInfo() = delete;
  	};
  
  } // end namespace Catch
  
  // end catch_assertioninfo.h
  // start catch_decomposer.h
  
  // start catch_tostring.h
  
  #include <vector>
  #include <cstddef>
  #include <type_traits>
  #include <string>
  // start catch_stream.h
  
  #include <iosfwd>
  #include <cstddef>
  #include <ostream>
  
  namespace Catch {
  
  	std::ostream& cout();
  	std::ostream& cerr();
  	std::ostream& clog();
  
  	class StringRef;
  
  	struct IStream {
  		virtual ~IStream();
  		virtual std::ostream& stream() const = 0;
  	};
  
  	auto makeStream(StringRef const &filename)->IStream const*;
  
  	class ReusableStringStream {
  		std::size_t m_index;
  		std::ostream* m_oss;
  	public:
  		ReusableStringStream();
  		~ReusableStringStream();
  
  		auto str() const->std::string;
  
  		template<typename T>
  		auto operator << (T const& value) -> ReusableStringStream& {
  			*m_oss << value;
  			return *this;
  		}
  		auto get() -> std::ostream& { return *m_oss; }
  
  		static void cleanup();
  	};
  }
  
  // end catch_stream.h
  
  #ifdef __OBJC__
  // start catch_objc_arc.hpp
  
  #import <Foundation/Foundation.h>
  
  #ifdef __has_feature
  #define CATCH_ARC_ENABLED __has_feature(objc_arc)
  #else
  #define CATCH_ARC_ENABLED 0
  #endif
  
  void arcSafeRelease(NSObject* obj);
  id performOptionalSelector(id obj, SEL sel);
  
  #if !CATCH_ARC_ENABLED
  inline void arcSafeRelease(NSObject* obj) {
  	[obj release];
  }
  inline id performOptionalSelector(id obj, SEL sel) {
  	if ([obj respondsToSelector : sel])
  		return[obj performSelector : sel];
  	return nil;
  }
  #define CATCH_UNSAFE_UNRETAINED
  #define CATCH_ARC_STRONG
  #else
  inline void arcSafeRelease(NSObject*) {}
  inline id performOptionalSelector(id obj, SEL sel) {
  #ifdef __clang__
  #pragma clang diagnostic push
  #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  #endif
  	if ([obj respondsToSelector : sel])
  		return[obj performSelector : sel];
  #ifdef __clang__
  #pragma clang diagnostic pop
  #endif
  	return nil;
  }
  #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
  #define CATCH_ARC_STRONG __strong
  #endif
  
  // end catch_objc_arc.hpp
  #endif
  
  #ifdef _MSC_VER
  #pragma warning(push)
  #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
  #endif
  
  // We need a dummy global operator<< so we can bring it into Catch namespace later
  struct Catch_global_namespace_dummy {};
  std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
  
  namespace Catch {
  	// Bring in operator<< from global namespace into Catch namespace
  	using ::operator<<;
  
  	namespace Detail {
  
  		extern const std::string unprintableString;
  
  		std::string rawMemoryToString(const void *object, std::size_t size);
  
  		template<typename T>
  		std::string rawMemoryToString(const T& object) {
  			return rawMemoryToString(&object, sizeof(object));
  		}
  
  		template<typename T>
  		class IsStreamInsertable {
  			template<typename SS, typename TT>
  			static auto test(int)
  				-> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
  
  			template<typename, typename>
  			static auto test(...)->std::false_type;
  
  		public:
  			static const bool value = decltype(test<std::ostream, const T&>(0))::value;
  		};
  
  		template<typename E>
  		std::string convertUnknownEnumToString(E e);
  
  		template<typename T>
  		typename std::enable_if<!std::is_enum<T>::value, std::string>::type convertUnstreamable(T const& value) {
  #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
  			(void)value;
  			return Detail::unprintableString;
  #else
  			return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
  #endif
  		}
  		template<typename T>
  		typename std::enable_if<std::is_enum<T>::value, std::string>::type convertUnstreamable(T const& value) {
  			return convertUnknownEnumToString(value);
  		}
  
  #if defined(_MANAGED)
  		//! Convert a CLR string to a utf8 std::string
  		template<typename T>
  		std::string clrReferenceToString(T^ ref) {
  			if (ref == nullptr)
  				return std::string("null");
  			auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
  			cli::pin_ptr<System::Byte> p = &bytes[0];
  			return std::string(reinterpret_cast<char const *>(p), bytes->Length);
  		}
  #endif
  
  	} // namespace Detail
  
  	// If we decide for C++14, change these to enable_if_ts
  	template <typename T, typename = void>
  	struct StringMaker {
  		template <typename Fake = T>
  		static
  			typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
  			convert(const Fake& value) {
  			ReusableStringStream rss;
  			rss << value;
  			return rss.str();
  		}
  
  		template <typename Fake = T>
  		static
  			typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
  			convert(const Fake& value) {
  			return Detail::convertUnstreamable(value);
  		}
  	};
  
  	namespace Detail {
  
  		// This function dispatches all stringification requests inside of Catch.
  		// Should be preferably called fully qualified, like ::Catch::Detail::stringify
  		template <typename T>
  		std::string stringify(const T& e) {
  			return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
  		}
  
  		template<typename E>
  		std::string convertUnknownEnumToString(E e) {
  			return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
  		}
  
  #if defined(_MANAGED)
  		template <typename T>
  		std::string stringify(T^ e) {
  			return ::Catch::StringMaker<T^>::convert(e);
  		}
  #endif
  
  	} // namespace Detail
  
  	// Some predefined specializations
  
  	template<>
  	struct StringMaker<std::string> {
  		static std::string convert(const std::string& str);
  	};
  #ifdef CATCH_CONFIG_WCHAR
  	template<>
  	struct StringMaker<std::wstring> {
  		static std::string convert(const std::wstring& wstr);
  	};
  #endif
  
  	template<>
  	struct StringMaker<char const *> {
  		static std::string convert(char const * str);
  	};
  	template<>
  	struct StringMaker<char *> {
  		static std::string convert(char * str);
  	};
  
  #ifdef CATCH_CONFIG_WCHAR
  	template<>
  	struct StringMaker<wchar_t const *> {
  		static std::string convert(wchar_t const * str);
  	};
  	template<>
  	struct StringMaker<wchar_t *> {
  		static std::string convert(wchar_t * str);
  	};
  #endif
  
  	// TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
  	//      while keeping string semantics?
  	template<int SZ>
  	struct StringMaker<char[SZ]> {
  		static std::string convert(char const* str) {
  			return ::Catch::Detail::stringify(std::string{ str });
  		}
  	};
  	template<int SZ>
  	struct StringMaker<signed char[SZ]> {
  		static std::string convert(signed char const* str) {
  			return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
  		}
  	};
  	template<int SZ>
  	struct StringMaker<unsigned char[SZ]> {
  		static std::string convert(unsigned char const* str) {
  			return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
  		}
  	};
  
  	template<>
  	struct StringMaker<int> {
  		static std::string convert(int value);
  	};
  	template<>
  	struct StringMaker<long> {
  		static std::string convert(long value);
  	};
  	template<>
  	struct StringMaker<long long> {
  		static std::string convert(long long value);
  	};
  	template<>
  	struct StringMaker<unsigned int> {
  		static std::string convert(unsigned int value);
  	};
  	template<>
  	struct StringMaker<unsigned long> {
  		static std::string convert(unsigned long value);
  	};
  	template<>
  	struct StringMaker<unsigned long long> {
  		static std::string convert(unsigned long long value);
  	};
  
  	template<>
  	struct StringMaker<bool> {
  		static std::string convert(bool b);
  	};
  
  	template<>
  	struct StringMaker<char> {
  		static std::string convert(char c);
  	};
  	template<>
  	struct StringMaker<signed char> {
  		static std::string convert(signed char c);
  	};
  	template<>
  	struct StringMaker<unsigned char> {
  		static std::string convert(unsigned char c);
  	};
  
  	template<>
  	struct StringMaker<std::nullptr_t> {
  		static std::string convert(std::nullptr_t);
  	};
  
  	template<>
  	struct StringMaker<float> {
  		static std::string convert(float value);
  	};
  	template<>
  	struct StringMaker<double> {
  		static std::string convert(double value);
  	};
  
  	template <typename T>
  	struct StringMaker<T*> {
  		template <typename U>
  		static std::string convert(U* p) {
  			if (p) {
  				return ::Catch::Detail::rawMemoryToString(p);
  			}
  			else {
  				return "nullptr";
  			}
  		}
  	};
  
  	template <typename R, typename C>
  	struct StringMaker<R C::*> {
  		static std::string convert(R C::* p) {
  			if (p) {
  				return ::Catch::Detail::rawMemoryToString(p);
  			}
  			else {
  				return "nullptr";
  			}
  		}
  	};
  
  #if defined(_MANAGED)
  	template <typename T>
  	struct StringMaker<T^> {
  		static std::string convert(T^ ref) {
  			return ::Catch::Detail::clrReferenceToString(ref);
  		}
  	};
  #endif
  
  	namespace Detail {
  		template<typename InputIterator>
  		std::string rangeToString(InputIterator first, InputIterator last) {
  			ReusableStringStream rss;
  			rss << "{ ";
  			if (first != last) {
  				rss << ::Catch::Detail::stringify(*first);
  				for (++first; first != last; ++first)
  					rss << ", " << ::Catch::Detail::stringify(*first);
  			}
  			rss << " }";
  			return rss.str();
  		}
  	}
  
  #ifdef __OBJC__
  	template<>
  	struct StringMaker<NSString*> {
  		static std::string convert(NSString * nsstring) {
  			if (!nsstring)
  				return "nil";
  			return std::string("@") + [nsstring UTF8String];
  		}
  	};
  	template<>
  	struct StringMaker<NSObject*> {
  		static std::string convert(NSObject* nsObject) {
  			return ::Catch::Detail::stringify([nsObject description]);
  		}
  
  	};
  	namespace Detail {
  		inline std::string stringify(NSString* nsstring) {
  			return StringMaker<NSString*>::convert(nsstring);
  		}
  
  	} // namespace Detail
  #endif // __OBJC__
  
  } // namespace Catch
  
  //////////////////////////////////////////////////////
  // Separate std-lib types stringification, so it can be selectively enabled
  // This means that we do not bring in
  
  #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
  #  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
  #  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
  #  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  #endif
  
  // Separate std::pair specialization
  #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
  #include <utility>
  namespace Catch {
  	template<typename T1, typename T2>
  	struct StringMaker<std::pair<T1, T2> > {
  		static std::string convert(const std::pair<T1, T2>& pair) {
  			ReusableStringStream rss;
  			rss << "{ "
  				<< ::Catch::Detail::stringify(pair.first)
  				<< ", "
  				<< ::Catch::Detail::stringify(pair.second)
  				<< " }";
  			return rss.str();
  		}
  	};
  }
  #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
  
  // Separate std::tuple specialization
  #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
  #include <tuple>
  namespace Catch {
  	namespace Detail {
  		template<
  			typename Tuple,
  			std::size_t N = 0,
  			bool = (N < std::tuple_size<Tuple>::value)
  			>
  			struct TupleElementPrinter {
  			static void print(const Tuple& tuple, std::ostream& os) {
  				os << (N ? ", " : " ")
  					<< ::Catch::Detail::stringify(std::get<N>(tuple));
  				TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
  			}
  		};
  
  		template<
  			typename Tuple,
  			std::size_t N
  		>
  			struct TupleElementPrinter<Tuple, N, false> {
  			static void print(const Tuple&, std::ostream&) {}
  		};
  
  	}
  
  	template<typename ...Types>
  	struct StringMaker<std::tuple<Types...>> {
  		static std::string convert(const std::tuple<Types...>& tuple) {
  			ReusableStringStream rss;
  			rss << '{';
  			Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
  			rss << " }";
  			return rss.str();
  		}
  	};
  }
  #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
  
  namespace Catch {
  	struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
  
  	// Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
  	using std::begin;
  	using std::end;
  
  	not_this_one begin(...);
  	not_this_one end(...);
  
  	template <typename T>
  	struct is_range {
  		static const bool value =
  			!std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
  			!std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
  	};
  
  #if defined(_MANAGED) // Managed types are never ranges
  	template <typename T>
  	struct is_range<T^> {
  		static const bool value = false;
  	};
  #endif
  
  	template<typename Range>
  	std::string rangeToString(Range const& range) {
  		return ::Catch::Detail::rangeToString(begin(range), end(range));
  	}
  
  	// Handle vector<bool> specially
  	template<typename Allocator>
  	std::string rangeToString(std::vector<bool, Allocator> const& v) {
  		ReusableStringStream rss;
  		rss << "{ ";
  		bool first = true;
  		for (bool b : v) {
  			if (first)
  				first = false;
  			else
  				rss << ", ";
  			rss << ::Catch::Detail::stringify(b);
  		}
  		rss << " }";
  		return rss.str();
  	}
  
  	template<typename R>
  	struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
  		static std::string convert(R const& range) {
  			return rangeToString(range);
  		}
  	};
  
  	template <typename T, int SZ>
  	struct StringMaker<T[SZ]> {
  		static std::string convert(T const(&arr)[SZ]) {
  			return rangeToString(arr);
  		}
  	};
  
  } // namespace Catch
  
  // Separate std::chrono::duration specialization
  #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  #include <ctime>
  #include <ratio>
  #include <chrono>
  
  namespace Catch {
  
  	template <class Ratio>
  	struct ratio_string {
  		static std::string symbol();
  	};
  
  	template <class Ratio>
  	std::string ratio_string<Ratio>::symbol() {
  		Catch::ReusableStringStream rss;
  		rss << '[' << Ratio::num << '/'
  			<< Ratio::den << ']';
  		return rss.str();
  	}
  	template <>
  	struct ratio_string<std::atto> {
  		static std::string symbol();
  	};
  	template <>
  	struct ratio_string<std::femto> {
  		static std::string symbol();
  	};
  	template <>
  	struct ratio_string<std::pico> {
  		static std::string symbol();
  	};
  	template <>
  	struct ratio_string<std::nano> {
  		static std::string symbol();
  	};
  	template <>
  	struct ratio_string<std::micro> {
  		static std::string symbol();
  	};
  	template <>
  	struct ratio_string<std::milli> {
  		static std::string symbol();
  	};
  
  	////////////
  	// std::chrono::duration specializations
  	template<typename Value, typename Ratio>
  	struct StringMaker<std::chrono::duration<Value, Ratio>> {
  		static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
  			ReusableStringStream rss;
  			rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
  			return rss.str();
  		}
  	};
  	template<typename Value>
  	struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
  		static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
  			ReusableStringStream rss;
  			rss << duration.count() << " s";
  			return rss.str();
  		}
  	};
  	template<typename Value>
  	struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
  		static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
  			ReusableStringStream rss;
  			rss << duration.count() << " m";
  			return rss.str();
  		}
  	};
  	template<typename Value>
  	struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
  		static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
  			ReusableStringStream rss;
  			rss << duration.count() << " h";
  			return rss.str();
  		}
  	};
  
  	////////////
  	// std::chrono::time_point specialization
  	// Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
  	template<typename Clock, typename Duration>
  	struct StringMaker<std::chrono::time_point<Clock, Duration>> {
  		static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
  			return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
  		}
  	};
  	// std::chrono::time_point<system_clock> specialization
  	template<typename Duration>
  	struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
  		static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
  			auto converted = std::chrono::system_clock::to_time_t(time_point);
  
  #ifdef _MSC_VER
  			std::tm timeInfo = {};
  			gmtime_s(&timeInfo, &converted);
  #else
  			std::tm* timeInfo = std::gmtime(&converted);
  #endif
  
  			auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  			char timeStamp[timeStampSize];
  			const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
  
  #ifdef _MSC_VER
  			std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  #else
  			std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
  #endif
  			return std::string(timeStamp);
  		}
  	};
  }
  #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  
  #ifdef _MSC_VER
  #pragma warning(pop)
  #endif
  
  // end catch_tostring.h
  #include <iosfwd>
  
  #ifdef _MSC_VER
  #pragma warning(push)
  #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
  #pragma warning(disable:4018) // more "signed/unsigned mismatch"
  #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
  #pragma warning(disable:4180) // qualifier applied to function type has no meaning
  #endif
  
  namespace Catch {
  
  	struct ITransientExpression {
  		auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
  		auto getResult() const -> bool { return m_result; }
  		virtual void streamReconstructedExpression(std::ostream &os) const = 0;
  
  		ITransientExpression(bool isBinaryExpression, bool result)
  			: m_isBinaryExpression(isBinaryExpression),
  			m_result(result)
  		{}
  
  		// We don't actually need a virtual destructor, but many static analysers
  		// complain if it's not here :-(
  		virtual ~ITransientExpression();
  
  		bool m_isBinaryExpression;
  		bool m_result;
  
  	};
  
  	void formatReconstructedExpression(std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs);
  
  	template<typename LhsT, typename RhsT>
  	class BinaryExpr : public ITransientExpression {
  		LhsT m_lhs;
  		StringRef m_op;
  		RhsT m_rhs;
  
  		void streamReconstructedExpression(std::ostream &os) const override {
  			formatReconstructedExpression
  			(os, Catch::Detail::stringify(m_lhs), m_op, Catch::Detail::stringify(m_rhs));
  		}
  
  	public:
  		BinaryExpr(bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs)
  			: ITransientExpression{ true, comparisonResult },
  			m_lhs(lhs),
  			m_op(op),
  			m_rhs(rhs)
  		{}
  	};
  
  	template<typename LhsT>
  	class UnaryExpr : public ITransientExpression {
  		LhsT m_lhs;
  
  		void streamReconstructedExpression(std::ostream &os) const override {
  			os << Catch::Detail::stringify(m_lhs);
  		}
  
  	public:
  		explicit UnaryExpr(LhsT lhs)
  			: ITransientExpression{ false, lhs ? true : false },
  			m_lhs(lhs)
  		{}
  	};
  
  	// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
  	template<typename LhsT, typename RhsT>
  	auto compareEqual(LhsT const& lhs, RhsT const& rhs) -> bool { return static_cast<bool>(lhs == rhs); }
  	template<typename T>
  	auto compareEqual(T* const& lhs, int rhs) -> bool { return lhs == reinterpret_cast<void const*>(rhs); }
  	template<typename T>
  	auto compareEqual(T* const& lhs, long rhs) -> bool { return lhs == reinterpret_cast<void const*>(rhs); }
  	template<typename T>
  	auto compareEqual(int lhs, T* const& rhs) -> bool { return reinterpret_cast<void const*>(lhs) == rhs; }
  	template<typename T>
  	auto compareEqual(long lhs, T* const& rhs) -> bool { return reinterpret_cast<void const*>(lhs) == rhs; }
  
  	template<typename LhsT, typename RhsT>
  	auto compareNotEqual(LhsT const& lhs, RhsT&& rhs) -> bool { return static_cast<bool>(lhs != rhs); }
  	template<typename T>
  	auto compareNotEqual(T* const& lhs, int rhs) -> bool { return lhs != reinterpret_cast<void const*>(rhs); }
  	template<typename T>
  	auto compareNotEqual(T* const& lhs, long rhs) -> bool { return lhs != reinterpret_cast<void const*>(rhs); }
  	template<typename T>
  	auto compareNotEqual(int lhs, T* const& rhs) -> bool { return reinterpret_cast<void const*>(lhs) != rhs; }
  	template<typename T>
  	auto compareNotEqual(long lhs, T* const& rhs) -> bool { return reinterpret_cast<void const*>(lhs) != rhs; }
  
  	template<typename LhsT>
  	class ExprLhs {
  		LhsT m_lhs;
  	public:
  		explicit ExprLhs(LhsT lhs) : m_lhs(lhs) {}
  
  		template<typename RhsT>
  		auto operator == (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  			return { compareEqual(m_lhs, rhs), m_lhs, "==", rhs };
  		}
  		auto operator == (bool rhs) -> BinaryExpr<LhsT, bool> const {
  			return { m_lhs == rhs, m_lhs, "==", rhs };
  		}
  
  		template<typename RhsT>
  		auto operator != (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  			return { compareNotEqual(m_lhs, rhs), m_lhs, "!=", rhs };
  		}
  		auto operator != (bool rhs) -> BinaryExpr<LhsT, bool> const {
  			return { m_lhs != rhs, m_lhs, "!=", rhs };
  		}
  
  		template<typename RhsT>
  		auto operator > (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  			return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
  		}
  		template<typename RhsT>
  		auto operator < (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  			return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
  		}
  		template<typename RhsT>
  		auto operator >= (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  			return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
  		}
  		template<typename RhsT>
  		auto operator <= (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  			return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
  		}
  
  		auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
  			return UnaryExpr<LhsT>{ m_lhs };
  		}
  	};
  
  	void handleExpression(ITransientExpression const& expr);
  
  	template<typename T>
  	void handleExpression(ExprLhs<T> const& expr) {
  		handleExpression(expr.makeUnaryExpr());
  	}
  
  	struct Decomposer {
  		template<typename T>
  		auto operator <= (T const& lhs) -> ExprLhs<T const&> {
  			return ExprLhs<T const&>{ lhs };
  		}
  
  		auto operator <=(bool value) -> ExprLhs<bool> {
  			return ExprLhs<bool>{ value };
  		}
  	};
  
  } // end namespace Catch
  
  #ifdef _MSC_VER
  #pragma warning(pop)
  #endif
  
  // end catch_decomposer.h
  // start catch_interfaces_capture.h
  
  #include <string>
  
  namespace Catch {
  
  	class AssertionResult;
  	struct AssertionInfo;
  	struct SectionInfo;
  	struct SectionEndInfo;
  	struct MessageInfo;
  	struct Counts;
  	struct BenchmarkInfo;
  	struct BenchmarkStats;
  	struct AssertionReaction;
  
  	struct ITransientExpression;
  
  	struct IResultCapture {
  
  		virtual ~IResultCapture();
  
  		virtual bool sectionStarted(SectionInfo const& sectionInfo,
  			Counts& assertions) = 0;
  		virtual void sectionEnded(SectionEndInfo const& endInfo) = 0;
  		virtual void sectionEndedEarly(SectionEndInfo const& endInfo) = 0;
  
  		virtual void benchmarkStarting(BenchmarkInfo const& info) = 0;
  		virtual void benchmarkEnded(BenchmarkStats const& stats) = 0;
  
  		virtual void pushScopedMessage(MessageInfo const& message) = 0;
  		virtual void popScopedMessage(MessageInfo const& message) = 0;
  
  		virtual void handleFatalErrorCondition(StringRef message) = 0;
  
  		virtual void handleExpr
  		(AssertionInfo const& info,
  			ITransientExpression const& expr,
  			AssertionReaction& reaction) = 0;
  		virtual void handleMessage
  		(AssertionInfo const& info,
  			ResultWas::OfType resultType,
  			StringRef const& message,
  			AssertionReaction& reaction) = 0;
  		virtual void handleUnexpectedExceptionNotThrown
  		(AssertionInfo const& info,
  			AssertionReaction& reaction) = 0;
  		virtual void handleUnexpectedInflightException
  		(AssertionInfo const& info,
  			std::string const& message,
  			AssertionReaction& reaction) = 0;
  		virtual void handleIncomplete
  		(AssertionInfo const& info) = 0;
  		virtual void handleNonExpr
  		(AssertionInfo const &info,
  			ResultWas::OfType resultType,
  			AssertionReaction &reaction) = 0;
  
  		virtual bool lastAssertionPassed() = 0;
  		virtual void assertionPassed() = 0;
  
  		// Deprecated, do not use:
  		virtual std::string getCurrentTestName() const = 0;
  		virtual const AssertionResult* getLastResult() const = 0;
  		virtual void exceptionEarlyReported() = 0;
  	};
  
  	IResultCapture& getResultCapture();
  }
  
  // end catch_interfaces_capture.h
  namespace Catch {
  
  	struct TestFailureException {};
  	struct AssertionResultData;
  	struct IResultCapture;
  	class RunContext;
  
  	class LazyExpression {
  		friend class AssertionHandler;
  		friend struct AssertionStats;
  		friend class RunContext;
  
  		ITransientExpression const* m_transientExpression = nullptr;
  		bool m_isNegated;
  	public:
  		LazyExpression(bool isNegated);
  		LazyExpression(LazyExpression const& other);
  		LazyExpression& operator = (LazyExpression const&) = delete;
  
  		explicit operator bool() const;
  
  		friend auto operator << (std::ostream& os, LazyExpression const& lazyExpr)->std::ostream&;
  	};
  
  	struct AssertionReaction {
  		bool shouldDebugBreak = false;
  		bool shouldThrow = false;
  	};
  
  	class AssertionHandler {
  		AssertionInfo m_assertionInfo;
  		AssertionReaction m_reaction;
  		bool m_completed = false;
  		IResultCapture& m_resultCapture;
  
  	public:
  		AssertionHandler
  		(StringRef macroName,
  			SourceLineInfo const& lineInfo,
  			StringRef capturedExpression,
  			ResultDisposition::Flags resultDisposition);
  		~AssertionHandler() {
  			if (!m_completed) {
  				m_resultCapture.handleIncomplete(m_assertionInfo);
  			}
  		}
  
  		template<typename T>
  		void handleExpr(ExprLhs<T> const& expr) {
  			handleExpr(expr.makeUnaryExpr());
  		}
  		void handleExpr(ITransientExpression const& expr);
  
  		void handleMessage(ResultWas::OfType resultType, StringRef const& message);
  
  		void handleExceptionThrownAsExpected();
  		void handleUnexpectedExceptionNotThrown();
  		void handleExceptionNotThrownAsExpected();
  		void handleThrowingCallSkipped();
  		void handleUnexpectedInflightException();
  
  		void complete();
  		void setCompleted();
  
  		// query
  		auto allowThrows() const -> bool;
  	};
  
  	void handleExceptionMatchExpr(AssertionHandler& handler, std::string const& str, StringRef matcherString);
  
  } // namespace Catch
  
  // end catch_assertionhandler.h
  // start catch_message.h
  
  #include <string>
  
  namespace Catch {
  
  	struct MessageInfo {
  		MessageInfo(std::string const& _macroName,
  			SourceLineInfo const& _lineInfo,
  			ResultWas::OfType _type);
  
  		std::string macroName;
  		std::string message;
  		SourceLineInfo lineInfo;
  		ResultWas::OfType type;
  		unsigned int sequence;
  
  		bool operator == (MessageInfo const& other) const;
  		bool operator < (MessageInfo const& other) const;
  	private:
  		static unsigned int globalCount;
  	};
  
  	struct MessageStream {
  
  		template<typename T>
  		MessageStream& operator << (T const& value) {
  			m_stream << value;
  			return *this;
  		}
  
  		ReusableStringStream m_stream;
  	};
  
  	struct MessageBuilder : MessageStream {
  		MessageBuilder(std::string const& macroName,
  			SourceLineInfo const& lineInfo,
  			ResultWas::OfType type);
  
  		template<typename T>
  		MessageBuilder& operator << (T const& value) {
  			m_stream << value;
  			return *this;
  		}
  
  		MessageInfo m_info;
  	};
  
  	class ScopedMessage {
  	public:
  		explicit ScopedMessage(MessageBuilder const& builder);
  		~ScopedMessage();
  
  		MessageInfo m_info;
  	};
  
  } // end namespace Catch
  
  // end catch_message.h
  #if !defined(CATCH_CONFIG_DISABLE)
  
  #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
  #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
  #else
  #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
  #endif
  
  #if defined(CATCH_CONFIG_FAST_COMPILE)
  
  ///////////////////////////////////////////////////////////////////////////////
  // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
  // macros.
  #define INTERNAL_CATCH_TRY
  #define INTERNAL_CATCH_CATCH( capturer )
  
  #else // CATCH_CONFIG_FAST_COMPILE
  
  #define INTERNAL_CATCH_TRY try
  #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
  
  #endif
  
  #define INTERNAL_CATCH_REACT( handler ) handler.complete();
  
  ///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
      do { \
          Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
          INTERNAL_CATCH_TRY { \
              CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
              catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
              CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
          } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
      } while( (void)0, false && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
  	// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
  
  ///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
      INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
      if( Catch::getResultCapture().lastAssertionPassed() )
  
  ///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
      INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
      if( !Catch::getResultCapture().lastAssertionPassed() )
  
  ///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
      do { \
          Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
          try { \
              static_cast<void>(__VA_ARGS__); \
              catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
          } \
          catch( ... ) { \
              catchAssertionHandler.handleUnexpectedInflightException(); \
          } \
          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
      } while( false )
  
  ///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
      do { \
          Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
          if( catchAssertionHandler.allowThrows() ) \
              try { \
                  static_cast<void>(__VA_ARGS__); \
                  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
              } \
              catch( ... ) { \
                  catchAssertionHandler.handleExceptionThrownAsExpected(); \
              } \
          else \
              catchAssertionHandler.handleThrowingCallSkipped(); \
          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
      } while( false )
  
  ///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
      do { \
          Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
          if( catchAssertionHandler.allowThrows() ) \
              try { \
                  static_cast<void>(expr); \
                  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
              } \
              catch( exceptionType const& ) { \
                  catchAssertionHandler.handleExceptionThrownAsExpected(); \
              } \
              catch( ... ) { \
                  catchAssertionHandler.handleUnexpectedInflightException(); \
              } \
          else \
              catchAssertionHandler.handleThrowingCallSkipped(); \
          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
      } while( false )
  
  ///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
      do { \
          Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
          catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
      } while( false )
  
  ///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_INFO( macroName, log ) \
      Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
  
  ///////////////////////////////////////////////////////////////////////////////
  // Although this is matcher-based, it can be used with just a string
  #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
      do { \
          Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
          if( catchAssertionHandler.allowThrows() ) \
              try { \
                  static_cast<void>(__VA_ARGS__); \
                  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
              } \
              catch( ... ) { \
                  Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \
              } \
          else \
              catchAssertionHandler.handleThrowingCallSkipped(); \
          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
      } while( false )
  
  #endif // CATCH_CONFIG_DISABLE
  
  // end catch_capture.hpp
  // start catch_section.h
  
  // start catch_section_info.h
  
  // start catch_totals.h
  
  #include <cstddef>
  
  namespace Catch {
  
  	struct Counts {
  		Counts operator - (Counts const& other) const;
  		Counts& operator += (Counts const& other);
  
  		std::size_t total() const;
  		bool allPassed() const;
  		bool allOk() const;
  
  		std::size_t passed = 0;
  		std::size_t failed = 0;
  		std::size_t failedButOk = 0;
  	};
  
  	struct Totals {
  
  		Totals operator - (Totals const& other) const;
  		Totals& operator += (Totals const& other);
  
  		Totals delta(Totals const& prevTotals) const;
  
  		int error = 0;
  		Counts assertions;
  		Counts testCases;
  	};
  }
  
  // end catch_totals.h
  #include <string>
  
  namespace Catch {
  
  	struct SectionInfo {
  		SectionInfo
  		(SourceLineInfo const& _lineInfo,
  			std::string const& _name,
  			std::string const& _description = std::string());
  
  		std::string name;
  		std::string description;
  		SourceLineInfo lineInfo;
  	};
  
  	struct SectionEndInfo {
  		SectionEndInfo(SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds);
  
  		SectionInfo sectionInfo;
  		Counts prevAssertions;
  		double durationInSeconds;
  	};
  
  } // end namespace Catch
  
  // end catch_section_info.h
  // start catch_timer.h
  
  #include <cstdint>
  
  namespace Catch {
  
  	auto getCurrentNanosecondsSinceEpoch()->uint64_t;
  	auto getEstimatedClockResolution()->uint64_t;
  
  	class Timer {
  		uint64_t m_nanoseconds = 0;
  	public:
  		void start();
  		auto getElapsedNanoseconds() const->uint64_t;
  		auto getElapsedMicroseconds() const->uint64_t;
  		auto getElapsedMilliseconds() const -> unsigned int;
  		auto getElapsedSeconds() const -> double;
  	};
  
  } // namespace Catch
  
  // end catch_timer.h
  #include <string>
  
  namespace Catch {
  
  	class Section : NonCopyable {
  	public:
  		Section(SectionInfo const& info);
  		~Section();
  
  		// This indicates whether the section should be executed or not
  		explicit operator bool() const;
  
  	private:
  		SectionInfo m_info;
  
  		std::string m_name;
  		Counts m_assertions;
  		bool m_sectionIncluded;
  		Timer m_timer;
  	};
  
  } // end namespace Catch
  
  #define INTERNAL_CATCH_SECTION( ... ) \
          if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
  
  // end catch_section.h
  // start catch_benchmark.h
  
  #include <cstdint>
  #include <string>
  
  namespace Catch {
  
  	class BenchmarkLooper {
  
  		std::string m_name;
  		std::size_t m_count = 0;
  		std::size_t m_iterationsToRun = 1;
  		uint64_t m_resolution;
  		Timer m_timer;
  
  		static auto getResolution()->uint64_t;
  	public:
  		// Keep most of this inline as it's on the code path that is being timed
  		BenchmarkLooper(StringRef name)
  			: m_name(name),
  			m_resolution(getResolution())
  		{
  			reportStart();
  			m_timer.start();
  		}
  
  		explicit operator bool() {
  			if (m_count < m_iterationsToRun)
  				return true;
  			return needsMoreIterations();
  		}
  
  		void increment() {
  			++m_count;
  		}
  
  		void reportStart();
  		auto needsMoreIterations() -> bool;
  	};
  
  } // end namespace Catch
  
  #define BENCHMARK( name ) \
      for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() )
  
  // end catch_benchmark.h
  // start catch_interfaces_exception.h
  
  // start catch_interfaces_registry_hub.h
  
  #include <string>
  #include <memory>
  
  namespace Catch {
  
  	class TestCase;
  	struct ITestCaseRegistry;
  	struct IExceptionTranslatorRegistry;
  	struct IExceptionTranslator;
  	struct IReporterRegistry;
  	struct IReporterFactory;
  	struct ITagAliasRegistry;
  	class StartupExceptionRegistry;
  
  	using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
  
  	struct IRegistryHub {
  		virtual ~IRegistryHub();
  
  		virtual IReporterRegistry const& getReporterRegistry() const = 0;
  		virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
  		virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
  
  		virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
  
  		virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
  	};
  
  	struct IMutableRegistryHub {
  		virtual ~IMutableRegistryHub();
  		virtual void registerReporter(std::string const& name, IReporterFactoryPtr const& factory) = 0;
  		virtual void registerListener(IReporterFactoryPtr const& factory) = 0;
  		virtual void registerTest(TestCase const& testInfo) = 0;
  		virtual void registerTranslator(const IExceptionTranslator* translator) = 0;
  		virtual void registerTagAlias(std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo) = 0;
  		virtual void registerStartupException() noexcept = 0;
  	};
  
  	IRegistryHub& getRegistryHub();
  	IMutableRegistryHub& getMutableRegistryHub();
  	void cleanUp();
  	std::string translateActiveException();
  
  }
  
  // end catch_interfaces_registry_hub.h
  #if defined(CATCH_CONFIG_DISABLE)
  #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
          static std::string translatorName( signature )
  #endif
  
  #include <exception>
  #include <string>
  #include <vector>
  
  namespace Catch {
  	using exceptionTranslateFunction = std::string(*)();
  
  	struct IExceptionTranslator;
  	using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
  
  	struct IExceptionTranslator {
  		virtual ~IExceptionTranslator();
  		virtual std::string translate(ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd) const = 0;
  	};
  
  	struct IExceptionTranslatorRegistry {
  		virtual ~IExceptionTranslatorRegistry();
  
  		virtual std::string translateActiveException() const = 0;
  	};
  
  	class ExceptionTranslatorRegistrar {
  		template<typename T>
  		class ExceptionTranslator : public IExceptionTranslator {
  		public:
  
  			ExceptionTranslator(std::string(*translateFunction)(T&))
  				: m_translateFunction(translateFunction)
  			{}
  
  			std::string translate(ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd) const override {
  				try {
  					if (it == itEnd)
  						std::rethrow_exception(std::current_exception());
  					else
  						return (*it)->translate(it + 1, itEnd);
  				}
  				catch (T& ex) {
  					return m_translateFunction(ex);
  				}
  			}
  
  		protected:
  			std::string(*m_translateFunction)(T&);
  		};
  
  	public:
  		template<typename T>
  		ExceptionTranslatorRegistrar(std::string(*translateFunction)(T&)) {
  			getMutableRegistryHub().registerTranslator
  			(new ExceptionTranslator<T>(translateFunction));
  		}
  	};
  }
  
  ///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
      static std::string translatorName( signature ); \
      CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
      namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
      CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
      static std::string translatorName( signature )
  
  #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
  
  // end catch_interfaces_exception.h
  // start catch_approx.h
  
  #include <type_traits>
  #include <stdexcept>
  
  namespace Catch {
  	namespace Detail {
  
  		class Approx {
  		private:
  			bool equalityComparisonImpl(double other) const;
  
  		public:
  			explicit Approx(double value);
  
  			static Approx custom();
  
  			template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  			Approx operator()(T const& value) {
  				Approx approx(static_cast<double>(value));
  				approx.epsilon(m_epsilon);
  				approx.margin(m_margin);
  				approx.scale(m_scale);
  				return approx;
  			}
  
  			template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  			explicit Approx(T const& value) : Approx(static_cast<double>(value))
  			{}
  
  			template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  			friend bool operator == (const T& lhs, Approx const& rhs) {
  				auto lhs_v = static_cast<double>(lhs);
  				return rhs.equalityComparisonImpl(lhs_v);
  			}
  
  			template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  			friend bool operator == (Approx const& lhs, const T& rhs) {
  				return operator==(rhs, lhs);
  			}
  
  			template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  			friend bool operator != (T const& lhs, Approx const& rhs) {
  				return !operator==(lhs, rhs);
  			}
  
  			template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  			friend bool operator != (Approx const& lhs, T const& rhs) {
  				return !operator==(rhs, lhs);
  			}
  
  			template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  			friend bool operator <= (T const& lhs, Approx const& rhs) {
  				return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
  			}
  
  			template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  			friend bool operator <= (Approx const& lhs, T const& rhs) {
  				return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
  			}
  
  			template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  			friend bool operator >= (T const& lhs, Approx const& rhs) {
  				return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
  			}
  
  			template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  			friend bool operator >= (Approx const& lhs, T const& rhs) {
  				return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
  			}
  
  			template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  			Approx& epsilon(T const& newEpsilon) {
  				double epsilonAsDouble = static_cast<double>(newEpsilon);
  				if (epsilonAsDouble < 0 || epsilonAsDouble > 1.0) {
  					throw std::domain_error
  					("Invalid Approx::epsilon: " +
  						Catch::Detail::stringify(epsilonAsDouble) +
  						", Approx::epsilon has to be between 0 and 1");
  				}
  				m_epsilon = epsilonAsDouble;
  				return *this;
  			}
  
  			template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  			Approx& margin(T const& newMargin) {
  				double marginAsDouble = static_cast<double>(newMargin);
  				if (marginAsDouble < 0) {
  					throw std::domain_error
  					("Invalid Approx::margin: " +
  						Catch::Detail::stringify(marginAsDouble) +
  						", Approx::Margin has to be non-negative.");
  
  				}
  				m_margin = marginAsDouble;
  				return *this;
  			}
  
  			template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  			Approx& scale(T const& newScale) {
  				m_scale = static_cast<double>(newScale);
  				return *this;
  			}
  
  			std::string toString() const;
  
  		private:
  			double m_epsilon;
  			double m_margin;
  			double m_scale;
  			double m_value;
  		};
  	}
  
  	template<>
  	struct StringMaker<Catch::Detail::Approx> {
  		static std::string convert(Catch::Detail::Approx const& value);
  	};
  
  } // end namespace Catch
  
  // end catch_approx.h
  // start catch_string_manip.h
  
  #include <string>
  #include <iosfwd>
  
  namespace Catch {
  
  	bool startsWith(std::string const& s, std::string const& prefix);
  	bool startsWith(std::string const& s, char prefix);
  	bool endsWith(std::string const& s, std::string const& suffix);
  	bool endsWith(std::string const& s, char suffix);
  	bool contains(std::string const& s, std::string const& infix);
  	void toLowerInPlace(std::string& s);
  	std::string toLower(std::string const& s);
  	std::string trim(std::string const& str);
  	bool replaceInPlace(std::string& str, std::string const& replaceThis, std::string const& withThis);
  
  	struct pluralise {
  		pluralise(std::size_t count, std::string const& label);
  
  		friend std::ostream& operator << (std::ostream& os, pluralise const& pluraliser);
  
  		std::size_t m_count;
  		std::string m_label;
  	};
  }
  
  // end catch_string_manip.h
  #ifndef CATCH_CONFIG_DISABLE_MATCHERS
  // start catch_capture_matchers.h
  
  // start catch_matchers.h
  
  #include <string>
  #include <vector>
  
  namespace Catch {
  	namespace Matchers {
  		namespace Impl {
  
  			template<typename ArgT> struct MatchAllOf;
  			template<typename ArgT> struct MatchAnyOf;
  			template<typename ArgT> struct MatchNotOf;
  
  			class MatcherUntypedBase {
  			public:
  				MatcherUntypedBase() = default;
  				MatcherUntypedBase(MatcherUntypedBase const&) = default;
  				MatcherUntypedBase& operator = (MatcherUntypedBase const&) = delete;
  				std::string toString() const;
  
  			protected:
  				virtual ~MatcherUntypedBase();
  				virtual std::string describe() const = 0;
  				mutable std::string m_cachedToString;
  			};
  
  			template<typename ObjectT>
  			struct MatcherMethod {
  				virtual bool match(ObjectT const& arg) const = 0;
  			};
  			template<typename PtrT>
  			struct MatcherMethod<PtrT*> {
  				virtual bool match(PtrT* arg) const = 0;
  			};
  
  			template<typename T>
  			struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
  
  				MatchAllOf<T> operator && (MatcherBase const& other) const;
  				MatchAnyOf<T> operator || (MatcherBase const& other) const;
  				MatchNotOf<T> operator ! () const;
  			};
  
  			template<typename ArgT>
  			struct MatchAllOf : MatcherBase<ArgT> {
  				bool match(ArgT const& arg) const override {
  					for (auto matcher : m_matchers) {
  						if (!matcher->match(arg))
  							return false;
  					}
  					return true;
  				}
  				std::string describe() const override {
  					std::string description;
  					description.reserve(4 + m_matchers.size() * 32);
  					description += "( ";
  					bool first = true;
  					for (auto matcher : m_matchers) {
  						if (first)
  							first = false;
  						else
  							description += " and ";
  						description += matcher->toString();
  					}
  					description += " )";
  					return description;
  				}
  
  				MatchAllOf<ArgT>& operator && (MatcherBase<ArgT> const& other) {
  					m_matchers.push_back(&other);
  					return *this;
  				}
  
  				std::vector<MatcherBase<ArgT> const*> m_matchers;
  			};
  			template<typename ArgT>
  			struct MatchAnyOf : MatcherBase<ArgT> {
  
  				bool match(ArgT const& arg) const override {
  					for (auto matcher : m_matchers) {
  						if (matcher->match(arg))
  							return true;
  					}
  					return false;
  				}
  				std::string describe() const override {
  					std::string description;
  					description.reserve(4 + m_matchers.size() * 32);
  					description += "( ";
  					bool first = true;
  					for (auto matcher : m_matchers) {
  						if (first)
  							first = false;
  						else
  							description += " or ";
  						description += matcher->toString();
  					}
  					description += " )";
  					return description;
  				}
  
  				MatchAnyOf<ArgT>& operator || (MatcherBase<ArgT> const& other) {
  					m_matchers.push_back(&other);
  					return *this;
  				}
  
  				std::vector<MatcherBase<ArgT> const*> m_matchers;
  			};
  
  			template<typename ArgT>
  			struct MatchNotOf : MatcherBase<ArgT> {
  
  				MatchNotOf(MatcherBase<ArgT> const& underlyingMatcher) : m_underlyingMatcher(underlyingMatcher) {}
  
  				bool match(ArgT const& arg) const override {
  					return !m_underlyingMatcher.match(arg);
  				}
  
  				std::string describe() const override {
  					return "not " + m_underlyingMatcher.toString();
  				}
  				MatcherBase<ArgT> const& m_underlyingMatcher;
  			};
  
  			template<typename T>
  			MatchAllOf<T> MatcherBase<T>::operator && (MatcherBase const& other) const {
  				return MatchAllOf<T>() && *this && other;
  			}
  			template<typename T>
  			MatchAnyOf<T> MatcherBase<T>::operator || (MatcherBase const& other) const {
  				return MatchAnyOf<T>() || *this || other;
  			}
  			template<typename T>
  			MatchNotOf<T> MatcherBase<T>::operator ! () const {
  				return MatchNotOf<T>(*this);
  			}
  
  		} // namespace Impl
  
  	} // namespace Matchers
  
  	using namespace Matchers;
  	using Matchers::Impl::MatcherBase;
  
  } // namespace Catch
  
  // end catch_matchers.h
  // start catch_matchers_floating.h
  
  #include <type_traits>
  #include <cmath>
  
  namespace Catch {
  	namespace Matchers {
  
  		namespace Floating {
  
  			enum class FloatingPointKind : uint8_t;
  
  			struct WithinAbsMatcher : MatcherBase<double> {
  				WithinAbsMatcher(double target, double margin);
  				bool match(double const& matchee) const override;
  				std::string describe() const override;
  			private:
  				double m_target;
  				double m_margin;
  			};
  
  			struct WithinUlpsMatcher : MatcherBase<double> {
  				WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
  				bool match(double const& matchee) const override;
  				std::string describe() const override;
  			private:
  				double m_target;
  				int m_ulps;
  				FloatingPointKind m_type;
  			};
  
  		} // namespace Floating
  
  		// The following functions create the actual matcher objects.
  		// This allows the types to be inferred
  		Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
  		Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
  		Floating::WithinAbsMatcher WithinAbs(double target, double margin);
  
  	} // namespace Matchers
  } // namespace Catch
  
  // end catch_matchers_floating.h
  // start catch_matchers_generic.hpp
  
  #include <functional>
  #include <string>
  
  namespace Catch {
  	namespace Matchers {
  		namespace Generic {
  
  			namespace Detail {
  				std::string finalizeDescription(const std::string& desc);
  			}
  
  			template <typename T>
  			class PredicateMatcher : public MatcherBase<T> {
  				std::function<bool(T const&)> m_predicate;
  				std::string m_description;
  			public:
  
  				PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
  					:m_predicate(std::move(elem)),
  					m_description(Detail::finalizeDescription(descr))
  				{}
  
  				bool match(T const& item) const override {
  					return m_predicate(item);
  				}
  
  				std::string describe() const override {
  					return m_description;
  				}
  			};
  
  		} // namespace Generic
  
  			// The following functions create the actual matcher objects.
  			// The user has to explicitly specify type to the function, because
  			// infering std::function<bool(T const&)> is hard (but possible) and
  			// requires a lot of TMP.
  		template<typename T>
  		Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
  			return Generic::PredicateMatcher<T>(predicate, description);
  		}
  
  	} // namespace Matchers
  } // namespace Catch
  
  // end catch_matchers_generic.hpp
  // start catch_matchers_string.h
  
  #include <string>
  
  namespace Catch {
  	namespace Matchers {
  
  		namespace StdString {
  
  			struct CasedString
  			{
  				CasedString(std::string const& str, CaseSensitive::Choice caseSensitivity);
  				std::string adjustString(std::string const& str) const;
  				std::string caseSensitivitySuffix() const;
  
  				CaseSensitive::Choice m_caseSensitivity;
  				std::string m_str;
  			};
  
  			struct StringMatcherBase : MatcherBase<std::string> {
  				StringMatcherBase(std::string const& operation, CasedString const& comparator);
  				std::string describe() const override;
  
  				CasedString m_comparator;
  				std::string m_operation;
  			};
  
  			struct EqualsMatcher : StringMatcherBase {
  				EqualsMatcher(CasedString const& comparator);
  				bool match(std::string const& source) const override;
  			};
  			struct ContainsMatcher : StringMatcherBase {
  				ContainsMatcher(CasedString const& comparator);
  				bool match(std::string const& source) const override;
  			};
  			struct StartsWithMatcher : StringMatcherBase {
  				StartsWithMatcher(CasedString const& comparator);
  				bool match(std::string const& source) const override;
  			};
  			struct EndsWithMatcher : StringMatcherBase {
  				EndsWithMatcher(CasedString const& comparator);
  				bool match(std::string const& source) const override;
  			};
  
  			struct RegexMatcher : MatcherBase<std::string> {
  				RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity);
  				bool match(std::string const& matchee) const override;
  				std::string describe() const override;
  
  			private:
  				std::string m_regex;
  				CaseSensitive::Choice m_caseSensitivity;
  			};
  
  		} // namespace StdString
  
  		// The following functions create the actual matcher objects.
  		// This allows the types to be inferred
  
  		StdString::EqualsMatcher Equals(std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
  		StdString::ContainsMatcher Contains(std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
  		StdString::EndsWithMatcher EndsWith(std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
  		StdString::StartsWithMatcher StartsWith(std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
  		StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes);
  
  	} // namespace Matchers
  } // namespace Catch
  
  // end catch_matchers_string.h
  // start catch_matchers_vector.h
  
  #include <algorithm>
  
  namespace Catch {
  	namespace Matchers {
  
  		namespace Vector {
  			namespace Detail {
  				template <typename InputIterator, typename T>
  				size_t count(InputIterator first, InputIterator last, T const& item) {
  					size_t cnt = 0;
  					for (; first != last; ++first) {
  						if (*first == item) {
  							++cnt;
  						}
  					}
  					return cnt;
  				}
  				template <typename InputIterator, typename T>
  				bool contains(InputIterator first, InputIterator last, T const& item) {
  					for (; first != last; ++first) {
  						if (*first == item) {
  							return true;
  						}
  					}
  					return false;
  				}
  			}
  
  			template<typename T>
  			struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
  
  				ContainsElementMatcher(T const &comparator) : m_comparator(comparator) {}
  
  				bool match(std::vector<T> const &v) const override {
  					for (auto const& el : v) {
  						if (el == m_comparator) {
  							return true;
  						}
  					}
  					return false;
  				}
  
  				std::string describe() const override {
  					return "Contains: " + ::Catch::Detail::stringify(m_comparator);
  				}
  
  				T const& m_comparator;
  			};
  
  			template<typename T>
  			struct ContainsMatcher : MatcherBase<std::vector<T>> {
  
  				ContainsMatcher(std::vector<T> const &comparator) : m_comparator(comparator) {}
  
  				bool match(std::vector<T> const &v) const override {
  					// !TBD: see note in EqualsMatcher
  					if (m_comparator.size() > v.size())
  						return false;
  					for (auto const& comparator : m_comparator) {
  						auto present = false;
  						for (const auto& el : v) {
  							if (el == comparator) {
  								present = true;
  								break;
  							}
  						}
  						if (!present) {
  							return false;
  						}
  					}
  					return true;
  				}
  				std::string describe() const override {
  					return "Contains: " + ::Catch::Detail::stringify(m_comparator);
  				}
  
  				std::vector<T> const& m_comparator;
  			};
  
  			template<typename T>
  			struct EqualsMatcher : MatcherBase<std::vector<T>> {
  
  				EqualsMatcher(std::vector<T> const &comparator) : m_comparator(comparator) {}
  
  				bool match(std::vector<T> const &v) const override {
  					// !TBD: This currently works if all elements can be compared using !=
  					// - a more general approach would be via a compare template that defaults
  					// to using !=. but could be specialised for, e.g. std::vector<T> etc
  					// - then just call that directly
  					if (m_comparator.size() != v.size())
  						return false;
  					for (std::size_t i = 0; i < v.size(); ++i)
  						if (m_comparator[i] != v[i])
  							return false;
  					return true;
  				}
  				std::string describe() const override {
  					return "Equals: " + ::Catch::Detail::stringify(m_comparator);
  				}
  				std::vector<T> const& m_comparator;
  			};
  
  			template<typename T>
  			struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
  				UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
  				bool match(std::vector<T> const& vec) const override {
  					// Note: This is a reimplementation of std::is_permutation,
  					//       because I don't want to include <algorithm> inside the common path
  					if (m_target.size() != vec.size()) {
  						return false;
  					}
  					auto lfirst = m_target.begin(), llast = m_target.end();
  					auto rfirst = vec.begin(), rlast = vec.end();
  					// Cut common prefix to optimize checking of permuted parts
  					while (lfirst != llast && *lfirst != *rfirst) {
  						++lfirst; ++rfirst;
  					}
  					if (lfirst == llast) {
  						return true;
  					}
  
  					for (auto mid = lfirst; mid != llast; ++mid) {
  						// Skip already counted items
  						if (Detail::contains(lfirst, mid, *mid)) {
  							continue;
  						}
  						size_t num_vec = Detail::count(rfirst, rlast, *mid);
  						if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) {
  							return false;
  						}
  					}
  
  					return true;
  				}
  
  				std::string describe() const override {
  					return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
  				}
  			private:
  				std::vector<T> const& m_target;
  			};
  
  		} // namespace Vector
  
  		// The following functions create the actual matcher objects.
  		// This allows the types to be inferred
  
  		template<typename T>
  		Vector::ContainsMatcher<T> Contains(std::vector<T> const& comparator) {
  			return Vector::ContainsMatcher<T>(comparator);
  		}
  
  		template<typename T>
  		Vector::ContainsElementMatcher<T> VectorContains(T const& comparator) {
  			return Vector::ContainsElementMatcher<T>(comparator);
  		}
  
  		template<typename T>
  		Vector::EqualsMatcher<T> Equals(std::vector<T> const& comparator) {
  			return Vector::EqualsMatcher<T>(comparator);
  		}
  
  		template<typename T>
  		Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
  			return Vector::UnorderedEqualsMatcher<T>(target);
  		}
  
  	} // namespace Matchers
  } // namespace Catch
  
  // end catch_matchers_vector.h
  namespace Catch {
  
  	template<typename ArgT, typename MatcherT>
  	class MatchExpr : public ITransientExpression {
  		ArgT const& m_arg;
  		MatcherT m_matcher;
  		StringRef m_matcherString;
  	public:
  		MatchExpr(ArgT const& arg, MatcherT const& matcher, StringRef matcherString)
  			: ITransientExpression{ true, matcher.match(arg) },
  			m_arg(arg),
  			m_matcher(matcher),
  			m_matcherString(matcherString)
  		{}
  
  		void streamReconstructedExpression(std::ostream &os) const override {
  			auto matcherAsString = m_matcher.toString();
  			os << Catch::Detail::stringify(m_arg) << ' ';
  			if (matcherAsString == Detail::unprintableString)
  				os << m_matcherString;
  			else
  				os << matcherAsString;
  		}
  	};
  
  	using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
  
  	void handleExceptionMatchExpr(AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString);
  
  	template<typename ArgT, typename MatcherT>
  	auto makeMatchExpr(ArgT const& arg, MatcherT const& matcher, StringRef matcherString) -> MatchExpr<ArgT, MatcherT> {
  		return MatchExpr<ArgT, MatcherT>(arg, matcher, matcherString);
  	}
  
  } // namespace Catch
  
  ///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
      do { \
          Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
          INTERNAL_CATCH_TRY { \
              catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher ) ); \
          } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
      } while( false )
  
  ///////////////////////////////////////////////////////////////////////////////
  #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
      do { \
          Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
          if( catchAssertionHandler.allowThrows() ) \
              try { \
                  static_cast<void>(__VA_ARGS__ ); \
                  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
              } \
              catch( exceptionType const& ex ) { \
                  catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher ) ); \
              } \
              catch( ... ) { \
                  catchAssertionHandler.handleUnexpectedInflightException(); \
              } \
          else \
              catchAssertionHandler.handleThrowingCallSkipped(); \
          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
      } while( false )
  
  // end catch_capture_matchers.h
  #endif
  
  // These files are included here so the single_include script doesn't put them
  // in the conditionally compiled sections
  // start catch_test_case_info.h
  
  #include <string>
  #include <vector>
  #include <memory>
  
  #ifdef __clang__
  #pragma clang diagnostic push
  #pragma clang diagnostic ignored "-Wpadded"
  #endif
  
  namespace Catch {
  
  	struct ITestInvoker;
  
  	struct TestCaseInfo {
  		enum SpecialProperties {
  			None = 0,
  			IsHidden = 1 << 1,
  			ShouldFail = 1 << 2,
  			MayFail = 1 << 3,
  			Throws = 1 << 4,
  			NonPortable = 1 << 5,
  			Benchmark = 1 << 6
  		};
  
  		TestCaseInfo(std::string const& _name,
  			std::string const& _className,
  			std::string const& _description,
  			std::vector<std::string> const& _tags,
  			SourceLineInfo const& _lineInfo);
  
  		friend void setTags(TestCaseInfo& testCaseInfo, std::vector<std::string> tags);
  
  		bool isHidden() const;
  		bool throws() const;
  		bool okToFail() const;
  		bool expectedToFail() const;
  
  		std::string tagsAsString() const;
  
  		std::string name;
  		std::string className;
  		std::string description;
  		std::vector<std::string> tags;
  		std::vector<std::string> lcaseTags;
  		SourceLineInfo lineInfo;
  		SpecialProperties properties;
  	};
  
  	class TestCase : public TestCaseInfo {
  	public:
  
  		TestCase(ITestInvoker* testCase, TestCaseInfo&& info);
  
  		TestCase withName(std::string const& _newName) const;
  
  		void invoke() const;
  
  		TestCaseInfo const& getTestCaseInfo() const;
  
  		bool operator == (TestCase const& other) const;
  		bool operator < (TestCase const& other) const;
  
  	private:
  		std::shared_ptr<ITestInvoker> test;
  	};
  
  	TestCase makeTestCase(ITestInvoker* testCase,
  		std::string const& className,
  		NameAndTags const& nameAndTags,
  		SourceLineInfo const& lineInfo);
  }
  
  #ifdef __clang__
  #pragma clang diagnostic pop
  #endif
  
  // end catch_test_case_info.h
  // start catch_interfaces_runner.h
  
  namespace Catch {
  
  	struct IRunner {
  		virtual ~IRunner();
  		virtual bool aborting() const = 0;
  	};
  }
  
  // end catch_interfaces_runner.h
  
  #ifdef __OBJC__
  // start catch_objc.hpp
  
  #import <objc/runtime.h>
  
  #include <string>
  
  // NB. Any general catch headers included here must be included
  // in catch.hpp first to make sure they are included by the single
  // header for non obj-usage
  
  ///////////////////////////////////////////////////////////////////////////////
  // This protocol is really only here for (self) documenting purposes, since
  // all its methods are optional.
  @protocol OcFixture
  
  @optional
  
  - (void)setUp;
  -(void)tearDown;
  
  @end
  
  namespace Catch {
  
  	class OcMethod : public ITestInvoker {
  
  	public:
  		OcMethod(Class cls, SEL sel) : m_cls(cls), m_sel(sel) {}
  
  		virtual void invoke() const {
  			id obj = [[m_cls alloc] init];
  
  			performOptionalSelector(obj, @selector(setUp)  );
  			performOptionalSelector(obj, m_sel);
  			performOptionalSelector(obj, @selector(tearDown)  );
  
  			arcSafeRelease(obj);
  		}
  	private:
  		virtual ~OcMethod() {}
  
  		Class m_cls;
  		SEL m_sel;
  	};
  
  	namespace Detail {
  
  		inline std::string getAnnotation(Class cls,
  			std::string const& annotationName,
  			std::string const& testCaseName) {
  			NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
  				SEL sel = NSSelectorFromString(selStr);
  			arcSafeRelease(selStr);
  			id value = performOptionalSelector(cls, sel);
  			if (value)
  				return[(NSString*)value UTF8String];
  			return "";
  		}
  	}
  
  	inline std::size_t registerTestMethods() {
  		std::size_t noTestMethods = 0;
  		int noClasses = objc_getClassList(nullptr, 0);
  
  		Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc(sizeof(Class) * noClasses);
  		objc_getClassList(classes, noClasses);
  
  		for (int c = 0; c < noClasses; c++) {
  			Class cls = classes[c];
  			{
  				u_int count;
  				Method* methods = class_copyMethodList(cls, &count);
  				for (u_int m = 0; m < count; m++) {
  					SEL selector = method_getName(methods[m]);
  					std::string methodName = sel_getName(selector);
  					if (startsWith(methodName, "Catch_TestCase_")) {
  						std::string testCaseName = methodName.substr(15);
  						std::string name = Detail::getAnnotation(cls, "Name", testCaseName);
  						std::string desc = Detail::getAnnotation(cls, "Description", testCaseName);
  						const char* className = class_getName(cls);
  
  						getMutableRegistryHub().registerTest(makeTestCase(new OcMethod(cls, selector), className, name.c_str(), desc.c_str(), SourceLineInfo("", 0)));
  						noTestMethods++;
  					}
  				}
  				free(methods);
  			}
  		}
  		return noTestMethods;
  	}
  
  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  
  	namespace Matchers {
  		namespace Impl {
  			namespace NSStringMatchers {
  
  				struct StringHolder : MatcherBase<NSString*> {
  					StringHolder(NSString* substr) : m_substr([substr copy]) {}
  					StringHolder(StringHolder const& other) : m_substr([other.m_substr copy]) {}
  					StringHolder() {
  						arcSafeRelease(m_substr);
  					}
  
  					bool match(NSString* arg) const override {
  						return false;
  					}
  
  					NSString* CATCH_ARC_STRONG m_substr;
  				};
  
  				struct Equals : StringHolder {
  					Equals(NSString* substr) : StringHolder(substr) {}
  
  					bool match(NSString* str) const override {
  						return  (str != nil || m_substr == nil) &&
  							[str isEqualToString : m_substr];
  					}
  
  					std::string describe() const override {
  						return "equals string: " + Catch::Detail::stringify(m_substr);
  					}
  				};
  
  				struct Contains : StringHolder {
  					Contains(NSString* substr) : StringHolder(substr) {}
  
  					bool match(NSString* str) const {
  						return  (str != nil || m_substr == nil) &&
  							[str rangeOfString : m_substr].location != NSNotFound;
  					}
  
  					std::string describe() const override {
  						return "contains string: " + Catch::Detail::stringify(m_substr);
  					}
  				};
  
  				struct StartsWith : StringHolder {
  					StartsWith(NSString* substr) : StringHolder(substr) {}
  
  					bool match(NSString* str) const override {
  						return  (str != nil || m_substr == nil) &&
  							[str rangeOfString : m_substr].location == 0;
  					}
  
  					std::string describe() const override {
  						return "starts with: " + Catch::Detail::stringify(m_substr);
  					}
  				};
  				struct EndsWith : StringHolder {
  					EndsWith(NSString* substr) : StringHolder(substr) {}
  
  					bool match(NSString* str) const override {
  						return  (str != nil || m_substr == nil) &&
  							[str rangeOfString : m_substr].location == [str length] - [m_substr length];
  					}
  
  					std::string describe() const override {
  						return "ends with: " + Catch::Detail::stringify(m_substr);
  					}
  				};
  
  			} // namespace NSStringMatchers
  		} // namespace Impl
  
  		inline Impl::NSStringMatchers::Equals
  			Equals(NSString* substr) { return Impl::NSStringMatchers::Equals(substr); }
  
  		inline Impl::NSStringMatchers::Contains
  			Contains(NSString* substr) { return Impl::NSStringMatchers::Contains(substr); }
  
  		inline Impl::NSStringMatchers::StartsWith
  			StartsWith(NSString* substr) { return Impl::NSStringMatchers::StartsWith(substr); }
  
  		inline Impl::NSStringMatchers::EndsWith
  			EndsWith(NSString* substr) { return Impl::NSStringMatchers::EndsWith(substr); }
  
  	} // namespace Matchers
  
  	using namespace Matchers;
  
  #endif // CATCH_CONFIG_DISABLE_MATCHERS
  
  } // namespace Catch
  
  ///////////////////////////////////////////////////////////////////////////////
  #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
  #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
  +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
  { \
  return @ name; \
  } \
  +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
  { \
  return @ desc; \
  } \
  -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
  
  #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
  
  // end catch_objc.hpp
  #endif
  
  #ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
  // start catch_external_interfaces.h
  
  // start catch_reporter_bases.hpp
  
  // start catch_interfaces_reporter.h
  
  // start catch_config.hpp
  
  // start catch_test_spec_parser.h
  
  #ifdef __clang__
  #pragma clang diagnostic push
  #pragma clang diagnostic ignored "-Wpadded"
  #endif
  
  // start catch_test_spec.h
  
  #ifdef __clang__
  #pragma clang diagnostic push
  #pragma clang diagnostic ignored "-Wpadded"
  #endif
  
  // start catch_wildcard_pattern.h
  
  namespace Catch
  {
  	class WildcardPattern {
  		enum WildcardPosition {
  			NoWildcard = 0,
  			WildcardAtStart = 1,
  			WildcardAtEnd = 2,
  			WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
  		};
  
  	public:
  
  		WildcardPattern(std::string const& pattern, CaseSensitive::Choice caseSensitivity);
  		virtual ~WildcardPattern() = default;
  		virtual bool matches(std::string const& str) const;
  
  	private:
  		std::string adjustCase(std::string const& str) const;
  		CaseSensitive::Choice m_caseSensitivity;
  		WildcardPosition m_wildcard = NoWildcard;
  		std::string m_pattern;
  	};
  }
  
  // end catch_wildcard_pattern.h
  #include <string>
  #include <vector>
  #include <memory>
  
  namespace Catch {
  
  	class TestSpec {
  		struct Pattern {
  			virtual ~Pattern();
  			virtual bool matches(TestCaseInfo const& testCase) const = 0;
  		};
  		using PatternPtr = std::shared_ptr<Pattern>;
  
  		class NamePattern : public Pattern {
  		public:
  			NamePattern(std::string const& name);
  			virtual ~NamePattern();
  			virtual bool matches(TestCaseInfo const& testCase) const override;
  		private:
  			WildcardPattern m_wildcardPattern;
  		};
  
  		class TagPattern : public Pattern {
  		public:
  			TagPattern(std::string const& tag);
  			virtual ~TagPattern();
  			virtual bool matches(TestCaseInfo const& testCase) const override;
  		private:
  			std::string m_tag;
  		};
  
  		class ExcludedPattern : public Pattern {
  		public:
  			ExcludedPattern(PatternPtr const& underlyingPattern);
  			virtual ~ExcludedPattern();
  			virtual bool matches(TestCaseInfo const& testCase) const override;
  		private:
  			PatternPtr m_underlyingPattern;
  		};
  
  		struct Filter {
  			std::vector<PatternPtr> m_patterns;
  
  			bool matches(TestCaseInfo const& testCase) const;
  		};
  
  	public:
  		bool hasFilters() const;
  		bool matches(TestCaseInfo const& testCase) const;
  
  	private:
  		std::vector<Filter> m_filters;
  
  		friend class TestSpecParser;
  	};
  }
  
  #ifdef __clang__
  #pragma clang diagnostic pop
  #endif
  
  // end catch_test_spec.h
  // start catch_interfaces_tag_alias_registry.h
  
  #include <string>
  
  namespace Catch {
  
  	struct TagAlias;
  
  	struct ITagAliasRegistry {
  		virtual ~ITagAliasRegistry();
  		// Nullptr if not present
  		virtual TagAlias const* find(std::string const& alias) const = 0;
  		virtual std::string expandAliases(std::string const& unexpandedTestSpec) const = 0;
  
  		static ITagAliasRegistry const& get();
  	};
  
  } // end namespace Catch
  
  // end catch_interfaces_tag_alias_registry.h
  namespace Catch {
  
  	class TestSpecParser {
  		enum Mode { None, Name, QuotedName, Tag, EscapedName };
  		Mode m_mode = None;
  		bool m_exclusion = false;
  		std::size_t m_start = std::string::npos, m_pos = 0;
  		std::string m_arg;
  		std::vector<std::size_t> m_escapeChars;
  		TestSpec::Filter m_currentFilter;
  		TestSpec m_testSpec;
  		ITagAliasRegistry const* m_tagAliases = nullptr;
  
  	public:
  		TestSpecParser(ITagAliasRegistry const& tagAliases);
  
  		TestSpecParser& parse(std::string const& arg);
  		TestSpec testSpec();
  
  	private:
  		void visitChar(char c);
  		void startNewMode(Mode mode, std::size_t start);
  		void escape();
  		std::string subString() const;
  
  		template<typename T>
  		void addPattern() {
  			std::string token = subString();
  			for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
  				token = token.substr(0, m_escapeChars[i] - m_start - i) + token.substr(m_escapeChars[i] - m_start - i + 1);
  			m_escapeChars.clear();
  			if (startsWith(token, "exclude:")) {
  				m_exclusion = true;
  				token = token.substr(8);
  			}
  			if (!token.empty()) {
  				TestSpec::PatternPtr pattern = std::make_shared<T>(token);
  				if (m_exclusion)
  					pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
  				m_currentFilter.m_patterns.push_back(pattern);
  			}
  			m_exclusion = false;
  			m_mode = None;
  		}
  
  		void addFilter();
  	};
  	TestSpec parseTestSpec(std::string const& arg);
  
  } // namespace Catch
  
  #ifdef __clang__
  #pragma clang diagnostic pop
  #endif
  
  // end catch_test_spec_parser.h
  // start catch_interfaces_config.h
  
  #include <iosfwd>
  #include <string>
  #include <vector>
  #include <memory>
  
  namespace Catch {
  
  	enum class Verbosity {
  		Quiet = 0,
  		Normal,
  		High
  	};
  
  	struct WarnAbout {
  		enum What {
  			Nothing = 0x00,
  			NoAssertions = 0x01,
  			NoTests = 0x02
  		};
  	};
  
  	struct ShowDurations {
  		enum OrNot {
  			DefaultForReporter,
  			Always,
  			Never
  		};
  	};
  	struct RunTests {
  		enum InWhatOrder {
  			InDeclarationOrder,
  			InLexicographicalOrder,
  			InRandomOrder
  		};
  	};
  	struct UseColour {
  		enum YesOrNo {
  			Auto,
  			Yes,
  			No
  		};
  	};
  	struct WaitForKeypress {
  		enum When {
  			Never,
  			BeforeStart = 1,
  			BeforeExit = 2,
  			BeforeStartAndExit = BeforeStart | BeforeExit
  		};
  	};
  
  	class TestSpec;
  
  	struct IConfig : NonCopyable {
  
  		virtual ~IConfig();
  
  		virtual bool allowThrows() const = 0;
  		virtual std::ostream& stream() const = 0;
  		virtual std::string name() const = 0;
  		virtual bool includeSuccessfulResults() const = 0;
  		virtual bool shouldDebugBreak() const = 0;
  		virtual bool warnAboutMissingAssertions() const = 0;
  		virtual bool warnAboutNoTests() const = 0;
  		virtual int abortAfter() const = 0;
  		virtual bool showInvisibles() const = 0;
  		virtual ShowDurations::OrNot showDurations() const = 0;
  		virtual TestSpec const& testSpec() const = 0;
  		virtual bool hasTestFilters() const = 0;
  		virtual RunTests::InWhatOrder runOrder() const = 0;
  		virtual unsigned int rngSeed() const = 0;
  		virtual int benchmarkResolutionMultiple() const = 0;
  		virtual UseColour::YesOrNo useColour() const = 0;
  		virtual std::vector<std::string> const& getSectionsToRun() const = 0;
  		virtual Verbosity verbosity() const = 0;
  	};
  
  	using IConfigPtr = std::shared_ptr<IConfig const>;
  }
  
  // end catch_interfaces_config.h
  // Libstdc++ doesn't like incomplete classes for unique_ptr
  
  #include <memory>
  #include <vector>
  #include <string>
  
  #ifndef CATCH_CONFIG_CONSOLE_WIDTH
  #define CATCH_CONFIG_CONSOLE_WIDTH 80
  #endif
  
  namespace Catch {
  
  	struct IStream;
  
  	struct ConfigData {
  		bool listTests = false;
  		bool listTags = false;
  		bool listReporters = false;
  		bool listTestNamesOnly = false;
  
  		bool showSuccessfulTests = false;
  		bool shouldDebugBreak = false;
  		bool noThrow = false;
  		bool showHelp = false;
  		bool showInvisibles = false;
  		bool filenamesAsTags = false;
  		bool libIdentify = false;
  
  		int abortAfter = -1;
  		unsigned int rngSeed = 0;
  		int benchmarkResolutionMultiple = 100;
  
  		Verbosity verbosity = Verbosity::Normal;
  		WarnAbout::What warnings = WarnAbout::Nothing;
  		ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
  		RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
  		UseColour::YesOrNo useColour = UseColour::Auto;
  		WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
  
  		std::string outputFilename;
  		std::string name;
  		std::string processName;
  
  		std::vector<std::string> reporterNames;
  		std::vector<std::string> testsOrTags;
  		std::vector<std::string> sectionsToRun;
  	};
  
  	class Config : public IConfig {
  	public:
  
  		Config() = default;
  		Config(ConfigData const& data);
  		virtual ~Config() = default;
  
  		std::string const& getFilename() const;
  
  		bool listTests() const;
  		bool listTestNamesOnly() const;
  		bool listTags() const;
  		bool listReporters() const;
  
  		std::string getProcessName() const;
  
  		std::vector<std::string> const& getReporterNames() const;
  		std::vector<std::string> const& getTestsOrTags() const;
  		std::vector<std::string> const& getSectionsToRun() const override;
  
  		virtual TestSpec const& testSpec() const override;
  		bool hasTestFilters() const override;
  
  		bool showHelp() const;
  
  		// IConfig interface
  		bool allowThrows() const override;
  		std::ostream& stream() const override;
  		std::string name() const override;
  		bool includeSuccessfulResults() const override;
  		bool warnAboutMissingAssertions() const override;
  		bool warnAboutNoTests() const override;
  		ShowDurations::OrNot showDurations() const override;
  		RunTests::InWhatOrder runOrder() const override;
  		unsigned int rngSeed() const override;
  		int benchmarkResolutionMultiple() const override;
  		UseColour::YesOrNo useColour() const override;
  		bool shouldDebugBreak() const override;
  		int abortAfter() const override;
  		bool showInvisibles() const override;
  		Verbosity verbosity() const override;
  
  	private:
  
  		IStream const* openStream();
  		ConfigData m_data;
  
  		std::unique_ptr<IStream const> m_stream;
  		TestSpec m_testSpec;
  		bool m_hasTestFilters = false;
  	};
  
  } // end namespace Catch
  
  // end catch_config.hpp
  // start catch_assertionresult.h
  
  #include <string>
  
  namespace Catch {
  
  	struct AssertionResultData
  	{
  		AssertionResultData() = delete;
  
  		AssertionResultData(ResultWas::OfType _resultType, LazyExpression const& _lazyExpression);
  
  		std::string message;
  		mutable std::string reconstructedExpression;
  		LazyExpression lazyExpression;
  		ResultWas::OfType resultType;
  
  		std::string reconstructExpression() const;
  	};
  
  	class AssertionResult {
  	public:
  		AssertionResult() = delete;
  		AssertionResult(AssertionInfo const& info, AssertionResultData const& data);
  
  		bool isOk() const;
  		bool succeeded() const;
  		ResultWas::OfType getResultType() const;
  		bool hasExpression() const;
  		bool hasMessage() const;
  		std::string getExpression() const;
  		std::string getExpressionInMacro() const;
  		bool hasExpandedExpression() const;
  		std::string getExpandedExpression() const;
  		std::string getMessage() const;
  		SourceLineInfo getSourceInfo() const;
  		StringRef getTestMacroName() const;
  
  		//protected:
  		AssertionInfo m_info;
  		AssertionResultData m_resultData;
  	};
  
  } // end namespace Catch
  
  // end catch_assertionresult.h
  // start catch_option.hpp
  
  namespace Catch {
  
  	// An optional type
  	template<typename T>
  	class Option {
  	public:
  		Option() : nullableValue(nullptr) {}
  		Option(T const& _value)
  			: nullableValue(new(storage) T(_value))
  		{}
  		Option(Option const& _other)
  			: nullableValue(_other ? new(storage) T(*_other) : nullptr)
  		{}
  
  		~Option() {
  			reset();
  		}
  
  		Option& operator= (Option const& _other) {
  			if (&_other != this) {
  				reset();
  				if (_other)
  					nullableValue = new(storage) T(*_other);
  			}
  			return *this;
  		}
  		Option& operator = (T const& _value) {
  			reset();
  			nullableValue = new(storage) T(_value);
  			return *this;
  		}
  
  		void reset() {
  			if (nullableValue)
  				nullableValue->~T();
  			nullableValue = nullptr;
  		}
  
  		T& operator*() { return *nullableValue; }
  		T const& operator*() const { return *nullableValue; }
  		T* operator->() { return nullableValue; }
  		const T* operator->() const { return nullableValue; }
  
  		T valueOr(T const& defaultValue) const {
  			return nullableValue ? *nullableValue : defaultValue;
  		}
  
  		bool some() const { return nullableValue != nullptr; }
  		bool none() const { return nullableValue == nullptr; }
  
  		bool operator !() const { return nullableValue == nullptr; }
  		explicit operator bool() const {
  			return some();
  		}
  
  	private:
  		T *nullableValue;
  		alignas(alignof(T)) char storage[sizeof(T)];
  	};
  
  } // end namespace Catch
  
  // end catch_option.hpp
  #include <string>
  #include <iosfwd>
  #include <map>
  #include <set>
  #include <memory>
  
  namespace Catch {
  
  	struct ReporterConfig {
  		explicit ReporterConfig(IConfigPtr const& _fullConfig);
  
  		ReporterConfig(IConfigPtr const& _fullConfig, std::ostream& _stream);
  
  		std::ostream& stream() const;
  		IConfigPtr fullConfig() const;
  
  	private:
  		std::ostream* m_stream;
  		IConfigPtr m_fullConfig;
  	};
  
  	struct ReporterPreferences {
  		bool shouldRedirectStdOut = false;
  	};
  
  	template<typename T>
  	struct LazyStat : Option<T> {
  		LazyStat& operator=(T const& _value) {
  			Option<T>::operator=(_value);
  			used = false;
  			return *this;
  		}
  		void reset() {
  			Option<T>::reset();
  			used = false;
  		}
  		bool used = false;
  	};
  
  	struct TestRunInfo {
  		TestRunInfo(std::string const& _name);
  		std::string name;
  	};
  	struct GroupInfo {
  		GroupInfo(std::string const& _name,
  			std::size_t _groupIndex,
  			std::size_t _groupsCount);
  
  		std::string name;
  		std::size_t groupIndex;
  		std::size_t groupsCounts;
  	};
  
  	struct AssertionStats {
  		AssertionStats(AssertionResult const& _assertionResult,
  			std::vector<MessageInfo> const& _infoMessages,
  			Totals const& _totals);
  
  		AssertionStats(AssertionStats const&) = default;
  		AssertionStats(AssertionStats &&) = default;
  		AssertionStats& operator = (AssertionStats const&) = default;
  		AssertionStats& operator = (AssertionStats &&) = default;
  		virtual ~AssertionStats();
  
  		AssertionResult assertionResult;
  		std::vector<MessageInfo> infoMessages;
  		Totals totals;
  	};
  
  	struct SectionStats {
  		SectionStats(SectionInfo const& _sectionInfo,
  			Counts const& _assertions,
  			double _durationInSeconds,
  			bool _missingAssertions);
  		SectionStats(SectionStats const&) = default;
  		SectionStats(SectionStats &&) = default;
  		SectionStats& operator = (SectionStats const&) = default;
  		SectionStats& operator = (SectionStats &&) = default;
  		virtual ~SectionStats();
  
  		SectionInfo sectionInfo;
  		Counts assertions;
  		double durationInSeconds;
  		bool missingAssertions;
  	};
  
  	struct TestCaseStats {
  		TestCaseStats(TestCaseInfo const& _testInfo,
  			Totals const& _totals,
  			std::string const& _stdOut,
  			std::string const& _stdErr,
  			bool _aborting);
  
  		TestCaseStats(TestCaseStats const&) = default;
  		TestCaseStats(TestCaseStats &&) = default;
  		TestCaseStats& operator = (TestCaseStats const&) = default;
  		TestCaseStats& operator = (TestCaseStats &&) = default;
  		virtual ~TestCaseStats();
  
  		TestCaseInfo testInfo;
  		Totals totals;
  		std::string stdOut;
  		std::string stdErr;
  		bool aborting;
  	};
  
  	struct TestGroupStats {
  		TestGroupStats(GroupInfo const& _groupInfo,
  			Totals const& _totals,
  			bool _aborting);
  		TestGroupStats(GroupInfo const& _groupInfo);
  
  		TestGroupStats(TestGroupStats const&) = default;
  		TestGroupStats(TestGroupStats &&) = default;
  		TestGroupStats& operator = (TestGroupStats const&) = default;
  		TestGroupStats& operator = (TestGroupStats &&) = default;
  		virtual ~TestGroupStats();
  
  		GroupInfo groupInfo;
  		Totals totals;
  		bool aborting;
  	};
  
  	struct TestRunStats {
  		TestRunStats(TestRunInfo const& _runInfo,
  			Totals const& _totals,
  			bool _aborting);
  
  		TestRunStats(TestRunStats const&) = default;
  		TestRunStats(TestRunStats &&) = default;
  		TestRunStats& operator = (TestRunStats const&) = default;
  		TestRunStats& operator = (TestRunStats &&) = default;
  		virtual ~TestRunStats();
  
  		TestRunInfo runInfo;
  		Totals totals;
  		bool aborting;
  	};
  
  	struct BenchmarkInfo {
  		std::string name;
  	};
  	struct BenchmarkStats {
  		BenchmarkInfo info;
  		std::size_t iterations;
  		uint64_t elapsedTimeInNanoseconds;
  	};
  
  	struct IStreamingReporter {
  		virtual ~IStreamingReporter() = default;
  
  		// Implementing class must also provide the following static methods:
  		// static std::string getDescription();
  		// static std::set<Verbosity> getSupportedVerbosities()
  
  		virtual ReporterPreferences getPreferences() const = 0;
  
  		virtual void noMatchingTestCases(std::string const& spec) = 0;
  
  		virtual void testRunStarting(TestRunInfo const& testRunInfo) = 0;
  		virtual void testGroupStarting(GroupInfo const& groupInfo) = 0;
  
  		virtual void testCaseStarting(TestCaseInfo const& testInfo) = 0;
  		virtual void sectionStarting(SectionInfo const& sectionInfo) = 0;
  
  		// *** experimental ***
  		virtual void benchmarkStarting(BenchmarkInfo const&) {}
  
  		virtual void assertionStarting(AssertionInfo const& assertionInfo) = 0;
  
  		// The return value indicates if the messages buffer should be cleared:
  		virtual bool assertionEnded(AssertionStats const& assertionStats) = 0;
  
  		// *** experimental ***
  		virtual void benchmarkEnded(BenchmarkStats const&) {}
  
  		virtual void sectionEnded(SectionStats const& sectionStats) = 0;
  		virtual void testCaseEnded(TestCaseStats const& testCaseStats) = 0;
  		virtual void testGroupEnded(TestGroupStats const& testGroupStats) = 0;
  		virtual void testRunEnded(TestRunStats const& testRunStats) = 0;
  
  		virtual void skipTest(TestCaseInfo const& testInfo) = 0;
  
  		// Default empty implementation provided
  		virtual void fatalErrorEncountered(StringRef name);
  
  		virtual bool isMulti() const;
  	};
  	using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
  
  	struct IReporterFactory {
  		virtual ~IReporterFactory();
  		virtual IStreamingReporterPtr create(ReporterConfig const& config) const = 0;
  		virtual std::string getDescription() const = 0;
  	};
  	using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
  
  	struct IReporterRegistry {
  		using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
  		using Listeners = std::vector<IReporterFactoryPtr>;
  
  		virtual ~IReporterRegistry();
  		virtual IStreamingReporterPtr create(std::string const& name, IConfigPtr const& config) const = 0;
  		virtual FactoryMap const& getFactories() const = 0;
  		virtual Listeners const& getListeners() const = 0;
  	};
  
  	void addReporter(IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter);
  
  } // end namespace Catch
  
  // end catch_interfaces_reporter.h
  #include <algorithm>
  #include <cstring>
  #include <cfloat>
  #include <cstdio>
  #include <assert.h>
  #include <memory>
  #include <ostream>
  
  namespace Catch {
  	void prepareExpandedExpression(AssertionResult& result);
  
  	// Returns double formatted as %.3f (format expected on output)
  	std::string getFormattedDuration(double duration);
  
  	template<typename DerivedT>
  	struct StreamingReporterBase : IStreamingReporter {
  
  		StreamingReporterBase(ReporterConfig const& _config)
  			: m_config(_config.fullConfig()),
  			stream(_config.stream())
  		{
  			m_reporterPrefs.shouldRedirectStdOut = false;
  			if (!DerivedT::getSupportedVerbosities().count(m_config->verbosity()))
  				throw std::domain_error("Verbosity level not supported by this reporter");
  		}
  
  		ReporterPreferences getPreferences() const override {
  			return m_reporterPrefs;
  		}
  
  		static std::set<Verbosity> getSupportedVerbosities() {
  			return { Verbosity::Normal };
  		}
  
  		~StreamingReporterBase() override = default;
  
  		void noMatchingTestCases(std::string const&) override {}
  
  		void testRunStarting(TestRunInfo const& _testRunInfo) override {
  			currentTestRunInfo = _testRunInfo;
  		}
  		void testGroupStarting(GroupInfo const& _groupInfo) override {
  			currentGroupInfo = _groupInfo;
  		}
  
  		void testCaseStarting(TestCaseInfo const& _testInfo) override {
  			currentTestCaseInfo = _testInfo;
  		}
  		void sectionStarting(SectionInfo const& _sectionInfo) override {
  			m_sectionStack.push_back(_sectionInfo);
  		}
  
  		void sectionEnded(SectionStats const& /* _sectionStats */) override {
  			m_sectionStack.pop_back();
  		}
  		void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
  			currentTestCaseInfo.reset();
  		}
  		void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
  			currentGroupInfo.reset();
  		}
  		void testRunEnded(TestRunStats const& /* _testRunStats */) override {
  			currentTestCaseInfo.reset();
  			currentGroupInfo.reset();
  			currentTestRunInfo.reset();
  		}
  
  		void skipTest(TestCaseInfo const&) override {
  			// Don't do anything with this by default.
  			// It can optionally be overridden in the derived class.
  		}
  
  		IConfigPtr m_config;
  		std::ostream& stream;
  
  		LazyStat<TestRunInfo> currentTestRunInfo;
  		LazyStat<GroupInfo> currentGroupInfo;
  		LazyStat<TestCaseInfo> currentTestCaseInfo;
  
  		std::vector<SectionInfo> m_sectionStack;
  		ReporterPreferences m_reporterPrefs;
  	};
  
  	template<typename DerivedT>
  	struct CumulativeReporterBase : IStreamingReporter {
  		template<typename T, typename ChildNodeT>
  		struct Node {
  			explicit Node(T const& _value) : value(_value) {}
  			virtual ~Node() {}
  
  			using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
  			T value;
  			ChildNodes children;
  		};
  		struct SectionNode {
  			explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
  			virtual ~SectionNode() = default;
  
  			bool operator == (SectionNode const& other) const {
  				return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
  			}
  			bool operator == (std::shared_ptr<SectionNode> const& other) const {
  				return operator==(*other);
  			}
  
  			SectionStats stats;
  			using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
  			using Assertions = std::vector<AssertionStats>;
  			ChildSections childSections;
  			Assertions assertions;
  			std::string stdOut;
  			std::string stdErr;
  		};
  
  		struct BySectionInfo {
  			BySectionInfo(SectionInfo const& other) : m_other(other) {}
  			BySectionInfo(BySectionInfo const& other) : m_other(other.m_other) {}
  			bool operator() (std::shared_ptr<SectionNode> const& node) const {
  				return ((node->stats.sectionInfo.name == m_other.name) &&
  					(node->stats.sectionInfo.lineInfo == m_other.lineInfo));
  			}
  			void operator=(BySectionInfo const&) = delete;
  
  		private:
  			SectionInfo const& m_other;
  		};
  
  		using TestCaseNode = Node<TestCaseStats, SectionNode>;
  		using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
  		using TestRunNode = Node<TestRunStats, TestGroupNode>;
  
  		CumulativeReporterBase(ReporterConfig const& _config)
  			: m_config(_config.fullConfig()),
  			stream(_config.stream())
  		{
  			m_reporterPrefs.shouldRedirectStdOut = false;
  			if (!DerivedT::getSupportedVerbosities().count(m_config->verbosity()))
  				throw std::domain_error("Verbosity level not supported by this reporter");
  		}
  		~CumulativeReporterBase() override = default;
  
  		ReporterPreferences getPreferences() const override {
  			return m_reporterPrefs;
  		}
  
  		static std::set<Verbosity> getSupportedVerbosities() {
  			return { Verbosity::Normal };
  		}
  
  		void testRunStarting(TestRunInfo const&) override {}
  		void testGroupStarting(GroupInfo const&) override {}
  
  		void testCaseStarting(TestCaseInfo const&) override {}
  
  		void sectionStarting(SectionInfo const& sectionInfo) override {
  			SectionStats incompleteStats(sectionInfo, Counts(), 0, false);
  			std::shared_ptr<SectionNode> node;
  			if (m_sectionStack.empty()) {
  				if (!m_rootSection)
  					m_rootSection = std::make_shared<SectionNode>(incompleteStats);
  				node = m_rootSection;
  			}
  			else {
  				SectionNode& parentNode = *m_sectionStack.back();
  				auto it =
  					std::find_if(parentNode.childSections.begin(),
  						parentNode.childSections.end(),
  						BySectionInfo(sectionInfo));
  				if (it == parentNode.childSections.end()) {
  					node = std::make_shared<SectionNode>(incompleteStats);
  					parentNode.childSections.push_back(node);
  				}
  				else
  					node = *it;
  			}
  			m_sectionStack.push_back(node);
  			m_deepestSection = std::move(node);
  		}
  
  		void assertionStarting(AssertionInfo const&) override {}
  
  		bool assertionEnded(AssertionStats const& assertionStats) override {
  			assert(!m_sectionStack.empty());
  			// AssertionResult holds a pointer to a temporary DecomposedExpression,
  			// which getExpandedExpression() calls to build the expression string.
  			// Our section stack copy of the assertionResult will likely outlive the
  			// temporary, so it must be expanded or discarded now to avoid calling
  			// a destroyed object later.
  			prepareExpandedExpression(const_cast<AssertionResult&>(assertionStats.assertionResult));
  			SectionNode& sectionNode = *m_sectionStack.back();
  			sectionNode.assertions.push_back(assertionStats);
  			return true;
  		}
  		void sectionEnded(SectionStats const& sectionStats) override {
  			assert(!m_sectionStack.empty());
  			SectionNode& node = *m_sectionStack.back();
  			node.stats = sectionStats;
  			m_sectionStack.pop_back();
  		}
  		void testCaseEnded(TestCaseStats const& testCaseStats) override {
  			auto node = std::make_shared<TestCaseNode>(testCaseStats);
  			assert(m_sectionStack.size() == 0);
  			node->children.push_back(m_rootSection);
  			m_testCases.push_back(node);
  			m_rootSection.reset();
  
  			assert(m_deepestSection);
  			m_deepestSection->stdOut = testCaseStats.stdOut;
  			m_deepestSection->stdErr = testCaseStats.stdErr;
  		}
  		void testGroupEnded(TestGroupStats const& testGroupStats) override {
  			auto node = std::make_shared<TestGroupNode>(testGroupStats);
  			node->children.swap(m_testCases);
  			m_testGroups.push_back(node);
  		}
  		void testRunEnded(TestRunStats const& testRunStats) override {
  			auto node = std::make_shared<TestRunNode>(testRunStats);
  			node->children.swap(m_testGroups);
  			m_testRuns.push_back(node);
  			testRunEndedCumulative();
  		}
  		virtual void testRunEndedCumulative() = 0;
  
  		void skipTest(TestCaseInfo const&) override {}
  
  		IConfigPtr m_config;
  		std::ostream& stream;
  		std::vector<AssertionStats> m_assertions;
  		std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
  		std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
  		std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
  
  		std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
  
  		std::shared_ptr<SectionNode> m_rootSection;
  		std::shared_ptr<SectionNode> m_deepestSection;
  		std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
  		ReporterPreferences m_reporterPrefs;
  	};
  
  	template<char C>
  	char const* getLineOfChars() {
  		static char line[CATCH_CONFIG_CONSOLE_WIDTH] = { 0 };
  		if (!*line) {
  			std::memset(line, C, CATCH_CONFIG_CONSOLE_WIDTH - 1);
  			line[CATCH_CONFIG_CONSOLE_WIDTH - 1] = 0;
  		}
  		return line;
  	}
  
  	struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
  		TestEventListenerBase(ReporterConfig const& _config);
  
  		void assertionStarting(AssertionInfo const&) override;
  		bool assertionEnded(AssertionStats const&) override;
  	};
  
  } // end namespace Catch
  
  // end catch_reporter_bases.hpp
  // start catch_console_colour.h
  
  namespace Catch {
  
  	struct Colour {
  		enum Code {
  			None = 0,
  
  			White,
  			Red,
  			Green,
  			Blue,
  			Cyan,
  			Yellow,
  			Grey,
  
  			Bright = 0x10,
  
  			BrightRed = Bright | Red,
  			BrightGreen = Bright | Green,
  			LightGrey = Bright | Grey,
  			BrightWhite = Bright | White,
  			BrightYellow = Bright | Yellow,
  
  			// By intention
  			FileName = LightGrey,
  			Warning = BrightYellow,
  			ResultError = BrightRed,
  			ResultSuccess = BrightGreen,
  			ResultExpectedFailure = Warning,
  
  			Error = BrightRed,
  			Success = Green,
  
  			OriginalExpression = Cyan,
  			ReconstructedExpression = BrightYellow,
  
  			SecondaryText = LightGrey,
  			Headers = White
  		};
  
  		// Use constructed object for RAII guard
  		Colour(Code _colourCode);
  		Colour(Colour&& other) noexcept;
  		Colour& operator=(Colour&& other) noexcept;
  		~Colour();
  
  		// Use static method for one-shot changes
  		static void use(Code _colourCode);
  
  	private:
  		bool m_moved = false;
  	};
  
  	std::ostream& operator << (std::ostream& os, Colour const&);
  
  } // end namespace Catch
  
  // end catch_console_colour.h
  // start catch_reporter_registrars.hpp
  
  
  namespace Catch {
  
  	template<typename T>
  	class ReporterRegistrar {
  
  		class ReporterFactory : public IReporterFactory {
  
  			virtual IStreamingReporterPtr create(ReporterConfig const& config) const override {
  				return std::unique_ptr<T>(new T(config));
  			}
  
  			virtual std::string getDescription() const override {
  				return T::getDescription();
  			}
  		};
  
  	public:
  
  		explicit ReporterRegistrar(std::string const& name) {
  			getMutableRegistryHub().registerReporter(name, std::make_shared<ReporterFactory>());
  		}
  	};
  
  	template<typename T>
  	class ListenerRegistrar {
  
  		class ListenerFactory : public IReporterFactory {
  
  			virtual IStreamingReporterPtr create(ReporterConfig const& config) const override {
  				return std::unique_ptr<T>(new T(config));
  			}
  			virtual std::string getDescription() const override {
  				return std::string();
  			}
  		};
  
  	public:
  
  		ListenerRegistrar() {
  			getMutableRegistryHub().registerListener(std::make_shared<ListenerFactory>());
  		}
  	};
  }
  
  #if !defined(CATCH_CONFIG_DISABLE)
  
  #define CATCH_REGISTER_REPORTER( name, reporterType ) \
      CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \
      namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
      CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  
  #define CATCH_REGISTER_LISTENER( listenerType ) \
       CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS   \
       namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
       CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
  #else // CATCH_CONFIG_DISABLE
  
  #define CATCH_REGISTER_REPORTER(name, reporterType)
  #define CATCH_REGISTER_LISTENER(listenerType)
  
  #endif // CATCH_CONFIG_DISABLE
  
  // end catch_reporter_registrars.hpp
  // Allow users to base their work off existing reporters
  // start catch_reporter_compact.h
  
  namespace Catch {
  
  	struct CompactReporter : StreamingReporterBase<CompactReporter> {
  
  		using StreamingReporterBase::StreamingReporterBase;
  
  		~CompactReporter() override;
  
  		static std::string getDescription();
  
  		ReporterPreferences getPreferences() const override;
  
  		void noMatchingTestCases(std::string const& spec) override;
  
  		void assertionStarting(AssertionInfo const&) override;
  
  		bool assertionEnded(AssertionStats const& _assertionStats) override;
  
  		void sectionEnded(SectionStats const& _sectionStats) override;
  
  		void testRunEnded(TestRunStats const& _testRunStats) override;
  
  	};
  
  } // end namespace Catch
  
  // end catch_reporter_compact.h
  // start catch_reporter_console.h
  
  #if defined(_MSC_VER)
  #pragma warning(push)
  #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  							  // Note that 4062 (not all labels are handled
  							  // and default is missing) is enabled
  #endif
  
  namespace Catch {
  	// Fwd decls
  	struct SummaryColumn;
  	class TablePrinter;
  
  	struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
  		std::unique_ptr<TablePrinter> m_tablePrinter;
  
  		ConsoleReporter(ReporterConfig const& config);
  		~ConsoleReporter() override;
  		static std::string getDescription();
  
  		void noMatchingTestCases(std::string const& spec) override;
  
  		void assertionStarting(AssertionInfo const&) override;
  
  		bool assertionEnded(AssertionStats const& _assertionStats) override;
  
  		void sectionStarting(SectionInfo const& _sectionInfo) override;
  		void sectionEnded(SectionStats const& _sectionStats) override;
  
  		void benchmarkStarting(BenchmarkInfo const& info) override;
  		void benchmarkEnded(BenchmarkStats const& stats) override;
  
  		void testCaseEnded(TestCaseStats const& _testCaseStats) override;
  		void testGroupEnded(TestGroupStats const& _testGroupStats) override;
  		void testRunEnded(TestRunStats const& _testRunStats) override;
  
  	private:
  
  		void lazyPrint();
  
  		void lazyPrintWithoutClosingBenchmarkTable();
  		void lazyPrintRunInfo();
  		void lazyPrintGroupInfo();
  		void printTestCaseAndSectionHeader();
  
  		void printClosedHeader(std::string const& _name);
  		void printOpenHeader(std::string const& _name);
  
  		// if string has a : in first line will set indent to follow it on
  		// subsequent lines
  		void printHeaderString(std::string const& _string, std::size_t indent = 0);
  
  		void printTotals(Totals const& totals);
  		void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
  
  		void printTotalsDivider(Totals const& totals);
  		void printSummaryDivider();
  
  	private:
  		bool m_headerPrinted = false;
  	};
  
  } // end namespace Catch
  
  #if defined(_MSC_VER)
  #pragma warning(pop)
  #endif
  
  // end catch_reporter_console.h
  // start catch_reporter_junit.h
  
  // start catch_xmlwriter.h
  
  #include <vector>
  
  namespace Catch {
  
  	class XmlEncode {
  	public:
  		enum ForWhat { ForTextNodes, ForAttributes };
  
  		XmlEncode(std::string const& str, ForWhat forWhat = ForTextNodes);
  
  		void encodeTo(std::ostream& os) const;
  
  		friend std::ostream& operator << (std::ostream& os, XmlEncode const& xmlEncode);
  
  	private:
  		std::string m_str;
  		ForWhat m_forWhat;
  	};
  
  	class XmlWriter {
  	public:
  
  		class ScopedElement {
  		public:
  			ScopedElement(XmlWriter* writer);
  
  			ScopedElement(ScopedElement&& other) noexcept;
  			ScopedElement& operator=(ScopedElement&& other) noexcept;
  
  			~ScopedElement();
  
  			ScopedElement& writeText(std::string const& text, bool indent = true);
  
  			template<typename T>
  			ScopedElement& writeAttribute(std::string const& name, T const& attribute) {
  				m_writer->writeAttribute(name, attribute);
  				return *this;
  			}
  
  		private:
  			mutable XmlWriter* m_writer = nullptr;
  		};
  
  		XmlWriter(std::ostream& os = Catch::cout());
  		~XmlWriter();
  
  		XmlWriter(XmlWriter const&) = delete;
  		XmlWriter& operator=(XmlWriter const&) = delete;
  
  		XmlWriter& startElement(std::string const& name);
  
  		ScopedElement scopedElement(std::string const& name);
  
  		XmlWriter& endElement();
  
  		XmlWriter& writeAttribute(std::string const& name, std::string const& attribute);
  
  		XmlWriter& writeAttribute(std::string const& name, bool attribute);
  
  		template<typename T>
  		XmlWriter& writeAttribute(std::string const& name, T const& attribute) {
  			ReusableStringStream rss;
  			rss << attribute;
  			return writeAttribute(name, rss.str());
  		}
  
  		XmlWriter& writeText(std::string const& text, bool indent = true);
  
  		XmlWriter& writeComment(std::string const& text);
  
  		void writeStylesheetRef(std::string const& url);
  
  		XmlWriter& writeBlankLine();
  
  		void ensureTagClosed();
  
  	private:
  
  		void writeDeclaration();
  
  		void newlineIfNecessary();
  
  		bool m_tagIsOpen = false;
  		bool m_needsNewline = false;
  		std::vector<std::string> m_tags;
  		std::string m_indent;
  		std::ostream& m_os;
  	};
  
  }
  
  // end catch_xmlwriter.h
  namespace Catch {
  
  	class JunitReporter : public CumulativeReporterBase<JunitReporter> {
  	public:
  		JunitReporter(ReporterConfig const& _config);
  
  		~JunitReporter() override;
  
  		static std::string getDescription();
  
  		void noMatchingTestCases(std::string const& /*spec*/) override;
  
  		void testRunStarting(TestRunInfo const& runInfo) override;
  
  		void testGroupStarting(GroupInfo const& groupInfo) override;
  
  		void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
  		bool assertionEnded(AssertionStats const& assertionStats) override;
  
  		void testCaseEnded(TestCaseStats const& testCaseStats) override;
  
  		void testGroupEnded(TestGroupStats const& testGroupStats) override;
  
  		void testRunEndedCumulative() override;
  
  		void writeGroup(TestGroupNode const& groupNode, double suiteTime);
  
  		void writeTestCase(TestCaseNode const& testCaseNode);
  
  		void writeSection(std::string const& className,
  			std::string const& rootName,
  			SectionNode const& sectionNode);
  
  		void writeAssertions(SectionNode const& sectionNode);
  		void writeAssertion(AssertionStats const& stats);
  
  		XmlWriter xml;
  		Timer suiteTimer;
  		std::string stdOutForSuite;
  		std::string stdErrForSuite;
  		unsigned int unexpectedExceptions = 0;
  		bool m_okToFail = false;
  	};
  
  } // end namespace Catch
  
  // end catch_reporter_junit.h
  // start catch_reporter_xml.h
  
  namespace Catch {
  	class XmlReporter : public StreamingReporterBase<XmlReporter> {
  	public:
  		XmlReporter(ReporterConfig const& _config);
  
  		~XmlReporter() override;
  
  		static std::string getDescription();
  
  		virtual std::string getStylesheetRef() const;
  
  		void writeSourceInfo(SourceLineInfo const& sourceInfo);
  
  	public: // StreamingReporterBase
  
  		void noMatchingTestCases(std::string const& s) override;
  
  		void testRunStarting(TestRunInfo const& testInfo) override;
  
  		void testGroupStarting(GroupInfo const& groupInfo) override;
  
  		void testCaseStarting(TestCaseInfo const& testInfo) override;
  
  		void sectionStarting(SectionInfo const& sectionInfo) override;
  
  		void assertionStarting(AssertionInfo const&) override;
  
  		bool assertionEnded(AssertionStats const& assertionStats) override;
  
  		void sectionEnded(SectionStats const& sectionStats) override;
  
  		void testCaseEnded(TestCaseStats const& testCaseStats) override;
  
  		void testGroupEnded(TestGroupStats const& testGroupStats) override;
  
  		void testRunEnded(TestRunStats const& testRunStats) override;
  
  	private:
  		Timer m_testCaseTimer;
  		XmlWriter m_xml;
  		int m_sectionDepth = 0;
  	};
  
  } // end namespace Catch
  
  // end catch_reporter_xml.h
  
  // end catch_external_interfaces.h
  #endif
  
  #endif // ! CATCH_CONFIG_IMPL_ONLY
  
  #ifdef CATCH_IMPL
  // start catch_impl.hpp
  
  #ifdef __clang__
  #pragma clang diagnostic push
  #pragma clang diagnostic ignored "-Wweak-vtables"
  #endif
  
  // Keep these here for external reporters
  // start catch_test_case_tracker.h
  
  #include <string>
  #include <vector>
  #include <memory>
  
  namespace Catch {
  	namespace TestCaseTracking {
  
  		struct NameAndLocation {
  			std::string name;
  			SourceLineInfo location;
  
  			NameAndLocation(std::string const& _name, SourceLineInfo const& _location);
  		};
  
  		struct ITracker;
  
  		using ITrackerPtr = std::shared_ptr<ITracker>;
  
  		struct ITracker {
  			virtual ~ITracker();
  
  			// static queries
  			virtual NameAndLocation const& nameAndLocation() const = 0;
  
  			// dynamic queries
  			virtual bool isComplete() const = 0; // Successfully completed or failed
  			virtual bool isSuccessfullyCompleted() const = 0;
  			virtual bool isOpen() const = 0; // Started but not complete
  			virtual bool hasChildren() const = 0;
  
  			virtual ITracker& parent() = 0;
  
  			// actions
  			virtual void close() = 0; // Successfully complete
  			virtual void fail() = 0;
  			virtual void markAsNeedingAnotherRun() = 0;
  
  			virtual void addChild(ITrackerPtr const& child) = 0;
  			virtual ITrackerPtr findChild(NameAndLocation const& nameAndLocation) = 0;
  			virtual void openChild() = 0;
  
  			// Debug/ checking
  			virtual bool isSectionTracker() const = 0;
  			virtual bool isIndexTracker() const = 0;
  		};
  
  		class TrackerContext {
  
  			enum RunState {
  				NotStarted,
  				Executing,
  				CompletedCycle
  			};
  
  			ITrackerPtr m_rootTracker;
  			ITracker* m_currentTracker = nullptr;
  			RunState m_runState = NotStarted;
  
  		public:
  
  			static TrackerContext& instance();
  
  			ITracker& startRun();
  			void endRun();
  
  			void startCycle();
  			void completeCycle();
  
  			bool completedCycle() const;
  			ITracker& currentTracker();
  			void setCurrentTracker(ITracker* tracker);
  		};
  
  		class TrackerBase : public ITracker {
  		protected:
  			enum CycleState {
  				NotStarted,
  				Executing,
  				ExecutingChildren,
  				NeedsAnotherRun,
  				CompletedSuccessfully,
  				Failed
  			};
  
  			class TrackerHasName {
  				NameAndLocation m_nameAndLocation;
  			public:
  				TrackerHasName(NameAndLocation const& nameAndLocation);
  				bool operator ()(ITrackerPtr const& tracker) const;
  			};
  
  			using Children = std::vector<ITrackerPtr>;
  			NameAndLocation m_nameAndLocation;
  			TrackerContext& m_ctx;
  			ITracker* m_parent;
  			Children m_children;
  			CycleState m_runState = NotStarted;
  
  		public:
  			TrackerBase(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent);
  
  			NameAndLocation const& nameAndLocation() const override;
  			bool isComplete() const override;
  			bool isSuccessfullyCompleted() const override;
  			bool isOpen() const override;
  			bool hasChildren() const override;
  
  			void addChild(ITrackerPtr const& child) override;
  
  			ITrackerPtr findChild(NameAndLocation const& nameAndLocation) override;
  			ITracker& parent() override;
  
  			void openChild() override;
  
  			bool isSectionTracker() const override;
  			bool isIndexTracker() const override;
  
  			void open();
  
  			void close() override;
  			void fail() override;
  			void markAsNeedingAnotherRun() override;
  
  		private:
  			void moveToParent();
  			void moveToThis();
  		};
  
  		class SectionTracker : public TrackerBase {
  			std::vector<std::string> m_filters;
  		public:
  			SectionTracker(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent);
  
  			bool isSectionTracker() const override;
  
  			static SectionTracker& acquire(TrackerContext& ctx, NameAndLocation const& nameAndLocation);
  
  			void tryOpen();
  
  			void addInitialFilters(std::vector<std::string> const& filters);
  			void addNextFilters(std::vector<std::string> const& filters);
  		};
  
  		class IndexTracker : public TrackerBase {
  			int m_size;
  			int m_index = -1;
  		public:
  			IndexTracker(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size);
  
  			bool isIndexTracker() const override;
  			void close() override;
  
  			static IndexTracker& acquire(TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size);
  
  			int index() const;
  
  			void moveNext();
  		};
  
  	} // namespace TestCaseTracking
  
  	using TestCaseTracking::ITracker;
  	using TestCaseTracking::TrackerContext;
  	using TestCaseTracking::SectionTracker;
  	using TestCaseTracking::IndexTracker;
  
  } // namespace Catch
  
  // end catch_test_case_tracker.h
  
  // start catch_leak_detector.h
  
  namespace Catch {
  
  	struct LeakDetector {
  		LeakDetector();
  	};
  
  }
  // end catch_leak_detector.h
  // Cpp files will be included in the single-header file here
  // start catch_approx.cpp
  
  #include <cmath>
  #include <limits>
  
  namespace {
  
  	// Performs equivalent check of std::fabs(lhs - rhs) <= margin
  	// But without the subtraction to allow for INFINITY in comparison
  	bool marginComparison(double lhs, double rhs, double margin) {
  		return (lhs + margin >= rhs) && (rhs + margin >= lhs);
  	}
  
  }
  
  namespace Catch {
  	namespace Detail {
  
  		Approx::Approx(double value)
  			: m_epsilon(std::numeric_limits<float>::epsilon() * 100),
  			m_margin(0.0),
  			m_scale(0.0),
  			m_value(value)
  		{}
  
  		Approx Approx::custom() {
  			return Approx(0);
  		}
  
  		std::string Approx::toString() const {
  			ReusableStringStream rss;
  			rss << "Approx( " << ::Catch::Detail::stringify(m_value) << " )";
  			return rss.str();
  		}
  
  		bool Approx::equalityComparisonImpl(const double other) const {
  			// First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
  			// Thanks to Richard Harris for his help refining the scaled margin value
  			return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
  		}
  
  	} // end namespace Detail
  
  	std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
  		return value.toString();
  	}
  
  } // end namespace Catch
  // end catch_approx.cpp
  // start catch_assertionhandler.cpp
  
  // start catch_context.h
  
  #include <memory>
  
  namespace Catch {
  
  	struct IResultCapture;
  	struct IRunner;
  	struct IConfig;
  	struct IMutableContext;
  
  	using IConfigPtr = std::shared_ptr<IConfig const>;
  
  	struct IContext
  	{
  		virtual ~IContext();
  
  		virtual IResultCapture* getResultCapture() = 0;
  		virtual IRunner* getRunner() = 0;
  		virtual IConfigPtr const& getConfig() const = 0;
  	};
  
  	struct IMutableContext : IContext
  	{
  		virtual ~IMutableContext();
  		virtual void setResultCapture(IResultCapture* resultCapture) = 0;
  		virtual void setRunner(IRunner* runner) = 0;
  		virtual void setConfig(IConfigPtr const& config) = 0;
  
  	private:
  		static IMutableContext *currentContext;
  		friend IMutableContext& getCurrentMutableContext();
  		friend void cleanUpContext();
  		static void createContext();
  	};
  
  	inline IMutableContext& getCurrentMutableContext()
  	{
  		if (!IMutableContext::currentContext)
  			IMutableContext::createContext();
  		return *IMutableContext::currentContext;
  	}
  
  	inline IContext& getCurrentContext()
  	{
  		return getCurrentMutableContext();
  	}
  
  	void cleanUpContext();
  }
  
  // end catch_context.h
  // start catch_debugger.h
  
  namespace Catch {
  	bool isDebuggerActive();
  }
  
  #ifdef CATCH_PLATFORM_MAC
  
  #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
  
  #elif defined(CATCH_PLATFORM_LINUX)
  // If we can use inline assembler, do it because this allows us to break
  // directly at the location of the failing check instead of breaking inside
  // raise() called from it, i.e. one stack frame below.
  #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
  #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
  #else // Fall back to the generic way.
  #include <signal.h>
  
  #define CATCH_TRAP() raise(SIGTRAP)
  #endif
  #elif defined(_MSC_VER)
  #define CATCH_TRAP() __debugbreak()
  #elif defined(__MINGW32__)
  extern "C" __declspec(dllimport) void __stdcall DebugBreak();
  #define CATCH_TRAP() DebugBreak()
  #endif
  
  #ifdef CATCH_TRAP
  #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
  #else
  namespace Catch {
  	inline void doNothing() {}
  }
  #define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing()
  #endif
  
  // end catch_debugger.h
  // start catch_run_context.h
  
  // start catch_fatal_condition.h
  
  // start catch_windows_h_proxy.h
  
  
  #if defined(CATCH_PLATFORM_WINDOWS)
  
  #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
  #  define CATCH_DEFINED_NOMINMAX
  #  define NOMINMAX
  #endif
  #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
  #  define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
  #  define WIN32_LEAN_AND_MEAN
  #endif
  
  #ifdef __AFXDLL
  #include <AfxWin.h>
  #else
  #include <windows.h>
  #endif
  
  #ifdef CATCH_DEFINED_NOMINMAX
  #  undef NOMINMAX
  #endif
  #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
  #  undef WIN32_LEAN_AND_MEAN
  #endif
  
  #endif // defined(CATCH_PLATFORM_WINDOWS)
  
  // end catch_windows_h_proxy.h
  #if defined( CATCH_CONFIG_WINDOWS_SEH )
  
  namespace Catch {
  
  	struct FatalConditionHandler {
  
  		static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
  		FatalConditionHandler();
  		static void reset();
  		~FatalConditionHandler();
  
  	private:
  		static bool isSet;
  		static ULONG guaranteeSize;
  		static PVOID exceptionHandlerHandle;
  	};
  
  } // namespace Catch
  
  #elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
  
  #include <signal.h>
  
  namespace Catch {
  
  	struct FatalConditionHandler {
  
  		static bool isSet;
  		static struct sigaction oldSigActions[];
  		static stack_t oldSigStack;
  		static char altStackMem[];
  
  		static void handleSignal(int sig);
  
  		FatalConditionHandler();
  		~FatalConditionHandler();
  		static void reset();
  	};
  
  } // namespace Catch
  
  #else
  
  namespace Catch {
  	struct FatalConditionHandler {
  		void reset();
  	};
  }
  
  #endif
  
  // end catch_fatal_condition.h
  #include <string>
  
  namespace Catch {
  
  	struct IMutableContext;
  
  	///////////////////////////////////////////////////////////////////////////
  
  	class RunContext : public IResultCapture, public IRunner {
  
  	public:
  		RunContext(RunContext const&) = delete;
  		RunContext& operator =(RunContext const&) = delete;
  
  		explicit RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter);
  
  		~RunContext() override;
  
  		void testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount);
  		void testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount);
  
  		Totals runTest(TestCase const& testCase);
  
  		IConfigPtr config() const;
  		IStreamingReporter& reporter() const;
  
  	public: // IResultCapture
  
  		// Assertion handlers
  		void handleExpr
  		(AssertionInfo const& info,
  			ITransientExpression const& expr,
  			AssertionReaction& reaction) override;
  		void handleMessage
  		(AssertionInfo const& info,
  			ResultWas::OfType resultType,
  			StringRef const& message,
  			AssertionReaction& reaction) override;
  		void handleUnexpectedExceptionNotThrown
  		(AssertionInfo const& info,
  			AssertionReaction& reaction) override;
  		void handleUnexpectedInflightException
  		(AssertionInfo const& info,
  			std::string const& message,
  			AssertionReaction& reaction) override;
  		void handleIncomplete
  		(AssertionInfo const& info) override;
  		void handleNonExpr
  		(AssertionInfo const &info,
  			ResultWas::OfType resultType,
  			AssertionReaction &reaction) override;
  
  		bool sectionStarted(SectionInfo const& sectionInfo, Counts& assertions) override;
  
  		void sectionEnded(SectionEndInfo const& endInfo) override;
  		void sectionEndedEarly(SectionEndInfo const& endInfo) override;
  
  		void benchmarkStarting(BenchmarkInfo const& info) override;
  		void benchmarkEnded(BenchmarkStats const& stats) override;
  
  		void pushScopedMessage(MessageInfo const& message) override;
  		void popScopedMessage(MessageInfo const& message) override;
  
  		std::string getCurrentTestName() const override;
  
  		const AssertionResult* getLastResult() const override;
  
  		void exceptionEarlyReported() override;
  
  		void handleFatalErrorCondition(StringRef message) override;
  
  		bool lastAssertionPassed() override;
  
  		void assertionPassed() override;
  
  	public:
  		// !TBD We need to do this another way!
  		bool aborting() const final;
  
  	private:
  
  		void runCurrentTest(std::string& redirectedCout, std::string& redirectedCerr);
  		void invokeActiveTestCase();
  
  		void resetAssertionInfo();
  		bool testForMissingAssertions(Counts& assertions);
  
  		void assertionEnded(AssertionResult const& result);
  		void reportExpr
  		(AssertionInfo const &info,
  			ResultWas::OfType resultType,
  			ITransientExpression const *expr,
  			bool negated);
  
  		void populateReaction(AssertionReaction& reaction);
  
  	private:
  
  		void handleUnfinishedSections();
  
  		TestRunInfo m_runInfo;
  		IMutableContext& m_context;
  		TestCase const* m_activeTestCase = nullptr;
  		ITracker* m_testCaseTracker;
  		Option<AssertionResult> m_lastResult;
  
  		IConfigPtr m_config;
  		Totals m_totals;
  		IStreamingReporterPtr m_reporter;
  		std::vector<MessageInfo> m_messages;
  		AssertionInfo m_lastAssertionInfo;
  		std::vector<SectionEndInfo> m_unfinishedSections;
  		std::vector<ITracker*> m_activeSections;
  		TrackerContext m_trackerContext;
  		bool m_lastAssertionPassed = false;
  		bool m_shouldReportUnexpected = true;
  		bool m_includeSuccessfulResults;
  	};
  
  } // end namespace Catch
  
  // end catch_run_context.h
  namespace Catch {
  
  	auto operator <<(std::ostream& os, ITransientExpression const& expr) -> std::ostream& {
  		expr.streamReconstructedExpression(os);
  		return os;
  	}
  
  	LazyExpression::LazyExpression(bool isNegated)
  		: m_isNegated(isNegated)
  	{}
  
  	LazyExpression::LazyExpression(LazyExpression const& other) : m_isNegated(other.m_isNegated) {}
  
  	LazyExpression::operator bool() const {
  		return m_transientExpression != nullptr;
  	}
  
  	auto operator << (std::ostream& os, LazyExpression const& lazyExpr) -> std::ostream& {
  		if (lazyExpr.m_isNegated)
  			os << "!";
  
  		if (lazyExpr) {
  			if (lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression())
  				os << "(" << *lazyExpr.m_transientExpression << ")";
  			else
  				os << *lazyExpr.m_transientExpression;
  		}
  		else {
  			os << "{** error - unchecked empty expression requested **}";
  		}
  		return os;
  	}
  
  	AssertionHandler::AssertionHandler
  	(StringRef macroName,
  		SourceLineInfo const& lineInfo,
  		StringRef capturedExpression,
  		ResultDisposition::Flags resultDisposition)
  		: m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
  		m_resultCapture(getResultCapture())
  	{}
  
  	void AssertionHandler::handleExpr(ITransientExpression const& expr) {
  		m_resultCapture.handleExpr(m_assertionInfo, expr, m_reaction);
  	}
  	void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
  		m_resultCapture.handleMessage(m_assertionInfo, resultType, message, m_reaction);
  	}
  
  	auto AssertionHandler::allowThrows() const -> bool {
  		return getCurrentContext().getConfig()->allowThrows();
  	}
  
  	void AssertionHandler::complete() {
  		setCompleted();
  		if (m_reaction.shouldDebugBreak) {
  
  			// If you find your debugger stopping you here then go one level up on the
  			// call-stack for the code that caused it (typically a failed assertion)
  
  			// (To go back to the test and change execution, jump over the throw, next)
  			CATCH_BREAK_INTO_DEBUGGER();
  		}
  		if (m_reaction.shouldThrow)
  			throw Catch::TestFailureException();
  	}
  	void AssertionHandler::setCompleted() {
  		m_completed = true;
  	}
  
  	void AssertionHandler::handleUnexpectedInflightException() {
  		m_resultCapture.handleUnexpectedInflightException(m_assertionInfo, Catch::translateActiveException(), m_reaction);
  	}
  
  	void AssertionHandler::handleExceptionThrownAsExpected() {
  		m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
  	}
  	void AssertionHandler::handleExceptionNotThrownAsExpected() {
  		m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
  	}
  
  	void AssertionHandler::handleUnexpectedExceptionNotThrown() {
  		m_resultCapture.handleUnexpectedExceptionNotThrown(m_assertionInfo, m_reaction);
  	}
  
  	void AssertionHandler::handleThrowingCallSkipped() {
  		m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
  	}
  
  	// This is the overload that takes a string and infers the Equals matcher from it
  	// The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
  	void handleExceptionMatchExpr(AssertionHandler& handler, std::string const& str, StringRef matcherString) {
  		handleExceptionMatchExpr(handler, Matchers::Equals(str), matcherString);
  	}
  
  } // namespace Catch
  // end catch_assertionhandler.cpp
  // start catch_assertionresult.cpp
  
  namespace Catch {
  	AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression) :
  		lazyExpression(_lazyExpression),
  		resultType(_resultType) {}
  
  	std::string AssertionResultData::reconstructExpression() const {
  
  		if (reconstructedExpression.empty()) {
  			if (lazyExpression) {
  				ReusableStringStream rss;
  				rss << lazyExpression;
  				reconstructedExpression = rss.str();
  			}
  		}
  		return reconstructedExpression;
  	}
  
  	AssertionResult::AssertionResult(AssertionInfo const& info, AssertionResultData const& data)
  		: m_info(info),
  		m_resultData(data)
  	{}
  
  	// Result was a success
  	bool AssertionResult::succeeded() const {
  		return Catch::isOk(m_resultData.resultType);
  	}
  
  	// Result was a success, or failure is suppressed
  	bool AssertionResult::isOk() const {
  		return Catch::isOk(m_resultData.resultType) || shouldSuppressFailure(m_info.resultDisposition);
  	}
  
  	ResultWas::OfType AssertionResult::getResultType() const {
  		return m_resultData.resultType;
  	}
  
  	bool AssertionResult::hasExpression() const {
  		return m_info.capturedExpression[0] != 0;
  	}
  
  	bool AssertionResult::hasMessage() const {
  		return !m_resultData.message.empty();
  	}
  
  	std::string AssertionResult::getExpression() const {
  		if (isFalseTest(m_info.resultDisposition))
  			return "!(" + m_info.capturedExpression + ")";
  		else
  			return m_info.capturedExpression;
  	}
  
  	std::string AssertionResult::getExpressionInMacro() const {
  		std::string expr;
  		if (m_info.macroName[0] == 0)
  			expr = m_info.capturedExpression;
  		else {
  			expr.reserve(m_info.macroName.size() + m_info.capturedExpression.size() + 4);
  			expr += m_info.macroName;
  			expr += "( ";
  			expr += m_info.capturedExpression;
  			expr += " )";
  		}
  		return expr;
  	}
  
  	bool AssertionResult::hasExpandedExpression() const {
  		return hasExpression() && getExpandedExpression() != getExpression();
  	}
  
  	std::string AssertionResult::getExpandedExpression() const {
  		std::string expr = m_resultData.reconstructExpression();
  		return expr.empty()
  			? getExpression()
  			: expr;
  	}
  
  	std::string AssertionResult::getMessage() const {
  		return m_resultData.message;
  	}
  	SourceLineInfo AssertionResult::getSourceInfo() const {
  		return m_info.lineInfo;
  	}
  
  	StringRef AssertionResult::getTestMacroName() const {
  		return m_info.macroName;
  	}
  
  } // end namespace Catch
  // end catch_assertionresult.cpp
  // start catch_benchmark.cpp
  
  namespace Catch {
  
  	auto BenchmarkLooper::getResolution() -> uint64_t {
  		return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple();
  	}
  
  	void BenchmarkLooper::reportStart() {
  		getResultCapture().benchmarkStarting({ m_name });
  	}
  	auto BenchmarkLooper::needsMoreIterations() -> bool {
  		auto elapsed = m_timer.getElapsedNanoseconds();
  
  		// Exponentially increasing iterations until we're confident in our timer resolution
  		if (elapsed < m_resolution) {
  			m_iterationsToRun *= 10;
  			return true;
  		}
  
  		getResultCapture().benchmarkEnded({ { m_name }, m_count, elapsed });
  		return false;
  	}
  
  } // end namespace Catch
  // end catch_benchmark.cpp
  // start catch_capture_matchers.cpp
  
  namespace Catch {
  
  	using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
  
  	// This is the general overload that takes a any string matcher
  	// There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
  	// the Equals matcher (so the header does not mention matchers)
  	void handleExceptionMatchExpr(AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString) {
  		std::string exceptionMessage = Catch::translateActiveException();
  		MatchExpr<std::string, StringMatcher const&> expr(exceptionMessage, matcher, matcherString);
  		handler.handleExpr(expr);
  	}
  
  } // namespace Catch
  // end catch_capture_matchers.cpp
  // start catch_commandline.cpp
  
  // start catch_commandline.h
  
  // start catch_clara.h
  
  // Use Catch's value for console width (store Clara's off to the side, if present)
  #ifdef CLARA_CONFIG_CONSOLE_WIDTH
  #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  #endif
  #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
  
  #ifdef __clang__
  #pragma clang diagnostic push
  #pragma clang diagnostic ignored "-Wweak-vtables"
  #pragma clang diagnostic ignored "-Wexit-time-destructors"
  #pragma clang diagnostic ignored "-Wshadow"
  #endif
  
  // start clara.hpp
  // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
  //
  // Distributed under the Boost Software License, Version 1.0. (See accompanying
  // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  //
  // See https://github.com/philsquared/Clara for more details
  
  // Clara v1.1.4
  
  
  #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
  #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
  #endif
  
  #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
  #endif
  
  #ifndef CLARA_CONFIG_OPTIONAL_TYPE
  #ifdef __has_include
  #if __has_include(<optional>) && __cplusplus >= 201703L
  #include <optional>
  #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
  #endif
  #endif
  #endif
  
  // ----------- #included from clara_textflow.hpp -----------
  
  // TextFlowCpp
  //
  // A single-header library for wrapping and laying out basic text, by Phil Nash
  //
  // This work is licensed under the BSD 2-Clause license.
  // See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause
  //
  // This project is hosted at https://github.com/philsquared/textflowcpp
  
  
  #include <cassert>
  #include <ostream>
  #include <sstream>
  #include <vector>
  
  #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
  #endif
  
  namespace Catch {
  	namespace clara {
  		namespace TextFlow {
  
  			inline auto isWhitespace(char c) -> bool {
  				static std::string chars = " \t\n\r";
  				return chars.find(c) != std::string::npos;
  			}
  			inline auto isBreakableBefore(char c) -> bool {
  				static std::string chars = "[({<|";
  				return chars.find(c) != std::string::npos;
  			}
  			inline auto isBreakableAfter(char c) -> bool {
  				static std::string chars = "])}>.,:;*+-=&/\\";
  				return chars.find(c) != std::string::npos;
  			}
  
  			class Columns;
  
  			class Column {
  				std::vector<std::string> m_strings;
  				size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
  				size_t m_indent = 0;
  				size_t m_initialIndent = std::string::npos;
  
  			public:
  				class iterator {
  					friend Column;
  
  					Column const& m_column;
  					size_t m_stringIndex = 0;
  					size_t m_pos = 0;
  
  					size_t m_len = 0;
  					size_t m_end = 0;
  					bool m_suffix = false;
  
  					iterator(Column const& column, size_t stringIndex)
  						: m_column(column),
  						m_stringIndex(stringIndex)
  					{}
  
  					auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
  
  					auto isBoundary(size_t at) const -> bool {
  						assert(at > 0);
  						assert(at <= line().size());
  
  						return at == line().size() ||
  							(isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
  							isBreakableBefore(line()[at]) ||
  							isBreakableAfter(line()[at - 1]);
  					}
  
  					void calcLength() {
  						assert(m_stringIndex < m_column.m_strings.size());
  
  						m_suffix = false;
  						auto width = m_column.m_width - indent();
  						m_end = m_pos;
  						while (m_end < line().size() && line()[m_end] != '\n')
  							++m_end;
  
  						if (m_end < m_pos + width) {
  							m_len = m_end - m_pos;
  						}
  						else {
  							size_t len = width;
  							while (len > 0 && !isBoundary(m_pos + len))
  								--len;
  							while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
  								--len;
  
  							if (len > 0) {
  								m_len = len;
  							}
  							else {
  								m_suffix = true;
  								m_len = width - 1;
  							}
  						}
  					}
  
  					auto indent() const -> size_t {
  						auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
  						return initial == std::string::npos ? m_column.m_indent : initial;
  					}
  
  					auto addIndentAndSuffix(std::string const &plain) const -> std::string {
  						return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
  					}
  
  				public:
  					explicit iterator(Column const& column) : m_column(column) {
  						assert(m_column.m_width > m_column.m_indent);
  						assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
  						calcLength();
  						if (m_len == 0)
  							m_stringIndex++; // Empty string
  					}
  
  					auto operator *() const -> std::string {
  						assert(m_stringIndex < m_column.m_strings.size());
  						assert(m_pos <= m_end);
  						if (m_pos + m_column.m_width < m_end)
  							return addIndentAndSuffix(line().substr(m_pos, m_len));
  						else
  							return addIndentAndSuffix(line().substr(m_pos, m_end - m_pos));
  					}
  
  					auto operator ++() -> iterator& {
  						m_pos += m_len;
  						if (m_pos < line().size() && line()[m_pos] == '\n')
  							m_pos += 1;
  						else
  							while (m_pos < line().size() && isWhitespace(line()[m_pos]))
  								++m_pos;
  
  						if (m_pos == line().size()) {
  							m_pos = 0;
  							++m_stringIndex;
  						}
  						if (m_stringIndex < m_column.m_strings.size())
  							calcLength();
  						return *this;
  					}
  					auto operator ++(int) -> iterator {
  						iterator prev(*this);
  						operator++();
  						return prev;
  					}
  
  					auto operator ==(iterator const& other) const -> bool {
  						return
  							m_pos == other.m_pos &&
  							m_stringIndex == other.m_stringIndex &&
  							&m_column == &other.m_column;
  					}
  					auto operator !=(iterator const& other) const -> bool {
  						return !operator==(other);
  					}
  				};
  				using const_iterator = iterator;
  
  				explicit Column(std::string const& text) { m_strings.push_back(text); }
  
  				auto width(size_t newWidth) -> Column& {
  					assert(newWidth > 0);
  					m_width = newWidth;
  					return *this;
  				}
  				auto indent(size_t newIndent) -> Column& {
  					m_indent = newIndent;
  					return *this;
  				}
  				auto initialIndent(size_t newIndent) -> Column& {
  					m_initialIndent = newIndent;
  					return *this;
  				}
  
  				auto width() const -> size_t { return m_width; }
  				auto begin() const -> iterator { return iterator(*this); }
  				auto end() const -> iterator { return { *this, m_strings.size() }; }
  
  				inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
  					bool first = true;
  					for (auto line : col) {
  						if (first)
  							first = false;
  						else
  							os << "\n";
  						os << line;
  					}
  					return os;
  				}
  
  				auto operator + (Column const& other)->Columns;
  
  				auto toString() const -> std::string {
  					std::ostringstream oss;
  					oss << *this;
  					return oss.str();
  				}
  			};
  
  			class Spacer : public Column {
  
  			public:
  				explicit Spacer(size_t spaceWidth) : Column("") {
  					width(spaceWidth);
  				}
  			};
  
  			class Columns {
  				std::vector<Column> m_columns;
  
  			public:
  
  				class iterator {
  					friend Columns;
  					struct EndTag {};
  
  					std::vector<Column> const& m_columns;
  					std::vector<Column::iterator> m_iterators;
  					size_t m_activeIterators;
  
  					iterator(Columns const& columns, EndTag)
  						: m_columns(columns.m_columns),
  						m_activeIterators(0)
  					{
  						m_iterators.reserve(m_columns.size());
  
  						for (auto const& col : m_columns)
  							m_iterators.push_back(col.end());
  					}
  
  				public:
  					explicit iterator(Columns const& columns)
  						: m_columns(columns.m_columns),
  						m_activeIterators(m_columns.size())
  					{
  						m_iterators.reserve(m_columns.size());
  
  						for (auto const& col : m_columns)
  							m_iterators.push_back(col.begin());
  					}
  
  					auto operator ==(iterator const& other) const -> bool {
  						return m_iterators == other.m_iterators;
  					}
  					auto operator !=(iterator const& other) const -> bool {
  						return m_iterators != other.m_iterators;
  					}
  					auto operator *() const -> std::string {
  						std::string row, padding;
  
  						for (size_t i = 0; i < m_columns.size(); ++i) {
  							auto width = m_columns[i].width();
  							if (m_iterators[i] != m_columns[i].end()) {
  								std::string col = *m_iterators[i];
  								row += padding + col;
  								if (col.size() < width)
  									padding = std::string(width - col.size(), ' ');
  								else
  									padding = "";
  							}
  							else {
  								padding += std::string(width, ' ');
  							}
  						}
  						return row;
  					}
  					auto operator ++() -> iterator& {
  						for (size_t i = 0; i < m_columns.size(); ++i) {
  							if (m_iterators[i] != m_columns[i].end())
  								++m_iterators[i];
  						}
  						return *this;
  					}
  					auto operator ++(int) -> iterator {
  						iterator prev(*this);
  						operator++();
  						return prev;
  					}
  				};
  				using const_iterator = iterator;
  
  				auto begin() const -> iterator { return iterator(*this); }
  				auto end() const -> iterator { return { *this, iterator::EndTag() }; }
  
  				auto operator += (Column const& col) -> Columns& {
  					m_columns.push_back(col);
  					return *this;
  				}
  				auto operator + (Column const& col) -> Columns {
  					Columns combined = *this;
  					combined += col;
  					return combined;
  				}
  
  				inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
  
  					bool first = true;
  					for (auto line : cols) {
  						if (first)
  							first = false;
  						else
  							os << "\n";
  						os << line;
  					}
  					return os;
  				}
  
  				auto toString() const -> std::string {
  					std::ostringstream oss;
  					oss << *this;
  					return oss.str();
  				}
  			};
  
  			inline auto Column::operator + (Column const& other) -> Columns {
  				Columns cols;
  				cols += *this;
  				cols += other;
  				return cols;
  			}
  		}
  	}
  } // namespace Catch::clara::TextFlow
  
  // ----------- end of #include from clara_textflow.hpp -----------
  // ........... back in clara.hpp
  
  #include <memory>
  #include <set>
  #include <algorithm>
  
  #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
  #define CATCH_PLATFORM_WINDOWS
  #endif
  
  namespace Catch {
  	namespace clara {
  		namespace detail {
  
  			// Traits for extracting arg and return type of lambdas (for single argument lambdas)
  			template<typename L>
  			struct UnaryLambdaTraits : UnaryLambdaTraits<decltype(&L::operator())> {};
  
  			template<typename ClassT, typename ReturnT, typename... Args>
  			struct UnaryLambdaTraits<ReturnT(ClassT::*)(Args...) const> {
  				static const bool isValid = false;
  			};
  
  			template<typename ClassT, typename ReturnT, typename ArgT>
  			struct UnaryLambdaTraits<ReturnT(ClassT::*)(ArgT) const> {
  				static const bool isValid = true;
  				using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
  				using ReturnType = ReturnT;
  			};
  
  			class TokenStream;
  
  			// Transport for raw args (copied from main args, or supplied via init list for testing)
  			class Args {
  				friend TokenStream;
  				std::string m_exeName;
  				std::vector<std::string> m_args;
  
  			public:
  				Args(int argc, char const* const* argv)
  					: m_exeName(argv[0]),
  					m_args(argv + 1, argv + argc) {}
  
  				Args(std::initializer_list<std::string> args)
  					: m_exeName(*args.begin()),
  					m_args(args.begin() + 1, args.end())
  				{}
  
  				auto exeName() const -> std::string {
  					return m_exeName;
  				}
  			};
  
  			// Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
  			// may encode an option + its argument if the : or = form is used
  			enum class TokenType {
  				Option, Argument
  			};
  			struct Token {
  				TokenType type;
  				std::string token;
  			};
  
  			inline auto isOptPrefix(char c) -> bool {
  				return c == '-'
  #ifdef CATCH_PLATFORM_WINDOWS
  					|| c == '/'
  #endif
  					;
  			}
  
  			// Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
  			class TokenStream {
  				using Iterator = std::vector<std::string>::const_iterator;
  				Iterator it;
  				Iterator itEnd;
  				std::vector<Token> m_tokenBuffer;
  
  				void loadBuffer() {
  					m_tokenBuffer.resize(0);
  
  					// Skip any empty strings
  					while (it != itEnd && it->empty())
  						++it;
  
  					if (it != itEnd) {
  						auto const &next = *it;
  						if (isOptPrefix(next[0])) {
  							auto delimiterPos = next.find_first_of(" :=");
  							if (delimiterPos != std::string::npos) {
  								m_tokenBuffer.push_back({ TokenType::Option, next.substr(0, delimiterPos) });
  								m_tokenBuffer.push_back({ TokenType::Argument, next.substr(delimiterPos + 1) });
  							}
  							else {
  								if (next[1] != '-' && next.size() > 2) {
  									std::string opt = "- ";
  									for (size_t i = 1; i < next.size(); ++i) {
  										opt[1] = next[i];
  										m_tokenBuffer.push_back({ TokenType::Option, opt });
  									}
  								}
  								else {
  									m_tokenBuffer.push_back({ TokenType::Option, next });
  								}
  							}
  						}
  						else {
  							m_tokenBuffer.push_back({ TokenType::Argument, next });
  						}
  					}
  				}
  
  			public:
  				explicit TokenStream(Args const &args) : TokenStream(args.m_args.begin(), args.m_args.end()) {}
  
  				TokenStream(Iterator it, Iterator itEnd) : it(it), itEnd(itEnd) {
  					loadBuffer();
  				}
  
  				explicit operator bool() const {
  					return !m_tokenBuffer.empty() || it != itEnd;
  				}
  
  				auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
  
  				auto operator*() const -> Token {
  					assert(!m_tokenBuffer.empty());
  					return m_tokenBuffer.front();
  				}
  
  				auto operator->() const -> Token const * {
  					assert(!m_tokenBuffer.empty());
  					return &m_tokenBuffer.front();
  				}
  
  				auto operator++() -> TokenStream & {
  					if (m_tokenBuffer.size() >= 2) {
  						m_tokenBuffer.erase(m_tokenBuffer.begin());
  					}
  					else {
  						if (it != itEnd)
  							++it;
  						loadBuffer();
  					}
  					return *this;
  				}
  			};
  
  			class ResultBase {
  			public:
  				enum Type {
  					Ok, LogicError, RuntimeError
  				};
  
  			protected:
  				ResultBase(Type type) : m_type(type) {}
  				virtual ~ResultBase() = default;
  
  				virtual void enforceOk() const = 0;
  
  				Type m_type;
  			};
  
  			template<typename T>
  			class ResultValueBase : public ResultBase {
  			public:
  				auto value() const -> T const & {
  					enforceOk();
  					return m_value;
  				}
  
  			protected:
  				ResultValueBase(Type type) : ResultBase(type) {}
  
  				ResultValueBase(ResultValueBase const &other) : ResultBase(other) {
  					if (m_type == ResultBase::Ok)
  						new(&m_value) T(other.m_value);
  				}
  
  				ResultValueBase(Type, T const &value) : ResultBase(Ok) {
  					new(&m_value) T(value);
  				}
  
  				auto operator=(ResultValueBase const &other) -> ResultValueBase & {
  					if (m_type == ResultBase::Ok)
  						m_value.~T();
  					ResultBase::operator=(other);
  					if (m_type == ResultBase::Ok)
  						new(&m_value) T(other.m_value);
  					return *this;
  				}
  
  				~ResultValueBase() override {
  					if (m_type == Ok)
  						m_value.~T();
  				}
  
  				union {
  					T m_value;
  				};
  			};
  
  			template<>
  			class ResultValueBase<void> : public ResultBase {
  			protected:
  				using ResultBase::ResultBase;
  			};
  
  			template<typename T = void>
  			class BasicResult : public ResultValueBase<T> {
  			public:
  				template<typename U>
  				explicit BasicResult(BasicResult<U> const &other)
  					: ResultValueBase<T>(other.type()),
  					m_errorMessage(other.errorMessage())
  				{
  					assert(type() != ResultBase::Ok);
  				}
  
  				template<typename U>
  				static auto ok(U const &value) -> BasicResult { return { ResultBase::Ok, value }; }
  				static auto ok() -> BasicResult { return { ResultBase::Ok }; }
  				static auto logicError(std::string const &message) -> BasicResult { return { ResultBase::LogicError, message }; }
  				static auto runtimeError(std::string const &message) -> BasicResult { return { ResultBase::RuntimeError, message }; }
  
  				explicit operator bool() const { return m_type == ResultBase::Ok; }
  				auto type() const -> ResultBase::Type { return m_type; }
  				auto errorMessage() const -> std::string { return m_errorMessage; }
  
  			protected:
  				void enforceOk() const override {
  
  					// Errors shouldn't reach this point, but if they do
  					// the actual error message will be in m_errorMessage
  					assert(m_type != ResultBase::LogicError);
  					assert(m_type != ResultBase::RuntimeError);
  					if (m_type != ResultBase::Ok)
  						std::abort();
  				}
  
  				std::string m_errorMessage; // Only populated if resultType is an error
  
  				BasicResult(ResultBase::Type type, std::string const &message)
  					: ResultValueBase<T>(type),
  					m_errorMessage(message)
  				{
  					assert(m_type != ResultBase::Ok);
  				}
  
  				using ResultValueBase<T>::ResultValueBase;
  				using ResultBase::m_type;
  			};
  
  			enum class ParseResultType {
  				Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
  			};
  
  			class ParseState {
  			public:
  
  				ParseState(ParseResultType type, TokenStream const &remainingTokens)
  					: m_type(type),
  					m_remainingTokens(remainingTokens)
  				{}
  
  				auto type() const -> ParseResultType { return m_type; }
  				auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
  
  			private:
  				ParseResultType m_type;
  				TokenStream m_remainingTokens;
  			};
  
  			using Result = BasicResult<void>;
  			using ParserResult = BasicResult<ParseResultType>;
  			using InternalParseResult = BasicResult<ParseState>;
  
  			struct HelpColumns {
  				std::string left;
  				std::string right;
  			};
  
  			template<typename T>
  			inline auto convertInto(std::string const &source, T& target) -> ParserResult {
  				std::stringstream ss;
  				ss << source;
  				ss >> target;
  				if (ss.fail())
  					return ParserResult::runtimeError("Unable to convert '" + source + "' to destination type");
  				else
  					return ParserResult::ok(ParseResultType::Matched);
  			}
  			inline auto convertInto(std::string const &source, std::string& target) -> ParserResult {
  				target = source;
  				return ParserResult::ok(ParseResultType::Matched);
  			}
  			inline auto convertInto(std::string const &source, bool &target) -> ParserResult {
  				std::string srcLC = source;
  				std::transform(srcLC.begin(), srcLC.end(), srcLC.begin(), [](char c) { return static_cast<char>(::tolower(c)); });
  				if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
  					target = true;
  				else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
  					target = false;
  				else
  					return ParserResult::runtimeError("Expected a boolean value but did not recognise: '" + source + "'");
  				return ParserResult::ok(ParseResultType::Matched);
  			}
  #ifdef CLARA_CONFIG_OPTIONAL_TYPE
  			template<typename T>
  			inline auto convertInto(std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target) -> ParserResult {
  				T temp;
  				auto result = convertInto(source, temp);
  				if (result)
  					target = std::move(temp);
  				return result;
  			}
  #endif // CLARA_CONFIG_OPTIONAL_TYPE
  
  			struct NonCopyable {
  				NonCopyable() = default;
  				NonCopyable(NonCopyable const &) = delete;
  				NonCopyable(NonCopyable &&) = delete;
  				NonCopyable &operator=(NonCopyable const &) = delete;
  				NonCopyable &operator=(NonCopyable &&) = delete;
  			};
  
  			struct BoundRef : NonCopyable {
  				virtual ~BoundRef() = default;
  				virtual auto isContainer() const -> bool { return false; }
  				virtual auto isFlag() const -> bool { return false; }
  			};
  			struct BoundValueRefBase : BoundRef {
  				virtual auto setValue(std::string const &arg)->ParserResult = 0;
  			};
  			struct BoundFlagRefBase : BoundRef {
  				virtual auto setFlag(bool flag)->ParserResult = 0;
  				virtual auto isFlag() const -> bool { return true; }
  			};
  
  			template<typename T>
  			struct BoundValueRef : BoundValueRefBase {
  				T &m_ref;
  
  				explicit BoundValueRef(T &ref) : m_ref(ref) {}
  
  				auto setValue(std::string const &arg) -> ParserResult override {
  					return convertInto(arg, m_ref);
  				}
  			};
  
  			template<typename T>
  			struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
  				std::vector<T> &m_ref;
  
  				explicit BoundValueRef(std::vector<T> &ref) : m_ref(ref) {}
  
  				auto isContainer() const -> bool override { return true; }
  
  				auto setValue(std::string const &arg) -> ParserResult override {
  					T temp;
  					auto result = convertInto(arg, temp);
  					if (result)
  						m_ref.push_back(temp);
  					return result;
  				}
  			};
  
  			struct BoundFlagRef : BoundFlagRefBase {
  				bool &m_ref;
  
  				explicit BoundFlagRef(bool &ref) : m_ref(ref) {}
  
  				auto setFlag(bool flag) -> ParserResult override {
  					m_ref = flag;
  					return ParserResult::ok(ParseResultType::Matched);
  				}
  			};
  
  			template<typename ReturnType>
  			struct LambdaInvoker {
  				static_assert(std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult");
  
  				template<typename L, typename ArgType>
  				static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult {
  					return lambda(arg);
  				}
  			};
  
  			template<>
  			struct LambdaInvoker<void> {
  				template<typename L, typename ArgType>
  				static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult {
  					lambda(arg);
  					return ParserResult::ok(ParseResultType::Matched);
  				}
  			};
  
  			template<typename ArgType, typename L>
  			inline auto invokeLambda(L const &lambda, std::string const &arg) -> ParserResult {
  				ArgType temp{};
  				auto result = convertInto(arg, temp);
  				return !result
  					? result
  					: LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke(lambda, temp);
  			}
  
  			template<typename L>
  			struct BoundLambda : BoundValueRefBase {
  				L m_lambda;
  
  				static_assert(UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument");
  				explicit BoundLambda(L const &lambda) : m_lambda(lambda) {}
  
  				auto setValue(std::string const &arg) -> ParserResult override {
  					return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>(m_lambda, arg);
  				}
  			};
  
  			template<typename L>
  			struct BoundFlagLambda : BoundFlagRefBase {
  				L m_lambda;
  
  				static_assert(UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument");
  				static_assert(std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean");
  
  				explicit BoundFlagLambda(L const &lambda) : m_lambda(lambda) {}
  
  				auto setFlag(bool flag) -> ParserResult override {
  					return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke(m_lambda, flag);
  				}
  			};
  
  			enum class Optionality { Optional, Required };
  
  			struct Parser;
  
  			class ParserBase {
  			public:
  				virtual ~ParserBase() = default;
  				virtual auto validate() const -> Result { return Result::ok(); }
  				virtual auto parse(std::string const& exeName, TokenStream const &tokens) const->InternalParseResult = 0;
  				virtual auto cardinality() const -> size_t { return 1; }
  
  				auto parse(Args const &args) const -> InternalParseResult {
  					return parse(args.exeName(), TokenStream(args));
  				}
  			};
  
  			template<typename DerivedT>
  			class ComposableParserImpl : public ParserBase {
  			public:
  				template<typename T>
  				auto operator|(T const &other) const->Parser;
  
  				template<typename T>
  				auto operator+(T const &other) const->Parser;
  			};
  
  			// Common code and state for Args and Opts
  			template<typename DerivedT>
  			class ParserRefImpl : public ComposableParserImpl<DerivedT> {
  			protected:
  				Optionality m_optionality = Optionality::Optional;
  				std::shared_ptr<BoundRef> m_ref;
  				std::string m_hint;
  				std::string m_description;
  
  				explicit ParserRefImpl(std::shared_ptr<BoundRef> const &ref) : m_ref(ref) {}
  
  			public:
  				template<typename T>
  				ParserRefImpl(T &ref, std::string const &hint)
  					: m_ref(std::make_shared<BoundValueRef<T>>(ref)),
  					m_hint(hint)
  				{}
  
  				template<typename LambdaT>
  				ParserRefImpl(LambdaT const &ref, std::string const &hint)
  					: m_ref(std::make_shared<BoundLambda<LambdaT>>(ref)),
  					m_hint(hint)
  				{}
  
  				auto operator()(std::string const &description) -> DerivedT & {
  					m_description = description;
  					return static_cast<DerivedT &>(*this);
  				}
  
  				auto optional() -> DerivedT & {
  					m_optionality = Optionality::Optional;
  					return static_cast<DerivedT &>(*this);
  				};
  
  				auto required() -> DerivedT & {
  					m_optionality = Optionality::Required;
  					return static_cast<DerivedT &>(*this);
  				};
  
  				auto isOptional() const -> bool {
  					return m_optionality == Optionality::Optional;
  				}
  
  				auto cardinality() const -> size_t override {
  					if (m_ref->isContainer())
  						return 0;
  					else
  						return 1;
  				}
  
  				auto hint() const -> std::string { return m_hint; }
  			};
  
  			class ExeName : public ComposableParserImpl<ExeName> {
  				std::shared_ptr<std::string> m_name;
  				std::shared_ptr<BoundValueRefBase> m_ref;
  
  				template<typename LambdaT>
  				static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
  					return std::make_shared<BoundLambda<LambdaT>>(lambda);
  				}
  
  			public:
  				ExeName() : m_name(std::make_shared<std::string>("<executable>")) {}
  
  				explicit ExeName(std::string &ref) : ExeName() {
  					m_ref = std::make_shared<BoundValueRef<std::string>>(ref);
  				}
  
  				template<typename LambdaT>
  				explicit ExeName(LambdaT const& lambda) : ExeName() {
  					m_ref = std::make_shared<BoundLambda<LambdaT>>(lambda);
  				}
  
  				// The exe name is not parsed out of the normal tokens, but is handled specially
  				auto parse(std::string const&, TokenStream const &tokens) const -> InternalParseResult override {
  					return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
  				}
  
  				auto name() const -> std::string { return *m_name; }
  				auto set(std::string const& newName) -> ParserResult {
  
  					auto lastSlash = newName.find_last_of("\\/");
  					auto filename = (lastSlash == std::string::npos)
  						? newName
  						: newName.substr(lastSlash + 1);
  
  					*m_name = filename;
  					if (m_ref)
  						return m_ref->setValue(filename);
  					else
  						return ParserResult::ok(ParseResultType::Matched);
  				}
  			};
  
  			class Arg : public ParserRefImpl<Arg> {
  			public:
  				using ParserRefImpl::ParserRefImpl;
  
  				auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override {
  					auto validationResult = validate();
  					if (!validationResult)
  						return InternalParseResult(validationResult);
  
  					auto remainingTokens = tokens;
  					auto const &token = *remainingTokens;
  					if (token.type != TokenType::Argument)
  						return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens));
  
  					assert(!m_ref->isFlag());
  					auto valueRef = static_cast<detail::BoundValueRefBase*>(m_ref.get());
  
  					auto result = valueRef->setValue(remainingTokens->token);
  					if (!result)
  						return InternalParseResult(result);
  					else
  						return InternalParseResult::ok(ParseState(ParseResultType::Matched, ++remainingTokens));
  				}
  			};
  
  			inline auto normaliseOpt(std::string const &optName) -> std::string {
  #ifdef CATCH_PLATFORM_WINDOWS
  				if (optName[0] == '/')
  					return "-" + optName.substr(1);
  				else
  #endif
  					return optName;
  			}
  
  			class Opt : public ParserRefImpl<Opt> {
  			protected:
  				std::vector<std::string> m_optNames;
  
  			public:
  				template<typename LambdaT>
  				explicit Opt(LambdaT const &ref) : ParserRefImpl(std::make_shared<BoundFlagLambda<LambdaT>>(ref)) {}
  
  				explicit Opt(bool &ref) : ParserRefImpl(std::make_shared<BoundFlagRef>(ref)) {}
  
  				template<typename LambdaT>
  				Opt(LambdaT const &ref, std::string const &hint) : ParserRefImpl(ref, hint) {}
  
  				template<typename T>
  				Opt(T &ref, std::string const &hint) : ParserRefImpl(ref, hint) {}
  
  				auto operator[](std::string const &optName) -> Opt & {
  					m_optNames.push_back(optName);
  					return *this;
  				}
  
  				auto getHelpColumns() const -> std::vector<HelpColumns> {
  					std::ostringstream oss;
  					bool first = true;
  					for (auto const &opt : m_optNames) {
  						if (first)
  							first = false;
  						else
  							oss << ", ";
  						oss << opt;
  					}
  					if (!m_hint.empty())
  						oss << " <" << m_hint << ">";
  					return { { oss.str(), m_description } };
  				}
  
  				auto isMatch(std::string const &optToken) const -> bool {
  					auto normalisedToken = normaliseOpt(optToken);
  					for (auto const &name : m_optNames) {
  						if (normaliseOpt(name) == normalisedToken)
  							return true;
  					}
  					return false;
  				}
  
  				using ParserBase::parse;
  
  				auto parse(std::string const&, TokenStream const &tokens) const -> InternalParseResult override {
  					auto validationResult = validate();
  					if (!validationResult)
  						return InternalParseResult(validationResult);
  
  					auto remainingTokens = tokens;
  					if (remainingTokens && remainingTokens->type == TokenType::Option) {
  						auto const &token = *remainingTokens;
  						if (isMatch(token.token)) {
  							if (m_ref->isFlag()) {
  								auto flagRef = static_cast<detail::BoundFlagRefBase*>(m_ref.get());
  								auto result = flagRef->setFlag(true);
  								if (!result)
  									return InternalParseResult(result);
  								if (result.value() == ParseResultType::ShortCircuitAll)
  									return InternalParseResult::ok(ParseState(result.value(), remainingTokens));
  							}
  							else {
  								auto valueRef = static_cast<detail::BoundValueRefBase*>(m_ref.get());
  								++remainingTokens;
  								if (!remainingTokens)
  									return InternalParseResult::runtimeError("Expected argument following " + token.token);
  								auto const &argToken = *remainingTokens;
  								if (argToken.type != TokenType::Argument)
  									return InternalParseResult::runtimeError("Expected argument following " + token.token);
  								auto result = valueRef->setValue(argToken.token);
  								if (!result)
  									return InternalParseResult(result);
  								if (result.value() == ParseResultType::ShortCircuitAll)
  									return InternalParseResult::ok(ParseState(result.value(), remainingTokens));
  							}
  							return InternalParseResult::ok(ParseState(ParseResultType::Matched, ++remainingTokens));
  						}
  					}
  					return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens));
  				}
  
  				auto validate() const -> Result override {
  					if (m_optNames.empty())
  						return Result::logicError("No options supplied to Opt");
  					for (auto const &name : m_optNames) {
  						if (name.empty())
  							return Result::logicError("Option name cannot be empty");
  #ifdef CATCH_PLATFORM_WINDOWS
  						if (name[0] != '-' && name[0] != '/')
  							return Result::logicError("Option name must begin with '-' or '/'");
  #else
  						if (name[0] != '-')
  							return Result::logicError("Option name must begin with '-'");
  #endif
  					}
  					return ParserRefImpl::validate();
  				}
  			};
  
  			struct Help : Opt {
  				Help(bool &showHelpFlag)
  					: Opt([&](bool flag) {
  					showHelpFlag = flag;
  					return ParserResult::ok(ParseResultType::ShortCircuitAll);
  				})
  				{
  					static_cast<Opt &>(*this)
  						("display usage information")
  						["-?"]["-h"]["--help"]
  						.optional();
  				}
  			};
  
  			struct Parser : ParserBase {
  
  				mutable ExeName m_exeName;
  				std::vector<Opt> m_options;
  				std::vector<Arg> m_args;
  
  				auto operator|=(ExeName const &exeName) -> Parser & {
  					m_exeName = exeName;
  					return *this;
  				}
  
  				auto operator|=(Arg const &arg) -> Parser & {
  					m_args.push_back(arg);
  					return *this;
  				}
  
  				auto operator|=(Opt const &opt) -> Parser & {
  					m_options.push_back(opt);
  					return *this;
  				}
  
  				auto operator|=(Parser const &other) -> Parser & {
  					m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
  					m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
  					return *this;
  				}
  
  				template<typename T>
  				auto operator|(T const &other) const -> Parser {
  					return Parser(*this) |= other;
  				}
  
  				// Forward deprecated interface with '+' instead of '|'
  				template<typename T>
  				auto operator+=(T const &other) -> Parser & { return operator|=(other); }
  				template<typename T>
  				auto operator+(T const &other) const -> Parser { return operator|(other); }
  
  				auto getHelpColumns() const -> std::vector<HelpColumns> {
  					std::vector<HelpColumns> cols;
  					for (auto const &o : m_options) {
  						auto childCols = o.getHelpColumns();
  						cols.insert(cols.end(), childCols.begin(), childCols.end());
  					}
  					return cols;
  				}
  
  				void writeToStream(std::ostream &os) const {
  					if (!m_exeName.name().empty()) {
  						os << "usage:\n" << "  " << m_exeName.name() << " ";
  						bool required = true, first = true;
  						for (auto const &arg : m_args) {
  							if (first)
  								first = false;
  							else
  								os << " ";
  							if (arg.isOptional() && required) {
  								os << "[";
  								required = false;
  							}
  							os << "<" << arg.hint() << ">";
  							if (arg.cardinality() == 0)
  								os << " ... ";
  						}
  						if (!required)
  							os << "]";
  						if (!m_options.empty())
  							os << " options";
  						os << "\n\nwhere options are:" << std::endl;
  					}
  
  					auto rows = getHelpColumns();
  					size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
  					size_t optWidth = 0;
  					for (auto const &cols : rows)
  						optWidth = (std::max)(optWidth, cols.left.size() + 2);
  
  					optWidth = (std::min)(optWidth, consoleWidth / 2);
  
  					for (auto const &cols : rows) {
  						auto row =
  							TextFlow::Column(cols.left).width(optWidth).indent(2) +
  							TextFlow::Spacer(4) +
  							TextFlow::Column(cols.right).width(consoleWidth - 7 - optWidth);
  						os << row << std::endl;
  					}
  				}
  
  				friend auto operator<<(std::ostream &os, Parser const &parser) -> std::ostream& {
  					parser.writeToStream(os);
  					return os;
  				}
  
  				auto validate() const -> Result override {
  					for (auto const &opt : m_options) {
  						auto result = opt.validate();
  						if (!result)
  							return result;
  					}
  					for (auto const &arg : m_args) {
  						auto result = arg.validate();
  						if (!result)
  							return result;
  					}
  					return Result::ok();
  				}
  
  				using ParserBase::parse;
  
  				auto parse(std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult override {
  
  					struct ParserInfo {
  						ParserBase const* parser = nullptr;
  						size_t count = 0;
  					};
  					const size_t totalParsers = m_options.size() + m_args.size();
  					assert(totalParsers < 512);
  					// ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
  					ParserInfo parseInfos[512];
  
  					{
  						size_t i = 0;
  						for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
  						for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
  					}
  
  					m_exeName.set(exeName);
  
  					auto result = InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
  					while (result.value().remainingTokens()) {
  						bool tokenParsed = false;
  
  						for (size_t i = 0; i < totalParsers; ++i) {
  							auto&  parseInfo = parseInfos[i];
  							if (parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality()) {
  								result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
  								if (!result)
  									return result;
  								if (result.value().type() != ParseResultType::NoMatch) {
  									tokenParsed = true;
  									++parseInfo.count;
  									break;
  								}
  							}
  						}
  
  						if (result.value().type() == ParseResultType::ShortCircuitAll)
  							return result;
  						if (!tokenParsed)
  							return InternalParseResult::runtimeError("Unrecognised token: " + result.value().remainingTokens()->token);
  					}
  					// !TBD Check missing required options
  					return result;
  				}
  			};
  
  			template<typename DerivedT>
  			template<typename T>
  			auto ComposableParserImpl<DerivedT>::operator|(T const &other) const -> Parser {
  				return Parser() | static_cast<DerivedT const &>(*this) | other;
  			}
  		} // namespace detail
  
  		// A Combined parser
  		using detail::Parser;
  
  		// A parser for options
  		using detail::Opt;
  
  		// A parser for arguments
  		using detail::Arg;
  
  		// Wrapper for argc, argv from main()
  		using detail::Args;
  
  		// Specifies the name of the executable
  		using detail::ExeName;
  
  		// Convenience wrapper for option parser that specifies the help option
  		using detail::Help;
  
  		// enum of result types from a parse
  		using detail::ParseResultType;
  
  		// Result type for parser operation
  		using detail::ParserResult;
  
  	}
  } // namespace Catch::clara
  
  // end clara.hpp
  #ifdef __clang__
  #pragma clang diagnostic pop
  #endif
  
  // Restore Clara's value for console width, if present
  #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  #endif
  
  // end catch_clara.h
  namespace Catch {
  
  	clara::Parser makeCommandLineParser(ConfigData& config);
  
  } // end namespace Catch
  
  // end catch_commandline.h
  #include <fstream>
  #include <ctime>
  
  namespace Catch {
  
  	clara::Parser makeCommandLineParser(ConfigData& config) {
  
  		using namespace clara;
  
  		auto const setWarning = [&](std::string const& warning) {
  			auto warningSet = [&]() {
  				if (warning == "NoAssertions")
  					return WarnAbout::NoAssertions;
  
  				if (warning == "NoTests")
  					return WarnAbout::NoTests;
  
  				return WarnAbout::Nothing;
  			}();
  
  			if (warningSet == WarnAbout::Nothing)
  				return ParserResult::runtimeError("Unrecognised warning: '" + warning + "'");
  			config.warnings = static_cast<WarnAbout::What>(config.warnings | warningSet);
  			return ParserResult::ok(ParseResultType::Matched);
  		};
  		auto const loadTestNamesFromFile = [&](std::string const& filename) {
  			std::ifstream f(filename.c_str());
  			if (!f.is_open())
  				return ParserResult::runtimeError("Unable to load input file: '" + filename + "'");
  
  			std::string line;
  			while (std::getline(f, line)) {
  				line = trim(line);
  				if (!line.empty() && !startsWith(line, '#')) {
  					if (!startsWith(line, '"'))
  						line = '"' + line + '"';
  					config.testsOrTags.push_back(line + ',');
  				}
  			}
  			return ParserResult::ok(ParseResultType::Matched);
  		};
  		auto const setTestOrder = [&](std::string const& order) {
  			if (startsWith("declared", order))
  				config.runOrder = RunTests::InDeclarationOrder;
  			else if (startsWith("lexical", order))
  				config.runOrder = RunTests::InLexicographicalOrder;
  			else if (startsWith("random", order))
  				config.runOrder = RunTests::InRandomOrder;
  			else
  				return clara::ParserResult::runtimeError("Unrecognised ordering: '" + order + "'");
  			return ParserResult::ok(ParseResultType::Matched);
  		};
  		auto const setRngSeed = [&](std::string const& seed) {
  			if (seed != "time")
  				return clara::detail::convertInto(seed, config.rngSeed);
  			config.rngSeed = static_cast<unsigned int>(std::time(nullptr));
  			return ParserResult::ok(ParseResultType::Matched);
  		};
  		auto const setColourUsage = [&](std::string const& useColour) {
  			auto mode = toLower(useColour);
  
  			if (mode == "yes")
  				config.useColour = UseColour::Yes;
  			else if (mode == "no")
  				config.useColour = UseColour::No;
  			else if (mode == "auto")
  				config.useColour = UseColour::Auto;
  			else
  				return ParserResult::runtimeError("colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised");
  			return ParserResult::ok(ParseResultType::Matched);
  		};
  		auto const setWaitForKeypress = [&](std::string const& keypress) {
  			auto keypressLc = toLower(keypress);
  			if (keypressLc == "start")
  				config.waitForKeypress = WaitForKeypress::BeforeStart;
  			else if (keypressLc == "exit")
  				config.waitForKeypress = WaitForKeypress::BeforeExit;
  			else if (keypressLc == "both")
  				config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
  			else
  				return ParserResult::runtimeError("keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised");
  			return ParserResult::ok(ParseResultType::Matched);
  		};
  		auto const setVerbosity = [&](std::string const& verbosity) {
  			auto lcVerbosity = toLower(verbosity);
  			if (lcVerbosity == "quiet")
  				config.verbosity = Verbosity::Quiet;
  			else if (lcVerbosity == "normal")
  				config.verbosity = Verbosity::Normal;
  			else if (lcVerbosity == "high")
  				config.verbosity = Verbosity::High;
  			else
  				return ParserResult::runtimeError("Unrecognised verbosity, '" + verbosity + "'");
  			return ParserResult::ok(ParseResultType::Matched);
  		};
  
  		auto cli
  			= ExeName(config.processName)
  			| Help(config.showHelp)
  			| Opt(config.listTests)
  			["-l"]["--list-tests"]
  			("list all/matching test cases")
  			| Opt(config.listTags)
  			["-t"]["--list-tags"]
  			("list all/matching tags")
  			| Opt(config.showSuccessfulTests)
  			["-s"]["--success"]
  			("include successful tests in output")
  			| Opt(config.shouldDebugBreak)
  			["-b"]["--break"]
  			("break into debugger on failure")
  			| Opt(config.noThrow)
  			["-e"]["--nothrow"]
  			("skip exception tests")
  			| Opt(config.showInvisibles)
  			["-i"]["--invisibles"]
  			("show invisibles (tabs, newlines)")
  			| Opt(config.outputFilename, "filename")
  			["-o"]["--out"]
  			("output filename")
  			| Opt(config.reporterNames, "name")
  			["-r"]["--reporter"]
  			("reporter to use (defaults to console)")
  			| Opt(config.name, "name")
  			["-n"]["--name"]
  			("suite name")
  			| Opt([&](bool) { config.abortAfter = 1; })
  			["-a"]["--abort"]
  			("abort at first failure")
  			| Opt([&](int x) { config.abortAfter = x; }, "no. failures")
  			["-x"]["--abortx"]
  			("abort after x failures")
  			| Opt(setWarning, "warning name")
  			["-w"]["--warn"]
  			("enable warnings")
  			| Opt([&](bool flag) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no")
  			["-d"]["--durations"]
  			("show test durations")
  			| Opt(loadTestNamesFromFile, "filename")
  			["-f"]["--input-file"]
  			("load test names to run from a file")
  			| Opt(config.filenamesAsTags)
  			["-#"]["--filenames-as-tags"]
  			("adds a tag for the filename")
  			| Opt(config.sectionsToRun, "section name")
  			["-c"]["--section"]
  			("specify section to run")
  			| Opt(setVerbosity, "quiet|normal|high")
  			["-v"]["--verbosity"]
  			("set output verbosity")
  			| Opt(config.listTestNamesOnly)
  			["--list-test-names-only"]
  		("list all/matching test cases names only")
  			| Opt(config.listReporters)
  			["--list-reporters"]
  		("list all reporters")
  			| Opt(setTestOrder, "decl|lex|rand")
  			["--order"]
  		("test case order (defaults to decl)")
  			| Opt(setRngSeed, "'time'|number")
  			["--rng-seed"]
  		("set a specific seed for random numbers")
  			| Opt(setColourUsage, "yes|no")
  			["--use-colour"]
  		("should output be colourised")
  			| Opt(config.libIdentify)
  			["--libidentify"]
  		("report name and version according to libidentify standard")
  			| Opt(setWaitForKeypress, "start|exit|both")
  			["--wait-for-keypress"]
  		("waits for a keypress before exiting")
  			| Opt(config.benchmarkResolutionMultiple, "multiplier")
  			["--benchmark-resolution-multiple"]
  		("multiple of clock resolution to run benchmarks")
  
  			| Arg(config.testsOrTags, "test name|pattern|tags")
  			("which test or tests to use");
  
  		return cli;
  	}
  
  } // end namespace Catch
  // end catch_commandline.cpp
  // start catch_common.cpp
  
  #include <cstring>
  #include <ostream>
  
  namespace Catch {
  
  	bool SourceLineInfo::empty() const noexcept {
  		return file[0] == '\0';
  	}
  	bool SourceLineInfo::operator == (SourceLineInfo const& other) const noexcept {
  		return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
  	}
  	bool SourceLineInfo::operator < (SourceLineInfo const& other) const noexcept {
  		return line < other.line || (line == other.line && (std::strcmp(file, other.file) < 0));
  	}
  
  	std::ostream& operator << (std::ostream& os, SourceLineInfo const& info) {
  #ifndef __GNUG__
  		os << info.file << '(' << info.line << ')';
  #else
  		os << info.file << ':' << info.line;
  #endif
  		return os;
  	}
  
  	std::string StreamEndStop::operator+() const {
  		return std::string();
  	}
  
  	NonCopyable::NonCopyable() = default;
  	NonCopyable::~NonCopyable() = default;
  
  }
  // end catch_common.cpp
  // start catch_config.cpp
  
  // start catch_enforce.h
  
  #include <stdexcept>
  
  #define CATCH_PREPARE_EXCEPTION( type, msg ) \
      type( ( Catch::ReusableStringStream() << msg ).str() )
  #define CATCH_INTERNAL_ERROR( msg ) \
      throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
  #define CATCH_ERROR( msg ) \
      throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg )
  #define CATCH_ENFORCE( condition, msg ) \
      do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
  
  // end catch_enforce.h
  namespace Catch {
  
  	Config::Config(ConfigData const& data)
  		: m_data(data),
  		m_stream(openStream())
  	{
  		TestSpecParser parser(ITagAliasRegistry::get());
  		if (data.testsOrTags.empty()) {
  			parser.parse("~[.]"); // All not hidden tests
  		}
  		else {
  			m_hasTestFilters = true;
  			for (auto const& testOrTags : data.testsOrTags)
  				parser.parse(testOrTags);
  		}
  		m_testSpec = parser.testSpec();
  	}
  
  	std::string const& Config::getFilename() const {
  		return m_data.outputFilename;
  	}
  
  	bool Config::listTests() const { return m_data.listTests; }
  	bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
  	bool Config::listTags() const { return m_data.listTags; }
  	bool Config::listReporters() const { return m_data.listReporters; }
  
  	std::string Config::getProcessName() const { return m_data.processName; }
  
  	std::vector<std::string> const& Config::getReporterNames() const { return m_data.reporterNames; }
  	std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
  	std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
  
  	TestSpec const& Config::testSpec() const { return m_testSpec; }
  	bool Config::hasTestFilters() const { return m_hasTestFilters; }
  
  	bool Config::showHelp() const { return m_data.showHelp; }
  
  	// IConfig interface
  	bool Config::allowThrows() const { return !m_data.noThrow; }
  	std::ostream& Config::stream() const { return m_stream->stream(); }
  	std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
  	bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
  	bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
  	bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
  	ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
  	RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
  	unsigned int Config::rngSeed() const { return m_data.rngSeed; }
  	int Config::benchmarkResolutionMultiple() const { return m_data.benchmarkResolutionMultiple; }
  	UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
  	bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
  	int Config::abortAfter() const { return m_data.abortAfter; }
  	bool Config::showInvisibles() const { return m_data.showInvisibles; }
  	Verbosity Config::verbosity() const { return m_data.verbosity; }
  
  	IStream const* Config::openStream() {
  		return Catch::makeStream(m_data.outputFilename);
  	}
  
  } // end namespace Catch
  // end catch_config.cpp
  // start catch_console_colour.cpp
  
  #if defined(__clang__)
  #    pragma clang diagnostic push
  #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  #endif
  
  // start catch_errno_guard.h
  
  namespace Catch {
  
  	class ErrnoGuard {
  	public:
  		ErrnoGuard();
  		~ErrnoGuard();
  	private:
  		int m_oldErrno;
  	};
  
  }
  
  // end catch_errno_guard.h
  #include <sstream>
  
  namespace Catch {
  	namespace {
  
  		struct IColourImpl {
  			virtual ~IColourImpl() = default;
  			virtual void use(Colour::Code _colourCode) = 0;
  		};
  
  		struct NoColourImpl : IColourImpl {
  			void use(Colour::Code) {}
  
  			static IColourImpl* instance() {
  				static NoColourImpl s_instance;
  				return &s_instance;
  			}
  		};
  
  	} // anon namespace
  } // namespace Catch
  
  #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
  #   ifdef CATCH_PLATFORM_WINDOWS
  #       define CATCH_CONFIG_COLOUR_WINDOWS
  #   else
  #       define CATCH_CONFIG_COLOUR_ANSI
  #   endif
  #endif
  
  #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
  
  namespace Catch {
  	namespace {
  
  		class Win32ColourImpl : public IColourImpl {
  		public:
  			Win32ColourImpl() : stdoutHandle(GetStdHandle(STD_OUTPUT_HANDLE))
  			{
  				CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
  				GetConsoleScreenBufferInfo(stdoutHandle, &csbiInfo);
  				originalForegroundAttributes = csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY);
  				originalBackgroundAttributes = csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
  			}
  
  			virtual void use(Colour::Code _colourCode) override {
  				switch (_colourCode) {
  				case Colour::None:      return setTextAttribute(originalForegroundAttributes);
  				case Colour::White:     return setTextAttribute(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
  				case Colour::Red:       return setTextAttribute(FOREGROUND_RED);
  				case Colour::Green:     return setTextAttribute(FOREGROUND_GREEN);
  				case Colour::Blue:      return setTextAttribute(FOREGROUND_BLUE);
  				case Colour::Cyan:      return setTextAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN);
  				case Colour::Yellow:    return setTextAttribute(FOREGROUND_RED | FOREGROUND_GREEN);
  				case Colour::Grey:      return setTextAttribute(0);
  
  				case Colour::LightGrey:     return setTextAttribute(FOREGROUND_INTENSITY);
  				case Colour::BrightRed:     return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_RED);
  				case Colour::BrightGreen:   return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_GREEN);
  				case Colour::BrightWhite:   return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
  				case Colour::BrightYellow:  return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
  
  				case Colour::Bright: CATCH_INTERNAL_ERROR("not a colour");
  
  				default:
  					CATCH_ERROR("Unknown colour requested");
  				}
  			}
  
  		private:
  			void setTextAttribute(WORD _textAttribute) {
  				SetConsoleTextAttribute(stdoutHandle, _textAttribute | originalBackgroundAttributes);
  			}
  			HANDLE stdoutHandle;
  			WORD originalForegroundAttributes;
  			WORD originalBackgroundAttributes;
  		};
  
  		IColourImpl* platformColourInstance() {
  			static Win32ColourImpl s_instance;
  
  			IConfigPtr config = getCurrentContext().getConfig();
  			UseColour::YesOrNo colourMode = config
  				? config->useColour()
  				: UseColour::Auto;
  			if (colourMode == UseColour::Auto)
  				colourMode = UseColour::Yes;
  			return colourMode == UseColour::Yes
  				? &s_instance
  				: NoColourImpl::instance();
  		}
  
  	} // end anon namespace
  } // end namespace Catch
  
  #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
  
  #include <unistd.h>
  
  namespace Catch {
  	namespace {
  
  		// use POSIX/ ANSI console terminal codes
  		// Thanks to Adam Strzelecki for original contribution
  		// (http://github.com/nanoant)
  		// https://github.com/philsquared/Catch/pull/131
  		class PosixColourImpl : public IColourImpl {
  		public:
  			virtual void use(Colour::Code _colourCode) override {
  				switch (_colourCode) {
  				case Colour::None:
  				case Colour::White:     return setColour("[0m");
  				case Colour::Red:       return setColour("[0;31m");
  				case Colour::Green:     return setColour("[0;32m");
  				case Colour::Blue:      return setColour("[0;34m");
  				case Colour::Cyan:      return setColour("[0;36m");
  				case Colour::Yellow:    return setColour("[0;33m");
  				case Colour::Grey:      return setColour("[1;30m");
  
  				case Colour::LightGrey:     return setColour("[0;37m");
  				case Colour::BrightRed:     return setColour("[1;31m");
  				case Colour::BrightGreen:   return setColour("[1;32m");
  				case Colour::BrightWhite:   return setColour("[1;37m");
  				case Colour::BrightYellow:  return setColour("[1;33m");
  
  				case Colour::Bright: CATCH_INTERNAL_ERROR("not a colour");
  				default: CATCH_INTERNAL_ERROR("Unknown colour requested");
  				}
  			}
  			static IColourImpl* instance() {
  				static PosixColourImpl s_instance;
  				return &s_instance;
  			}
  
  		private:
  			void setColour(const char* _escapeCode) {
  				Catch::cout() << '\033' << _escapeCode;
  			}
  		};
  
  		bool useColourOnPlatform() {
  			return
  #ifdef CATCH_PLATFORM_MAC
  				!isDebuggerActive() &&
  #endif
  #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
  				isatty(STDOUT_FILENO)
  #else
  				false
  #endif
  				;
  		}
  		IColourImpl* platformColourInstance() {
  			ErrnoGuard guard;
  			IConfigPtr config = getCurrentContext().getConfig();
  			UseColour::YesOrNo colourMode = config
  				? config->useColour()
  				: UseColour::Auto;
  			if (colourMode == UseColour::Auto)
  				colourMode = useColourOnPlatform()
  				? UseColour::Yes
  				: UseColour::No;
  			return colourMode == UseColour::Yes
  				? PosixColourImpl::instance()
  				: NoColourImpl::instance();
  		}
  
  	} // end anon namespace
  } // end namespace Catch
  
  #else  // not Windows or ANSI ///////////////////////////////////////////////
  
  namespace Catch {
  
  	static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
  
  } // end namespace Catch
  
  #endif // Windows/ ANSI/ None
  
  namespace Catch {
  
  	Colour::Colour(Code _colourCode) { use(_colourCode); }
  	Colour::Colour(Colour&& rhs) noexcept {
  		m_moved = rhs.m_moved;
  		rhs.m_moved = true;
  	}
  	Colour& Colour::operator=(Colour&& rhs) noexcept {
  		m_moved = rhs.m_moved;
  		rhs.m_moved = true;
  		return *this;
  	}
  
  	Colour::~Colour() { if (!m_moved) use(None); }
  
  	void Colour::use(Code _colourCode) {
  		static IColourImpl* impl = platformColourInstance();
  		impl->use(_colourCode);
  	}
  
  	std::ostream& operator << (std::ostream& os, Colour const&) {
  		return os;
  	}
  
  } // end namespace Catch
  
  #if defined(__clang__)
  #    pragma clang diagnostic pop
  #endif
  
  // end catch_console_colour.cpp
  // start catch_context.cpp
  
  namespace Catch {
  
  	class Context : public IMutableContext, NonCopyable {
  
  	public: // IContext
  		virtual IResultCapture* getResultCapture() override {
  			return m_resultCapture;
  		}
  		virtual IRunner* getRunner() override {
  			return m_runner;
  		}
  
  		virtual IConfigPtr const& getConfig() const override {
  			return m_config;
  		}
  
  		virtual ~Context() override;
  
  	public: // IMutableContext
  		virtual void setResultCapture(IResultCapture* resultCapture) override {
  			m_resultCapture = resultCapture;
  		}
  		virtual void setRunner(IRunner* runner) override {
  			m_runner = runner;
  		}
  		virtual void setConfig(IConfigPtr const& config) override {
  			m_config = config;
  		}
  
  		friend IMutableContext& getCurrentMutableContext();
  
  	private:
  		IConfigPtr m_config;
  		IRunner* m_runner = nullptr;
  		IResultCapture* m_resultCapture = nullptr;
  	};
  
  	IMutableContext *IMutableContext::currentContext = nullptr;
  
  	void IMutableContext::createContext()
  	{
  		currentContext = new Context();
  	}
  
  	void cleanUpContext() {
  		delete IMutableContext::currentContext;
  		IMutableContext::currentContext = nullptr;
  	}
  	IContext::~IContext() = default;
  	IMutableContext::~IMutableContext() = default;
  	Context::~Context() = default;
  }
  // end catch_context.cpp
  // start catch_debug_console.cpp
  
  // start catch_debug_console.h
  
  #include <string>
  
  namespace Catch {
  	void writeToDebugConsole(std::string const& text);
  }
  
  // end catch_debug_console.h
  #ifdef CATCH_PLATFORM_WINDOWS
  
  namespace Catch {
  	void writeToDebugConsole(std::string const& text) {
  		::OutputDebugStringA(text.c_str());
  	}
  }
  
  #else
  
  namespace Catch {
  	void writeToDebugConsole(std::string const& text) {
  		// !TBD: Need a version for Mac/ XCode and other IDEs
  		Catch::cout() << text;
  	}
  }
  
  #endif // Platform
  // end catch_debug_console.cpp
  // start catch_debugger.cpp
  
  #ifdef CATCH_PLATFORM_MAC
  
  #  include <assert.h>
  #  include <stdbool.h>
  #  include <sys/types.h>
  #  include <unistd.h>
  #  include <sys/sysctl.h>
  #  include <cstddef>
  #  include <ostream>
  
  namespace Catch {
  
  	// The following function is taken directly from the following technical note:
  	// http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
  
  	// Returns true if the current process is being debugged (either
  	// running under the debugger or has a debugger attached post facto).
  	bool isDebuggerActive() {
  
  		int                 mib[4];
  		struct kinfo_proc   info;
  		std::size_t         size;
  
  		// Initialize the flags so that, if sysctl fails for some bizarre
  		// reason, we get a predictable result.
  
  		info.kp_proc.p_flag = 0;
  
  		// Initialize mib, which tells sysctl the info we want, in this case
  		// we're looking for information about a specific process ID.
  
  		mib[0] = CTL_KERN;
  		mib[1] = KERN_PROC;
  		mib[2] = KERN_PROC_PID;
  		mib[3] = getpid();
  
  		// Call sysctl.
  
  		size = sizeof(info);
  		if (sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0) {
  			Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
  			return false;
  		}
  
  		// We're being debugged if the P_TRACED flag is set.
  
  		return ((info.kp_proc.p_flag & P_TRACED) != 0);
  	}
  } // namespace Catch
  
  #elif defined(CATCH_PLATFORM_LINUX)
  #include <fstream>
  #include <string>
  
  namespace Catch {
  	// The standard POSIX way of detecting a debugger is to attempt to
  	// ptrace() the process, but this needs to be done from a child and not
  	// this process itself to still allow attaching to this process later
  	// if wanted, so is rather heavy. Under Linux we have the PID of the
  	// "debugger" (which doesn't need to be gdb, of course, it could also
  	// be strace, for example) in /proc/$PID/status, so just get it from
  	// there instead.
  	bool isDebuggerActive() {
  		// Libstdc++ has a bug, where std::ifstream sets errno to 0
  		// This way our users can properly assert over errno values
  		ErrnoGuard guard;
  		std::ifstream in("/proc/self/status");
  		for (std::string line; std::getline(in, line); ) {
  			static const int PREFIX_LEN = 11;
  			if (line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0) {
  				// We're traced if the PID is not 0 and no other PID starts
  				// with 0 digit, so it's enough to check for just a single
  				// character.
  				return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
  			}
  		}
  
  		return false;
  	}
  } // namespace Catch
  #elif defined(_MSC_VER)
  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  namespace Catch {
  	bool isDebuggerActive() {
  		return IsDebuggerPresent() != 0;
  	}
  }
  #elif defined(__MINGW32__)
  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  namespace Catch {
  	bool isDebuggerActive() {
  		return IsDebuggerPresent() != 0;
  	}
  }
  #else
  namespace Catch {
  	bool isDebuggerActive() { return false; }
  }
  #endif // Platform
  // end catch_debugger.cpp
  // start catch_decomposer.cpp
  
  namespace Catch {
  
  	ITransientExpression::~ITransientExpression() = default;
  
  	void formatReconstructedExpression(std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs) {
  		if (lhs.size() + rhs.size() < 40 &&
  			lhs.find('\n') == std::string::npos &&
  			rhs.find('\n') == std::string::npos)
  			os << lhs << " " << op << " " << rhs;
  		else
  			os << lhs << "\n" << op << "\n" << rhs;
  	}
  }
  // end catch_decomposer.cpp
  // start catch_errno_guard.cpp
  
  #include <cerrno>
  
  namespace Catch {
  	ErrnoGuard::ErrnoGuard() :m_oldErrno(errno) {}
  	ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
  }
  // end catch_errno_guard.cpp
  // start catch_exception_translator_registry.cpp
  
  // start catch_exception_translator_registry.h
  
  #include <vector>
  #include <string>
  #include <memory>
  
  namespace Catch {
  
  	class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
  	public:
  		~ExceptionTranslatorRegistry();
  		virtual void registerTranslator(const IExceptionTranslator* translator);
  		virtual std::string translateActiveException() const override;
  		std::string tryTranslators() const;
  
  	private:
  		std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
  	};
  }
  
  // end catch_exception_translator_registry.h
  #ifdef __OBJC__
  #import "Foundation/Foundation.h"
  #endif
  
  namespace Catch {
  
  	ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
  	}
  
  	void ExceptionTranslatorRegistry::registerTranslator(const IExceptionTranslator* translator) {
  		m_translators.push_back(std::unique_ptr<const IExceptionTranslator>(translator));
  	}
  
  	std::string ExceptionTranslatorRegistry::translateActiveException() const {
  		try {
  #ifdef __OBJC__
  			// In Objective-C try objective-c exceptions first
  			@try {
  				return tryTranslators();
  			}
  			@catch (NSException *exception) {
  				return Catch::Detail::stringify([exception description]);
  			}
  #else
  			// Compiling a mixed mode project with MSVC means that CLR
  			// exceptions will be caught in (...) as well. However, these
  			// do not fill-in std::current_exception and thus lead to crash
  			// when attempting rethrow.
  			// /EHa switch also causes structured exceptions to be caught
  			// here, but they fill-in current_exception properly, so
  			// at worst the output should be a little weird, instead of
  			// causing a crash.
  			if (std::current_exception() == nullptr) {
  				return "Non C++ exception. Possibly a CLR exception.";
  			}
  			return tryTranslators();
  #endif
  		}
  		catch (TestFailureException&) {
  			std::rethrow_exception(std::current_exception());
  		}
  		catch (std::exception& ex) {
  			return ex.what();
  		}
  		catch (std::string& msg) {
  			return msg;
  		}
  		catch (const char* msg) {
  			return msg;
  		}
  		catch (...) {
  			return "Unknown exception";
  		}
  	}
  
  	std::string ExceptionTranslatorRegistry::tryTranslators() const {
  		if (m_translators.empty())
  			std::rethrow_exception(std::current_exception());
  		else
  			return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
  	}
  }
  // end catch_exception_translator_registry.cpp
  // start catch_fatal_condition.cpp
  
  #if defined(__GNUC__)
  #    pragma GCC diagnostic push
  #    pragma GCC diagnostic ignored "-Wmissing-field-initializers"
  #endif
  
  #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
  
  namespace {
  	// Report the error condition
  	void reportFatal(char const * const message) {
  		Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition(message);
  	}
  }
  
  #endif // signals/SEH handling
  
  #if defined( CATCH_CONFIG_WINDOWS_SEH )
  
  namespace Catch {
  	struct SignalDefs { DWORD id; const char* name; };
  
  	// There is no 1-1 mapping between signals and windows exceptions.
  	// Windows can easily distinguish between SO and SigSegV,
  	// but SigInt, SigTerm, etc are handled differently.
  	static SignalDefs signalDefs[] = {
  		{ EXCEPTION_ILLEGAL_INSTRUCTION,  "SIGILL - Illegal instruction signal" },
  		{ EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
  		{ EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
  		{ EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
  	};
  
  	LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
  		for (auto const& def : signalDefs) {
  			if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
  				reportFatal(def.name);
  			}
  		}
  		// If its not an exception we care about, pass it along.
  		// This stops us from eating debugger breaks etc.
  		return EXCEPTION_CONTINUE_SEARCH;
  	}
  
  	FatalConditionHandler::FatalConditionHandler() {
  		isSet = true;
  		// 32k seems enough for Catch to handle stack overflow,
  		// but the value was found experimentally, so there is no strong guarantee
  		guaranteeSize = 32 * 1024;
  		exceptionHandlerHandle = nullptr;
  		// Register as first handler in current chain
  		exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
  		// Pass in guarantee size to be filled
  		SetThreadStackGuarantee(&guaranteeSize);
  	}
  
  	void FatalConditionHandler::reset() {
  		if (isSet) {
  			RemoveVectoredExceptionHandler(exceptionHandlerHandle);
  			SetThreadStackGuarantee(&guaranteeSize);
  			exceptionHandlerHandle = nullptr;
  			isSet = false;
  		}
  	}
  
  	FatalConditionHandler::~FatalConditionHandler() {
  		reset();
  	}
  
  	bool FatalConditionHandler::isSet = false;
  	ULONG FatalConditionHandler::guaranteeSize = 0;
  	PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
  
  } // namespace Catch
  
  #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
  
  namespace Catch {
  
  	struct SignalDefs {
  		int id;
  		const char* name;
  	};
  	static SignalDefs signalDefs[] = {
  		{ SIGINT,  "SIGINT - Terminal interrupt signal" },
  		{ SIGILL,  "SIGILL - Illegal instruction signal" },
  		{ SIGFPE,  "SIGFPE - Floating point error signal" },
  		{ SIGSEGV, "SIGSEGV - Segmentation violation signal" },
  		{ SIGTERM, "SIGTERM - Termination request signal" },
  		{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
  	};
  
  	void FatalConditionHandler::handleSignal(int sig) {
  		char const * name = "<unknown signal>";
  		for (auto const& def : signalDefs) {
  			if (sig == def.id) {
  				name = def.name;
  				break;
  			}
  		}
  		reset();
  		reportFatal(name);
  		raise(sig);
  	}
  
  	FatalConditionHandler::FatalConditionHandler() {
  		isSet = true;
  		stack_t sigStack;
  		sigStack.ss_sp = altStackMem;
  		sigStack.ss_size = SIGSTKSZ;
  		sigStack.ss_flags = 0;
  		sigaltstack(&sigStack, &oldSigStack);
  		struct sigaction sa = { };
  
  		sa.sa_handler = handleSignal;
  		sa.sa_flags = SA_ONSTACK;
  		for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
  			sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
  		}
  	}
  
  	FatalConditionHandler::~FatalConditionHandler() {
  		reset();
  	}
  
  	void FatalConditionHandler::reset() {
  		if (isSet) {
  			// Set signals back to previous values -- hopefully nobody overwrote them in the meantime
  			for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
  				sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
  			}
  			// Return the old stack
  			sigaltstack(&oldSigStack, nullptr);
  			isSet = false;
  		}
  	}
  
  	bool FatalConditionHandler::isSet = false;
  	struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)] = {};
  	stack_t FatalConditionHandler::oldSigStack = {};
  	char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
  
  } // namespace Catch
  
  #else
  
  namespace Catch {
  	void FatalConditionHandler::reset() {}
  }
  
  #endif // signals/SEH handling
  
  #if defined(__GNUC__)
  #    pragma GCC diagnostic pop
  #endif
  // end catch_fatal_condition.cpp
  // start catch_interfaces_capture.cpp
  
  namespace Catch {
  	IResultCapture::~IResultCapture() = default;
  }
  // end catch_interfaces_capture.cpp
  // start catch_interfaces_config.cpp
  
  namespace Catch {
  	IConfig::~IConfig() = default;
  }
  // end catch_interfaces_config.cpp
  // start catch_interfaces_exception.cpp
  
  namespace Catch {
  	IExceptionTranslator::~IExceptionTranslator() = default;
  	IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
  }
  // end catch_interfaces_exception.cpp
  // start catch_interfaces_registry_hub.cpp
  
  namespace Catch {
  	IRegistryHub::~IRegistryHub() = default;
  	IMutableRegistryHub::~IMutableRegistryHub() = default;
  }
  // end catch_interfaces_registry_hub.cpp
  // start catch_interfaces_reporter.cpp
  
  // start catch_reporter_multi.h
  
  namespace Catch {
  
  	class MultipleReporters : public IStreamingReporter {
  		using Reporters = std::vector<IStreamingReporterPtr>;
  		Reporters m_reporters;
  
  	public:
  		void add(IStreamingReporterPtr&& reporter);
  
  	public: // IStreamingReporter
  
  		ReporterPreferences getPreferences() const override;
  
  		void noMatchingTestCases(std::string const& spec) override;
  
  		static std::set<Verbosity> getSupportedVerbosities();
  
  		void benchmarkStarting(BenchmarkInfo const& benchmarkInfo) override;
  		void benchmarkEnded(BenchmarkStats const& benchmarkStats) override;
  
  		void testRunStarting(TestRunInfo const& testRunInfo) override;
  		void testGroupStarting(GroupInfo const& groupInfo) override;
  		void testCaseStarting(TestCaseInfo const& testInfo) override;
  		void sectionStarting(SectionInfo const& sectionInfo) override;
  		void assertionStarting(AssertionInfo const& assertionInfo) override;
  
  		// The return value indicates if the messages buffer should be cleared:
  		bool assertionEnded(AssertionStats const& assertionStats) override;
  		void sectionEnded(SectionStats const& sectionStats) override;
  		void testCaseEnded(TestCaseStats const& testCaseStats) override;
  		void testGroupEnded(TestGroupStats const& testGroupStats) override;
  		void testRunEnded(TestRunStats const& testRunStats) override;
  
  		void skipTest(TestCaseInfo const& testInfo) override;
  		bool isMulti() const override;
  
  	};
  
  } // end namespace Catch
  
  // end catch_reporter_multi.h
  namespace Catch {
  
  	ReporterConfig::ReporterConfig(IConfigPtr const& _fullConfig)
  		: m_stream(&_fullConfig->stream()), m_fullConfig(_fullConfig) {}
  
  	ReporterConfig::ReporterConfig(IConfigPtr const& _fullConfig, std::ostream& _stream)
  		: m_stream(&_stream), m_fullConfig(_fullConfig) {}
  
  	std::ostream& ReporterConfig::stream() const { return *m_stream; }
  	IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
  
  	TestRunInfo::TestRunInfo(std::string const& _name) : name(_name) {}
  
  	GroupInfo::GroupInfo(std::string const& _name,
  		std::size_t _groupIndex,
  		std::size_t _groupsCount)
  		: name(_name),
  		groupIndex(_groupIndex),
  		groupsCounts(_groupsCount)
  	{}
  
  	AssertionStats::AssertionStats(AssertionResult const& _assertionResult,
  		std::vector<MessageInfo> const& _infoMessages,
  		Totals const& _totals)
  		: assertionResult(_assertionResult),
  		infoMessages(_infoMessages),
  		totals(_totals)
  	{
  		assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
  
  		if (assertionResult.hasMessage()) {
  			// Copy message into messages list.
  			// !TBD This should have been done earlier, somewhere
  			MessageBuilder builder(assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType());
  			builder << assertionResult.getMessage();
  			builder.m_info.message = builder.m_stream.str();
  
  			infoMessages.push_back(builder.m_info);
  		}
  	}
  
  	AssertionStats::~AssertionStats() = default;
  
  	SectionStats::SectionStats(SectionInfo const& _sectionInfo,
  		Counts const& _assertions,
  		double _durationInSeconds,
  		bool _missingAssertions)
  		: sectionInfo(_sectionInfo),
  		assertions(_assertions),
  		durationInSeconds(_durationInSeconds),
  		missingAssertions(_missingAssertions)
  	{}
  
  	SectionStats::~SectionStats() = default;
  
  	TestCaseStats::TestCaseStats(TestCaseInfo const& _testInfo,
  		Totals const& _totals,
  		std::string const& _stdOut,
  		std::string const& _stdErr,
  		bool _aborting)
  		: testInfo(_testInfo),
  		totals(_totals),
  		stdOut(_stdOut),
  		stdErr(_stdErr),
  		aborting(_aborting)
  	{}
  
  	TestCaseStats::~TestCaseStats() = default;
  
  	TestGroupStats::TestGroupStats(GroupInfo const& _groupInfo,
  		Totals const& _totals,
  		bool _aborting)
  		: groupInfo(_groupInfo),
  		totals(_totals),
  		aborting(_aborting)
  	{}
  
  	TestGroupStats::TestGroupStats(GroupInfo const& _groupInfo)
  		: groupInfo(_groupInfo),
  		aborting(false)
  	{}
  
  	TestGroupStats::~TestGroupStats() = default;
  
  	TestRunStats::TestRunStats(TestRunInfo const& _runInfo,
  		Totals const& _totals,
  		bool _aborting)
  		: runInfo(_runInfo),
  		totals(_totals),
  		aborting(_aborting)
  	{}
  
  	TestRunStats::~TestRunStats() = default;
  
  	void IStreamingReporter::fatalErrorEncountered(StringRef) {}
  	bool IStreamingReporter::isMulti() const { return false; }
  
  	IReporterFactory::~IReporterFactory() = default;
  	IReporterRegistry::~IReporterRegistry() = default;
  
  	void addReporter(IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter) {
  
  		if (!existingReporter) {
  			existingReporter = std::move(additionalReporter);
  			return;
  		}
  
  		MultipleReporters* multi = nullptr;
  
  		if (existingReporter->isMulti()) {
  			multi = static_cast<MultipleReporters*>(existingReporter.get());
  		}
  		else {
  			auto newMulti = std::unique_ptr<MultipleReporters>(new MultipleReporters);
  			newMulti->add(std::move(existingReporter));
  			multi = newMulti.get();
  			existingReporter = std::move(newMulti);
  		}
  		multi->add(std::move(additionalReporter));
  	}
  
  } // end namespace Catch
  // end catch_interfaces_reporter.cpp
  // start catch_interfaces_runner.cpp
  
  namespace Catch {
  	IRunner::~IRunner() = default;
  }
  // end catch_interfaces_runner.cpp
  // start catch_interfaces_testcase.cpp
  
  namespace Catch {
  	ITestInvoker::~ITestInvoker() = default;
  	ITestCaseRegistry::~ITestCaseRegistry() = default;
  }
  // end catch_interfaces_testcase.cpp
  // start catch_leak_detector.cpp
  
  #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
  #include <crtdbg.h>
  
  namespace Catch {
  
  	LeakDetector::LeakDetector() {
  		int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  		flag |= _CRTDBG_LEAK_CHECK_DF;
  		flag |= _CRTDBG_ALLOC_MEM_DF;
  		_CrtSetDbgFlag(flag);
  		_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
  		_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  		// Change this to leaking allocation's number to break there
  		_CrtSetBreakAlloc(-1);
  	}
  }
  
  #else
  
  Catch::LeakDetector::LeakDetector() {}
  
  #endif
  // end catch_leak_detector.cpp
  // start catch_list.cpp
  
  // start catch_list.h
  
  #include <set>
  
  namespace Catch {
  
  	std::size_t listTests(Config const& config);
  
  	std::size_t listTestsNamesOnly(Config const& config);
  
  	struct TagInfo {
  		void add(std::string const& spelling);
  		std::string all() const;
  
  		std::set<std::string> spellings;
  		std::size_t count = 0;
  	};
  
  	std::size_t listTags(Config const& config);
  
  	std::size_t listReporters(Config const& /*config*/);
  
  	Option<std::size_t> list(Config const& config);
  
  } // end namespace Catch
  
  // end catch_list.h
  // start catch_text.h
  
  namespace Catch {
  	using namespace clara::TextFlow;
  }
  
  // end catch_text.h
  #include <limits>
  #include <algorithm>
  #include <iomanip>
  
  namespace Catch {
  
  	std::size_t listTests(Config const& config) {
  		TestSpec testSpec = config.testSpec();
  		if (config.hasTestFilters())
  			Catch::cout() << "Matching test cases:\n";
  		else {
  			Catch::cout() << "All available test cases:\n";
  		}
  
  		auto matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config);
  		for (auto const& testCaseInfo : matchedTestCases) {
  			Colour::Code colour = testCaseInfo.isHidden()
  				? Colour::SecondaryText
  				: Colour::None;
  			Colour colourGuard(colour);
  
  			Catch::cout() << Column(testCaseInfo.name).initialIndent(2).indent(4) << "\n";
  			if (config.verbosity() >= Verbosity::High) {
  				Catch::cout() << Column(Catch::Detail::stringify(testCaseInfo.lineInfo)).indent(4) << std::endl;
  				std::string description = testCaseInfo.description;
  				if (description.empty())
  					description = "(NO DESCRIPTION)";
  				Catch::cout() << Column(description).indent(4) << std::endl;
  			}
  			if (!testCaseInfo.tags.empty())
  				Catch::cout() << Column(testCaseInfo.tagsAsString()).indent(6) << "\n";
  		}
  
  		if (!config.hasTestFilters())
  			Catch::cout() << pluralise(matchedTestCases.size(), "test case") << '\n' << std::endl;
  		else
  			Catch::cout() << pluralise(matchedTestCases.size(), "matching test case") << '\n' << std::endl;
  		return matchedTestCases.size();
  	}
  
  	std::size_t listTestsNamesOnly(Config const& config) {
  		TestSpec testSpec = config.testSpec();
  		std::size_t matchedTests = 0;
  		std::vector<TestCase> matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config);
  		for (auto const& testCaseInfo : matchedTestCases) {
  			matchedTests++;
  			if (startsWith(testCaseInfo.name, '#'))
  				Catch::cout() << '"' << testCaseInfo.name << '"';
  			else
  				Catch::cout() << testCaseInfo.name;
  			if (config.verbosity() >= Verbosity::High)
  				Catch::cout() << "\t@" << testCaseInfo.lineInfo;
  			Catch::cout() << std::endl;
  		}
  		return matchedTests;
  	}
  
  	void TagInfo::add(std::string const& spelling) {
  		++count;
  		spellings.insert(spelling);
  	}
  
  	std::string TagInfo::all() const {
  		std::string out;
  		for (auto const& spelling : spellings)
  			out += "[" + spelling + "]";
  		return out;
  	}
  
  	std::size_t listTags(Config const& config) {
  		TestSpec testSpec = config.testSpec();
  		if (config.hasTestFilters())
  			Catch::cout() << "Tags for matching test cases:\n";
  		else {
  			Catch::cout() << "All available tags:\n";
  		}
  
  		std::map<std::string, TagInfo> tagCounts;
  
  		std::vector<TestCase> matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config);
  		for (auto const& testCase : matchedTestCases) {
  			for (auto const& tagName : testCase.getTestCaseInfo().tags) {
  				std::string lcaseTagName = toLower(tagName);
  				auto countIt = tagCounts.find(lcaseTagName);
  				if (countIt == tagCounts.end())
  					countIt = tagCounts.insert(std::make_pair(lcaseTagName, TagInfo())).first;
  				countIt->second.add(tagName);
  			}
  		}
  
  		for (auto const& tagCount : tagCounts) {
  			ReusableStringStream rss;
  			rss << "  " << std::setw(2) << tagCount.second.count << "  ";
  			auto str = rss.str();
  			auto wrapper = Column(tagCount.second.all())
  				.initialIndent(0)
  				.indent(str.size())
  				.width(CATCH_CONFIG_CONSOLE_WIDTH - 10);
  			Catch::cout() << str << wrapper << '\n';
  		}
  		Catch::cout() << pluralise(tagCounts.size(), "tag") << '\n' << std::endl;
  		return tagCounts.size();
  	}
  
  	std::size_t listReporters(Config const& /*config*/) {
  		Catch::cout() << "Available reporters:\n";
  		IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
  		std::size_t maxNameLen = 0;
  		for (auto const& factoryKvp : factories)
  			maxNameLen = (std::max)(maxNameLen, factoryKvp.first.size());
  
  		for (auto const& factoryKvp : factories) {
  			Catch::cout()
  				<< Column(factoryKvp.first + ":")
  				.indent(2)
  				.width(5 + maxNameLen)
  				+ Column(factoryKvp.second->getDescription())
  				.initialIndent(0)
  				.indent(2)
  				.width(CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen - 8)
  				<< "\n";
  		}
  		Catch::cout() << std::endl;
  		return factories.size();
  	}
  
  	Option<std::size_t> list(Config const& config) {
  		Option<std::size_t> listedCount;
  		if (config.listTests())
  			listedCount = listedCount.valueOr(0) + listTests(config);
  		if (config.listTestNamesOnly())
  			listedCount = listedCount.valueOr(0) + listTestsNamesOnly(config);
  		if (config.listTags())
  			listedCount = listedCount.valueOr(0) + listTags(config);
  		if (config.listReporters())
  			listedCount = listedCount.valueOr(0) + listReporters(config);
  		return listedCount;
  	}
  
  } // end namespace Catch
  // end catch_list.cpp
  // start catch_matchers.cpp
  
  namespace Catch {
  	namespace Matchers {
  		namespace Impl {
  
  			std::string MatcherUntypedBase::toString() const {
  				if (m_cachedToString.empty())
  					m_cachedToString = describe();
  				return m_cachedToString;
  			}
  
  			MatcherUntypedBase::~MatcherUntypedBase() = default;
  
  		} // namespace Impl
  	} // namespace Matchers
  
  	using namespace Matchers;
  	using Matchers::Impl::MatcherBase;
  
  } // namespace Catch
  // end catch_matchers.cpp
  // start catch_matchers_floating.cpp
  
  #include <cstdlib>
  #include <cstdint>
  #include <cstring>
  #include <stdexcept>
  
  namespace Catch {
  	namespace Matchers {
  		namespace Floating {
  			enum class FloatingPointKind : uint8_t {
  				Float,
  				Double
  			};
  		}
  	}
  }
  
  namespace {
  
  	template <typename T>
  	struct Converter;
  
  	template <>
  	struct Converter<float> {
  		static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
  		Converter(float f) {
  			std::memcpy(&i, &f, sizeof(f));
  		}
  		int32_t i;
  	};
  
  	template <>
  	struct Converter<double> {
  		static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
  		Converter(double d) {
  			std::memcpy(&i, &d, sizeof(d));
  		}
  		int64_t i;
  	};
  
  	template <typename T>
  	auto convert(T t) -> Converter<T> {
  		return Converter<T>(t);
  	}
  
  	template <typename FP>
  	bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) {
  		// Comparison with NaN should always be false.
  		// This way we can rule it out before getting into the ugly details
  		if (std::isnan(lhs) || std::isnan(rhs)) {
  			return false;
  		}
  
  		auto lc = convert(lhs);
  		auto rc = convert(rhs);
  
  		if ((lc.i < 0) != (rc.i < 0)) {
  			// Potentially we can have +0 and -0
  			return lhs == rhs;
  		}
  
  		auto ulpDiff = std::abs(lc.i - rc.i);
  		return ulpDiff <= maxUlpDiff;
  	}
  
  }
  
  namespace Catch {
  	namespace Matchers {
  		namespace Floating {
  			WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
  				:m_target{ target }, m_margin{ margin } {
  				if (m_margin < 0) {
  					throw std::domain_error("Allowed margin difference has to be >= 0");
  				}
  			}
  
  			// Performs equivalent check of std::fabs(lhs - rhs) <= margin
  			// But without the subtraction to allow for INFINITY in comparison
  			bool WithinAbsMatcher::match(double const& matchee) const {
  				return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
  			}
  
  			std::string WithinAbsMatcher::describe() const {
  				return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
  			}
  
  			WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
  				:m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
  				if (m_ulps < 0) {
  					throw std::domain_error("Allowed ulp difference has to be >= 0");
  				}
  			}
  
  			bool WithinUlpsMatcher::match(double const& matchee) const {
  				switch (m_type) {
  				case FloatingPointKind::Float:
  					return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
  				case FloatingPointKind::Double:
  					return almostEqualUlps<double>(matchee, m_target, m_ulps);
  				default:
  					throw std::domain_error("Unknown FloatingPointKind value");
  				}
  			}
  
  			std::string WithinUlpsMatcher::describe() const {
  				return "is within " + std::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float) ? "f" : "");
  			}
  
  		}// namespace Floating
  
  		Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) {
  			return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
  		}
  
  		Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) {
  			return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
  		}
  
  		Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
  			return Floating::WithinAbsMatcher(target, margin);
  		}
  
  	} // namespace Matchers
  } // namespace Catch
  
  // end catch_matchers_floating.cpp
  // start catch_matchers_generic.cpp
  
  std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
  	if (desc.empty()) {
  		return "matches undescribed predicate";
  	}
  	else {
  		return "matches predicate: \"" + desc + '"';
  	}
  }
  // end catch_matchers_generic.cpp
  // start catch_matchers_string.cpp
  
  #include <regex>
  
  namespace Catch {
  	namespace Matchers {
  
  		namespace StdString {
  
  			CasedString::CasedString(std::string const& str, CaseSensitive::Choice caseSensitivity)
  				: m_caseSensitivity(caseSensitivity),
  				m_str(adjustString(str))
  			{}
  			std::string CasedString::adjustString(std::string const& str) const {
  				return m_caseSensitivity == CaseSensitive::No
  					? toLower(str)
  					: str;
  			}
  			std::string CasedString::caseSensitivitySuffix() const {
  				return m_caseSensitivity == CaseSensitive::No
  					? " (case insensitive)"
  					: std::string();
  			}
  
  			StringMatcherBase::StringMatcherBase(std::string const& operation, CasedString const& comparator)
  				: m_comparator(comparator),
  				m_operation(operation) {
  			}
  
  			std::string StringMatcherBase::describe() const {
  				std::string description;
  				description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
  					m_comparator.caseSensitivitySuffix().size());
  				description += m_operation;
  				description += ": \"";
  				description += m_comparator.m_str;
  				description += "\"";
  				description += m_comparator.caseSensitivitySuffix();
  				return description;
  			}
  
  			EqualsMatcher::EqualsMatcher(CasedString const& comparator) : StringMatcherBase("equals", comparator) {}
  
  			bool EqualsMatcher::match(std::string const& source) const {
  				return m_comparator.adjustString(source) == m_comparator.m_str;
  			}
  
  			ContainsMatcher::ContainsMatcher(CasedString const& comparator) : StringMatcherBase("contains", comparator) {}
  
  			bool ContainsMatcher::match(std::string const& source) const {
  				return contains(m_comparator.adjustString(source), m_comparator.m_str);
  			}
  
  			StartsWithMatcher::StartsWithMatcher(CasedString const& comparator) : StringMatcherBase("starts with", comparator) {}
  
  			bool StartsWithMatcher::match(std::string const& source) const {
  				return startsWith(m_comparator.adjustString(source), m_comparator.m_str);
  			}
  
  			EndsWithMatcher::EndsWithMatcher(CasedString const& comparator) : StringMatcherBase("ends with", comparator) {}
  
  			bool EndsWithMatcher::match(std::string const& source) const {
  				return endsWith(m_comparator.adjustString(source), m_comparator.m_str);
  			}
  
  			RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity) : m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
  
  			bool RegexMatcher::match(std::string const& matchee) const {
  				auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
  				if (m_caseSensitivity == CaseSensitive::Choice::No) {
  					flags |= std::regex::icase;
  				}
  				auto reg = std::regex(m_regex, flags);
  				return std::regex_match(matchee, reg);
  			}
  
  			std::string RegexMatcher::describe() const {
  				return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes) ? " case sensitively" : " case insensitively");
  			}
  
  		} // namespace StdString
  
  		StdString::EqualsMatcher Equals(std::string const& str, CaseSensitive::Choice caseSensitivity) {
  			return StdString::EqualsMatcher(StdString::CasedString(str, caseSensitivity));
  		}
  		StdString::ContainsMatcher Contains(std::string const& str, CaseSensitive::Choice caseSensitivity) {
  			return StdString::ContainsMatcher(StdString::CasedString(str, caseSensitivity));
  		}
  		StdString::EndsWithMatcher EndsWith(std::string const& str, CaseSensitive::Choice caseSensitivity) {
  			return StdString::EndsWithMatcher(StdString::CasedString(str, caseSensitivity));
  		}
  		StdString::StartsWithMatcher StartsWith(std::string const& str, CaseSensitive::Choice caseSensitivity) {
  			return StdString::StartsWithMatcher(StdString::CasedString(str, caseSensitivity));
  		}
  
  		StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
  			return StdString::RegexMatcher(regex, caseSensitivity);
  		}
  
  	} // namespace Matchers
  } // namespace Catch
  // end catch_matchers_string.cpp
  // start catch_message.cpp
  
  // start catch_uncaught_exceptions.h
  
  namespace Catch {
  	bool uncaught_exceptions();
  } // end namespace Catch
  
  // end catch_uncaught_exceptions.h
  namespace Catch {
  
  	MessageInfo::MessageInfo(std::string const& _macroName,
  		SourceLineInfo const& _lineInfo,
  		ResultWas::OfType _type)
  		: macroName(_macroName),
  		lineInfo(_lineInfo),
  		type(_type),
  		sequence(++globalCount)
  	{}
  
  	bool MessageInfo::operator==(MessageInfo const& other) const {
  		return sequence == other.sequence;
  	}
  
  	bool MessageInfo::operator<(MessageInfo const& other) const {
  		return sequence < other.sequence;
  	}
  
  	// This may need protecting if threading support is added
  	unsigned int MessageInfo::globalCount = 0;
  
  	////////////////////////////////////////////////////////////////////////////
  
  	Catch::MessageBuilder::MessageBuilder(std::string const& macroName,
  		SourceLineInfo const& lineInfo,
  		ResultWas::OfType type)
  		:m_info(macroName, lineInfo, type) {}
  
  	////////////////////////////////////////////////////////////////////////////
  
  	ScopedMessage::ScopedMessage(MessageBuilder const& builder)
  		: m_info(builder.m_info)
  	{
  		m_info.message = builder.m_stream.str();
  		getResultCapture().pushScopedMessage(m_info);
  	}
  
  	ScopedMessage::~ScopedMessage() {
  		if (!uncaught_exceptions()) {
  			getResultCapture().popScopedMessage(m_info);
  		}
  	}
  } // end namespace Catch
  // end catch_message.cpp
  // start catch_random_number_generator.cpp
  
  // start catch_random_number_generator.h
  
  #include <algorithm>
  
  namespace Catch {
  
  	struct IConfig;
  
  	void seedRng(IConfig const& config);
  
  	unsigned int rngSeed();
  
  	struct RandomNumberGenerator {
  		using result_type = unsigned int;
  
  		static constexpr result_type(min)() { return 0; }
  		static constexpr result_type(max)() { return 1000000; }
  
  		result_type operator()(result_type n) const;
  		result_type operator()() const;
  
  		template<typename V>
  		static void shuffle(V& vector) {
  			RandomNumberGenerator rng;
  			std::shuffle(vector.begin(), vector.end(), rng);
  		}
  	};
  
  }
  
  // end catch_random_number_generator.h
  #include <cstdlib>
  
  namespace Catch {
  
  	void seedRng(IConfig const& config) {
  		if (config.rngSeed() != 0)
  			std::srand(config.rngSeed());
  	}
  	unsigned int rngSeed() {
  		return getCurrentContext().getConfig()->rngSeed();
  	}
  
  	RandomNumberGenerator::result_type RandomNumberGenerator::operator()(result_type n) const {
  		return std::rand() % n;
  	}
  	RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
  		return std::rand() % (max)();
  	}
  
  }
  // end catch_random_number_generator.cpp
  // start catch_registry_hub.cpp
  
  // start catch_test_case_registry_impl.h
  
  #include <vector>
  #include <set>
  #include <algorithm>
  #include <ios>
  
  namespace Catch {
  
  	class TestCase;
  	struct IConfig;
  
  	std::vector<TestCase> sortTests(IConfig const& config, std::vector<TestCase> const& unsortedTestCases);
  	bool matchTest(TestCase const& testCase, TestSpec const& testSpec, IConfig const& config);
  
  	void enforceNoDuplicateTestCases(std::vector<TestCase> const& functions);
  
  	std::vector<TestCase> filterTests(std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config);
  	std::vector<TestCase> const& getAllTestCasesSorted(IConfig const& config);
  
  	class TestRegistry : public ITestCaseRegistry {
  	public:
  		virtual ~TestRegistry() = default;
  
  		virtual void registerTest(TestCase const& testCase);
  
  		std::vector<TestCase> const& getAllTests() const override;
  		std::vector<TestCase> const& getAllTestsSorted(IConfig const& config) const override;
  
  	private:
  		std::vector<TestCase> m_functions;
  		mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
  		mutable std::vector<TestCase> m_sortedFunctions;
  		std::size_t m_unnamedCount = 0;
  		std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
  	};
  
  	///////////////////////////////////////////////////////////////////////////
  
  	class TestInvokerAsFunction : public ITestInvoker {
  		void(*m_testAsFunction)();
  	public:
  		TestInvokerAsFunction(void(*testAsFunction)()) noexcept;
  
  		void invoke() const override;
  	};
  
  	std::string extractClassName(StringRef const& classOrQualifiedMethodName);
  
  	///////////////////////////////////////////////////////////////////////////
  
  } // end namespace Catch
  
  // end catch_test_case_registry_impl.h
  // start catch_reporter_registry.h
  
  #include <map>
  
  namespace Catch {
  
  	class ReporterRegistry : public IReporterRegistry {
  
  	public:
  
  		~ReporterRegistry() override;
  
  		IStreamingReporterPtr create(std::string const& name, IConfigPtr const& config) const override;
  
  		void registerReporter(std::string const& name, IReporterFactoryPtr const& factory);
  		void registerListener(IReporterFactoryPtr const& factory);
  
  		FactoryMap const& getFactories() const override;
  		Listeners const& getListeners() const override;
  
  	private:
  		FactoryMap m_factories;
  		Listeners m_listeners;
  	};
  }
  
  // end catch_reporter_registry.h
  // start catch_tag_alias_registry.h
  
  // start catch_tag_alias.h
  
  #include <string>
  
  namespace Catch {
  
  	struct TagAlias {
  		TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
  
  		std::string tag;
  		SourceLineInfo lineInfo;
  	};
  
  } // end namespace Catch
  
  // end catch_tag_alias.h
  #include <map>
  
  namespace Catch {
  
  	class TagAliasRegistry : public ITagAliasRegistry {
  	public:
  		~TagAliasRegistry() override;
  		TagAlias const* find(std::string const& alias) const override;
  		std::string expandAliases(std::string const& unexpandedTestSpec) const override;
  		void add(std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo);
  
  	private:
  		std::map<std::string, TagAlias> m_registry;
  	};
  
  } // end namespace Catch
  
  // end catch_tag_alias_registry.h
  // start catch_startup_exception_registry.h
  
  #include <vector>
  #include <exception>
  
  namespace Catch {
  
  	class StartupExceptionRegistry {
  	public:
  		void add(std::exception_ptr const& exception) noexcept;
  		std::vector<std::exception_ptr> const& getExceptions() const noexcept;
  	private:
  		std::vector<std::exception_ptr> m_exceptions;
  	};
  
  } // end namespace Catch
  
  // end catch_startup_exception_registry.h
  namespace Catch {
  
  	namespace {
  
  		class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
  			private NonCopyable {
  
  		public: // IRegistryHub
  			RegistryHub() = default;
  			IReporterRegistry const& getReporterRegistry() const override {
  				return m_reporterRegistry;
  			}
  			ITestCaseRegistry const& getTestCaseRegistry() const override {
  				return m_testCaseRegistry;
  			}
  			IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() override {
  				return m_exceptionTranslatorRegistry;
  			}
  			ITagAliasRegistry const& getTagAliasRegistry() const override {
  				return m_tagAliasRegistry;
  			}
  			StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
  				return m_exceptionRegistry;
  			}
  
  		public: // IMutableRegistryHub
  			void registerReporter(std::string const& name, IReporterFactoryPtr const& factory) override {
  				m_reporterRegistry.registerReporter(name, factory);
  			}
  			void registerListener(IReporterFactoryPtr const& factory) override {
  				m_reporterRegistry.registerListener(factory);
  			}
  			void registerTest(TestCase const& testInfo) override {
  				m_testCaseRegistry.registerTest(testInfo);
  			}
  			void registerTranslator(const IExceptionTranslator* translator) override {
  				m_exceptionTranslatorRegistry.registerTranslator(translator);
  			}
  			void registerTagAlias(std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo) override {
  				m_tagAliasRegistry.add(alias, tag, lineInfo);
  			}
  			void registerStartupException() noexcept override {
  				m_exceptionRegistry.add(std::current_exception());
  			}
  
  		private:
  			TestRegistry m_testCaseRegistry;
  			ReporterRegistry m_reporterRegistry;
  			ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
  			TagAliasRegistry m_tagAliasRegistry;
  			StartupExceptionRegistry m_exceptionRegistry;
  		};
  
  		// Single, global, instance
  		RegistryHub*& getTheRegistryHub() {
  			static RegistryHub* theRegistryHub = nullptr;
  			if (!theRegistryHub)
  				theRegistryHub = new RegistryHub();
  			return theRegistryHub;
  		}
  	}
  
  	IRegistryHub& getRegistryHub() {
  		return *getTheRegistryHub();
  	}
  	IMutableRegistryHub& getMutableRegistryHub() {
  		return *getTheRegistryHub();
  	}
  	void cleanUp() {
  		delete getTheRegistryHub();
  		getTheRegistryHub() = nullptr;
  		cleanUpContext();
  		ReusableStringStream::cleanup();
  	}
  	std::string translateActiveException() {
  		return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
  	}
  
  } // end namespace Catch
  // end catch_registry_hub.cpp
  // start catch_reporter_registry.cpp
  
  namespace Catch {
  
  	ReporterRegistry::~ReporterRegistry() = default;
  
  	IStreamingReporterPtr ReporterRegistry::create(std::string const& name, IConfigPtr const& config) const {
  		auto it = m_factories.find(name);
  		if (it == m_factories.end())
  			return nullptr;
  		return it->second->create(ReporterConfig(config));
  	}
  
  	void ReporterRegistry::registerReporter(std::string const& name, IReporterFactoryPtr const& factory) {
  		m_factories.emplace(name, factory);
  	}
  	void ReporterRegistry::registerListener(IReporterFactoryPtr const& factory) {
  		m_listeners.push_back(factory);
  	}
  
  	IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
  		return m_factories;
  	}
  	IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
  		return m_listeners;
  	}
  
  }
  // end catch_reporter_registry.cpp
  // start catch_result_type.cpp
  
  namespace Catch {
  
  	bool isOk(ResultWas::OfType resultType) {
  		return (resultType & ResultWas::FailureBit) == 0;
  	}
  	bool isJustInfo(int flags) {
  		return flags == ResultWas::Info;
  	}
  
  	ResultDisposition::Flags operator | (ResultDisposition::Flags lhs, ResultDisposition::Flags rhs) {
  		return static_cast<ResultDisposition::Flags>(static_cast<int>(lhs) | static_cast<int>(rhs));
  	}
  
  	bool shouldContinueOnFailure(int flags) { return (flags & ResultDisposition::ContinueOnFailure) != 0; }
  	bool shouldSuppressFailure(int flags) { return (flags & ResultDisposition::SuppressFail) != 0; }
  
  } // end namespace Catch
  // end catch_result_type.cpp
  // start catch_run_context.cpp
  
  #include <cassert>
  #include <algorithm>
  #include <sstream>
  
  namespace Catch {
  
  	class RedirectedStream {
  		std::ostream& m_originalStream;
  		std::ostream& m_redirectionStream;
  		std::streambuf* m_prevBuf;
  
  	public:
  		RedirectedStream(std::ostream& originalStream, std::ostream& redirectionStream)
  			: m_originalStream(originalStream),
  			m_redirectionStream(redirectionStream),
  			m_prevBuf(m_originalStream.rdbuf())
  		{
  			m_originalStream.rdbuf(m_redirectionStream.rdbuf());
  		}
  		~RedirectedStream() {
  			m_originalStream.rdbuf(m_prevBuf);
  		}
  	};
  
  	class RedirectedStdOut {
  		ReusableStringStream m_rss;
  		RedirectedStream m_cout;
  	public:
  		RedirectedStdOut() : m_cout(Catch::cout(), m_rss.get()) {}
  		auto str() const -> std::string { return m_rss.str(); }
  	};
  
  	// StdErr has two constituent streams in C++, std::cerr and std::clog
  	// This means that we need to redirect 2 streams into 1 to keep proper
  	// order of writes
  	class RedirectedStdErr {
  		ReusableStringStream m_rss;
  		RedirectedStream m_cerr;
  		RedirectedStream m_clog;
  	public:
  		RedirectedStdErr()
  			: m_cerr(Catch::cerr(), m_rss.get()),
  			m_clog(Catch::clog(), m_rss.get())
  		{}
  		auto str() const -> std::string { return m_rss.str(); }
  	};
  
  	RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
  		: m_runInfo(_config->name()),
  		m_context(getCurrentMutableContext()),
  		m_config(_config),
  		m_reporter(std::move(reporter)),
  		m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
  		m_includeSuccessfulResults(m_config->includeSuccessfulResults())
  	{
  		m_context.setRunner(this);
  		m_context.setConfig(m_config);
  		m_context.setResultCapture(this);
  		m_reporter->testRunStarting(m_runInfo);
  	}
  
  	RunContext::~RunContext() {
  		m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
  	}
  
  	void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
  		m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
  	}
  
  	void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
  		m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
  	}
  
  	Totals RunContext::runTest(TestCase const& testCase) {
  		Totals prevTotals = m_totals;
  
  		std::string redirectedCout;
  		std::string redirectedCerr;
  
  		auto const& testInfo = testCase.getTestCaseInfo();
  
  		m_reporter->testCaseStarting(testInfo);
  
  		m_activeTestCase = &testCase;
  
  		ITracker& rootTracker = m_trackerContext.startRun();
  		assert(rootTracker.isSectionTracker());
  		static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
  		do {
  			m_trackerContext.startCycle();
  			m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
  			runCurrentTest(redirectedCout, redirectedCerr);
  		} while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
  
  		Totals deltaTotals = m_totals.delta(prevTotals);
  		if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
  			deltaTotals.assertions.failed++;
  			deltaTotals.testCases.passed--;
  			deltaTotals.testCases.failed++;
  		}
  		m_totals.testCases += deltaTotals.testCases;
  		m_reporter->testCaseEnded(TestCaseStats(testInfo,
  			deltaTotals,
  			redirectedCout,
  			redirectedCerr,
  			aborting()));
  
  		m_activeTestCase = nullptr;
  		m_testCaseTracker = nullptr;
  
  		return deltaTotals;
  	}
  
  	IConfigPtr RunContext::config() const {
  		return m_config;
  	}
  
  	IStreamingReporter& RunContext::reporter() const {
  		return *m_reporter;
  	}
  
  	void RunContext::assertionEnded(AssertionResult const & result) {
  		if (result.getResultType() == ResultWas::Ok) {
  			m_totals.assertions.passed++;
  			m_lastAssertionPassed = true;
  		}
  		else if (!result.isOk()) {
  			m_lastAssertionPassed = false;
  			if (m_activeTestCase->getTestCaseInfo().okToFail())
  				m_totals.assertions.failedButOk++;
  			else
  				m_totals.assertions.failed++;
  		}
  		else {
  			m_lastAssertionPassed = true;
  		}
  
  		// We have no use for the return value (whether messages should be cleared), because messages were made scoped
  		// and should be let to clear themselves out.
  		static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
  
  		// Reset working state
  		resetAssertionInfo();
  		m_lastResult = result;
  	}
  	void RunContext::resetAssertionInfo() {
  		m_lastAssertionInfo.macroName = StringRef();
  		m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
  	}
  
  	bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
  		ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
  		if (!sectionTracker.isOpen())
  			return false;
  		m_activeSections.push_back(&sectionTracker);
  
  		m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
  
  		m_reporter->sectionStarting(sectionInfo);
  
  		assertions = m_totals.assertions;
  
  		return true;
  	}
  
  	bool RunContext::testForMissingAssertions(Counts& assertions) {
  		if (assertions.total() != 0)
  			return false;
  		if (!m_config->warnAboutMissingAssertions())
  			return false;
  		if (m_trackerContext.currentTracker().hasChildren())
  			return false;
  		m_totals.assertions.failed++;
  		assertions.failed++;
  		return true;
  	}
  
  	void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
  		Counts assertions = m_totals.assertions - endInfo.prevAssertions;
  		bool missingAssertions = testForMissingAssertions(assertions);
  
  		if (!m_activeSections.empty()) {
  			m_activeSections.back()->close();
  			m_activeSections.pop_back();
  		}
  
  		m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
  		m_messages.clear();
  	}
  
  	void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
  		if (m_unfinishedSections.empty())
  			m_activeSections.back()->fail();
  		else
  			m_activeSections.back()->close();
  		m_activeSections.pop_back();
  
  		m_unfinishedSections.push_back(endInfo);
  	}
  	void RunContext::benchmarkStarting(BenchmarkInfo const& info) {
  		m_reporter->benchmarkStarting(info);
  	}
  	void RunContext::benchmarkEnded(BenchmarkStats const& stats) {
  		m_reporter->benchmarkEnded(stats);
  	}
  
  	void RunContext::pushScopedMessage(MessageInfo const & message) {
  		m_messages.push_back(message);
  	}
  
  	void RunContext::popScopedMessage(MessageInfo const & message) {
  		m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
  	}
  
  	std::string RunContext::getCurrentTestName() const {
  		return m_activeTestCase
  			? m_activeTestCase->getTestCaseInfo().name
  			: std::string();
  	}
  
  	const AssertionResult * RunContext::getLastResult() const {
  		return &(*m_lastResult);
  	}
  
  	void RunContext::exceptionEarlyReported() {
  		m_shouldReportUnexpected = false;
  	}
  
  	void RunContext::handleFatalErrorCondition(StringRef message) {
  		// First notify reporter that bad things happened
  		m_reporter->fatalErrorEncountered(message);
  
  		// Don't rebuild the result -- the stringification itself can cause more fatal errors
  		// Instead, fake a result data.
  		AssertionResultData tempResult(ResultWas::FatalErrorCondition, { false });
  		tempResult.message = message;
  		AssertionResult result(m_lastAssertionInfo, tempResult);
  
  		assertionEnded(result);
  
  		handleUnfinishedSections();
  
  		// Recreate section for test case (as we will lose the one that was in scope)
  		auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  		SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
  
  		Counts assertions;
  		assertions.failed = 1;
  		SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
  		m_reporter->sectionEnded(testCaseSectionStats);
  
  		auto const& testInfo = m_activeTestCase->getTestCaseInfo();
  
  		Totals deltaTotals;
  		deltaTotals.testCases.failed = 1;
  		deltaTotals.assertions.failed = 1;
  		m_reporter->testCaseEnded(TestCaseStats(testInfo,
  			deltaTotals,
  			std::string(),
  			std::string(),
  			false));
  		m_totals.testCases.failed++;
  		testGroupEnded(std::string(), m_totals, 1, 1);
  		m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
  	}
  
  	bool RunContext::lastAssertionPassed() {
  		return m_lastAssertionPassed;
  	}
  
  	void RunContext::assertionPassed() {
  		m_lastAssertionPassed = true;
  		++m_totals.assertions.passed;
  		resetAssertionInfo();
  	}
  
  	bool RunContext::aborting() const {
  		return m_totals.assertions.failed == static_cast<std::size_t>(m_config->abortAfter());
  	}
  
  	void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
  		auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  		SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
  		m_reporter->sectionStarting(testCaseSection);
  		Counts prevAssertions = m_totals.assertions;
  		double duration = 0;
  		m_shouldReportUnexpected = true;
  		m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
  
  		seedRng(*m_config);
  
  		Timer timer;
  		try {
  			if (m_reporter->getPreferences().shouldRedirectStdOut) {
  				RedirectedStdOut redirectedStdOut;
  				RedirectedStdErr redirectedStdErr;
  				timer.start();
  				invokeActiveTestCase();
  				redirectedCout += redirectedStdOut.str();
  				redirectedCerr += redirectedStdErr.str();
  
  			}
  			else {
  				timer.start();
  				invokeActiveTestCase();
  			}
  			duration = timer.getElapsedSeconds();
  		}
  		catch (TestFailureException&) {
  			// This just means the test was aborted due to failure
  		}
  		catch (...) {
  			// Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
  			// are reported without translation at the point of origin.
  			if (m_shouldReportUnexpected) {
  				AssertionReaction dummyReaction;
  				handleUnexpectedInflightException(m_lastAssertionInfo, translateActiveException(), dummyReaction);
  			}
  		}
  		Counts assertions = m_totals.assertions - prevAssertions;
  		bool missingAssertions = testForMissingAssertions(assertions);
  
  		m_testCaseTracker->close();
  		handleUnfinishedSections();
  		m_messages.clear();
  
  		SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
  		m_reporter->sectionEnded(testCaseSectionStats);
  	}
  
  	void RunContext::invokeActiveTestCase() {
  		FatalConditionHandler fatalConditionHandler; // Handle signals
  		m_activeTestCase->invoke();
  		fatalConditionHandler.reset();
  	}
  
  	void RunContext::handleUnfinishedSections() {
  		// If sections ended prematurely due to an exception we stored their
  		// infos here so we can tear them down outside the unwind process.
  		for (auto it = m_unfinishedSections.rbegin(),
  			itEnd = m_unfinishedSections.rend();
  			it != itEnd;
  			++it)
  			sectionEnded(*it);
  		m_unfinishedSections.clear();
  	}
  
  	void RunContext::handleExpr(
  		AssertionInfo const& info,
  		ITransientExpression const& expr,
  		AssertionReaction& reaction
  	) {
  		m_reporter->assertionStarting(info);
  
  		bool negated = isFalseTest(info.resultDisposition);
  		bool result = expr.getResult() != negated;
  
  		if (result) {
  			if (!m_includeSuccessfulResults) {
  				assertionPassed();
  			}
  			else {
  				reportExpr(info, ResultWas::Ok, &expr, negated);
  			}
  		}
  		else {
  			reportExpr(info, ResultWas::ExpressionFailed, &expr, negated);
  			populateReaction(reaction);
  		}
  	}
  	void RunContext::reportExpr(
  		AssertionInfo const &info,
  		ResultWas::OfType resultType,
  		ITransientExpression const *expr,
  		bool negated) {
  
  		m_lastAssertionInfo = info;
  		AssertionResultData data(resultType, LazyExpression(negated));
  
  		AssertionResult assertionResult{ info, data };
  		assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
  
  		assertionEnded(assertionResult);
  	}
  
  	void RunContext::handleMessage(
  		AssertionInfo const& info,
  		ResultWas::OfType resultType,
  		StringRef const& message,
  		AssertionReaction& reaction
  	) {
  		m_reporter->assertionStarting(info);
  
  		m_lastAssertionInfo = info;
  
  		AssertionResultData data(resultType, LazyExpression(false));
  		data.message = message;
  		AssertionResult assertionResult{ m_lastAssertionInfo, data };
  		assertionEnded(assertionResult);
  		if (!assertionResult.isOk())
  			populateReaction(reaction);
  	}
  	void RunContext::handleUnexpectedExceptionNotThrown(
  		AssertionInfo const& info,
  		AssertionReaction& reaction
  	) {
  		handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
  	}
  
  	void RunContext::handleUnexpectedInflightException(
  		AssertionInfo const& info,
  		std::string const& message,
  		AssertionReaction& reaction
  	) {
  		m_lastAssertionInfo = info;
  
  		AssertionResultData data(ResultWas::ThrewException, LazyExpression(false));
  		data.message = message;
  		AssertionResult assertionResult{ info, data };
  		assertionEnded(assertionResult);
  		populateReaction(reaction);
  	}
  
  	void RunContext::populateReaction(AssertionReaction& reaction) {
  		reaction.shouldDebugBreak = m_config->shouldDebugBreak();
  		reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
  	}
  
  	void RunContext::handleIncomplete(
  		AssertionInfo const& info
  	) {
  		m_lastAssertionInfo = info;
  
  		AssertionResultData data(ResultWas::ThrewException, LazyExpression(false));
  		data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
  		AssertionResult assertionResult{ info, data };
  		assertionEnded(assertionResult);
  	}
  	void RunContext::handleNonExpr(
  		AssertionInfo const &info,
  		ResultWas::OfType resultType,
  		AssertionReaction &reaction
  	) {
  		m_lastAssertionInfo = info;
  
  		AssertionResultData data(resultType, LazyExpression(false));
  		AssertionResult assertionResult{ info, data };
  		assertionEnded(assertionResult);
  
  		if (!assertionResult.isOk())
  			populateReaction(reaction);
  	}
  
  	IResultCapture& getResultCapture() {
  		if (auto* capture = getCurrentContext().getResultCapture())
  			return *capture;
  		else
  			CATCH_INTERNAL_ERROR("No result capture instance");
  	}
  }
  // end catch_run_context.cpp
  // start catch_section.cpp
  
  namespace Catch {
  
  	Section::Section(SectionInfo const& info)
  		: m_info(info),
  		m_sectionIncluded(getResultCapture().sectionStarted(m_info, m_assertions))
  	{
  		m_timer.start();
  	}
  
  	Section::~Section() {
  		if (m_sectionIncluded) {
  			SectionEndInfo endInfo(m_info, m_assertions, m_timer.getElapsedSeconds());
  			if (uncaught_exceptions())
  				getResultCapture().sectionEndedEarly(endInfo);
  			else
  				getResultCapture().sectionEnded(endInfo);
  		}
  	}
  
  	// This indicates whether the section should be executed or not
  	Section::operator bool() const {
  		return m_sectionIncluded;
  	}
  
  } // end namespace Catch
  // end catch_section.cpp
  // start catch_section_info.cpp
  
  namespace Catch {
  
  	SectionInfo::SectionInfo
  	(SourceLineInfo const& _lineInfo,
  		std::string const& _name,
  		std::string const& _description)
  		: name(_name),
  		description(_description),
  		lineInfo(_lineInfo)
  	{}
  
  	SectionEndInfo::SectionEndInfo(SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds)
  		: sectionInfo(_sectionInfo), prevAssertions(_prevAssertions), durationInSeconds(_durationInSeconds)
  	{}
  
  } // end namespace Catch
  // end catch_section_info.cpp
  // start catch_session.cpp
  
  // start catch_session.h
  
  #include <memory>
  
  namespace Catch {
  
  	class Session : NonCopyable {
  	public:
  
  		Session();
  		~Session() override;
  
  		void showHelp() const;
  		void libIdentify();
  
  		int applyCommandLine(int argc, char const * const * argv);
  
  		void useConfigData(ConfigData const& configData);
  
  		int run(int argc, char* argv[]);
  #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
  		int run(int argc, wchar_t* const argv[]);
  #endif
  		int run();
  
  		clara::Parser const& cli() const;
  		void cli(clara::Parser const& newParser);
  		ConfigData& configData();
  		Config& config();
  	private:
  		int runInternal();
  
  		clara::Parser m_cli;
  		ConfigData m_configData;
  		std::shared_ptr<Config> m_config;
  		bool m_startupExceptions = false;
  	};
  
  } // end namespace Catch
  
  // end catch_session.h
  // start catch_version.h
  
  #include <iosfwd>
  
  namespace Catch {
  
  	// Versioning information
  	struct Version {
  		Version(Version const&) = delete;
  		Version& operator=(Version const&) = delete;
  		Version(unsigned int _majorVersion,
  			unsigned int _minorVersion,
  			unsigned int _patchNumber,
  			char const * const _branchName,
  			unsigned int _buildNumber);
  
  		unsigned int const majorVersion;
  		unsigned int const minorVersion;
  		unsigned int const patchNumber;
  
  		// buildNumber is only used if branchName is not null
  		char const * const branchName;
  		unsigned int const buildNumber;
  
  		friend std::ostream& operator << (std::ostream& os, Version const& version);
  	};
  
  	Version const& libraryVersion();
  }
  
  // end catch_version.h
  #include <cstdlib>
  #include <iomanip>
  
  namespace Catch {
  
  	namespace {
  		const int MaxExitCode = 255;
  
  		IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
  			auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
  			CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
  
  			return reporter;
  		}
  
  #ifndef CATCH_CONFIG_DEFAULT_REPORTER
  #define CATCH_CONFIG_DEFAULT_REPORTER "console"
  #endif
  
  		IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
  			auto const& reporterNames = config->getReporterNames();
  			if (reporterNames.empty())
  				return createReporter(CATCH_CONFIG_DEFAULT_REPORTER, config);
  
  			IStreamingReporterPtr reporter;
  			for (auto const& name : reporterNames)
  				addReporter(reporter, createReporter(name, config));
  			return reporter;
  		}
  
  #undef CATCH_CONFIG_DEFAULT_REPORTER
  
  		void addListeners(IStreamingReporterPtr& reporters, IConfigPtr const& config) {
  			auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
  			for (auto const& listener : listeners)
  				addReporter(reporters, listener->create(Catch::ReporterConfig(config)));
  		}
  
  		Catch::Totals runTests(std::shared_ptr<Config> const& config) {
  			IStreamingReporterPtr reporter = makeReporter(config);
  			addListeners(reporter, config);
  
  			RunContext context(config, std::move(reporter));
  
  			Totals totals;
  
  			context.testGroupStarting(config->name(), 1, 1);
  
  			TestSpec testSpec = config->testSpec();
  
  			auto const& allTestCases = getAllTestCasesSorted(*config);
  			for (auto const& testCase : allTestCases) {
  				if (!context.aborting() && matchTest(testCase, testSpec, *config))
  					totals += context.runTest(testCase);
  				else
  					context.reporter().skipTest(testCase);
  			}
  
  			if (config->warnAboutNoTests() && totals.testCases.total() == 0) {
  				ReusableStringStream testConfig;
  
  				bool first = true;
  				for (const auto& input : config->getTestsOrTags()) {
  					if (!first) { testConfig << ' '; }
  					first = false;
  					testConfig << input;
  				}
  
  				context.reporter().noMatchingTestCases(testConfig.str());
  				totals.error = -1;
  			}
  
  			context.testGroupEnded(config->name(), totals, 1, 1);
  			return totals;
  		}
  
  		void applyFilenamesAsTags(Catch::IConfig const& config) {
  			auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
  			for (auto& testCase : tests) {
  				auto tags = testCase.tags;
  
  				std::string filename = testCase.lineInfo.file;
  				auto lastSlash = filename.find_last_of("\\/");
  				if (lastSlash != std::string::npos) {
  					filename.erase(0, lastSlash);
  					filename[0] = '#';
  				}
  
  				auto lastDot = filename.find_last_of('.');
  				if (lastDot != std::string::npos) {
  					filename.erase(lastDot);
  				}
  
  				tags.push_back(std::move(filename));
  				setTags(testCase, tags);
  			}
  		}
  
  	} // anon namespace
  
  	Session::Session() {
  		static bool alreadyInstantiated = false;
  		if (alreadyInstantiated) {
  			try { CATCH_INTERNAL_ERROR("Only one instance of Catch::Session can ever be used"); }
  			catch (...) { getMutableRegistryHub().registerStartupException(); }
  		}
  
  		const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
  		if (!exceptions.empty()) {
  			m_startupExceptions = true;
  			Colour colourGuard(Colour::Red);
  			Catch::cerr() << "Errors occurred during startup!" << '\n';
  			// iterate over all exceptions and notify user
  			for (const auto& ex_ptr : exceptions) {
  				try {
  					std::rethrow_exception(ex_ptr);
  				}
  				catch (std::exception const& ex) {
  					Catch::cerr() << Column(ex.what()).indent(2) << '\n';
  				}
  			}
  		}
  
  		alreadyInstantiated = true;
  		m_cli = makeCommandLineParser(m_configData);
  	}
  	Session::~Session() {
  		Catch::cleanUp();
  	}
  
  	void Session::showHelp() const {
  		Catch::cout()
  			<< "\nCatch v" << libraryVersion() << "\n"
  			<< m_cli << std::endl
  			<< "For more detailed usage please see the project docs\n" << std::endl;
  	}
  	void Session::libIdentify() {
  		Catch::cout()
  			<< std::left << std::setw(16) << "description: " << "A Catch test executable\n"
  			<< std::left << std::setw(16) << "category: " << "testframework\n"
  			<< std::left << std::setw(16) << "framework: " << "Catch Test\n"
  			<< std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
  	}
  
  	int Session::applyCommandLine(int argc, char const * const * argv) {
  		if (m_startupExceptions)
  			return 1;
  
  		auto result = m_cli.parse(clara::Args(argc, argv));
  		if (!result) {
  			Catch::cerr()
  				<< Colour(Colour::Red)
  				<< "\nError(s) in input:\n"
  				<< Column(result.errorMessage()).indent(2)
  				<< "\n\n";
  			Catch::cerr() << "Run with -? for usage\n" << std::endl;
  			return MaxExitCode;
  		}
  
  		if (m_configData.showHelp)
  			showHelp();
  		if (m_configData.libIdentify)
  			libIdentify();
  		m_config.reset();
  		return 0;
  	}
  
  	void Session::useConfigData(ConfigData const& configData) {
  		m_configData = configData;
  		m_config.reset();
  	}
  
  	int Session::run(int argc, char* argv[]) {
  		if (m_startupExceptions)
  			return 1;
  		int returnCode = applyCommandLine(argc, argv);
  		if (returnCode == 0)
  			returnCode = run();
  		return returnCode;
  	}
  
  #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
  	int Session::run(int argc, wchar_t* const argv[]) {
  
  		char **utf8Argv = new char *[argc];
  
  		for (int i = 0; i < argc; ++i) {
  			int bufSize = WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL);
  
  			utf8Argv[i] = new char[bufSize];
  
  			WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL);
  		}
  
  		int returnCode = run(argc, utf8Argv);
  
  		for (int i = 0; i < argc; ++i)
  			delete[] utf8Argv[i];
  
  		delete[] utf8Argv;
  
  		return returnCode;
  	}
  #endif
  	int Session::run() {
  		if ((m_configData.waitForKeypress & WaitForKeypress::BeforeStart) != 0) {
  			Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
  			static_cast<void>(std::getchar());
  		}
  		int exitCode = runInternal();
  		if ((m_configData.waitForKeypress & WaitForKeypress::BeforeExit) != 0) {
  			Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
  			static_cast<void>(std::getchar());
  		}
  		return exitCode;
  	}
  
  	clara::Parser const& Session::cli() const {
  		return m_cli;
  	}
  	void Session::cli(clara::Parser const& newParser) {
  		m_cli = newParser;
  	}
  	ConfigData& Session::configData() {
  		return m_configData;
  	}
  	Config& Session::config() {
  		if (!m_config)
  			m_config = std::make_shared<Config>(m_configData);
  		return *m_config;
  	}
  
  	int Session::runInternal() {
  		if (m_startupExceptions)
  			return 1;
  
  		if (m_configData.showHelp || m_configData.libIdentify)
  			return 0;
  
  		try
  		{
  			config(); // Force config to be constructed
  
  			seedRng(*m_config);
  
  			if (m_configData.filenamesAsTags)
  				applyFilenamesAsTags(*m_config);
  
  			// Handle list request
  			if (Option<std::size_t> listed = list(config()))
  				return static_cast<int>(*listed);
  
  			auto totals = runTests(m_config);
  			// Note that on unices only the lower 8 bits are usually used, clamping
  			// the return value to 255 prevents false negative when some multiple
  			// of 256 tests has failed
  			return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
  		}
  		catch (std::exception& ex) {
  			Catch::cerr() << ex.what() << std::endl;
  			return MaxExitCode;
  		}
  	}
  
  } // end namespace Catch
  // end catch_session.cpp
  // start catch_startup_exception_registry.cpp
  
  namespace Catch {
  	void StartupExceptionRegistry::add(std::exception_ptr const& exception) noexcept {
  		try {
  			m_exceptions.push_back(exception);
  		}
  		catch (...) {
  			// If we run out of memory during start-up there's really not a lot more we can do about it
  			std::terminate();
  		}
  	}
  
  	std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
  		return m_exceptions;
  	}
  
  } // end namespace Catch
  // end catch_startup_exception_registry.cpp
  // start catch_stream.cpp
  
  #include <cstdio>
  #include <iostream>
  #include <fstream>
  #include <sstream>
  #include <vector>
  #include <memory>
  
  #if defined(__clang__)
  #    pragma clang diagnostic push
  #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  #endif
  
  namespace Catch {
  
  	Catch::IStream::~IStream() = default;
  
  	namespace detail {
  		namespace {
  			template<typename WriterF, std::size_t bufferSize = 256>
  			class StreamBufImpl : public std::streambuf {
  				char data[bufferSize];
  				WriterF m_writer;
  
  			public:
  				StreamBufImpl() {
  					setp(data, data + sizeof(data));
  				}
  
  				~StreamBufImpl() noexcept {
  					StreamBufImpl::sync();
  				}
  
  			private:
  				int overflow(int c) override {
  					sync();
  
  					if (c != EOF) {
  						if (pbase() == epptr())
  							m_writer(std::string(1, static_cast<char>(c)));
  						else
  							sputc(static_cast<char>(c));
  					}
  					return 0;
  				}
  
  				int sync() override {
  					if (pbase() != pptr()) {
  						m_writer(std::string(pbase(), static_cast<std::string::size_type>(pptr() - pbase())));
  						setp(pbase(), epptr());
  					}
  					return 0;
  				}
  			};
  
  			///////////////////////////////////////////////////////////////////////////
  
  			struct OutputDebugWriter {
  
  				void operator()(std::string const&str) {
  					writeToDebugConsole(str);
  				}
  			};
  
  			///////////////////////////////////////////////////////////////////////////
  
  			class FileStream : public IStream {
  				mutable std::ofstream m_ofs;
  			public:
  				FileStream(StringRef filename) {
  					m_ofs.open(filename.c_str());
  					CATCH_ENFORCE(!m_ofs.fail(), "Unable to open file: '" << filename << "'");
  				}
  				~FileStream() override = default;
  			public: // IStream
  				std::ostream& stream() const override {
  					return m_ofs;
  				}
  			};
  
  			///////////////////////////////////////////////////////////////////////////
  
  			class CoutStream : public IStream {
  				mutable std::ostream m_os;
  			public:
  				// Store the streambuf from cout up-front because
  				// cout may get redirected when running tests
  				CoutStream() : m_os(Catch::cout().rdbuf()) {}
  				~CoutStream() override = default;
  
  			public: // IStream
  				std::ostream& stream() const override { return m_os; }
  			};
  
  			///////////////////////////////////////////////////////////////////////////
  
  			class DebugOutStream : public IStream {
  				std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
  				mutable std::ostream m_os;
  			public:
  				DebugOutStream()
  					: m_streamBuf(new StreamBufImpl<OutputDebugWriter>()),
  					m_os(m_streamBuf.get())
  				{}
  
  				~DebugOutStream() override = default;
  
  			public: // IStream
  				std::ostream& stream() const override { return m_os; }
  			};
  
  		}
  	} // namespace anon::detail
  
     ///////////////////////////////////////////////////////////////////////////
  
  	auto makeStream(StringRef const &filename) -> IStream const* {
  		if (filename.empty())
  			return new detail::CoutStream();
  		else if (filename[0] == '%') {
  			if (filename == "%debug")
  				return new detail::DebugOutStream();
  			else
  				CATCH_ERROR("Unrecognised stream: '" << filename << "'");
  		}
  		else
  			return new detail::FileStream(filename);
  	}
  
  	// This class encapsulates the idea of a pool of ostringstreams that can be reused.
  	struct StringStreams {
  		std::vector<std::unique_ptr<std::ostringstream>> m_streams;
  		std::vector<std::size_t> m_unused;
  		std::ostringstream m_referenceStream; // Used for copy state/ flags from
  		static StringStreams* s_instance;
  
  		auto add() -> std::size_t {
  			if (m_unused.empty()) {
  				m_streams.push_back(std::unique_ptr<std::ostringstream>(new std::ostringstream));
  				return m_streams.size() - 1;
  			}
  			else {
  				auto index = m_unused.back();
  				m_unused.pop_back();
  				return index;
  			}
  		}
  
  		void release(std::size_t index) {
  			m_streams[index]->copyfmt(m_referenceStream); // Restore initial flags and other state
  			m_unused.push_back(index);
  		}
  
  		// !TBD: put in TLS
  		static auto instance() -> StringStreams& {
  			if (!s_instance)
  				s_instance = new StringStreams();
  			return *s_instance;
  		}
  		static void cleanup() {
  			delete s_instance;
  			s_instance = nullptr;
  		}
  	};
  
  	StringStreams* StringStreams::s_instance = nullptr;
  
  	void ReusableStringStream::cleanup() {
  		StringStreams::cleanup();
  	}
  
  	ReusableStringStream::ReusableStringStream()
  		: m_index(StringStreams::instance().add()),
  		m_oss(StringStreams::instance().m_streams[m_index].get())
  	{}
  
  	ReusableStringStream::~ReusableStringStream() {
  		static_cast<std::ostringstream*>(m_oss)->str("");
  		m_oss->clear();
  		StringStreams::instance().release(m_index);
  	}
  
  	auto ReusableStringStream::str() const -> std::string {
  		return static_cast<std::ostringstream*>(m_oss)->str();
  	}
  
  	///////////////////////////////////////////////////////////////////////////
  
  #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
  	std::ostream& cout() { return std::cout; }
  	std::ostream& cerr() { return std::cerr; }
  	std::ostream& clog() { return std::clog; }
  #endif
  }
  
  #if defined(__clang__)
  #    pragma clang diagnostic pop
  #endif
  // end catch_stream.cpp
  // start catch_string_manip.cpp
  
  #include <algorithm>
  #include <ostream>
  #include <cstring>
  #include <cctype>
  
  namespace Catch {
  
  	bool startsWith(std::string const& s, std::string const& prefix) {
  		return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
  	}
  	bool startsWith(std::string const& s, char prefix) {
  		return !s.empty() && s[0] == prefix;
  	}
  	bool endsWith(std::string const& s, std::string const& suffix) {
  		return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
  	}
  	bool endsWith(std::string const& s, char suffix) {
  		return !s.empty() && s[s.size() - 1] == suffix;
  	}
  	bool contains(std::string const& s, std::string const& infix) {
  		return s.find(infix) != std::string::npos;
  	}
  	char toLowerCh(char c) {
  		return static_cast<char>(std::tolower(c));
  	}
  	void toLowerInPlace(std::string& s) {
  		std::transform(s.begin(), s.end(), s.begin(), toLowerCh);
  	}
  	std::string toLower(std::string const& s) {
  		std::string lc = s;
  		toLowerInPlace(lc);
  		return lc;
  	}
  	std::string trim(std::string const& str) {
  		static char const* whitespaceChars = "\n\r\t ";
  		std::string::size_type start = str.find_first_not_of(whitespaceChars);
  		std::string::size_type end = str.find_last_not_of(whitespaceChars);
  
  		return start != std::string::npos ? str.substr(start, 1 + end - start) : std::string();
  	}
  
  	bool replaceInPlace(std::string& str, std::string const& replaceThis, std::string const& withThis) {
  		bool replaced = false;
  		std::size_t i = str.find(replaceThis);
  		while (i != std::string::npos) {
  			replaced = true;
  			str = str.substr(0, i) + withThis + str.substr(i + replaceThis.size());
  			if (i < str.size() - withThis.size())
  				i = str.find(replaceThis, i + withThis.size());
  			else
  				i = std::string::npos;
  		}
  		return replaced;
  	}
  
  	pluralise::pluralise(std::size_t count, std::string const& label)
  		: m_count(count),
  		m_label(label)
  	{}
  
  	std::ostream& operator << (std::ostream& os, pluralise const& pluraliser) {
  		os << pluraliser.m_count << ' ' << pluraliser.m_label;
  		if (pluraliser.m_count != 1)
  			os << 's';
  		return os;
  	}
  
  }
  // end catch_string_manip.cpp
  // start catch_stringref.cpp
  
  #if defined(__clang__)
  #    pragma clang diagnostic push
  #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  #endif
  
  #include <ostream>
  #include <cstring>
  #include <cstdint>
  
  namespace {
  	const uint32_t byte_2_lead = 0xC0;
  	const uint32_t byte_3_lead = 0xE0;
  	const uint32_t byte_4_lead = 0xF0;
  }
  
  namespace Catch {
  	StringRef::StringRef(char const* rawChars) noexcept
  		: StringRef(rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars)))
  	{}
  
  	StringRef::operator std::string() const {
  		return std::string(m_start, m_size);
  	}
  
  	void StringRef::swap(StringRef& other) noexcept {
  		std::swap(m_start, other.m_start);
  		std::swap(m_size, other.m_size);
  		std::swap(m_data, other.m_data);
  	}
  
  	auto StringRef::c_str() const -> char const* {
  		if (isSubstring())
  			const_cast<StringRef*>(this)->takeOwnership();
  		return m_start;
  	}
  	auto StringRef::currentData() const noexcept -> char const* {
  		return m_start;
  	}
  
  	auto StringRef::isOwned() const noexcept -> bool {
  		return m_data != nullptr;
  	}
  	auto StringRef::isSubstring() const noexcept -> bool {
  		return m_start[m_size] != '\0';
  	}
  
  	void StringRef::takeOwnership() {
  		if (!isOwned()) {
  			m_data = new char[m_size + 1];
  			memcpy(m_data, m_start, m_size);
  			m_data[m_size] = '\0';
  			m_start = m_data;
  		}
  	}
  	auto StringRef::substr(size_type start, size_type size) const noexcept -> StringRef {
  		if (start < m_size)
  			return StringRef(m_start + start, size);
  		else
  			return StringRef();
  	}
  	auto StringRef::operator == (StringRef const& other) const noexcept -> bool {
  		return
  			size() == other.size() &&
  			(std::strncmp(m_start, other.m_start, size()) == 0);
  	}
  	auto StringRef::operator != (StringRef const& other) const noexcept -> bool {
  		return !operator==(other);
  	}
  
  	auto StringRef::operator[](size_type index) const noexcept -> char {
  		return m_start[index];
  	}
  
  	auto StringRef::numberOfCharacters() const noexcept -> size_type {
  		size_type noChars = m_size;
  		// Make adjustments for uft encodings
  		for (size_type i = 0; i < m_size; ++i) {
  			char c = m_start[i];
  			if ((c & byte_2_lead) == byte_2_lead) {
  				noChars--;
  				if ((c & byte_3_lead) == byte_3_lead)
  					noChars--;
  				if ((c & byte_4_lead) == byte_4_lead)
  					noChars--;
  			}
  		}
  		return noChars;
  	}
  
  	auto operator + (StringRef const& lhs, StringRef const& rhs) -> std::string {
  		std::string str;
  		str.reserve(lhs.size() + rhs.size());
  		str += lhs;
  		str += rhs;
  		return str;
  	}
  	auto operator + (StringRef const& lhs, const char* rhs) -> std::string {
  		return std::string(lhs) + std::string(rhs);
  	}
  	auto operator + (char const* lhs, StringRef const& rhs) -> std::string {
  		return std::string(lhs) + std::string(rhs);
  	}
  
  	auto operator << (std::ostream& os, StringRef const& str) -> std::ostream& {
  		return os.write(str.currentData(), str.size());
  	}
  
  	auto operator+=(std::string& lhs, StringRef const& rhs) -> std::string& {
  		lhs.append(rhs.currentData(), rhs.size());
  		return lhs;
  	}
  
  } // namespace Catch
  
  #if defined(__clang__)
  #    pragma clang diagnostic pop
  #endif
  // end catch_stringref.cpp
  // start catch_tag_alias.cpp
  
  namespace Catch {
  	TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo) : tag(_tag), lineInfo(_lineInfo) {}
  }
  // end catch_tag_alias.cpp
  // start catch_tag_alias_autoregistrar.cpp
  
  namespace Catch {
  
  	RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
  		try {
  			getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
  		}
  		catch (...) {
  			// Do not throw when constructing global objects, instead register the exception to be processed later
  			getMutableRegistryHub().registerStartupException();
  		}
  	}
  
  }
  // end catch_tag_alias_autoregistrar.cpp
  // start catch_tag_alias_registry.cpp
  
  #include <sstream>
  
  namespace Catch {
  
  	TagAliasRegistry::~TagAliasRegistry() {}
  
  	TagAlias const* TagAliasRegistry::find(std::string const& alias) const {
  		auto it = m_registry.find(alias);
  		if (it != m_registry.end())
  			return &(it->second);
  		else
  			return nullptr;
  	}
  
  	std::string TagAliasRegistry::expandAliases(std::string const& unexpandedTestSpec) const {
  		std::string expandedTestSpec = unexpandedTestSpec;
  		for (auto const& registryKvp : m_registry) {
  			std::size_t pos = expandedTestSpec.find(registryKvp.first);
  			if (pos != std::string::npos) {
  				expandedTestSpec = expandedTestSpec.substr(0, pos) +
  					registryKvp.second.tag +
  					expandedTestSpec.substr(pos + registryKvp.first.size());
  			}
  		}
  		return expandedTestSpec;
  	}
  
  	void TagAliasRegistry::add(std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo) {
  		CATCH_ENFORCE(startsWith(alias, "[@") && endsWith(alias, ']'),
  			"error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo);
  
  		CATCH_ENFORCE(m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
  			"error: tag alias, '" << alias << "' already registered.\n"
  			<< "\tFirst seen at: " << find(alias)->lineInfo << "\n"
  			<< "\tRedefined at: " << lineInfo);
  	}
  
  	ITagAliasRegistry::~ITagAliasRegistry() {}
  
  	ITagAliasRegistry const& ITagAliasRegistry::get() {
  		return getRegistryHub().getTagAliasRegistry();
  	}
  
  } // end namespace Catch
  // end catch_tag_alias_registry.cpp
  // start catch_test_case_info.cpp
  
  #include <cctype>
  #include <exception>
  #include <algorithm>
  #include <sstream>
  
  namespace Catch {
  
  	TestCaseInfo::SpecialProperties parseSpecialTag(std::string const& tag) {
  		if (startsWith(tag, '.') ||
  			tag == "!hide")
  			return TestCaseInfo::IsHidden;
  		else if (tag == "!throws")
  			return TestCaseInfo::Throws;
  		else if (tag == "!shouldfail")
  			return TestCaseInfo::ShouldFail;
  		else if (tag == "!mayfail")
  			return TestCaseInfo::MayFail;
  		else if (tag == "!nonportable")
  			return TestCaseInfo::NonPortable;
  		else if (tag == "!benchmark")
  			return static_cast<TestCaseInfo::SpecialProperties>(TestCaseInfo::Benchmark | TestCaseInfo::IsHidden);
  		else
  			return TestCaseInfo::None;
  	}
  	bool isReservedTag(std::string const& tag) {
  		return parseSpecialTag(tag) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum(tag[0]);
  	}
  	void enforceNotReservedTag(std::string const& tag, SourceLineInfo const& _lineInfo) {
  		CATCH_ENFORCE(!isReservedTag(tag),
  			"Tag name: [" << tag << "] is not allowed.\n"
  			<< "Tag names starting with non alpha-numeric characters are reserved\n"
  			<< _lineInfo);
  	}
  
  	TestCase makeTestCase(ITestInvoker* _testCase,
  		std::string const& _className,
  		NameAndTags const& nameAndTags,
  		SourceLineInfo const& _lineInfo)
  	{
  		bool isHidden = false;
  
  		// Parse out tags
  		std::vector<std::string> tags;
  		std::string desc, tag;
  		bool inTag = false;
  		std::string _descOrTags = nameAndTags.tags;
  		for (char c : _descOrTags) {
  			if (!inTag) {
  				if (c == '[')
  					inTag = true;
  				else
  					desc += c;
  			}
  			else {
  				if (c == ']') {
  					TestCaseInfo::SpecialProperties prop = parseSpecialTag(tag);
  					if ((prop & TestCaseInfo::IsHidden) != 0)
  						isHidden = true;
  					else if (prop == TestCaseInfo::None)
  						enforceNotReservedTag(tag, _lineInfo);
  
  					tags.push_back(tag);
  					tag.clear();
  					inTag = false;
  				}
  				else
  					tag += c;
  			}
  		}
  		if (isHidden) {
  			tags.push_back(".");
  		}
  
  		TestCaseInfo info(nameAndTags.name, _className, desc, tags, _lineInfo);
  		return TestCase(_testCase, std::move(info));
  	}
  
  	void setTags(TestCaseInfo& testCaseInfo, std::vector<std::string> tags) {
  		std::sort(begin(tags), end(tags));
  		tags.erase(std::unique(begin(tags), end(tags)), end(tags));
  		testCaseInfo.lcaseTags.clear();
  
  		for (auto const& tag : tags) {
  			std::string lcaseTag = toLower(tag);
  			testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>(testCaseInfo.properties | parseSpecialTag(lcaseTag));
  			testCaseInfo.lcaseTags.push_back(lcaseTag);
  		}
  		testCaseInfo.tags = std::move(tags);
  	}
  
  	TestCaseInfo::TestCaseInfo(std::string const& _name,
  		std::string const& _className,
  		std::string const& _description,
  		std::vector<std::string> const& _tags,
  		SourceLineInfo const& _lineInfo)
  		: name(_name),
  		className(_className),
  		description(_description),
  		lineInfo(_lineInfo),
  		properties(None)
  	{
  		setTags(*this, _tags);
  	}
  
  	bool TestCaseInfo::isHidden() const {
  		return (properties & IsHidden) != 0;
  	}
  	bool TestCaseInfo::throws() const {
  		return (properties & Throws) != 0;
  	}
  	bool TestCaseInfo::okToFail() const {
  		return (properties & (ShouldFail | MayFail)) != 0;
  	}
  	bool TestCaseInfo::expectedToFail() const {
  		return (properties & (ShouldFail)) != 0;
  	}
  
  	std::string TestCaseInfo::tagsAsString() const {
  		std::string ret;
  		// '[' and ']' per tag
  		std::size_t full_size = 2 * tags.size();
  		for (const auto& tag : tags) {
  			full_size += tag.size();
  		}
  		ret.reserve(full_size);
  		for (const auto& tag : tags) {
  			ret.push_back('[');
  			ret.append(tag);
  			ret.push_back(']');
  		}
  
  		return ret;
  	}
  
  	TestCase::TestCase(ITestInvoker* testCase, TestCaseInfo&& info) : TestCaseInfo(std::move(info)), test(testCase) {}
  
  	TestCase TestCase::withName(std::string const& _newName) const {
  		TestCase other(*this);
  		other.name = _newName;
  		return other;
  	}
  
  	void TestCase::invoke() const {
  		test->invoke();
  	}
  
  	bool TestCase::operator == (TestCase const& other) const {
  		return  test.get() == other.test.get() &&
  			name == other.name &&
  			className == other.className;
  	}
  
  	bool TestCase::operator < (TestCase const& other) const {
  		return name < other.name;
  	}
  
  	TestCaseInfo const& TestCase::getTestCaseInfo() const
  	{
  		return *this;
  	}
  
  } // end namespace Catch
  // end catch_test_case_info.cpp
  // start catch_test_case_registry_impl.cpp
  
  #include <sstream>
  
  namespace Catch {
  
  	std::vector<TestCase> sortTests(IConfig const& config, std::vector<TestCase> const& unsortedTestCases) {
  
  		std::vector<TestCase> sorted = unsortedTestCases;
  
  		switch (config.runOrder()) {
  		case RunTests::InLexicographicalOrder:
  			std::sort(sorted.begin(), sorted.end());
  			break;
  		case RunTests::InRandomOrder:
  			seedRng(config);
  			RandomNumberGenerator::shuffle(sorted);
  			break;
  		case RunTests::InDeclarationOrder:
  			// already in declaration order
  			break;
  		}
  		return sorted;
  	}
  	bool matchTest(TestCase const& testCase, TestSpec const& testSpec, IConfig const& config) {
  		return testSpec.matches(testCase) && (config.allowThrows() || !testCase.throws());
  	}
  
  	void enforceNoDuplicateTestCases(std::vector<TestCase> const& functions) {
  		std::set<TestCase> seenFunctions;
  		for (auto const& function : functions) {
  			auto prev = seenFunctions.insert(function);
  			CATCH_ENFORCE(prev.second,
  				"error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
  				<< "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
  				<< "\tRedefined at " << function.getTestCaseInfo().lineInfo);
  		}
  	}
  
  	std::vector<TestCase> filterTests(std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config) {
  		std::vector<TestCase> filtered;
  		filtered.reserve(testCases.size());
  		for (auto const& testCase : testCases)
  			if (matchTest(testCase, testSpec, config))
  				filtered.push_back(testCase);
  		return filtered;
  	}
  	std::vector<TestCase> const& getAllTestCasesSorted(IConfig const& config) {
  		return getRegistryHub().getTestCaseRegistry().getAllTestsSorted(config);
  	}
  
  	void TestRegistry::registerTest(TestCase const& testCase) {
  		std::string name = testCase.getTestCaseInfo().name;
  		if (name.empty()) {
  			ReusableStringStream rss;
  			rss << "Anonymous test case " << ++m_unnamedCount;
  			return registerTest(testCase.withName(rss.str()));
  		}
  		m_functions.push_back(testCase);
  	}
  
  	std::vector<TestCase> const& TestRegistry::getAllTests() const {
  		return m_functions;
  	}
  	std::vector<TestCase> const& TestRegistry::getAllTestsSorted(IConfig const& config) const {
  		if (m_sortedFunctions.empty())
  			enforceNoDuplicateTestCases(m_functions);
  
  		if (m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty()) {
  			m_sortedFunctions = sortTests(config, m_functions);
  			m_currentSortOrder = config.runOrder();
  		}
  		return m_sortedFunctions;
  	}
  
  	///////////////////////////////////////////////////////////////////////////
  	TestInvokerAsFunction::TestInvokerAsFunction(void(*testAsFunction)()) noexcept : m_testAsFunction(testAsFunction) {}
  
  	void TestInvokerAsFunction::invoke() const {
  		m_testAsFunction();
  	}
  
  	std::string extractClassName(StringRef const& classOrQualifiedMethodName) {
  		std::string className = classOrQualifiedMethodName;
  		if (startsWith(className, '&'))
  		{
  			std::size_t lastColons = className.rfind("::");
  			std::size_t penultimateColons = className.rfind("::", lastColons - 1);
  			if (penultimateColons == std::string::npos)
  				penultimateColons = 1;
  			className = className.substr(penultimateColons, lastColons - penultimateColons);
  		}
  		return className;
  	}
  
  } // end namespace Catch
  // end catch_test_case_registry_impl.cpp
  // start catch_test_case_tracker.cpp
  
  #include <algorithm>
  #include <assert.h>
  #include <stdexcept>
  #include <memory>
  #include <sstream>
  
  #if defined(__clang__)
  #    pragma clang diagnostic push
  #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  #endif
  
  namespace Catch {
  	namespace TestCaseTracking {
  
  		NameAndLocation::NameAndLocation(std::string const& _name, SourceLineInfo const& _location)
  			: name(_name),
  			location(_location)
  		{}
  
  		ITracker::~ITracker() = default;
  
  		TrackerContext& TrackerContext::instance() {
  			static TrackerContext s_instance;
  			return s_instance;
  		}
  
  		ITracker& TrackerContext::startRun() {
  			m_rootTracker = std::make_shared<SectionTracker>(NameAndLocation("{root}", CATCH_INTERNAL_LINEINFO), *this, nullptr);
  			m_currentTracker = nullptr;
  			m_runState = Executing;
  			return *m_rootTracker;
  		}
  
  		void TrackerContext::endRun() {
  			m_rootTracker.reset();
  			m_currentTracker = nullptr;
  			m_runState = NotStarted;
  		}
  
  		void TrackerContext::startCycle() {
  			m_currentTracker = m_rootTracker.get();
  			m_runState = Executing;
  		}
  		void TrackerContext::completeCycle() {
  			m_runState = CompletedCycle;
  		}
  
  		bool TrackerContext::completedCycle() const {
  			return m_runState == CompletedCycle;
  		}
  		ITracker& TrackerContext::currentTracker() {
  			return *m_currentTracker;
  		}
  		void TrackerContext::setCurrentTracker(ITracker* tracker) {
  			m_currentTracker = tracker;
  		}
  
  		TrackerBase::TrackerHasName::TrackerHasName(NameAndLocation const& nameAndLocation) : m_nameAndLocation(nameAndLocation) {}
  		bool TrackerBase::TrackerHasName::operator ()(ITrackerPtr const& tracker) const {
  			return
  				tracker->nameAndLocation().name == m_nameAndLocation.name &&
  				tracker->nameAndLocation().location == m_nameAndLocation.location;
  		}
  
  		TrackerBase::TrackerBase(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent)
  			: m_nameAndLocation(nameAndLocation),
  			m_ctx(ctx),
  			m_parent(parent)
  		{}
  
  		NameAndLocation const& TrackerBase::nameAndLocation() const {
  			return m_nameAndLocation;
  		}
  		bool TrackerBase::isComplete() const {
  			return m_runState == CompletedSuccessfully || m_runState == Failed;
  		}
  		bool TrackerBase::isSuccessfullyCompleted() const {
  			return m_runState == CompletedSuccessfully;
  		}
  		bool TrackerBase::isOpen() const {
  			return m_runState != NotStarted && !isComplete();
  		}
  		bool TrackerBase::hasChildren() const {
  			return !m_children.empty();
  		}
  
  		void TrackerBase::addChild(ITrackerPtr const& child) {
  			m_children.push_back(child);
  		}
  
  		ITrackerPtr TrackerBase::findChild(NameAndLocation const& nameAndLocation) {
  			auto it = std::find_if(m_children.begin(), m_children.end(), TrackerHasName(nameAndLocation));
  			return(it != m_children.end())
  				? *it
  				: nullptr;
  		}
  		ITracker& TrackerBase::parent() {
  			assert(m_parent); // Should always be non-null except for root
  			return *m_parent;
  		}
  
  		void TrackerBase::openChild() {
  			if (m_runState != ExecutingChildren) {
  				m_runState = ExecutingChildren;
  				if (m_parent)
  					m_parent->openChild();
  			}
  		}
  
  		bool TrackerBase::isSectionTracker() const { return false; }
  		bool TrackerBase::isIndexTracker() const { return false; }
  
  		void TrackerBase::open() {
  			m_runState = Executing;
  			moveToThis();
  			if (m_parent)
  				m_parent->openChild();
  		}
  
  		void TrackerBase::close() {
  
  			// Close any still open children (e.g. generators)
  			while (&m_ctx.currentTracker() != this)
  				m_ctx.currentTracker().close();
  
  			switch (m_runState) {
  			case NeedsAnotherRun:
  				break;
  
  			case Executing:
  				m_runState = CompletedSuccessfully;
  				break;
  			case ExecutingChildren:
  				if (m_children.empty() || m_children.back()->isComplete())
  					m_runState = CompletedSuccessfully;
  				break;
  
  			case NotStarted:
  			case CompletedSuccessfully:
  			case Failed:
  				CATCH_INTERNAL_ERROR("Illogical state: " << m_runState);
  
  			default:
  				CATCH_INTERNAL_ERROR("Unknown state: " << m_runState);
  			}
  			moveToParent();
  			m_ctx.completeCycle();
  		}
  		void TrackerBase::fail() {
  			m_runState = Failed;
  			if (m_parent)
  				m_parent->markAsNeedingAnotherRun();
  			moveToParent();
  			m_ctx.completeCycle();
  		}
  		void TrackerBase::markAsNeedingAnotherRun() {
  			m_runState = NeedsAnotherRun;
  		}
  
  		void TrackerBase::moveToParent() {
  			assert(m_parent);
  			m_ctx.setCurrentTracker(m_parent);
  		}
  		void TrackerBase::moveToThis() {
  			m_ctx.setCurrentTracker(this);
  		}
  
  		SectionTracker::SectionTracker(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent)
  			: TrackerBase(nameAndLocation, ctx, parent)
  		{
  			if (parent) {
  				while (!parent->isSectionTracker())
  					parent = &parent->parent();
  
  				SectionTracker& parentSection = static_cast<SectionTracker&>(*parent);
  				addNextFilters(parentSection.m_filters);
  			}
  		}
  
  		bool SectionTracker::isSectionTracker() const { return true; }
  
  		SectionTracker& SectionTracker::acquire(TrackerContext& ctx, NameAndLocation const& nameAndLocation) {
  			std::shared_ptr<SectionTracker> section;
  
  			ITracker& currentTracker = ctx.currentTracker();
  			if (ITrackerPtr childTracker = currentTracker.findChild(nameAndLocation)) {
  				assert(childTracker);
  				assert(childTracker->isSectionTracker());
  				section = std::static_pointer_cast<SectionTracker>(childTracker);
  			}
  			else {
  				section = std::make_shared<SectionTracker>(nameAndLocation, ctx, &currentTracker);
  				currentTracker.addChild(section);
  			}
  			if (!ctx.completedCycle())
  				section->tryOpen();
  			return *section;
  		}
  
  		void SectionTracker::tryOpen() {
  			if (!isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name))
  				open();
  		}
  
  		void SectionTracker::addInitialFilters(std::vector<std::string> const& filters) {
  			if (!filters.empty()) {
  				m_filters.push_back(""); // Root - should never be consulted
  				m_filters.push_back(""); // Test Case - not a section filter
  				m_filters.insert(m_filters.end(), filters.begin(), filters.end());
  			}
  		}
  		void SectionTracker::addNextFilters(std::vector<std::string> const& filters) {
  			if (filters.size() > 1)
  				m_filters.insert(m_filters.end(), ++filters.begin(), filters.end());
  		}
  
  		IndexTracker::IndexTracker(NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size)
  			: TrackerBase(nameAndLocation, ctx, parent),
  			m_size(size)
  		{}
  
  		bool IndexTracker::isIndexTracker() const { return true; }
  
  		IndexTracker& IndexTracker::acquire(TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size) {
  			std::shared_ptr<IndexTracker> tracker;
  
  			ITracker& currentTracker = ctx.currentTracker();
  			if (ITrackerPtr childTracker = currentTracker.findChild(nameAndLocation)) {
  				assert(childTracker);
  				assert(childTracker->isIndexTracker());
  				tracker = std::static_pointer_cast<IndexTracker>(childTracker);
  			}
  			else {
  				tracker = std::make_shared<IndexTracker>(nameAndLocation, ctx, &currentTracker, size);
  				currentTracker.addChild(tracker);
  			}
  
  			if (!ctx.completedCycle() && !tracker->isComplete()) {
  				if (tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun)
  					tracker->moveNext();
  				tracker->open();
  			}
  
  			return *tracker;
  		}
  
  		int IndexTracker::index() const { return m_index; }
  
  		void IndexTracker::moveNext() {
  			m_index++;
  			m_children.clear();
  		}
  
  		void IndexTracker::close() {
  			TrackerBase::close();
  			if (m_runState == CompletedSuccessfully && m_index < m_size - 1)
  				m_runState = Executing;
  		}
  
  	} // namespace TestCaseTracking
  
  	using TestCaseTracking::ITracker;
  	using TestCaseTracking::TrackerContext;
  	using TestCaseTracking::SectionTracker;
  	using TestCaseTracking::IndexTracker;
  
  } // namespace Catch
  
  #if defined(__clang__)
  #    pragma clang diagnostic pop
  #endif
  // end catch_test_case_tracker.cpp
  // start catch_test_registry.cpp
  
  namespace Catch {
  
  	auto makeTestInvoker(void(*testAsFunction)()) noexcept -> ITestInvoker* {
  		return new(std::nothrow) TestInvokerAsFunction(testAsFunction);
  	}
  
  	NameAndTags::NameAndTags(StringRef const& name_, StringRef const& tags_) noexcept : name(name_), tags(tags_) {}
  
  	AutoReg::AutoReg(ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags) noexcept {
  		try {
  			getMutableRegistryHub()
  				.registerTest(
  					makeTestCase(
  						invoker,
  						extractClassName(classOrMethod),
  						nameAndTags,
  						lineInfo));
  		}
  		catch (...) {
  			// Do not throw when constructing global objects, instead register the exception to be processed later
  			getMutableRegistryHub().registerStartupException();
  		}
  	}
  
  	AutoReg::~AutoReg() = default;
  }
  // end catch_test_registry.cpp
  // start catch_test_spec.cpp
  
  #include <algorithm>
  #include <string>
  #include <vector>
  #include <memory>
  
  namespace Catch {
  
  	TestSpec::Pattern::~Pattern() = default;
  	TestSpec::NamePattern::~NamePattern() = default;
  	TestSpec::TagPattern::~TagPattern() = default;
  	TestSpec::ExcludedPattern::~ExcludedPattern() = default;
  
  	TestSpec::NamePattern::NamePattern(std::string const& name)
  		: m_wildcardPattern(toLower(name), CaseSensitive::No)
  	{}
  	bool TestSpec::NamePattern::matches(TestCaseInfo const& testCase) const {
  		return m_wildcardPattern.matches(toLower(testCase.name));
  	}
  
  	TestSpec::TagPattern::TagPattern(std::string const& tag) : m_tag(toLower(tag)) {}
  	bool TestSpec::TagPattern::matches(TestCaseInfo const& testCase) const {
  		return std::find(begin(testCase.lcaseTags),
  			end(testCase.lcaseTags),
  			m_tag) != end(testCase.lcaseTags);
  	}
  
  	TestSpec::ExcludedPattern::ExcludedPattern(PatternPtr const& underlyingPattern) : m_underlyingPattern(underlyingPattern) {}
  	bool TestSpec::ExcludedPattern::matches(TestCaseInfo const& testCase) const { return !m_underlyingPattern->matches(testCase); }
  
  	bool TestSpec::Filter::matches(TestCaseInfo const& testCase) const {
  		// All patterns in a filter must match for the filter to be a match
  		for (auto const& pattern : m_patterns) {
  			if (!pattern->matches(testCase))
  				return false;
  		}
  		return true;
  	}
  
  	bool TestSpec::hasFilters() const {
  		return !m_filters.empty();
  	}
  	bool TestSpec::matches(TestCaseInfo const& testCase) const {
  		// A TestSpec matches if any filter matches
  		for (auto const& filter : m_filters)
  			if (filter.matches(testCase))
  				return true;
  		return false;
  	}
  }
  // end catch_test_spec.cpp
  // start catch_test_spec_parser.cpp
  
  namespace Catch {
  
  	TestSpecParser::TestSpecParser(ITagAliasRegistry const& tagAliases) : m_tagAliases(&tagAliases) {}
  
  	TestSpecParser& TestSpecParser::parse(std::string const& arg) {
  		m_mode = None;
  		m_exclusion = false;
  		m_start = std::string::npos;
  		m_arg = m_tagAliases->expandAliases(arg);
  		m_escapeChars.clear();
  		for (m_pos = 0; m_pos < m_arg.size(); ++m_pos)
  			visitChar(m_arg[m_pos]);
  		if (m_mode == Name)
  			addPattern<TestSpec::NamePattern>();
  		return *this;
  	}
  	TestSpec TestSpecParser::testSpec() {
  		addFilter();
  		return m_testSpec;
  	}
  
  	void TestSpecParser::visitChar(char c) {
  		if (m_mode == None) {
  			switch (c) {
  			case ' ': return;
  			case '~': m_exclusion = true; return;
  			case '[': return startNewMode(Tag, ++m_pos);
  			case '"': return startNewMode(QuotedName, ++m_pos);
  			case '\\': return escape();
  			default: startNewMode(Name, m_pos); break;
  			}
  		}
  		if (m_mode == Name) {
  			if (c == ',') {
  				addPattern<TestSpec::NamePattern>();
  				addFilter();
  			}
  			else if (c == '[') {
  				if (subString() == "exclude:")
  					m_exclusion = true;
  				else
  					addPattern<TestSpec::NamePattern>();
  				startNewMode(Tag, ++m_pos);
  			}
  			else if (c == '\\')
  				escape();
  		}
  		else if (m_mode == EscapedName)
  			m_mode = Name;
  		else if (m_mode == QuotedName && c == '"')
  			addPattern<TestSpec::NamePattern>();
  		else if (m_mode == Tag && c == ']')
  			addPattern<TestSpec::TagPattern>();
  	}
  	void TestSpecParser::startNewMode(Mode mode, std::size_t start) {
  		m_mode = mode;
  		m_start = start;
  	}
  	void TestSpecParser::escape() {
  		if (m_mode == None)
  			m_start = m_pos;
  		m_mode = EscapedName;
  		m_escapeChars.push_back(m_pos);
  	}
  	std::string TestSpecParser::subString() const { return m_arg.substr(m_start, m_pos - m_start); }
  
  	void TestSpecParser::addFilter() {
  		if (!m_currentFilter.m_patterns.empty()) {
  			m_testSpec.m_filters.push_back(m_currentFilter);
  			m_currentFilter = TestSpec::Filter();
  		}
  	}
  
  	TestSpec parseTestSpec(std::string const& arg) {
  		return TestSpecParser(ITagAliasRegistry::get()).parse(arg).testSpec();
  	}
  
  } // namespace Catch
  // end catch_test_spec_parser.cpp
  // start catch_timer.cpp
  
  #include <chrono>
  
  static const uint64_t nanosecondsInSecond = 1000000000;
  
  namespace Catch {
  
  	auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
  		return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
  	}
  
  	auto estimateClockResolution() -> uint64_t {
  		uint64_t sum = 0;
  		static const uint64_t iterations = 1000000;
  
  		auto startTime = getCurrentNanosecondsSinceEpoch();
  
  		for (std::size_t i = 0; i < iterations; ++i) {
  
  			uint64_t ticks;
  			uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
  			do {
  				ticks = getCurrentNanosecondsSinceEpoch();
  			} while (ticks == baseTicks);
  
  			auto delta = ticks - baseTicks;
  			sum += delta;
  
  			// If we have been calibrating for over 3 seconds -- the clock
  			// is terrible and we should move on.
  			// TBD: How to signal that the measured resolution is probably wrong?
  			if (ticks > startTime + 3 * nanosecondsInSecond) {
  				return sum / i;
  			}
  		}
  
  		// We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
  		// - and potentially do more iterations if there's a high variance.
  		return sum / iterations;
  	}
  	auto getEstimatedClockResolution() -> uint64_t {
  		static auto s_resolution = estimateClockResolution();
  		return s_resolution;
  	}
  
  	void Timer::start() {
  		m_nanoseconds = getCurrentNanosecondsSinceEpoch();
  	}
  	auto Timer::getElapsedNanoseconds() const -> uint64_t {
  		return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
  	}
  	auto Timer::getElapsedMicroseconds() const -> uint64_t {
  		return getElapsedNanoseconds() / 1000;
  	}
  	auto Timer::getElapsedMilliseconds() const -> unsigned int {
  		return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);
  	}
  	auto Timer::getElapsedSeconds() const -> double {
  		return getElapsedMicroseconds() / 1000000.0;
  	}
  
  } // namespace Catch
  // end catch_timer.cpp
  // start catch_tostring.cpp
  
  #if defined(__clang__)
  #    pragma clang diagnostic push
  #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  #    pragma clang diagnostic ignored "-Wglobal-constructors"
  #endif
  
  // Enable specific decls locally
  #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  #endif
  
  #include <cmath>
  #include <iomanip>
  
  namespace Catch {
  
  	namespace Detail {
  
  		const std::string unprintableString = "{?}";
  
  		namespace {
  			const int hexThreshold = 255;
  
  			struct Endianness {
  				enum Arch { Big, Little };
  
  				static Arch which() {
  					union _ {
  						int asInt;
  						char asChar[sizeof(int)];
  					} u;
  
  					u.asInt = 1;
  					return (u.asChar[sizeof(int) - 1] == 1) ? Big : Little;
  				}
  			};
  		}
  
  		std::string rawMemoryToString(const void *object, std::size_t size) {
  			// Reverse order for little endian architectures
  			int i = 0, end = static_cast<int>(size), inc = 1;
  			if (Endianness::which() == Endianness::Little) {
  				i = end - 1;
  				end = inc = -1;
  			}
  
  			unsigned char const *bytes = static_cast<unsigned char const *>(object);
  			ReusableStringStream rss;
  			rss << "0x" << std::setfill('0') << std::hex;
  			for (; i != end; i += inc)
  				rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
  			return rss.str();
  		}
  	}
  
  	template<typename T>
  	std::string fpToString(T value, int precision) {
  		if (std::isnan(value)) {
  			return "nan";
  		}
  
  		ReusableStringStream rss;
  		rss << std::setprecision(precision)
  			<< std::fixed
  			<< value;
  		std::string d = rss.str();
  		std::size_t i = d.find_last_not_of('0');
  		if (i != std::string::npos && i != d.size() - 1) {
  			if (d[i] == '.')
  				i++;
  			d = d.substr(0, i + 1);
  		}
  		return d;
  	}
  
  	//// ======================================================= ////
  	//
  	//   Out-of-line defs for full specialization of StringMaker
  	//
  	//// ======================================================= ////
  
  	std::string StringMaker<std::string>::convert(const std::string& str) {
  		if (!getCurrentContext().getConfig()->showInvisibles()) {
  			return '"' + str + '"';
  		}
  
  		std::string s("\"");
  		for (char c : str) {
  			switch (c) {
  			case '\n':
  				s.append("\\n");
  				break;
  			case '\t':
  				s.append("\\t");
  				break;
  			default:
  				s.push_back(c);
  				break;
  			}
  		}
  		s.append("\"");
  		return s;
  	}
  
  #ifdef CATCH_CONFIG_WCHAR
  	std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
  		std::string s;
  		s.reserve(wstr.size());
  		for (auto c : wstr) {
  			s += (c <= 0xff) ? static_cast<char>(c) : '?';
  		}
  		return ::Catch::Detail::stringify(s);
  	}
  #endif
  
  	std::string StringMaker<char const*>::convert(char const* str) {
  		if (str) {
  			return ::Catch::Detail::stringify(std::string{ str });
  		}
  		else {
  			return{ "{null string}" };
  		}
  	}
  	std::string StringMaker<char*>::convert(char* str) {
  		if (str) {
  			return ::Catch::Detail::stringify(std::string{ str });
  		}
  		else {
  			return{ "{null string}" };
  		}
  	}
  #ifdef CATCH_CONFIG_WCHAR
  	std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
  		if (str) {
  			return ::Catch::Detail::stringify(std::wstring{ str });
  		}
  		else {
  			return{ "{null string}" };
  		}
  	}
  	std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
  		if (str) {
  			return ::Catch::Detail::stringify(std::wstring{ str });
  		}
  		else {
  			return{ "{null string}" };
  		}
  	}
  #endif
  
  	std::string StringMaker<int>::convert(int value) {
  		return ::Catch::Detail::stringify(static_cast<long long>(value));
  	}
  	std::string StringMaker<long>::convert(long value) {
  		return ::Catch::Detail::stringify(static_cast<long long>(value));
  	}
  	std::string StringMaker<long long>::convert(long long value) {
  		ReusableStringStream rss;
  		rss << value;
  		if (value > Detail::hexThreshold) {
  			rss << " (0x" << std::hex << value << ')';
  		}
  		return rss.str();
  	}
  
  	std::string StringMaker<unsigned int>::convert(unsigned int value) {
  		return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  	}
  	std::string StringMaker<unsigned long>::convert(unsigned long value) {
  		return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  	}
  	std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
  		ReusableStringStream rss;
  		rss << value;
  		if (value > Detail::hexThreshold) {
  			rss << " (0x" << std::hex << value << ')';
  		}
  		return rss.str();
  	}
  
  	std::string StringMaker<bool>::convert(bool b) {
  		return b ? "true" : "false";
  	}
  
  	std::string StringMaker<char>::convert(char value) {
  		if (value == '\r') {
  			return "'\\r'";
  		}
  		else if (value == '\f') {
  			return "'\\f'";
  		}
  		else if (value == '\n') {
  			return "'\\n'";
  		}
  		else if (value == '\t') {
  			return "'\\t'";
  		}
  		else if ('\0' <= value && value < ' ') {
  			return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
  		}
  		else {
  			char chstr[] = "' '";
  			chstr[1] = value;
  			return chstr;
  		}
  	}
  	std::string StringMaker<signed char>::convert(signed char c) {
  		return ::Catch::Detail::stringify(static_cast<char>(c));
  	}
  	std::string StringMaker<unsigned char>::convert(unsigned char c) {
  		return ::Catch::Detail::stringify(static_cast<char>(c));
  	}
  
  	std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
  		return "nullptr";
  	}
  
  	std::string StringMaker<float>::convert(float value) {
  		return fpToString(value, 5) + 'f';
  	}
  	std::string StringMaker<double>::convert(double value) {
  		return fpToString(value, 10);
  	}
  
  	std::string ratio_string<std::atto>::symbol() { return "a"; }
  	std::string ratio_string<std::femto>::symbol() { return "f"; }
  	std::string  ratio_string<std::pico>::symbol() { return "p"; }
  	std::string  ratio_string<std::nano>::symbol() { return "n"; }
  	std::string ratio_string<std::micro>::symbol() { return "u"; }
  	std::string ratio_string<std::milli>::symbol() { return "m"; }
  
  } // end namespace Catch
  
  #if defined(__clang__)
  #    pragma clang diagnostic pop
  #endif
  
  // end catch_tostring.cpp
  // start catch_totals.cpp
  
  namespace Catch {
  
  	Counts Counts::operator - (Counts const& other) const {
  		Counts diff;
  		diff.passed = passed - other.passed;
  		diff.failed = failed - other.failed;
  		diff.failedButOk = failedButOk - other.failedButOk;
  		return diff;
  	}
  
  	Counts& Counts::operator += (Counts const& other) {
  		passed += other.passed;
  		failed += other.failed;
  		failedButOk += other.failedButOk;
  		return *this;
  	}
  
  	std::size_t Counts::total() const {
  		return passed + failed + failedButOk;
  	}
  	bool Counts::allPassed() const {
  		return failed == 0 && failedButOk == 0;
  	}
  	bool Counts::allOk() const {
  		return failed == 0;
  	}
  
  	Totals Totals::operator - (Totals const& other) const {
  		Totals diff;
  		diff.assertions = assertions - other.assertions;
  		diff.testCases = testCases - other.testCases;
  		return diff;
  	}
  
  	Totals& Totals::operator += (Totals const& other) {
  		assertions += other.assertions;
  		testCases += other.testCases;
  		return *this;
  	}
  
  	Totals Totals::delta(Totals const& prevTotals) const {
  		Totals diff = *this - prevTotals;
  		if (diff.assertions.failed > 0)
  			++diff.testCases.failed;
  		else if (diff.assertions.failedButOk > 0)
  			++diff.testCases.failedButOk;
  		else
  			++diff.testCases.passed;
  		return diff;
  	}
  
  }
  // end catch_totals.cpp
  // start catch_uncaught_exceptions.cpp
  
  #include <exception>
  
  namespace Catch {
  	bool uncaught_exceptions() {
  #if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
  		return std::uncaught_exceptions() > 0;
  #else
  		return std::uncaught_exception();
  #endif
  	}
  } // end namespace Catch
  // end catch_uncaught_exceptions.cpp
  // start catch_version.cpp
  
  #include <ostream>
  
  namespace Catch {
  
  	Version::Version
  	(unsigned int _majorVersion,
  		unsigned int _minorVersion,
  		unsigned int _patchNumber,
  		char const * const _branchName,
  		unsigned int _buildNumber)
  		: majorVersion(_majorVersion),
  		minorVersion(_minorVersion),
  		patchNumber(_patchNumber),
  		branchName(_branchName),
  		buildNumber(_buildNumber)
  	{}
  
  	std::ostream& operator << (std::ostream& os, Version const& version) {
  		os << version.majorVersion << '.'
  			<< version.minorVersion << '.'
  			<< version.patchNumber;
  		// branchName is never null -> 0th char is \0 if it is empty
  		if (version.branchName[0]) {
  			os << '-' << version.branchName
  				<< '.' << version.buildNumber;
  		}
  		return os;
  	}
  
  	Version const& libraryVersion() {
  		static Version version(2, 2, 2, "", 0);
  		return version;
  	}
  
  }
  // end catch_version.cpp
  // start catch_wildcard_pattern.cpp
  
  #include <sstream>
  
  namespace Catch {
  
  	WildcardPattern::WildcardPattern(std::string const& pattern,
  		CaseSensitive::Choice caseSensitivity)
  		: m_caseSensitivity(caseSensitivity),
  		m_pattern(adjustCase(pattern))
  	{
  		if (startsWith(m_pattern, '*')) {
  			m_pattern = m_pattern.substr(1);
  			m_wildcard = WildcardAtStart;
  		}
  		if (endsWith(m_pattern, '*')) {
  			m_pattern = m_pattern.substr(0, m_pattern.size() - 1);
  			m_wildcard = static_cast<WildcardPosition>(m_wildcard | WildcardAtEnd);
  		}
  	}
  
  	bool WildcardPattern::matches(std::string const& str) const {
  		switch (m_wildcard) {
  		case NoWildcard:
  			return m_pattern == adjustCase(str);
  		case WildcardAtStart:
  			return endsWith(adjustCase(str), m_pattern);
  		case WildcardAtEnd:
  			return startsWith(adjustCase(str), m_pattern);
  		case WildcardAtBothEnds:
  			return contains(adjustCase(str), m_pattern);
  		default:
  			CATCH_INTERNAL_ERROR("Unknown enum");
  		}
  	}
  
  	std::string WildcardPattern::adjustCase(std::string const& str) const {
  		return m_caseSensitivity == CaseSensitive::No ? toLower(str) : str;
  	}
  }
  // end catch_wildcard_pattern.cpp
  // start catch_xmlwriter.cpp
  
  #include <iomanip>
  
  using uchar = unsigned char;
  
  namespace Catch {
  
  	namespace {
  
  		size_t trailingBytes(unsigned char c) {
  			if ((c & 0xE0) == 0xC0) {
  				return 2;
  			}
  			if ((c & 0xF0) == 0xE0) {
  				return 3;
  			}
  			if ((c & 0xF8) == 0xF0) {
  				return 4;
  			}
  			CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  		}
  
  		uint32_t headerValue(unsigned char c) {
  			if ((c & 0xE0) == 0xC0) {
  				return c & 0x1F;
  			}
  			if ((c & 0xF0) == 0xE0) {
  				return c & 0x0F;
  			}
  			if ((c & 0xF8) == 0xF0) {
  				return c & 0x07;
  			}
  			CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  		}
  
  		void hexEscapeChar(std::ostream& os, unsigned char c) {
  			os << "\\x"
  				<< std::uppercase << std::hex << std::setfill('0') << std::setw(2)
  				<< static_cast<int>(c);
  		}
  
  	} // anonymous namespace
  
  	XmlEncode::XmlEncode(std::string const& str, ForWhat forWhat)
  		: m_str(str),
  		m_forWhat(forWhat)
  	{}
  
  	void XmlEncode::encodeTo(std::ostream& os) const {
  		// Apostrophe escaping not necessary if we always use " to write attributes
  		// (see: http://www.w3.org/TR/xml/#syntax)
  
  		for (std::size_t idx = 0; idx < m_str.size(); ++idx) {
  			uchar c = m_str[idx];
  			switch (c) {
  			case '<':   os << "&lt;"; break;
  			case '&':   os << "&amp;"; break;
  
  			case '>':
  				// See: http://www.w3.org/TR/xml/#syntax
  				if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
  					os << "&gt;";
  				else
  					os << c;
  				break;
  
  			case '\"':
  				if (m_forWhat == ForAttributes)
  					os << "&quot;";
  				else
  					os << c;
  				break;
  
  			default:
  				// Check for control characters and invalid utf-8
  
  				// Escape control characters in standard ascii
  				// see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
  				if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
  					hexEscapeChar(os, c);
  					break;
  				}
  
  				// Plain ASCII: Write it to stream
  				if (c < 0x7F) {
  					os << c;
  					break;
  				}
  
  				// UTF-8 territory
  				// Check if the encoding is valid and if it is not, hex escape bytes.
  				// Important: We do not check the exact decoded values for validity, only the encoding format
  				// First check that this bytes is a valid lead byte:
  				// This means that it is not encoded as 1111 1XXX
  				// Or as 10XX XXXX
  				if (c < 0xC0 ||
  					c >= 0xF8) {
  					hexEscapeChar(os, c);
  					break;
  				}
  
  				auto encBytes = trailingBytes(c);
  				// Are there enough bytes left to avoid accessing out-of-bounds memory?
  				if (idx + encBytes - 1 >= m_str.size()) {
  					hexEscapeChar(os, c);
  					break;
  				}
  				// The header is valid, check data
  				// The next encBytes bytes must together be a valid utf-8
  				// This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
  				bool valid = true;
  				uint32_t value = headerValue(c);
  				for (std::size_t n = 1; n < encBytes; ++n) {
  					uchar nc = m_str[idx + n];
  					valid &= ((nc & 0xC0) == 0x80);
  					value = (value << 6) | (nc & 0x3F);
  				}
  
  				if (
  					// Wrong bit pattern of following bytes
  					(!valid) ||
  					// Overlong encodings
  					(value < 0x80) ||
  					(0x80 <= value && value < 0x800 && encBytes > 2) ||
  					(0x800 < value && value < 0x10000 && encBytes > 3) ||
  					// Encoded value out of range
  					(value >= 0x110000)
  					) {
  					hexEscapeChar(os, c);
  					break;
  				}
  
  				// If we got here, this is in fact a valid(ish) utf-8 sequence
  				for (std::size_t n = 0; n < encBytes; ++n) {
  					os << m_str[idx + n];
  				}
  				idx += encBytes - 1;
  				break;
  			}
  		}
  	}
  
  	std::ostream& operator << (std::ostream& os, XmlEncode const& xmlEncode) {
  		xmlEncode.encodeTo(os);
  		return os;
  	}
  
  	XmlWriter::ScopedElement::ScopedElement(XmlWriter* writer)
  		: m_writer(writer)
  	{}
  
  	XmlWriter::ScopedElement::ScopedElement(ScopedElement&& other) noexcept
  		: m_writer(other.m_writer) {
  		other.m_writer = nullptr;
  	}
  	XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=(ScopedElement&& other) noexcept {
  		if (m_writer) {
  			m_writer->endElement();
  		}
  		m_writer = other.m_writer;
  		other.m_writer = nullptr;
  		return *this;
  	}
  
  	XmlWriter::ScopedElement::~ScopedElement() {
  		if (m_writer)
  			m_writer->endElement();
  	}
  
  	XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText(std::string const& text, bool indent) {
  		m_writer->writeText(text, indent);
  		return *this;
  	}
  
  	XmlWriter::XmlWriter(std::ostream& os) : m_os(os)
  	{
  		writeDeclaration();
  	}
  
  	XmlWriter::~XmlWriter() {
  		while (!m_tags.empty())
  			endElement();
  	}
  
  	XmlWriter& XmlWriter::startElement(std::string const& name) {
  		ensureTagClosed();
  		newlineIfNecessary();
  		m_os << m_indent << '<' << name;
  		m_tags.push_back(name);
  		m_indent += "  ";
  		m_tagIsOpen = true;
  		return *this;
  	}
  
  	XmlWriter::ScopedElement XmlWriter::scopedElement(std::string const& name) {
  		ScopedElement scoped(this);
  		startElement(name);
  		return scoped;
  	}
  
  	XmlWriter& XmlWriter::endElement() {
  		newlineIfNecessary();
  		m_indent = m_indent.substr(0, m_indent.size() - 2);
  		if (m_tagIsOpen) {
  			m_os << "/>";
  			m_tagIsOpen = false;
  		}
  		else {
  			m_os << m_indent << "</" << m_tags.back() << ">";
  		}
  		m_os << std::endl;
  		m_tags.pop_back();
  		return *this;
  	}
  
  	XmlWriter& XmlWriter::writeAttribute(std::string const& name, std::string const& attribute) {
  		if (!name.empty() && !attribute.empty())
  			m_os << ' ' << name << "=\"" << XmlEncode(attribute, XmlEncode::ForAttributes) << '"';
  		return *this;
  	}
  
  	XmlWriter& XmlWriter::writeAttribute(std::string const& name, bool attribute) {
  		m_os << ' ' << name << "=\"" << (attribute ? "true" : "false") << '"';
  		return *this;
  	}
  
  	XmlWriter& XmlWriter::writeText(std::string const& text, bool indent) {
  		if (!text.empty()) {
  			bool tagWasOpen = m_tagIsOpen;
  			ensureTagClosed();
  			if (tagWasOpen && indent)
  				m_os << m_indent;
  			m_os << XmlEncode(text);
  			m_needsNewline = true;
  		}
  		return *this;
  	}
  
  	XmlWriter& XmlWriter::writeComment(std::string const& text) {
  		ensureTagClosed();
  		m_os << m_indent << "<!--" << text << "-->";
  		m_needsNewline = true;
  		return *this;
  	}
  
  	void XmlWriter::writeStylesheetRef(std::string const& url) {
  		m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
  	}
  
  	XmlWriter& XmlWriter::writeBlankLine() {
  		ensureTagClosed();
  		m_os << '\n';
  		return *this;
  	}
  
  	void XmlWriter::ensureTagClosed() {
  		if (m_tagIsOpen) {
  			m_os << ">" << std::endl;
  			m_tagIsOpen = false;
  		}
  	}
  
  	void XmlWriter::writeDeclaration() {
  		m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  	}
  
  	void XmlWriter::newlineIfNecessary() {
  		if (m_needsNewline) {
  			m_os << std::endl;
  			m_needsNewline = false;
  		}
  	}
  }
  // end catch_xmlwriter.cpp
  // start catch_reporter_bases.cpp
  
  #include <cstring>
  #include <cfloat>
  #include <cstdio>
  #include <assert.h>
  #include <memory>
  
  namespace Catch {
  	void prepareExpandedExpression(AssertionResult& result) {
  		result.getExpandedExpression();
  	}
  
  	// Because formatting using c++ streams is stateful, drop down to C is required
  	// Alternatively we could use stringstream, but its performance is... not good.
  	std::string getFormattedDuration(double duration) {
  		// Max exponent + 1 is required to represent the whole part
  		// + 1 for decimal point
  		// + 3 for the 3 decimal places
  		// + 1 for null terminator
  		const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
  		char buffer[maxDoubleSize];
  
  		// Save previous errno, to prevent sprintf from overwriting it
  		ErrnoGuard guard;
  #ifdef _MSC_VER
  		sprintf_s(buffer, "%.3f", duration);
  #else
  		sprintf(buffer, "%.3f", duration);
  #endif
  		return std::string(buffer);
  	}
  
  	TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
  		:StreamingReporterBase(_config) {}
  
  	void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
  
  	bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
  		return false;
  	}
  
  } // end namespace Catch
  // end catch_reporter_bases.cpp
  // start catch_reporter_compact.cpp
  
  namespace {
  
  #ifdef CATCH_PLATFORM_MAC
  	const char* failedString() { return "FAILED"; }
  	const char* passedString() { return "PASSED"; }
  #else
  	const char* failedString() { return "failed"; }
  	const char* passedString() { return "passed"; }
  #endif
  
  	// Colour::LightGrey
  	Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
  
  	std::string bothOrAll(std::size_t count) {
  		return count == 1 ? std::string() :
  			count == 2 ? "both " : "all ";
  	}
  
  } // anon namespace
  
  namespace Catch {
  	namespace {
  		// Colour, message variants:
  		// - white: No tests ran.
  		// -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
  		// - white: Passed [both/all] N test cases (no assertions).
  		// -   red: Failed N tests cases, failed M assertions.
  		// - green: Passed [both/all] N tests cases with M assertions.
  		void printTotals(std::ostream& out, const Totals& totals) {
  			if (totals.testCases.total() == 0) {
  				out << "No tests ran.";
  			}
  			else if (totals.testCases.failed == totals.testCases.total()) {
  				Colour colour(Colour::ResultError);
  				const std::string qualify_assertions_failed =
  					totals.assertions.failed == totals.assertions.total() ?
  					bothOrAll(totals.assertions.failed) : std::string();
  				out <<
  					"Failed " << bothOrAll(totals.testCases.failed)
  					<< pluralise(totals.testCases.failed, "test case") << ", "
  					"failed " << qualify_assertions_failed <<
  					pluralise(totals.assertions.failed, "assertion") << '.';
  			}
  			else if (totals.assertions.total() == 0) {
  				out <<
  					"Passed " << bothOrAll(totals.testCases.total())
  					<< pluralise(totals.testCases.total(), "test case")
  					<< " (no assertions).";
  			}
  			else if (totals.assertions.failed) {
  				Colour colour(Colour::ResultError);
  				out <<
  					"Failed " << pluralise(totals.testCases.failed, "test case") << ", "
  					"failed " << pluralise(totals.assertions.failed, "assertion") << '.';
  			}
  			else {
  				Colour colour(Colour::ResultSuccess);
  				out <<
  					"Passed " << bothOrAll(totals.testCases.passed)
  					<< pluralise(totals.testCases.passed, "test case") <<
  					" with " << pluralise(totals.assertions.passed, "assertion") << '.';
  			}
  		}
  
  		// Implementation of CompactReporter formatting
  		class AssertionPrinter {
  		public:
  			AssertionPrinter& operator= (AssertionPrinter const&) = delete;
  			AssertionPrinter(AssertionPrinter const&) = delete;
  			AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
  				: stream(_stream)
  				, result(_stats.assertionResult)
  				, messages(_stats.infoMessages)
  				, itMessage(_stats.infoMessages.begin())
  				, printInfoMessages(_printInfoMessages) {}
  
  			void print() {
  				printSourceInfo();
  
  				itMessage = messages.begin();
  
  				switch (result.getResultType()) {
  				case ResultWas::Ok:
  					printResultType(Colour::ResultSuccess, passedString());
  					printOriginalExpression();
  					printReconstructedExpression();
  					if (!result.hasExpression())
  						printRemainingMessages(Colour::None);
  					else
  						printRemainingMessages();
  					break;
  				case ResultWas::ExpressionFailed:
  					if (result.isOk())
  						printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
  					else
  						printResultType(Colour::Error, failedString());
  					printOriginalExpression();
  					printReconstructedExpression();
  					printRemainingMessages();
  					break;
  				case ResultWas::ThrewException:
  					printResultType(Colour::Error, failedString());
  					printIssue("unexpected exception with message:");
  					printMessage();
  					printExpressionWas();
  					printRemainingMessages();
  					break;
  				case ResultWas::FatalErrorCondition:
  					printResultType(Colour::Error, failedString());
  					printIssue("fatal error condition with message:");
  					printMessage();
  					printExpressionWas();
  					printRemainingMessages();
  					break;
  				case ResultWas::DidntThrowException:
  					printResultType(Colour::Error, failedString());
  					printIssue("expected exception, got none");
  					printExpressionWas();
  					printRemainingMessages();
  					break;
  				case ResultWas::Info:
  					printResultType(Colour::None, "info");
  					printMessage();
  					printRemainingMessages();
  					break;
  				case ResultWas::Warning:
  					printResultType(Colour::None, "warning");
  					printMessage();
  					printRemainingMessages();
  					break;
  				case ResultWas::ExplicitFailure:
  					printResultType(Colour::Error, failedString());
  					printIssue("explicitly");
  					printRemainingMessages(Colour::None);
  					break;
  					// These cases are here to prevent compiler warnings
  				case ResultWas::Unknown:
  				case ResultWas::FailureBit:
  				case ResultWas::Exception:
  					printResultType(Colour::Error, "** internal error **");
  					break;
  				}
  			}
  
  		private:
  			void printSourceInfo() const {
  				Colour colourGuard(Colour::FileName);
  				stream << result.getSourceInfo() << ':';
  			}
  
  			void printResultType(Colour::Code colour, std::string const& passOrFail) const {
  				if (!passOrFail.empty()) {
  					{
  						Colour colourGuard(colour);
  						stream << ' ' << passOrFail;
  					}
  					stream << ':';
  				}
  			}
  
  			void printIssue(std::string const& issue) const {
  				stream << ' ' << issue;
  			}
  
  			void printExpressionWas() {
  				if (result.hasExpression()) {
  					stream << ';';
  					{
  						Colour colour(dimColour());
  						stream << " expression was:";
  					}
  					printOriginalExpression();
  				}
  			}
  
  			void printOriginalExpression() const {
  				if (result.hasExpression()) {
  					stream << ' ' << result.getExpression();
  				}
  			}
  
  			void printReconstructedExpression() const {
  				if (result.hasExpandedExpression()) {
  					{
  						Colour colour(dimColour());
  						stream << " for: ";
  					}
  					stream << result.getExpandedExpression();
  				}
  			}
  
  			void printMessage() {
  				if (itMessage != messages.end()) {
  					stream << " '" << itMessage->message << '\'';
  					++itMessage;
  				}
  			}
  
  			void printRemainingMessages(Colour::Code colour = dimColour()) {
  				if (itMessage == messages.end())
  					return;
  
  				// using messages.end() directly yields (or auto) compilation error:
  				std::vector<MessageInfo>::const_iterator itEnd = messages.end();
  				const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
  
  				{
  					Colour colourGuard(colour);
  					stream << " with " << pluralise(N, "message") << ':';
  				}
  
  				for (; itMessage != itEnd; ) {
  					// If this assertion is a warning ignore any INFO messages
  					if (printInfoMessages || itMessage->type != ResultWas::Info) {
  						stream << " '" << itMessage->message << '\'';
  						if (++itMessage != itEnd) {
  							Colour colourGuard(dimColour());
  							stream << " and";
  						}
  					}
  				}
  			}
  
  		private:
  			std::ostream& stream;
  			AssertionResult const& result;
  			std::vector<MessageInfo> messages;
  			std::vector<MessageInfo>::const_iterator itMessage;
  			bool printInfoMessages;
  		};
  
  	} // anon namespace
  
  	std::string CompactReporter::getDescription() {
  		return "Reports test results on a single line, suitable for IDEs";
  	}
  
  	ReporterPreferences CompactReporter::getPreferences() const {
  		ReporterPreferences prefs;
  		prefs.shouldRedirectStdOut = false;
  		return prefs;
  	}
  
  	void CompactReporter::noMatchingTestCases(std::string const& spec) {
  		stream << "No test cases matched '" << spec << '\'' << std::endl;
  	}
  
  	void CompactReporter::assertionStarting(AssertionInfo const&) {}
  
  	bool CompactReporter::assertionEnded(AssertionStats const& _assertionStats) {
  		AssertionResult const& result = _assertionStats.assertionResult;
  
  		bool printInfoMessages = true;
  
  		// Drop out if result was successful and we're not printing those
  		if (!m_config->includeSuccessfulResults() && result.isOk()) {
  			if (result.getResultType() != ResultWas::Warning)
  				return false;
  			printInfoMessages = false;
  		}
  
  		AssertionPrinter printer(stream, _assertionStats, printInfoMessages);
  		printer.print();
  
  		stream << std::endl;
  		return true;
  	}
  
  	void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
  		if (m_config->showDurations() == ShowDurations::Always) {
  			stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  		}
  	}
  
  	void CompactReporter::testRunEnded(TestRunStats const& _testRunStats) {
  		printTotals(stream, _testRunStats.totals);
  		stream << '\n' << std::endl;
  		StreamingReporterBase::testRunEnded(_testRunStats);
  	}
  
  	CompactReporter::~CompactReporter() {}
  
  	CATCH_REGISTER_REPORTER("compact", CompactReporter)
  
  } // end namespace Catch
  // end catch_reporter_compact.cpp
  // start catch_reporter_console.cpp
  
  #include <cfloat>
  #include <cstdio>
  
  #if defined(_MSC_VER)
  #pragma warning(push)
  #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
   // Note that 4062 (not all labels are handled
   // and default is missing) is enabled
  #endif
  
  namespace Catch {
  
  	namespace {
  
  		// Formatter impl for ConsoleReporter
  		class ConsoleAssertionPrinter {
  		public:
  			ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
  			ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
  			ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
  				: stream(_stream),
  				stats(_stats),
  				result(_stats.assertionResult),
  				colour(Colour::None),
  				message(result.getMessage()),
  				messages(_stats.infoMessages),
  				printInfoMessages(_printInfoMessages) {
  				switch (result.getResultType()) {
  				case ResultWas::Ok:
  					colour = Colour::Success;
  					passOrFail = "PASSED";
  					//if( result.hasMessage() )
  					if (_stats.infoMessages.size() == 1)
  						messageLabel = "with message";
  					if (_stats.infoMessages.size() > 1)
  						messageLabel = "with messages";
  					break;
  				case ResultWas::ExpressionFailed:
  					if (result.isOk()) {
  						colour = Colour::Success;
  						passOrFail = "FAILED - but was ok";
  					}
  					else {
  						colour = Colour::Error;
  						passOrFail = "FAILED";
  					}
  					if (_stats.infoMessages.size() == 1)
  						messageLabel = "with message";
  					if (_stats.infoMessages.size() > 1)
  						messageLabel = "with messages";
  					break;
  				case ResultWas::ThrewException:
  					colour = Colour::Error;
  					passOrFail = "FAILED";
  					messageLabel = "due to unexpected exception with ";
  					if (_stats.infoMessages.size() == 1)
  						messageLabel += "message";
  					if (_stats.infoMessages.size() > 1)
  						messageLabel += "messages";
  					break;
  				case ResultWas::FatalErrorCondition:
  					colour = Colour::Error;
  					passOrFail = "FAILED";
  					messageLabel = "due to a fatal error condition";
  					break;
  				case ResultWas::DidntThrowException:
  					colour = Colour::Error;
  					passOrFail = "FAILED";
  					messageLabel = "because no exception was thrown where one was expected";
  					break;
  				case ResultWas::Info:
  					messageLabel = "info";
  					break;
  				case ResultWas::Warning:
  					messageLabel = "warning";
  					break;
  				case ResultWas::ExplicitFailure:
  					passOrFail = "FAILED";
  					colour = Colour::Error;
  					if (_stats.infoMessages.size() == 1)
  						messageLabel = "explicitly with message";
  					if (_stats.infoMessages.size() > 1)
  						messageLabel = "explicitly with messages";
  					break;
  					// These cases are here to prevent compiler warnings
  				case ResultWas::Unknown:
  				case ResultWas::FailureBit:
  				case ResultWas::Exception:
  					passOrFail = "** internal error **";
  					colour = Colour::Error;
  					break;
  				}
  			}
  
  			void print() const {
  				printSourceInfo();
  				if (stats.totals.assertions.total() > 0) {
  					if (result.isOk())
  						stream << '\n';
  					printResultType();
  					printOriginalExpression();
  					printReconstructedExpression();
  				}
  				else {
  					stream << '\n';
  				}
  				printMessage();
  			}
  
  		private:
  			void printResultType() const {
  				if (!passOrFail.empty()) {
  					Colour colourGuard(colour);
  					stream << passOrFail << ":\n";
  				}
  			}
  			void printOriginalExpression() const {
  				if (result.hasExpression()) {
  					Colour colourGuard(Colour::OriginalExpression);
  					stream << "  ";
  					stream << result.getExpressionInMacro();
  					stream << '\n';
  				}
  			}
  			void printReconstructedExpression() const {
  				if (result.hasExpandedExpression()) {
  					stream << "with expansion:\n";
  					Colour colourGuard(Colour::ReconstructedExpression);
  					stream << Column(result.getExpandedExpression()).indent(2) << '\n';
  				}
  			}
  			void printMessage() const {
  				if (!messageLabel.empty())
  					stream << messageLabel << ':' << '\n';
  				for (auto const& msg : messages) {
  					// If this assertion is a warning ignore any INFO messages
  					if (printInfoMessages || msg.type != ResultWas::Info)
  						stream << Column(msg.message).indent(2) << '\n';
  				}
  			}
  			void printSourceInfo() const {
  				Colour colourGuard(Colour::FileName);
  				stream << result.getSourceInfo() << ": ";
  			}
  
  			std::ostream& stream;
  			AssertionStats const& stats;
  			AssertionResult const& result;
  			Colour::Code colour;
  			std::string passOrFail;
  			std::string messageLabel;
  			std::string message;
  			std::vector<MessageInfo> messages;
  			bool printInfoMessages;
  		};
  
  		std::size_t makeRatio(std::size_t number, std::size_t total) {
  			std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
  			return (ratio == 0 && number > 0) ? 1 : ratio;
  		}
  
  		std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
  			if (i > j && i > k)
  				return i;
  			else if (j > k)
  				return j;
  			else
  				return k;
  		}
  
  		struct ColumnInfo {
  			enum Justification { Left, Right };
  			std::string name;
  			int width;
  			Justification justification;
  		};
  		struct ColumnBreak {};
  		struct RowBreak {};
  
  		class Duration {
  			enum class Unit {
  				Auto,
  				Nanoseconds,
  				Microseconds,
  				Milliseconds,
  				Seconds,
  				Minutes
  			};
  			static const uint64_t s_nanosecondsInAMicrosecond = 1000;
  			static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
  			static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
  			static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
  
  			uint64_t m_inNanoseconds;
  			Unit m_units;
  
  		public:
  			explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
  				: m_inNanoseconds(inNanoseconds),
  				m_units(units) {
  				if (m_units == Unit::Auto) {
  					if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
  						m_units = Unit::Nanoseconds;
  					else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
  						m_units = Unit::Microseconds;
  					else if (m_inNanoseconds < s_nanosecondsInASecond)
  						m_units = Unit::Milliseconds;
  					else if (m_inNanoseconds < s_nanosecondsInAMinute)
  						m_units = Unit::Seconds;
  					else
  						m_units = Unit::Minutes;
  				}
  
  			}
  
  			auto value() const -> double {
  				switch (m_units) {
  				case Unit::Microseconds:
  					return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
  				case Unit::Milliseconds:
  					return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
  				case Unit::Seconds:
  					return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
  				case Unit::Minutes:
  					return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
  				default:
  					return static_cast<double>(m_inNanoseconds);
  				}
  			}
  			auto unitsAsString() const -> std::string {
  				switch (m_units) {
  				case Unit::Nanoseconds:
  					return "ns";
  				case Unit::Microseconds:
  					return "�s";
  				case Unit::Milliseconds:
  					return "ms";
  				case Unit::Seconds:
  					return "s";
  				case Unit::Minutes:
  					return "m";
  				default:
  					return "** internal error **";
  				}
  
  			}
  			friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
  				return os << duration.value() << " " << duration.unitsAsString();
  			}
  		};
  	} // end anon namespace
  
  	class TablePrinter {
  		std::ostream& m_os;
  		std::vector<ColumnInfo> m_columnInfos;
  		std::ostringstream m_oss;
  		int m_currentColumn = -1;
  		bool m_isOpen = false;
  
  	public:
  		TablePrinter(std::ostream& os, std::vector<ColumnInfo> columnInfos)
  			: m_os(os),
  			m_columnInfos(std::move(columnInfos)) {}
  
  		auto columnInfos() const -> std::vector<ColumnInfo> const& {
  			return m_columnInfos;
  		}
  
  		void open() {
  			if (!m_isOpen) {
  				m_isOpen = true;
  				*this << RowBreak();
  				for (auto const& info : m_columnInfos)
  					*this << info.name << ColumnBreak();
  				*this << RowBreak();
  				m_os << Catch::getLineOfChars<'-'>() << "\n";
  			}
  		}
  		void close() {
  			if (m_isOpen) {
  				*this << RowBreak();
  				m_os << std::endl;
  				m_isOpen = false;
  			}
  		}
  
  		template<typename T>
  		friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
  			tp.m_oss << value;
  			return tp;
  		}
  
  		friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
  			auto colStr = tp.m_oss.str();
  			// This takes account of utf8 encodings
  			auto strSize = Catch::StringRef(colStr).numberOfCharacters();
  			tp.m_oss.str("");
  			tp.open();
  			if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
  				tp.m_currentColumn = -1;
  				tp.m_os << "\n";
  			}
  			tp.m_currentColumn++;
  
  			auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
  			auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width))
  				? std::string(colInfo.width - (strSize + 2), ' ')
  				: std::string();
  			if (colInfo.justification == ColumnInfo::Left)
  				tp.m_os << colStr << padding << " ";
  			else
  				tp.m_os << padding << colStr << " ";
  			return tp;
  		}
  
  		friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
  			if (tp.m_currentColumn > 0) {
  				tp.m_os << "\n";
  				tp.m_currentColumn = -1;
  			}
  			return tp;
  		}
  	};
  
  	ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
  		: StreamingReporterBase(config),
  		m_tablePrinter(new TablePrinter(config.stream(),
  			{
  				{ "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
  				{ "iters", 8, ColumnInfo::Right },
  				{ "elapsed ns", 14, ColumnInfo::Right },
  				{ "average", 14, ColumnInfo::Right }
  			})) {}
  	ConsoleReporter::~ConsoleReporter() = default;
  
  	std::string ConsoleReporter::getDescription() {
  		return "Reports test results as plain lines of text";
  	}
  
  	void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
  		stream << "No test cases matched '" << spec << '\'' << std::endl;
  	}
  
  	void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
  
  	bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
  		AssertionResult const& result = _assertionStats.assertionResult;
  
  		bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  
  		// Drop out if result was successful but we're not printing them.
  		if (!includeResults && result.getResultType() != ResultWas::Warning)
  			return false;
  
  		lazyPrint();
  
  		ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
  		printer.print();
  		stream << std::endl;
  		return true;
  	}
  
  	void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
  		m_headerPrinted = false;
  		StreamingReporterBase::sectionStarting(_sectionInfo);
  	}
  	void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
  		m_tablePrinter->close();
  		if (_sectionStats.missingAssertions) {
  			lazyPrint();
  			Colour colour(Colour::ResultError);
  			if (m_sectionStack.size() > 1)
  				stream << "\nNo assertions in section";
  			else
  				stream << "\nNo assertions in test case";
  			stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
  		}
  		if (m_config->showDurations() == ShowDurations::Always) {
  			stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  		}
  		if (m_headerPrinted) {
  			m_headerPrinted = false;
  		}
  		StreamingReporterBase::sectionEnded(_sectionStats);
  	}
  
  	void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
  		lazyPrintWithoutClosingBenchmarkTable();
  
  		auto nameCol = Column(info.name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
  
  		bool firstLine = true;
  		for (auto line : nameCol) {
  			if (!firstLine)
  				(*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
  			else
  				firstLine = false;
  
  			(*m_tablePrinter) << line << ColumnBreak();
  		}
  	}
  	void ConsoleReporter::benchmarkEnded(BenchmarkStats const& stats) {
  		Duration average(stats.elapsedTimeInNanoseconds / stats.iterations);
  		(*m_tablePrinter)
  			<< stats.iterations << ColumnBreak()
  			<< stats.elapsedTimeInNanoseconds << ColumnBreak()
  			<< average << ColumnBreak();
  	}
  
  	void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
  		m_tablePrinter->close();
  		StreamingReporterBase::testCaseEnded(_testCaseStats);
  		m_headerPrinted = false;
  	}
  	void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
  		if (currentGroupInfo.used) {
  			printSummaryDivider();
  			stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
  			printTotals(_testGroupStats.totals);
  			stream << '\n' << std::endl;
  		}
  		StreamingReporterBase::testGroupEnded(_testGroupStats);
  	}
  	void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
  		printTotalsDivider(_testRunStats.totals);
  		printTotals(_testRunStats.totals);
  		stream << std::endl;
  		StreamingReporterBase::testRunEnded(_testRunStats);
  	}
  
  	void ConsoleReporter::lazyPrint() {
  
  		m_tablePrinter->close();
  		lazyPrintWithoutClosingBenchmarkTable();
  	}
  
  	void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
  
  		if (!currentTestRunInfo.used)
  			lazyPrintRunInfo();
  		if (!currentGroupInfo.used)
  			lazyPrintGroupInfo();
  
  		if (!m_headerPrinted) {
  			printTestCaseAndSectionHeader();
  			m_headerPrinted = true;
  		}
  	}
  	void ConsoleReporter::lazyPrintRunInfo() {
  		stream << '\n' << getLineOfChars<'~'>() << '\n';
  		Colour colour(Colour::SecondaryText);
  		stream << currentTestRunInfo->name
  			<< " is a Catch v" << libraryVersion() << " host application.\n"
  			<< "Run with -? for options\n\n";
  
  		if (m_config->rngSeed() != 0)
  			stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
  
  		currentTestRunInfo.used = true;
  	}
  	void ConsoleReporter::lazyPrintGroupInfo() {
  		if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
  			printClosedHeader("Group: " + currentGroupInfo->name);
  			currentGroupInfo.used = true;
  		}
  	}
  	void ConsoleReporter::printTestCaseAndSectionHeader() {
  		assert(!m_sectionStack.empty());
  		printOpenHeader(currentTestCaseInfo->name);
  
  		if (m_sectionStack.size() > 1) {
  			Colour colourGuard(Colour::Headers);
  
  			auto
  				it = m_sectionStack.begin() + 1, // Skip first section (test case)
  				itEnd = m_sectionStack.end();
  			for (; it != itEnd; ++it)
  				printHeaderString(it->name, 2);
  		}
  
  		SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
  
  		if (!lineInfo.empty()) {
  			stream << getLineOfChars<'-'>() << '\n';
  			Colour colourGuard(Colour::FileName);
  			stream << lineInfo << '\n';
  		}
  		stream << getLineOfChars<'.'>() << '\n' << std::endl;
  	}
  
  	void ConsoleReporter::printClosedHeader(std::string const& _name) {
  		printOpenHeader(_name);
  		stream << getLineOfChars<'.'>() << '\n';
  	}
  	void ConsoleReporter::printOpenHeader(std::string const& _name) {
  		stream << getLineOfChars<'-'>() << '\n';
  		{
  			Colour colourGuard(Colour::Headers);
  			printHeaderString(_name);
  		}
  	}
  
  	// if string has a : in first line will set indent to follow it on
  	// subsequent lines
  	void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
  		std::size_t i = _string.find(": ");
  		if (i != std::string::npos)
  			i += 2;
  		else
  			i = 0;
  		stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
  	}
  
  	struct SummaryColumn {
  
  		SummaryColumn(std::string _label, Colour::Code _colour)
  			: label(std::move(_label)),
  			colour(_colour) {}
  		SummaryColumn addRow(std::size_t count) {
  			ReusableStringStream rss;
  			rss << count;
  			std::string row = rss.str();
  			for (auto& oldRow : rows) {
  				while (oldRow.size() < row.size())
  					oldRow = ' ' + oldRow;
  				while (oldRow.size() > row.size())
  					row = ' ' + row;
  			}
  			rows.push_back(row);
  			return *this;
  		}
  
  		std::string label;
  		Colour::Code colour;
  		std::vector<std::string> rows;
  
  	};
  
  	void ConsoleReporter::printTotals(Totals const& totals) {
  		if (totals.testCases.total() == 0) {
  			stream << Colour(Colour::Warning) << "No tests ran\n";
  		}
  		else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
  			stream << Colour(Colour::ResultSuccess) << "All tests passed";
  			stream << " ("
  				<< pluralise(totals.assertions.passed, "assertion") << " in "
  				<< pluralise(totals.testCases.passed, "test case") << ')'
  				<< '\n';
  		}
  		else {
  
  			std::vector<SummaryColumn> columns;
  			columns.push_back(SummaryColumn("", Colour::None)
  				.addRow(totals.testCases.total())
  				.addRow(totals.assertions.total()));
  			columns.push_back(SummaryColumn("passed", Colour::Success)
  				.addRow(totals.testCases.passed)
  				.addRow(totals.assertions.passed));
  			columns.push_back(SummaryColumn("failed", Colour::ResultError)
  				.addRow(totals.testCases.failed)
  				.addRow(totals.assertions.failed));
  			columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
  				.addRow(totals.testCases.failedButOk)
  				.addRow(totals.assertions.failedButOk));
  
  			printSummaryRow("test cases", columns, 0);
  			printSummaryRow("assertions", columns, 1);
  		}
  	}
  	void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
  		for (auto col : cols) {
  			std::string value = col.rows[row];
  			if (col.label.empty()) {
  				stream << label << ": ";
  				if (value != "0")
  					stream << value;
  				else
  					stream << Colour(Colour::Warning) << "- none -";
  			}
  			else if (value != "0") {
  				stream << Colour(Colour::LightGrey) << " | ";
  				stream << Colour(col.colour)
  					<< value << ' ' << col.label;
  			}
  		}
  		stream << '\n';
  	}
  
  	void ConsoleReporter::printTotalsDivider(Totals const& totals) {
  		if (totals.testCases.total() > 0) {
  			std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
  			std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
  			std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
  			while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
  				findMax(failedRatio, failedButOkRatio, passedRatio)++;
  			while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
  				findMax(failedRatio, failedButOkRatio, passedRatio)--;
  
  			stream << Colour(Colour::Error) << std::string(failedRatio, '=');
  			stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
  			if (totals.testCases.allPassed())
  				stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
  			else
  				stream << Colour(Colour::Success) << std::string(passedRatio, '=');
  		}
  		else {
  			stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
  		}
  		stream << '\n';
  	}
  	void ConsoleReporter::printSummaryDivider() {
  		stream << getLineOfChars<'-'>() << '\n';
  	}
  
  	CATCH_REGISTER_REPORTER("console", ConsoleReporter)
  
  } // end namespace Catch
  
  #if defined(_MSC_VER)
  #pragma warning(pop)
  #endif
  // end catch_reporter_console.cpp
  // start catch_reporter_junit.cpp
  
  #include <assert.h>
  #include <sstream>
  #include <ctime>
  #include <algorithm>
  
  namespace Catch {
  
  	namespace {
  		std::string getCurrentTimestamp() {
  			// Beware, this is not reentrant because of backward compatibility issues
  			// Also, UTC only, again because of backward compatibility (%z is C++11)
  			time_t rawtime;
  			std::time(&rawtime);
  			auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  
  #ifdef _MSC_VER
  			std::tm timeInfo = {};
  			gmtime_s(&timeInfo, &rawtime);
  #else
  			std::tm* timeInfo;
  			timeInfo = std::gmtime(&rawtime);
  #endif
  
  			char timeStamp[timeStampSize];
  			const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
  
  #ifdef _MSC_VER
  			std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  #else
  			std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
  #endif
  			return std::string(timeStamp);
  		}
  
  		std::string fileNameTag(const std::vector<std::string> &tags) {
  			auto it = std::find_if(begin(tags),
  				end(tags),
  				[](std::string const& tag) {return tag.front() == '#'; });
  			if (it != tags.end())
  				return it->substr(1);
  			return std::string();
  		}
  	} // anonymous namespace
  
  	JunitReporter::JunitReporter(ReporterConfig const& _config)
  		: CumulativeReporterBase(_config),
  		xml(_config.stream())
  	{
  		m_reporterPrefs.shouldRedirectStdOut = true;
  	}
  
  	JunitReporter::~JunitReporter() {}
  
  	std::string JunitReporter::getDescription() {
  		return "Reports test results in an XML format that looks like Ant's junitreport target";
  	}
  
  	void JunitReporter::noMatchingTestCases(std::string const& /*spec*/) {}
  
  	void JunitReporter::testRunStarting(TestRunInfo const& runInfo) {
  		CumulativeReporterBase::testRunStarting(runInfo);
  		xml.startElement("testsuites");
  	}
  
  	void JunitReporter::testGroupStarting(GroupInfo const& groupInfo) {
  		suiteTimer.start();
  		stdOutForSuite.clear();
  		stdErrForSuite.clear();
  		unexpectedExceptions = 0;
  		CumulativeReporterBase::testGroupStarting(groupInfo);
  	}
  
  	void JunitReporter::testCaseStarting(TestCaseInfo const& testCaseInfo) {
  		m_okToFail = testCaseInfo.okToFail();
  	}
  
  	bool JunitReporter::assertionEnded(AssertionStats const& assertionStats) {
  		if (assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail)
  			unexpectedExceptions++;
  		return CumulativeReporterBase::assertionEnded(assertionStats);
  	}
  
  	void JunitReporter::testCaseEnded(TestCaseStats const& testCaseStats) {
  		stdOutForSuite += testCaseStats.stdOut;
  		stdErrForSuite += testCaseStats.stdErr;
  		CumulativeReporterBase::testCaseEnded(testCaseStats);
  	}
  
  	void JunitReporter::testGroupEnded(TestGroupStats const& testGroupStats) {
  		double suiteTime = suiteTimer.getElapsedSeconds();
  		CumulativeReporterBase::testGroupEnded(testGroupStats);
  		writeGroup(*m_testGroups.back(), suiteTime);
  	}
  
  	void JunitReporter::testRunEndedCumulative() {
  		xml.endElement();
  	}
  
  	void JunitReporter::writeGroup(TestGroupNode const& groupNode, double suiteTime) {
  		XmlWriter::ScopedElement e = xml.scopedElement("testsuite");
  		TestGroupStats const& stats = groupNode.value;
  		xml.writeAttribute("name", stats.groupInfo.name);
  		xml.writeAttribute("errors", unexpectedExceptions);
  		xml.writeAttribute("failures", stats.totals.assertions.failed - unexpectedExceptions);
  		xml.writeAttribute("tests", stats.totals.assertions.total());
  		xml.writeAttribute("hostname", "tbd"); // !TBD
  		if (m_config->showDurations() == ShowDurations::Never)
  			xml.writeAttribute("time", "");
  		else
  			xml.writeAttribute("time", suiteTime);
  		xml.writeAttribute("timestamp", getCurrentTimestamp());
  
  		// Write test cases
  		for (auto const& child : groupNode.children)
  			writeTestCase(*child);
  
  		xml.scopedElement("system-out").writeText(trim(stdOutForSuite), false);
  		xml.scopedElement("system-err").writeText(trim(stdErrForSuite), false);
  	}
  
  	void JunitReporter::writeTestCase(TestCaseNode const& testCaseNode) {
  		TestCaseStats const& stats = testCaseNode.value;
  
  		// All test cases have exactly one section - which represents the
  		// test case itself. That section may have 0-n nested sections
  		assert(testCaseNode.children.size() == 1);
  		SectionNode const& rootSection = *testCaseNode.children.front();
  
  		std::string className = stats.testInfo.className;
  
  		if (className.empty()) {
  			className = fileNameTag(stats.testInfo.tags);
  			if (className.empty())
  				className = "global";
  		}
  
  		if (!m_config->name().empty())
  			className = m_config->name() + "." + className;
  
  		writeSection(className, "", rootSection);
  	}
  
  	void JunitReporter::writeSection(std::string const& className,
  		std::string const& rootName,
  		SectionNode const& sectionNode) {
  		std::string name = trim(sectionNode.stats.sectionInfo.name);
  		if (!rootName.empty())
  			name = rootName + '/' + name;
  
  		if (!sectionNode.assertions.empty() ||
  			!sectionNode.stdOut.empty() ||
  			!sectionNode.stdErr.empty()) {
  			XmlWriter::ScopedElement e = xml.scopedElement("testcase");
  			if (className.empty()) {
  				xml.writeAttribute("classname", name);
  				xml.writeAttribute("name", "root");
  			}
  			else {
  				xml.writeAttribute("classname", className);
  				xml.writeAttribute("name", name);
  			}
  			xml.writeAttribute("time", ::Catch::Detail::stringify(sectionNode.stats.durationInSeconds));
  
  			writeAssertions(sectionNode);
  
  			if (!sectionNode.stdOut.empty())
  				xml.scopedElement("system-out").writeText(trim(sectionNode.stdOut), false);
  			if (!sectionNode.stdErr.empty())
  				xml.scopedElement("system-err").writeText(trim(sectionNode.stdErr), false);
  		}
  		for (auto const& childNode : sectionNode.childSections)
  			if (className.empty())
  				writeSection(name, "", *childNode);
  			else
  				writeSection(className, name, *childNode);
  	}
  
  	void JunitReporter::writeAssertions(SectionNode const& sectionNode) {
  		for (auto const& assertion : sectionNode.assertions)
  			writeAssertion(assertion);
  	}
  
  	void JunitReporter::writeAssertion(AssertionStats const& stats) {
  		AssertionResult const& result = stats.assertionResult;
  		if (!result.isOk()) {
  			std::string elementName;
  			switch (result.getResultType()) {
  			case ResultWas::ThrewException:
  			case ResultWas::FatalErrorCondition:
  				elementName = "error";
  				break;
  			case ResultWas::ExplicitFailure:
  				elementName = "failure";
  				break;
  			case ResultWas::ExpressionFailed:
  				elementName = "failure";
  				break;
  			case ResultWas::DidntThrowException:
  				elementName = "failure";
  				break;
  
  				// We should never see these here:
  			case ResultWas::Info:
  			case ResultWas::Warning:
  			case ResultWas::Ok:
  			case ResultWas::Unknown:
  			case ResultWas::FailureBit:
  			case ResultWas::Exception:
  				elementName = "internalError";
  				break;
  			}
  
  			XmlWriter::ScopedElement e = xml.scopedElement(elementName);
  
  			xml.writeAttribute("message", result.getExpandedExpression());
  			xml.writeAttribute("type", result.getTestMacroName());
  
  			ReusableStringStream rss;
  			if (!result.getMessage().empty())
  				rss << result.getMessage() << '\n';
  			for (auto const& msg : stats.infoMessages)
  				if (msg.type == ResultWas::Info)
  					rss << msg.message << '\n';
  
  			rss << "at " << result.getSourceInfo();
  			xml.writeText(rss.str(), false);
  		}
  	}
  
  	CATCH_REGISTER_REPORTER("junit", JunitReporter)
  
  } // end namespace Catch
  // end catch_reporter_junit.cpp
  // start catch_reporter_multi.cpp
  
  namespace Catch {
  
  	void MultipleReporters::add(IStreamingReporterPtr&& reporter) {
  		m_reporters.push_back(std::move(reporter));
  	}
  
  	ReporterPreferences MultipleReporters::getPreferences() const {
  		return m_reporters[0]->getPreferences();
  	}
  
  	std::set<Verbosity> MultipleReporters::getSupportedVerbosities() {
  		return std::set<Verbosity>{ };
  	}
  
  	void MultipleReporters::noMatchingTestCases(std::string const& spec) {
  		for (auto const& reporter : m_reporters)
  			reporter->noMatchingTestCases(spec);
  	}
  
  	void MultipleReporters::benchmarkStarting(BenchmarkInfo const& benchmarkInfo) {
  		for (auto const& reporter : m_reporters)
  			reporter->benchmarkStarting(benchmarkInfo);
  	}
  	void MultipleReporters::benchmarkEnded(BenchmarkStats const& benchmarkStats) {
  		for (auto const& reporter : m_reporters)
  			reporter->benchmarkEnded(benchmarkStats);
  	}
  
  	void MultipleReporters::testRunStarting(TestRunInfo const& testRunInfo) {
  		for (auto const& reporter : m_reporters)
  			reporter->testRunStarting(testRunInfo);
  	}
  
  	void MultipleReporters::testGroupStarting(GroupInfo const& groupInfo) {
  		for (auto const& reporter : m_reporters)
  			reporter->testGroupStarting(groupInfo);
  	}
  
  	void MultipleReporters::testCaseStarting(TestCaseInfo const& testInfo) {
  		for (auto const& reporter : m_reporters)
  			reporter->testCaseStarting(testInfo);
  	}
  
  	void MultipleReporters::sectionStarting(SectionInfo const& sectionInfo) {
  		for (auto const& reporter : m_reporters)
  			reporter->sectionStarting(sectionInfo);
  	}
  
  	void MultipleReporters::assertionStarting(AssertionInfo const& assertionInfo) {
  		for (auto const& reporter : m_reporters)
  			reporter->assertionStarting(assertionInfo);
  	}
  
  	// The return value indicates if the messages buffer should be cleared:
  	bool MultipleReporters::assertionEnded(AssertionStats const& assertionStats) {
  		bool clearBuffer = false;
  		for (auto const& reporter : m_reporters)
  			clearBuffer |= reporter->assertionEnded(assertionStats);
  		return clearBuffer;
  	}
  
  	void MultipleReporters::sectionEnded(SectionStats const& sectionStats) {
  		for (auto const& reporter : m_reporters)
  			reporter->sectionEnded(sectionStats);
  	}
  
  	void MultipleReporters::testCaseEnded(TestCaseStats const& testCaseStats) {
  		for (auto const& reporter : m_reporters)
  			reporter->testCaseEnded(testCaseStats);
  	}
  
  	void MultipleReporters::testGroupEnded(TestGroupStats const& testGroupStats) {
  		for (auto const& reporter : m_reporters)
  			reporter->testGroupEnded(testGroupStats);
  	}
  
  	void MultipleReporters::testRunEnded(TestRunStats const& testRunStats) {
  		for (auto const& reporter : m_reporters)
  			reporter->testRunEnded(testRunStats);
  	}
  
  	void MultipleReporters::skipTest(TestCaseInfo const& testInfo) {
  		for (auto const& reporter : m_reporters)
  			reporter->skipTest(testInfo);
  	}
  
  	bool MultipleReporters::isMulti() const {
  		return true;
  	}
  
  } // end namespace Catch
  // end catch_reporter_multi.cpp
  // start catch_reporter_xml.cpp
  
  #if defined(_MSC_VER)
  #pragma warning(push)
  #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  							  // Note that 4062 (not all labels are handled
  							  // and default is missing) is enabled
  #endif
  
  namespace Catch {
  	XmlReporter::XmlReporter(ReporterConfig const& _config)
  		: StreamingReporterBase(_config),
  		m_xml(_config.stream())
  	{
  		m_reporterPrefs.shouldRedirectStdOut = true;
  	}
  
  	XmlReporter::~XmlReporter() = default;
  
  	std::string XmlReporter::getDescription() {
  		return "Reports test results as an XML document";
  	}
  
  	std::string XmlReporter::getStylesheetRef() const {
  		return std::string();
  	}
  
  	void XmlReporter::writeSourceInfo(SourceLineInfo const& sourceInfo) {
  		m_xml
  			.writeAttribute("filename", sourceInfo.file)
  			.writeAttribute("line", sourceInfo.line);
  	}
  
  	void XmlReporter::noMatchingTestCases(std::string const& s) {
  		StreamingReporterBase::noMatchingTestCases(s);
  	}
  
  	void XmlReporter::testRunStarting(TestRunInfo const& testInfo) {
  		StreamingReporterBase::testRunStarting(testInfo);
  		std::string stylesheetRef = getStylesheetRef();
  		if (!stylesheetRef.empty())
  			m_xml.writeStylesheetRef(stylesheetRef);
  		m_xml.startElement("Catch");
  		if (!m_config->name().empty())
  			m_xml.writeAttribute("name", m_config->name());
  	}
  
  	void XmlReporter::testGroupStarting(GroupInfo const& groupInfo) {
  		StreamingReporterBase::testGroupStarting(groupInfo);
  		m_xml.startElement("Group")
  			.writeAttribute("name", groupInfo.name);
  	}
  
  	void XmlReporter::testCaseStarting(TestCaseInfo const& testInfo) {
  		StreamingReporterBase::testCaseStarting(testInfo);
  		m_xml.startElement("TestCase")
  			.writeAttribute("name", trim(testInfo.name))
  			.writeAttribute("description", testInfo.description)
  			.writeAttribute("tags", testInfo.tagsAsString());
  
  		writeSourceInfo(testInfo.lineInfo);
  
  		if (m_config->showDurations() == ShowDurations::Always)
  			m_testCaseTimer.start();
  		m_xml.ensureTagClosed();
  	}
  
  	void XmlReporter::sectionStarting(SectionInfo const& sectionInfo) {
  		StreamingReporterBase::sectionStarting(sectionInfo);
  		if (m_sectionDepth++ > 0) {
  			m_xml.startElement("Section")
  				.writeAttribute("name", trim(sectionInfo.name))
  				.writeAttribute("description", sectionInfo.description);
  			writeSourceInfo(sectionInfo.lineInfo);
  			m_xml.ensureTagClosed();
  		}
  	}
  
  	void XmlReporter::assertionStarting(AssertionInfo const&) { }
  
  	bool XmlReporter::assertionEnded(AssertionStats const& assertionStats) {
  
  		AssertionResult const& result = assertionStats.assertionResult;
  
  		bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  
  		if (includeResults || result.getResultType() == ResultWas::Warning) {
  			// Print any info messages in <Info> tags.
  			for (auto const& msg : assertionStats.infoMessages) {
  				if (msg.type == ResultWas::Info && includeResults) {
  					m_xml.scopedElement("Info")
  						.writeText(msg.message);
  				}
  				else if (msg.type == ResultWas::Warning) {
  					m_xml.scopedElement("Warning")
  						.writeText(msg.message);
  				}
  			}
  		}
  
  		// Drop out if result was successful but we're not printing them.
  		if (!includeResults && result.getResultType() != ResultWas::Warning)
  			return true;
  
  		// Print the expression if there is one.
  		if (result.hasExpression()) {
  			m_xml.startElement("Expression")
  				.writeAttribute("success", result.succeeded())
  				.writeAttribute("type", result.getTestMacroName());
  
  			writeSourceInfo(result.getSourceInfo());
  
  			m_xml.scopedElement("Original")
  				.writeText(result.getExpression());
  			m_xml.scopedElement("Expanded")
  				.writeText(result.getExpandedExpression());
  		}
  
  		// And... Print a result applicable to each result type.
  		switch (result.getResultType()) {
  		case ResultWas::ThrewException:
  			m_xml.startElement("Exception");
  			writeSourceInfo(result.getSourceInfo());
  			m_xml.writeText(result.getMessage());
  			m_xml.endElement();
  			break;
  		case ResultWas::FatalErrorCondition:
  			m_xml.startElement("FatalErrorCondition");
  			writeSourceInfo(result.getSourceInfo());
  			m_xml.writeText(result.getMessage());
  			m_xml.endElement();
  			break;
  		case ResultWas::Info:
  			m_xml.scopedElement("Info")
  				.writeText(result.getMessage());
  			break;
  		case ResultWas::Warning:
  			// Warning will already have been written
  			break;
  		case ResultWas::ExplicitFailure:
  			m_xml.startElement("Failure");
  			writeSourceInfo(result.getSourceInfo());
  			m_xml.writeText(result.getMessage());
  			m_xml.endElement();
  			break;
  		default:
  			break;
  		}
  
  		if (result.hasExpression())
  			m_xml.endElement();
  
  		return true;
  	}
  
  	void XmlReporter::sectionEnded(SectionStats const& sectionStats) {
  		StreamingReporterBase::sectionEnded(sectionStats);
  		if (--m_sectionDepth > 0) {
  			XmlWriter::ScopedElement e = m_xml.scopedElement("OverallResults");
  			e.writeAttribute("successes", sectionStats.assertions.passed);
  			e.writeAttribute("failures", sectionStats.assertions.failed);
  			e.writeAttribute("expectedFailures", sectionStats.assertions.failedButOk);
  
  			if (m_config->showDurations() == ShowDurations::Always)
  				e.writeAttribute("durationInSeconds", sectionStats.durationInSeconds);
  
  			m_xml.endElement();
  		}
  	}
  
  	void XmlReporter::testCaseEnded(TestCaseStats const& testCaseStats) {
  		StreamingReporterBase::testCaseEnded(testCaseStats);
  		XmlWriter::ScopedElement e = m_xml.scopedElement("OverallResult");
  		e.writeAttribute("success", testCaseStats.totals.assertions.allOk());
  
  		if (m_config->showDurations() == ShowDurations::Always)
  			e.writeAttribute("durationInSeconds", m_testCaseTimer.getElapsedSeconds());
  
  		if (!testCaseStats.stdOut.empty())
  			m_xml.scopedElement("StdOut").writeText(trim(testCaseStats.stdOut), false);
  		if (!testCaseStats.stdErr.empty())
  			m_xml.scopedElement("StdErr").writeText(trim(testCaseStats.stdErr), false);
  
  		m_xml.endElement();
  	}
  
  	void XmlReporter::testGroupEnded(TestGroupStats const& testGroupStats) {
  		StreamingReporterBase::testGroupEnded(testGroupStats);
  		// TODO: Check testGroupStats.aborting and act accordingly.
  		m_xml.scopedElement("OverallResults")
  			.writeAttribute("successes", testGroupStats.totals.assertions.passed)
  			.writeAttribute("failures", testGroupStats.totals.assertions.failed)
  			.writeAttribute("expectedFailures", testGroupStats.totals.assertions.failedButOk);
  		m_xml.endElement();
  	}
  
  	void XmlReporter::testRunEnded(TestRunStats const& testRunStats) {
  		StreamingReporterBase::testRunEnded(testRunStats);
  		m_xml.scopedElement("OverallResults")
  			.writeAttribute("successes", testRunStats.totals.assertions.passed)
  			.writeAttribute("failures", testRunStats.totals.assertions.failed)
  			.writeAttribute("expectedFailures", testRunStats.totals.assertions.failedButOk);
  		m_xml.endElement();
  	}
  
  	CATCH_REGISTER_REPORTER("xml", XmlReporter)
  
  } // end namespace Catch
  
  #if defined(_MSC_VER)
  #pragma warning(pop)
  #endif
  // end catch_reporter_xml.cpp
  
  namespace Catch {
  	LeakDetector leakDetector;
  }
  
  #ifdef __clang__
  #pragma clang diagnostic pop
  #endif
  
  // end catch_impl.hpp
  #endif
  
  #ifdef CATCH_CONFIG_MAIN
  // start catch_default_main.hpp
  
  #ifndef __OBJC__
  
  #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
  // Standard C/C++ Win32 Unicode wmain entry point
  extern "C" int wmain(int argc, wchar_t * argv[], wchar_t *[]) {
  #else
  // Standard C/C++ main entry point
  int main(int argc, char * argv[]) {
  #endif
  
  	return Catch::Session().run(argc, argv);
  }
  
  #else // __OBJC__
  
  // Objective-C entry point
  int main(int argc, char * const argv[]) {
  #if !CATCH_ARC_ENABLED
  	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  #endif
  
  	Catch::registerTestMethods();
  	int result = Catch::Session().run(argc, (char**)argv);
  
  #if !CATCH_ARC_ENABLED
  	[pool drain];
  #endif
  
  	return result;
  }
  
  #endif // __OBJC__
  
  // end catch_default_main.hpp
  #endif
  
  #if !defined(CATCH_CONFIG_IMPL_ONLY)
  
  #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
  #  undef CLARA_CONFIG_MAIN
  #endif
  
  #if !defined(CATCH_CONFIG_DISABLE)
  //////
  // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  #ifdef CATCH_CONFIG_PREFIX_ALL
  
  #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  
  #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", __VA_ARGS__ )
  #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  #endif// CATCH_CONFIG_DISABLE_MATCHERS
  #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  
  #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  
  #define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", __VA_ARGS__ )
  #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  #endif // CATCH_CONFIG_DISABLE_MATCHERS
  #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  
  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  
  #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  #endif // CATCH_CONFIG_DISABLE_MATCHERS
  
  #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
  #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
  
  #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  
  #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  
  // "BDD-style" convenience wrappers
  #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
  #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  #define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc )
  #define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc )
  #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc )
  #define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc )
  #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc )
  
  // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  #else
  
  #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__  )
  #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  
  #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  #endif // CATCH_CONFIG_DISABLE_MATCHERS
  #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  
  #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  
  #define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  #endif // CATCH_CONFIG_DISABLE_MATCHERS
  #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  
  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  
  #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  #endif // CATCH_CONFIG_DISABLE_MATCHERS
  
  #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
  #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  #define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
  
  #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  
  #endif
  
  #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
  
  // "BDD-style" convenience wrappers
  #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
  #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  
  #define GIVEN( desc )    SECTION( std::string("   Given: ") + desc )
  #define WHEN( desc )     SECTION( std::string("    When: ") + desc )
  #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc )
  #define THEN( desc )     SECTION( std::string("    Then: ") + desc )
  #define AND_THEN( desc ) SECTION( std::string("     And: ") + desc )
  
  using Catch::Detail::Approx;
  
  #else
  //////
  // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  #ifdef CATCH_CONFIG_PREFIX_ALL
  
  #define CATCH_REQUIRE( ... )        (void)(0)
  #define CATCH_REQUIRE_FALSE( ... )  (void)(0)
  
  #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
  #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  #define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0)
  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  #endif// CATCH_CONFIG_DISABLE_MATCHERS
  #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
  
  #define CATCH_CHECK( ... )         (void)(0)
  #define CATCH_CHECK_FALSE( ... )   (void)(0)
  #define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__)
  #define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__))
  #define CATCH_CHECK_NOFAIL( ... )  (void)(0)
  
  #define CATCH_CHECK_THROWS( ... )  (void)(0)
  #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  #define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0)
  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  #endif // CATCH_CONFIG_DISABLE_MATCHERS
  #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
  
  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  #define CATCH_CHECK_THAT( arg, matcher )   (void)(0)
  
  #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
  #endif // CATCH_CONFIG_DISABLE_MATCHERS
  
  #define CATCH_INFO( msg )    (void)(0)
  #define CATCH_WARN( msg )    (void)(0)
  #define CATCH_CAPTURE( msg ) (void)(0)
  
  #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  #define CATCH_METHOD_AS_TEST_CASE( method, ... )
  #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
  #define CATCH_SECTION( ... )
  #define CATCH_FAIL( ... ) (void)(0)
  #define CATCH_FAIL_CHECK( ... ) (void)(0)
  #define CATCH_SUCCEED( ... ) (void)(0)
  
  #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  
  // "BDD-style" convenience wrappers
  #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  #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 )
  #define CATCH_GIVEN( desc )
  #define CATCH_WHEN( desc )
  #define CATCH_AND_WHEN( desc )
  #define CATCH_THEN( desc )
  #define CATCH_AND_THEN( desc )
  
  // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  #else
  
  #define REQUIRE( ... )       (void)(0)
  #define REQUIRE_FALSE( ... ) (void)(0)
  
  #define REQUIRE_THROWS( ... ) (void)(0)
  #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  #endif // CATCH_CONFIG_DISABLE_MATCHERS
  #define REQUIRE_NOTHROW( ... ) (void)(0)
  
  #define CHECK( ... ) (void)(0)
  #define CHECK_FALSE( ... ) (void)(0)
  #define CHECKED_IF( ... ) if (__VA_ARGS__)
  #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
  #define CHECK_NOFAIL( ... ) (void)(0)
  
  #define CHECK_THROWS( ... )  (void)(0)
  #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  #endif // CATCH_CONFIG_DISABLE_MATCHERS
  #define CHECK_NOTHROW( ... ) (void)(0)
  
  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  #define CHECK_THAT( arg, matcher ) (void)(0)
  
  #define REQUIRE_THAT( arg, matcher ) (void)(0)
  #endif // CATCH_CONFIG_DISABLE_MATCHERS
  
  #define INFO( msg ) (void)(0)
  #define WARN( msg ) (void)(0)
  #define CAPTURE( msg ) (void)(0)
  
  #define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  #define METHOD_AS_TEST_CASE( method, ... )
  #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
  #define SECTION( ... )
  #define FAIL( ... ) (void)(0)
  #define FAIL_CHECK( ... ) (void)(0)
  #define SUCCEED( ... ) (void)(0)
  #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  
  #endif
  
  #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
  
  // "BDD-style" convenience wrappers
  #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
  #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
  
  #define GIVEN( desc )
  #define WHEN( desc )
  #define AND_WHEN( desc )
  #define THEN( desc )
  #define AND_THEN( desc )
  
  using Catch::Detail::Approx;
  
  #endif
  
  #endif // ! CATCH_CONFIG_IMPL_ONLY
  
  // start catch_reenable_warnings.h
  
  
  #ifdef __clang__
  #    ifdef __ICC // icpc defines the __clang__ macro
  #        pragma warning(pop)
  #    else
  #        pragma clang diagnostic pop
  #    endif
  #elif defined __GNUC__
  #    pragma GCC diagnostic pop
  #endif
  
  // end catch_reenable_warnings.h
  // end catch.hpp
  #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
  
  
  