Compare View

switch
from
...
to
 
Commits (2)
CMakeLists.txt 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +cmake_minimum_required(VERSION 3.0)
  2 +project(cbutils)
  3 +
  4 +include_directories( ${cbutils_SOURCE_DIR}/include )
  5 +include(CTest)
  6 +if(BUILD_TESTING)
  7 + enable_testing()
  8 + add_subdirectory( tests )
  9 +endif()
... ...
include/catch.hpp 0 → 100644
Changes suppressed. Click to show
... ... @@ -0,0 +1,14020 @@
  1 +/*
  2 + * Catch v2.4.1
  3 + * Generated: 2018-09-28 15:50:15.645795
  4 + * ----------------------------------------------------------
  5 + * This file has been merged from multiple headers. Please don't edit it directly
  6 + * Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved.
  7 + *
  8 + * Distributed under the Boost Software License, Version 1.0. (See accompanying
  9 + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10 + */
  11 +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
  12 +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
  13 +// start catch.hpp
  14 +
  15 +
  16 +#define CATCH_VERSION_MAJOR 2
  17 +#define CATCH_VERSION_MINOR 4
  18 +#define CATCH_VERSION_PATCH 1
  19 +
  20 +#ifdef __clang__
  21 +# pragma clang system_header
  22 +#elif defined __GNUC__
  23 +# pragma GCC system_header
  24 +#endif
  25 +
  26 +// start catch_suppress_warnings.h
  27 +
  28 +#ifdef __clang__
  29 +# ifdef __ICC // icpc defines the __clang__ macro
  30 +# pragma warning(push)
  31 +# pragma warning(disable: 161 1682)
  32 +# else // __ICC
  33 +# pragma clang diagnostic push
  34 +# pragma clang diagnostic ignored "-Wpadded"
  35 +# pragma clang diagnostic ignored "-Wswitch-enum"
  36 +# pragma clang diagnostic ignored "-Wcovered-switch-default"
  37 +# endif
  38 +#elif defined __GNUC__
  39 + // GCC likes to warn on REQUIREs, and we cannot suppress them
  40 + // locally because g++'s support for _Pragma is lacking in older,
  41 + // still supported, versions
  42 +# pragma GCC diagnostic ignored "-Wparentheses"
  43 +# pragma GCC diagnostic push
  44 +# pragma GCC diagnostic ignored "-Wunused-variable"
  45 +# pragma GCC diagnostic ignored "-Wpadded"
  46 +#endif
  47 +// end catch_suppress_warnings.h
  48 +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
  49 +# define CATCH_IMPL
  50 +# define CATCH_CONFIG_ALL_PARTS
  51 +#endif
  52 +
  53 +// In the impl file, we want to have access to all parts of the headers
  54 +// Can also be used to sanely support PCHs
  55 +#if defined(CATCH_CONFIG_ALL_PARTS)
  56 +# define CATCH_CONFIG_EXTERNAL_INTERFACES
  57 +# if defined(CATCH_CONFIG_DISABLE_MATCHERS)
  58 +# undef CATCH_CONFIG_DISABLE_MATCHERS
  59 +# endif
  60 +# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  61 +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  62 +# endif
  63 +#endif
  64 +
  65 +#if !defined(CATCH_CONFIG_IMPL_ONLY)
  66 +// start catch_platform.h
  67 +
  68 +#ifdef __APPLE__
  69 +# include <TargetConditionals.h>
  70 +# if TARGET_OS_OSX == 1
  71 +# define CATCH_PLATFORM_MAC
  72 +# elif TARGET_OS_IPHONE == 1
  73 +# define CATCH_PLATFORM_IPHONE
  74 +# endif
  75 +
  76 +#elif defined(linux) || defined(__linux) || defined(__linux__)
  77 +# define CATCH_PLATFORM_LINUX
  78 +
  79 +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
  80 +# define CATCH_PLATFORM_WINDOWS
  81 +#endif
  82 +
  83 +// end catch_platform.h
  84 +
  85 +#ifdef CATCH_IMPL
  86 +# ifndef CLARA_CONFIG_MAIN
  87 +# define CLARA_CONFIG_MAIN_NOT_DEFINED
  88 +# define CLARA_CONFIG_MAIN
  89 +# endif
  90 +#endif
  91 +
  92 +// start catch_user_interfaces.h
  93 +
  94 +namespace Catch {
  95 + unsigned int rngSeed();
  96 +}
  97 +
  98 +// end catch_user_interfaces.h
  99 +// start catch_tag_alias_autoregistrar.h
  100 +
  101 +// start catch_common.h
  102 +
  103 +// start catch_compiler_capabilities.h
  104 +
  105 +// Detect a number of compiler features - by compiler
  106 +// The following features are defined:
  107 +//
  108 +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
  109 +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
  110 +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
  111 +// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
  112 +// ****************
  113 +// Note to maintainers: if new toggles are added please document them
  114 +// in configuration.md, too
  115 +// ****************
  116 +
  117 +// In general each macro has a _NO_<feature name> form
  118 +// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
  119 +// Many features, at point of detection, define an _INTERNAL_ macro, so they
  120 +// can be combined, en-mass, with the _NO_ forms later.
  121 +
  122 +#ifdef __cplusplus
  123 +
  124 +# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
  125 +# define CATCH_CPP14_OR_GREATER
  126 +# endif
  127 +
  128 +# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  129 +# define CATCH_CPP17_OR_GREATER
  130 +# endif
  131 +
  132 +#endif
  133 +
  134 +#if defined(CATCH_CPP17_OR_GREATER)
  135 +# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  136 +#endif
  137 +
  138 +#ifdef __clang__
  139 +
  140 +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  141 + _Pragma( "clang diagnostic push" ) \
  142 + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
  143 + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
  144 +# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  145 + _Pragma( "clang diagnostic pop" )
  146 +
  147 +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
  148 + _Pragma( "clang diagnostic push" ) \
  149 + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
  150 +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
  151 + _Pragma( "clang diagnostic pop" )
  152 +
  153 +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
  154 + _Pragma( "clang diagnostic push" ) \
  155 + _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
  156 +# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
  157 + _Pragma( "clang diagnostic pop" )
  158 +
  159 +#endif // __clang__
  160 +
  161 +////////////////////////////////////////////////////////////////////////////////
  162 +// Assume that non-Windows platforms support posix signals by default
  163 +#if !defined(CATCH_PLATFORM_WINDOWS)
  164 + #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
  165 +#endif
  166 +
  167 +////////////////////////////////////////////////////////////////////////////////
  168 +// We know some environments not to support full POSIX signals
  169 +#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
  170 + #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  171 +#endif
  172 +
  173 +#ifdef __OS400__
  174 +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  175 +# define CATCH_CONFIG_COLOUR_NONE
  176 +#endif
  177 +
  178 +////////////////////////////////////////////////////////////////////////////////
  179 +// Android somehow still does not support std::to_string
  180 +#if defined(__ANDROID__)
  181 +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
  182 +#endif
  183 +
  184 +////////////////////////////////////////////////////////////////////////////////
  185 +// Not all Windows environments support SEH properly
  186 +#if defined(__MINGW32__)
  187 +# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
  188 +#endif
  189 +
  190 +////////////////////////////////////////////////////////////////////////////////
  191 +// PS4
  192 +#if defined(__ORBIS__)
  193 +# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
  194 +#endif
  195 +
  196 +////////////////////////////////////////////////////////////////////////////////
  197 +// Cygwin
  198 +#ifdef __CYGWIN__
  199 +
  200 +// Required for some versions of Cygwin to declare gettimeofday
  201 +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
  202 +# define _BSD_SOURCE
  203 +// some versions of cygwin (most) do not support std::to_string. Use the libstd check.
  204 +// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
  205 +# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
  206 + && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
  207 +
  208 +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
  209 +
  210 +# endif
  211 +#endif // __CYGWIN__
  212 +
  213 +////////////////////////////////////////////////////////////////////////////////
  214 +// Visual C++
  215 +#ifdef _MSC_VER
  216 +
  217 +# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
  218 +# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  219 +# endif
  220 +
  221 +// Universal Windows platform does not support SEH
  222 +// Or console colours (or console at all...)
  223 +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
  224 +# define CATCH_CONFIG_COLOUR_NONE
  225 +# else
  226 +# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
  227 +# endif
  228 +
  229 +#endif // _MSC_VER
  230 +
  231 +////////////////////////////////////////////////////////////////////////////////
  232 +// Check if we are compiled with -fno-exceptions or equivalent
  233 +#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
  234 +# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
  235 +#endif
  236 +
  237 +////////////////////////////////////////////////////////////////////////////////
  238 +// DJGPP
  239 +#ifdef __DJGPP__
  240 +# define CATCH_INTERNAL_CONFIG_NO_WCHAR
  241 +#endif // __DJGPP__
  242 +
  243 +////////////////////////////////////////////////////////////////////////////////
  244 +
  245 +// Use of __COUNTER__ is suppressed during code analysis in
  246 +// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
  247 +// handled by it.
  248 +// Otherwise all supported compilers support COUNTER macro,
  249 +// but user still might want to turn it off
  250 +#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
  251 + #define CATCH_INTERNAL_CONFIG_COUNTER
  252 +#endif
  253 +
  254 +////////////////////////////////////////////////////////////////////////////////
  255 +// Check if string_view is available and usable
  256 +// The check is split apart to work around v140 (VS2015) preprocessor issue...
  257 +#if defined(__has_include)
  258 +#if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
  259 +# define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
  260 +#endif
  261 +#endif
  262 +
  263 +////////////////////////////////////////////////////////////////////////////////
  264 +// Check if variant is available and usable
  265 +#if defined(__has_include)
  266 +# if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
  267 +# if defined(__clang__) && (__clang_major__ < 8)
  268 + // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
  269 + // fix should be in clang 8, workaround in libstdc++ 8.2
  270 +# include <ciso646>
  271 +# if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
  272 +# define CATCH_CONFIG_NO_CPP17_VARIANT
  273 +# else
  274 +# define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
  275 +# endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
  276 +# endif // defined(__clang__) && (__clang_major__ < 8)
  277 +# endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
  278 +#endif // __has_include
  279 +
  280 +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
  281 +# define CATCH_CONFIG_COUNTER
  282 +#endif
  283 +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
  284 +# define CATCH_CONFIG_WINDOWS_SEH
  285 +#endif
  286 +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
  287 +#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)
  288 +# define CATCH_CONFIG_POSIX_SIGNALS
  289 +#endif
  290 +// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
  291 +#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
  292 +# define CATCH_CONFIG_WCHAR
  293 +#endif
  294 +
  295 +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
  296 +# define CATCH_CONFIG_CPP11_TO_STRING
  297 +#endif
  298 +
  299 +#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
  300 +# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  301 +#endif
  302 +
  303 +#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
  304 +# define CATCH_CONFIG_CPP17_STRING_VIEW
  305 +#endif
  306 +
  307 +#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
  308 +# define CATCH_CONFIG_CPP17_VARIANT
  309 +#endif
  310 +
  311 +#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
  312 +# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
  313 +#endif
  314 +
  315 +#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
  316 +# define CATCH_CONFIG_NEW_CAPTURE
  317 +#endif
  318 +
  319 +#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  320 +# define CATCH_CONFIG_DISABLE_EXCEPTIONS
  321 +#endif
  322 +
  323 +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
  324 +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
  325 +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
  326 +#endif
  327 +#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
  328 +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
  329 +# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  330 +#endif
  331 +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
  332 +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
  333 +# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
  334 +#endif
  335 +
  336 +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  337 +#define CATCH_TRY if ((true))
  338 +#define CATCH_CATCH_ALL if ((false))
  339 +#define CATCH_CATCH_ANON(type) if ((false))
  340 +#else
  341 +#define CATCH_TRY try
  342 +#define CATCH_CATCH_ALL catch (...)
  343 +#define CATCH_CATCH_ANON(type) catch (type)
  344 +#endif
  345 +
  346 +// end catch_compiler_capabilities.h
  347 +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
  348 +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
  349 +#ifdef CATCH_CONFIG_COUNTER
  350 +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
  351 +#else
  352 +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
  353 +#endif
  354 +
  355 +#include <iosfwd>
  356 +#include <string>
  357 +#include <cstdint>
  358 +
  359 +namespace Catch {
  360 +
  361 + struct CaseSensitive { enum Choice {
  362 + Yes,
  363 + No
  364 + }; };
  365 +
  366 + class NonCopyable {
  367 + NonCopyable( NonCopyable const& ) = delete;
  368 + NonCopyable( NonCopyable && ) = delete;
  369 + NonCopyable& operator = ( NonCopyable const& ) = delete;
  370 + NonCopyable& operator = ( NonCopyable && ) = delete;
  371 +
  372 + protected:
  373 + NonCopyable();
  374 + virtual ~NonCopyable();
  375 + };
  376 +
  377 + struct SourceLineInfo {
  378 +
  379 + SourceLineInfo() = delete;
  380 + SourceLineInfo( char const* _file, std::size_t _line ) noexcept
  381 + : file( _file ),
  382 + line( _line )
  383 + {}
  384 +
  385 + SourceLineInfo( SourceLineInfo const& other ) = default;
  386 + SourceLineInfo( SourceLineInfo && ) = default;
  387 + SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
  388 + SourceLineInfo& operator = ( SourceLineInfo && ) = default;
  389 +
  390 + bool empty() const noexcept;
  391 + bool operator == ( SourceLineInfo const& other ) const noexcept;
  392 + bool operator < ( SourceLineInfo const& other ) const noexcept;
  393 +
  394 + char const* file;
  395 + std::size_t line;
  396 + };
  397 +
  398 + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
  399 +
  400 + // Use this in variadic streaming macros to allow
  401 + // >> +StreamEndStop
  402 + // as well as
  403 + // >> stuff +StreamEndStop
  404 + struct StreamEndStop {
  405 + std::string operator+() const;
  406 + };
  407 + template<typename T>
  408 + T const& operator + ( T const& value, StreamEndStop ) {
  409 + return value;
  410 + }
  411 +}
  412 +
  413 +#define CATCH_INTERNAL_LINEINFO \
  414 + ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
  415 +
  416 +// end catch_common.h
  417 +namespace Catch {
  418 +
  419 + struct RegistrarForTagAliases {
  420 + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
  421 + };
  422 +
  423 +} // end namespace Catch
  424 +
  425 +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
  426 + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  427 + namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
  428 + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  429 +
  430 +// end catch_tag_alias_autoregistrar.h
  431 +// start catch_test_registry.h
  432 +
  433 +// start catch_interfaces_testcase.h
  434 +
  435 +#include <vector>
  436 +#include <memory>
  437 +
  438 +namespace Catch {
  439 +
  440 + class TestSpec;
  441 +
  442 + struct ITestInvoker {
  443 + virtual void invoke () const = 0;
  444 + virtual ~ITestInvoker();
  445 + };
  446 +
  447 + using ITestCasePtr = std::shared_ptr<ITestInvoker>;
  448 +
  449 + class TestCase;
  450 + struct IConfig;
  451 +
  452 + struct ITestCaseRegistry {
  453 + virtual ~ITestCaseRegistry();
  454 + virtual std::vector<TestCase> const& getAllTests() const = 0;
  455 + virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
  456 + };
  457 +
  458 + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
  459 + std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
  460 + std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
  461 +
  462 +}
  463 +
  464 +// end catch_interfaces_testcase.h
  465 +// start catch_stringref.h
  466 +
  467 +#include <cstddef>
  468 +#include <string>
  469 +#include <iosfwd>
  470 +
  471 +namespace Catch {
  472 +
  473 + class StringData;
  474 +
  475 + /// A non-owning string class (similar to the forthcoming std::string_view)
  476 + /// Note that, because a StringRef may be a substring of another string,
  477 + /// it may not be null terminated. c_str() must return a null terminated
  478 + /// string, however, and so the StringRef will internally take ownership
  479 + /// (taking a copy), if necessary. In theory this ownership is not externally
  480 + /// visible - but it does mean (substring) StringRefs should not be shared between
  481 + /// threads.
  482 + class StringRef {
  483 + public:
  484 + using size_type = std::size_t;
  485 +
  486 + private:
  487 + friend struct StringRefTestAccess;
  488 +
  489 + char const* m_start;
  490 + size_type m_size;
  491 +
  492 + char* m_data = nullptr;
  493 +
  494 + void takeOwnership();
  495 +
  496 + static constexpr char const* const s_empty = "";
  497 +
  498 + public: // construction/ assignment
  499 + StringRef() noexcept
  500 + : StringRef( s_empty, 0 )
  501 + {}
  502 +
  503 + StringRef( StringRef const& other ) noexcept
  504 + : m_start( other.m_start ),
  505 + m_size( other.m_size )
  506 + {}
  507 +
  508 + StringRef( StringRef&& other ) noexcept
  509 + : m_start( other.m_start ),
  510 + m_size( other.m_size ),
  511 + m_data( other.m_data )
  512 + {
  513 + other.m_data = nullptr;
  514 + }
  515 +
  516 + StringRef( char const* rawChars ) noexcept;
  517 +
  518 + StringRef( char const* rawChars, size_type size ) noexcept
  519 + : m_start( rawChars ),
  520 + m_size( size )
  521 + {}
  522 +
  523 + StringRef( std::string const& stdString ) noexcept
  524 + : m_start( stdString.c_str() ),
  525 + m_size( stdString.size() )
  526 + {}
  527 +
  528 + ~StringRef() noexcept {
  529 + delete[] m_data;
  530 + }
  531 +
  532 + auto operator = ( StringRef const &other ) noexcept -> StringRef& {
  533 + delete[] m_data;
  534 + m_data = nullptr;
  535 + m_start = other.m_start;
  536 + m_size = other.m_size;
  537 + return *this;
  538 + }
  539 +
  540 + operator std::string() const;
  541 +
  542 + void swap( StringRef& other ) noexcept;
  543 +
  544 + public: // operators
  545 + auto operator == ( StringRef const& other ) const noexcept -> bool;
  546 + auto operator != ( StringRef const& other ) const noexcept -> bool;
  547 +
  548 + auto operator[] ( size_type index ) const noexcept -> char;
  549 +
  550 + public: // named queries
  551 + auto empty() const noexcept -> bool {
  552 + return m_size == 0;
  553 + }
  554 + auto size() const noexcept -> size_type {
  555 + return m_size;
  556 + }
  557 +
  558 + auto numberOfCharacters() const noexcept -> size_type;
  559 + auto c_str() const -> char const*;
  560 +
  561 + public: // substrings and searches
  562 + auto substr( size_type start, size_type size ) const noexcept -> StringRef;
  563 +
  564 + // Returns the current start pointer.
  565 + // Note that the pointer can change when if the StringRef is a substring
  566 + auto currentData() const noexcept -> char const*;
  567 +
  568 + private: // ownership queries - may not be consistent between calls
  569 + auto isOwned() const noexcept -> bool;
  570 + auto isSubstring() const noexcept -> bool;
  571 + };
  572 +
  573 + auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
  574 + auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
  575 + auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
  576 +
  577 + auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
  578 + auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
  579 +
  580 + inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
  581 + return StringRef( rawChars, size );
  582 + }
  583 +
  584 +} // namespace Catch
  585 +
  586 +inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
  587 + return Catch::StringRef( rawChars, size );
  588 +}
  589 +
  590 +// end catch_stringref.h
  591 +namespace Catch {
  592 +
  593 +template<typename C>
  594 +class TestInvokerAsMethod : public ITestInvoker {
  595 + void (C::*m_testAsMethod)();
  596 +public:
  597 + TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
  598 +
  599 + void invoke() const override {
  600 + C obj;
  601 + (obj.*m_testAsMethod)();
  602 + }
  603 +};
  604 +
  605 +auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
  606 +
  607 +template<typename C>
  608 +auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
  609 + return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
  610 +}
  611 +
  612 +struct NameAndTags {
  613 + NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
  614 + StringRef name;
  615 + StringRef tags;
  616 +};
  617 +
  618 +struct AutoReg : NonCopyable {
  619 + AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
  620 + ~AutoReg();
  621 +};
  622 +
  623 +} // end namespace Catch
  624 +
  625 +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
  626 +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
  627 +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
  628 +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
  629 +
  630 +#if defined(CATCH_CONFIG_DISABLE)
  631 + #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
  632 + static void TestName()
  633 + #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
  634 + namespace{ \
  635 + struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
  636 + void test(); \
  637 + }; \
  638 + } \
  639 + void TestName::test()
  640 +
  641 +#endif
  642 +
  643 + ///////////////////////////////////////////////////////////////////////////////
  644 + #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
  645 + static void TestName(); \
  646 + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  647 + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  648 + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  649 + static void TestName()
  650 + #define INTERNAL_CATCH_TESTCASE( ... ) \
  651 + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
  652 +
  653 + ///////////////////////////////////////////////////////////////////////////////
  654 + #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
  655 + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  656 + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  657 + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  658 +
  659 + ///////////////////////////////////////////////////////////////////////////////
  660 + #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
  661 + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  662 + namespace{ \
  663 + struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
  664 + void test(); \
  665 + }; \
  666 + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  667 + } \
  668 + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  669 + void TestName::test()
  670 + #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
  671 + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
  672 +
  673 + ///////////////////////////////////////////////////////////////////////////////
  674 + #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
  675 + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  676 + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  677 + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  678 +
  679 +// end catch_test_registry.h
  680 +// start catch_capture.hpp
  681 +
  682 +// start catch_assertionhandler.h
  683 +
  684 +// start catch_assertioninfo.h
  685 +
  686 +// start catch_result_type.h
  687 +
  688 +namespace Catch {
  689 +
  690 + // ResultWas::OfType enum
  691 + struct ResultWas { enum OfType {
  692 + Unknown = -1,
  693 + Ok = 0,
  694 + Info = 1,
  695 + Warning = 2,
  696 +
  697 + FailureBit = 0x10,
  698 +
  699 + ExpressionFailed = FailureBit | 1,
  700 + ExplicitFailure = FailureBit | 2,
  701 +
  702 + Exception = 0x100 | FailureBit,
  703 +
  704 + ThrewException = Exception | 1,
  705 + DidntThrowException = Exception | 2,
  706 +
  707 + FatalErrorCondition = 0x200 | FailureBit
  708 +
  709 + }; };
  710 +
  711 + bool isOk( ResultWas::OfType resultType );
  712 + bool isJustInfo( int flags );
  713 +
  714 + // ResultDisposition::Flags enum
  715 + struct ResultDisposition { enum Flags {
  716 + Normal = 0x01,
  717 +
  718 + ContinueOnFailure = 0x02, // Failures fail test, but execution continues
  719 + FalseTest = 0x04, // Prefix expression with !
  720 + SuppressFail = 0x08 // Failures are reported but do not fail the test
  721 + }; };
  722 +
  723 + ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
  724 +
  725 + bool shouldContinueOnFailure( int flags );
  726 + inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
  727 + bool shouldSuppressFailure( int flags );
  728 +
  729 +} // end namespace Catch
  730 +
  731 +// end catch_result_type.h
  732 +namespace Catch {
  733 +
  734 + struct AssertionInfo
  735 + {
  736 + StringRef macroName;
  737 + SourceLineInfo lineInfo;
  738 + StringRef capturedExpression;
  739 + ResultDisposition::Flags resultDisposition;
  740 +
  741 + // We want to delete this constructor but a compiler bug in 4.8 means
  742 + // the struct is then treated as non-aggregate
  743 + //AssertionInfo() = delete;
  744 + };
  745 +
  746 +} // end namespace Catch
  747 +
  748 +// end catch_assertioninfo.h
  749 +// start catch_decomposer.h
  750 +
  751 +// start catch_tostring.h
  752 +
  753 +#include <vector>
  754 +#include <cstddef>
  755 +#include <type_traits>
  756 +#include <string>
  757 +// start catch_stream.h
  758 +
  759 +#include <iosfwd>
  760 +#include <cstddef>
  761 +#include <ostream>
  762 +
  763 +namespace Catch {
  764 +
  765 + std::ostream& cout();
  766 + std::ostream& cerr();
  767 + std::ostream& clog();
  768 +
  769 + class StringRef;
  770 +
  771 + struct IStream {
  772 + virtual ~IStream();
  773 + virtual std::ostream& stream() const = 0;
  774 + };
  775 +
  776 + auto makeStream( StringRef const &filename ) -> IStream const*;
  777 +
  778 + class ReusableStringStream {
  779 + std::size_t m_index;
  780 + std::ostream* m_oss;
  781 + public:
  782 + ReusableStringStream();
  783 + ~ReusableStringStream();
  784 +
  785 + auto str() const -> std::string;
  786 +
  787 + template<typename T>
  788 + auto operator << ( T const& value ) -> ReusableStringStream& {
  789 + *m_oss << value;
  790 + return *this;
  791 + }
  792 + auto get() -> std::ostream& { return *m_oss; }
  793 + };
  794 +}
  795 +
  796 +// end catch_stream.h
  797 +
  798 +#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  799 +#include <string_view>
  800 +#endif
  801 +
  802 +#ifdef __OBJC__
  803 +// start catch_objc_arc.hpp
  804 +
  805 +#import <Foundation/Foundation.h>
  806 +
  807 +#ifdef __has_feature
  808 +#define CATCH_ARC_ENABLED __has_feature(objc_arc)
  809 +#else
  810 +#define CATCH_ARC_ENABLED 0
  811 +#endif
  812 +
  813 +void arcSafeRelease( NSObject* obj );
  814 +id performOptionalSelector( id obj, SEL sel );
  815 +
  816 +#if !CATCH_ARC_ENABLED
  817 +inline void arcSafeRelease( NSObject* obj ) {
  818 + [obj release];
  819 +}
  820 +inline id performOptionalSelector( id obj, SEL sel ) {
  821 + if( [obj respondsToSelector: sel] )
  822 + return [obj performSelector: sel];
  823 + return nil;
  824 +}
  825 +#define CATCH_UNSAFE_UNRETAINED
  826 +#define CATCH_ARC_STRONG
  827 +#else
  828 +inline void arcSafeRelease( NSObject* ){}
  829 +inline id performOptionalSelector( id obj, SEL sel ) {
  830 +#ifdef __clang__
  831 +#pragma clang diagnostic push
  832 +#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  833 +#endif
  834 + if( [obj respondsToSelector: sel] )
  835 + return [obj performSelector: sel];
  836 +#ifdef __clang__
  837 +#pragma clang diagnostic pop
  838 +#endif
  839 + return nil;
  840 +}
  841 +#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
  842 +#define CATCH_ARC_STRONG __strong
  843 +#endif
  844 +
  845 +// end catch_objc_arc.hpp
  846 +#endif
  847 +
  848 +#ifdef _MSC_VER
  849 +#pragma warning(push)
  850 +#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
  851 +#endif
  852 +
  853 +// We need a dummy global operator<< so we can bring it into Catch namespace later
  854 +struct Catch_global_namespace_dummy {};
  855 +std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
  856 +
  857 +namespace Catch {
  858 + // Bring in operator<< from global namespace into Catch namespace
  859 + using ::operator<<;
  860 +
  861 + namespace Detail {
  862 +
  863 + extern const std::string unprintableString;
  864 +
  865 + std::string rawMemoryToString( const void *object, std::size_t size );
  866 +
  867 + template<typename T>
  868 + std::string rawMemoryToString( const T& object ) {
  869 + return rawMemoryToString( &object, sizeof(object) );
  870 + }
  871 +
  872 + template<typename T>
  873 + class IsStreamInsertable {
  874 + template<typename SS, typename TT>
  875 + static auto test(int)
  876 + -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
  877 +
  878 + template<typename, typename>
  879 + static auto test(...)->std::false_type;
  880 +
  881 + public:
  882 + static const bool value = decltype(test<std::ostream, const T&>(0))::value;
  883 + };
  884 +
  885 + template<typename E>
  886 + std::string convertUnknownEnumToString( E e );
  887 +
  888 + template<typename T>
  889 + typename std::enable_if<
  890 + !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
  891 + std::string>::type convertUnstreamable( T const& ) {
  892 + return Detail::unprintableString;
  893 + }
  894 + template<typename T>
  895 + typename std::enable_if<
  896 + !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
  897 + std::string>::type convertUnstreamable(T const& ex) {
  898 + return ex.what();
  899 + }
  900 +
  901 + template<typename T>
  902 + typename std::enable_if<
  903 + std::is_enum<T>::value
  904 + , std::string>::type convertUnstreamable( T const& value ) {
  905 + return convertUnknownEnumToString( value );
  906 + }
  907 +
  908 +#if defined(_MANAGED)
  909 + //! Convert a CLR string to a utf8 std::string
  910 + template<typename T>
  911 + std::string clrReferenceToString( T^ ref ) {
  912 + if (ref == nullptr)
  913 + return std::string("null");
  914 + auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
  915 + cli::pin_ptr<System::Byte> p = &bytes[0];
  916 + return std::string(reinterpret_cast<char const *>(p), bytes->Length);
  917 + }
  918 +#endif
  919 +
  920 + } // namespace Detail
  921 +
  922 + // If we decide for C++14, change these to enable_if_ts
  923 + template <typename T, typename = void>
  924 + struct StringMaker {
  925 + template <typename Fake = T>
  926 + static
  927 + typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
  928 + convert(const Fake& value) {
  929 + ReusableStringStream rss;
  930 + // NB: call using the function-like syntax to avoid ambiguity with
  931 + // user-defined templated operator<< under clang.
  932 + rss.operator<<(value);
  933 + return rss.str();
  934 + }
  935 +
  936 + template <typename Fake = T>
  937 + static
  938 + typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
  939 + convert( const Fake& value ) {
  940 +#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
  941 + return Detail::convertUnstreamable(value);
  942 +#else
  943 + return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
  944 +#endif
  945 + }
  946 + };
  947 +
  948 + namespace Detail {
  949 +
  950 + // This function dispatches all stringification requests inside of Catch.
  951 + // Should be preferably called fully qualified, like ::Catch::Detail::stringify
  952 + template <typename T>
  953 + std::string stringify(const T& e) {
  954 + return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
  955 + }
  956 +
  957 + template<typename E>
  958 + std::string convertUnknownEnumToString( E e ) {
  959 + return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
  960 + }
  961 +
  962 +#if defined(_MANAGED)
  963 + template <typename T>
  964 + std::string stringify( T^ e ) {
  965 + return ::Catch::StringMaker<T^>::convert(e);
  966 + }
  967 +#endif
  968 +
  969 + } // namespace Detail
  970 +
  971 + // Some predefined specializations
  972 +
  973 + template<>
  974 + struct StringMaker<std::string> {
  975 + static std::string convert(const std::string& str);
  976 + };
  977 +
  978 +#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  979 + template<>
  980 + struct StringMaker<std::string_view> {
  981 + static std::string convert(std::string_view str);
  982 + };
  983 +#endif
  984 +
  985 + template<>
  986 + struct StringMaker<char const *> {
  987 + static std::string convert(char const * str);
  988 + };
  989 + template<>
  990 + struct StringMaker<char *> {
  991 + static std::string convert(char * str);
  992 + };
  993 +
  994 +#ifdef CATCH_CONFIG_WCHAR
  995 + template<>
  996 + struct StringMaker<std::wstring> {
  997 + static std::string convert(const std::wstring& wstr);
  998 + };
  999 +
  1000 +# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  1001 + template<>
  1002 + struct StringMaker<std::wstring_view> {
  1003 + static std::string convert(std::wstring_view str);
  1004 + };
  1005 +# endif
  1006 +
  1007 + template<>
  1008 + struct StringMaker<wchar_t const *> {
  1009 + static std::string convert(wchar_t const * str);
  1010 + };
  1011 + template<>
  1012 + struct StringMaker<wchar_t *> {
  1013 + static std::string convert(wchar_t * str);
  1014 + };
  1015 +#endif
  1016 +
  1017 + // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
  1018 + // while keeping string semantics?
  1019 + template<int SZ>
  1020 + struct StringMaker<char[SZ]> {
  1021 + static std::string convert(char const* str) {
  1022 + return ::Catch::Detail::stringify(std::string{ str });
  1023 + }
  1024 + };
  1025 + template<int SZ>
  1026 + struct StringMaker<signed char[SZ]> {
  1027 + static std::string convert(signed char const* str) {
  1028 + return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
  1029 + }
  1030 + };
  1031 + template<int SZ>
  1032 + struct StringMaker<unsigned char[SZ]> {
  1033 + static std::string convert(unsigned char const* str) {
  1034 + return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
  1035 + }
  1036 + };
  1037 +
  1038 + template<>
  1039 + struct StringMaker<int> {
  1040 + static std::string convert(int value);
  1041 + };
  1042 + template<>
  1043 + struct StringMaker<long> {
  1044 + static std::string convert(long value);
  1045 + };
  1046 + template<>
  1047 + struct StringMaker<long long> {
  1048 + static std::string convert(long long value);
  1049 + };
  1050 + template<>
  1051 + struct StringMaker<unsigned int> {
  1052 + static std::string convert(unsigned int value);
  1053 + };
  1054 + template<>
  1055 + struct StringMaker<unsigned long> {
  1056 + static std::string convert(unsigned long value);
  1057 + };
  1058 + template<>
  1059 + struct StringMaker<unsigned long long> {
  1060 + static std::string convert(unsigned long long value);
  1061 + };
  1062 +
  1063 + template<>
  1064 + struct StringMaker<bool> {
  1065 + static std::string convert(bool b);
  1066 + };
  1067 +
  1068 + template<>
  1069 + struct StringMaker<char> {
  1070 + static std::string convert(char c);
  1071 + };
  1072 + template<>
  1073 + struct StringMaker<signed char> {
  1074 + static std::string convert(signed char c);
  1075 + };
  1076 + template<>
  1077 + struct StringMaker<unsigned char> {
  1078 + static std::string convert(unsigned char c);
  1079 + };
  1080 +
  1081 + template<>
  1082 + struct StringMaker<std::nullptr_t> {
  1083 + static std::string convert(std::nullptr_t);
  1084 + };
  1085 +
  1086 + template<>
  1087 + struct StringMaker<float> {
  1088 + static std::string convert(float value);
  1089 + };
  1090 + template<>
  1091 + struct StringMaker<double> {
  1092 + static std::string convert(double value);
  1093 + };
  1094 +
  1095 + template <typename T>
  1096 + struct StringMaker<T*> {
  1097 + template <typename U>
  1098 + static std::string convert(U* p) {
  1099 + if (p) {
  1100 + return ::Catch::Detail::rawMemoryToString(p);
  1101 + } else {
  1102 + return "nullptr";
  1103 + }
  1104 + }
  1105 + };
  1106 +
  1107 + template <typename R, typename C>
  1108 + struct StringMaker<R C::*> {
  1109 + static std::string convert(R C::* p) {
  1110 + if (p) {
  1111 + return ::Catch::Detail::rawMemoryToString(p);
  1112 + } else {
  1113 + return "nullptr";
  1114 + }
  1115 + }
  1116 + };
  1117 +
  1118 +#if defined(_MANAGED)
  1119 + template <typename T>
  1120 + struct StringMaker<T^> {
  1121 + static std::string convert( T^ ref ) {
  1122 + return ::Catch::Detail::clrReferenceToString(ref);
  1123 + }
  1124 + };
  1125 +#endif
  1126 +
  1127 + namespace Detail {
  1128 + template<typename InputIterator>
  1129 + std::string rangeToString(InputIterator first, InputIterator last) {
  1130 + ReusableStringStream rss;
  1131 + rss << "{ ";
  1132 + if (first != last) {
  1133 + rss << ::Catch::Detail::stringify(*first);
  1134 + for (++first; first != last; ++first)
  1135 + rss << ", " << ::Catch::Detail::stringify(*first);
  1136 + }
  1137 + rss << " }";
  1138 + return rss.str();
  1139 + }
  1140 + }
  1141 +
  1142 +#ifdef __OBJC__
  1143 + template<>
  1144 + struct StringMaker<NSString*> {
  1145 + static std::string convert(NSString * nsstring) {
  1146 + if (!nsstring)
  1147 + return "nil";
  1148 + return std::string("@") + [nsstring UTF8String];
  1149 + }
  1150 + };
  1151 + template<>
  1152 + struct StringMaker<NSObject*> {
  1153 + static std::string convert(NSObject* nsObject) {
  1154 + return ::Catch::Detail::stringify([nsObject description]);
  1155 + }
  1156 +
  1157 + };
  1158 + namespace Detail {
  1159 + inline std::string stringify( NSString* nsstring ) {
  1160 + return StringMaker<NSString*>::convert( nsstring );
  1161 + }
  1162 +
  1163 + } // namespace Detail
  1164 +#endif // __OBJC__
  1165 +
  1166 +} // namespace Catch
  1167 +
  1168 +//////////////////////////////////////////////////////
  1169 +// Separate std-lib types stringification, so it can be selectively enabled
  1170 +// This means that we do not bring in
  1171 +
  1172 +#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
  1173 +# define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
  1174 +# define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
  1175 +# define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
  1176 +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  1177 +#endif
  1178 +
  1179 +// Separate std::pair specialization
  1180 +#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
  1181 +#include <utility>
  1182 +namespace Catch {
  1183 + template<typename T1, typename T2>
  1184 + struct StringMaker<std::pair<T1, T2> > {
  1185 + static std::string convert(const std::pair<T1, T2>& pair) {
  1186 + ReusableStringStream rss;
  1187 + rss << "{ "
  1188 + << ::Catch::Detail::stringify(pair.first)
  1189 + << ", "
  1190 + << ::Catch::Detail::stringify(pair.second)
  1191 + << " }";
  1192 + return rss.str();
  1193 + }
  1194 + };
  1195 +}
  1196 +#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
  1197 +
  1198 +// Separate std::tuple specialization
  1199 +#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
  1200 +#include <tuple>
  1201 +namespace Catch {
  1202 + namespace Detail {
  1203 + template<
  1204 + typename Tuple,
  1205 + std::size_t N = 0,
  1206 + bool = (N < std::tuple_size<Tuple>::value)
  1207 + >
  1208 + struct TupleElementPrinter {
  1209 + static void print(const Tuple& tuple, std::ostream& os) {
  1210 + os << (N ? ", " : " ")
  1211 + << ::Catch::Detail::stringify(std::get<N>(tuple));
  1212 + TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
  1213 + }
  1214 + };
  1215 +
  1216 + template<
  1217 + typename Tuple,
  1218 + std::size_t N
  1219 + >
  1220 + struct TupleElementPrinter<Tuple, N, false> {
  1221 + static void print(const Tuple&, std::ostream&) {}
  1222 + };
  1223 +
  1224 + }
  1225 +
  1226 + template<typename ...Types>
  1227 + struct StringMaker<std::tuple<Types...>> {
  1228 + static std::string convert(const std::tuple<Types...>& tuple) {
  1229 + ReusableStringStream rss;
  1230 + rss << '{';
  1231 + Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
  1232 + rss << " }";
  1233 + return rss.str();
  1234 + }
  1235 + };
  1236 +}
  1237 +#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
  1238 +
  1239 +#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
  1240 +#include <variant>
  1241 +namespace Catch {
  1242 + template<>
  1243 + struct StringMaker<std::monostate> {
  1244 + static std::string convert(const std::monostate&) {
  1245 + return "{ }";
  1246 + }
  1247 + };
  1248 +
  1249 + template<typename... Elements>
  1250 + struct StringMaker<std::variant<Elements...>> {
  1251 + static std::string convert(const std::variant<Elements...>& variant) {
  1252 + if (variant.valueless_by_exception()) {
  1253 + return "{valueless variant}";
  1254 + } else {
  1255 + return std::visit(
  1256 + [](const auto& value) {
  1257 + return ::Catch::Detail::stringify(value);
  1258 + },
  1259 + variant
  1260 + );
  1261 + }
  1262 + }
  1263 + };
  1264 +}
  1265 +#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
  1266 +
  1267 +namespace Catch {
  1268 + struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
  1269 +
  1270 + // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
  1271 + using std::begin;
  1272 + using std::end;
  1273 +
  1274 + not_this_one begin( ... );
  1275 + not_this_one end( ... );
  1276 +
  1277 + template <typename T>
  1278 + struct is_range {
  1279 + static const bool value =
  1280 + !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
  1281 + !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
  1282 + };
  1283 +
  1284 +#if defined(_MANAGED) // Managed types are never ranges
  1285 + template <typename T>
  1286 + struct is_range<T^> {
  1287 + static const bool value = false;
  1288 + };
  1289 +#endif
  1290 +
  1291 + template<typename Range>
  1292 + std::string rangeToString( Range const& range ) {
  1293 + return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
  1294 + }
  1295 +
  1296 + // Handle vector<bool> specially
  1297 + template<typename Allocator>
  1298 + std::string rangeToString( std::vector<bool, Allocator> const& v ) {
  1299 + ReusableStringStream rss;
  1300 + rss << "{ ";
  1301 + bool first = true;
  1302 + for( bool b : v ) {
  1303 + if( first )
  1304 + first = false;
  1305 + else
  1306 + rss << ", ";
  1307 + rss << ::Catch::Detail::stringify( b );
  1308 + }
  1309 + rss << " }";
  1310 + return rss.str();
  1311 + }
  1312 +
  1313 + template<typename R>
  1314 + struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
  1315 + static std::string convert( R const& range ) {
  1316 + return rangeToString( range );
  1317 + }
  1318 + };
  1319 +
  1320 + template <typename T, int SZ>
  1321 + struct StringMaker<T[SZ]> {
  1322 + static std::string convert(T const(&arr)[SZ]) {
  1323 + return rangeToString(arr);
  1324 + }
  1325 + };
  1326 +
  1327 +} // namespace Catch
  1328 +
  1329 +// Separate std::chrono::duration specialization
  1330 +#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  1331 +#include <ctime>
  1332 +#include <ratio>
  1333 +#include <chrono>
  1334 +
  1335 +namespace Catch {
  1336 +
  1337 +template <class Ratio>
  1338 +struct ratio_string {
  1339 + static std::string symbol();
  1340 +};
  1341 +
  1342 +template <class Ratio>
  1343 +std::string ratio_string<Ratio>::symbol() {
  1344 + Catch::ReusableStringStream rss;
  1345 + rss << '[' << Ratio::num << '/'
  1346 + << Ratio::den << ']';
  1347 + return rss.str();
  1348 +}
  1349 +template <>
  1350 +struct ratio_string<std::atto> {
  1351 + static std::string symbol();
  1352 +};
  1353 +template <>
  1354 +struct ratio_string<std::femto> {
  1355 + static std::string symbol();
  1356 +};
  1357 +template <>
  1358 +struct ratio_string<std::pico> {
  1359 + static std::string symbol();
  1360 +};
  1361 +template <>
  1362 +struct ratio_string<std::nano> {
  1363 + static std::string symbol();
  1364 +};
  1365 +template <>
  1366 +struct ratio_string<std::micro> {
  1367 + static std::string symbol();
  1368 +};
  1369 +template <>
  1370 +struct ratio_string<std::milli> {
  1371 + static std::string symbol();
  1372 +};
  1373 +
  1374 + ////////////
  1375 + // std::chrono::duration specializations
  1376 + template<typename Value, typename Ratio>
  1377 + struct StringMaker<std::chrono::duration<Value, Ratio>> {
  1378 + static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
  1379 + ReusableStringStream rss;
  1380 + rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
  1381 + return rss.str();
  1382 + }
  1383 + };
  1384 + template<typename Value>
  1385 + struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
  1386 + static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
  1387 + ReusableStringStream rss;
  1388 + rss << duration.count() << " s";
  1389 + return rss.str();
  1390 + }
  1391 + };
  1392 + template<typename Value>
  1393 + struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
  1394 + static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
  1395 + ReusableStringStream rss;
  1396 + rss << duration.count() << " m";
  1397 + return rss.str();
  1398 + }
  1399 + };
  1400 + template<typename Value>
  1401 + struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
  1402 + static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
  1403 + ReusableStringStream rss;
  1404 + rss << duration.count() << " h";
  1405 + return rss.str();
  1406 + }
  1407 + };
  1408 +
  1409 + ////////////
  1410 + // std::chrono::time_point specialization
  1411 + // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
  1412 + template<typename Clock, typename Duration>
  1413 + struct StringMaker<std::chrono::time_point<Clock, Duration>> {
  1414 + static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
  1415 + return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
  1416 + }
  1417 + };
  1418 + // std::chrono::time_point<system_clock> specialization
  1419 + template<typename Duration>
  1420 + struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
  1421 + static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
  1422 + auto converted = std::chrono::system_clock::to_time_t(time_point);
  1423 +
  1424 +#ifdef _MSC_VER
  1425 + std::tm timeInfo = {};
  1426 + gmtime_s(&timeInfo, &converted);
  1427 +#else
  1428 + std::tm* timeInfo = std::gmtime(&converted);
  1429 +#endif
  1430 +
  1431 + auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  1432 + char timeStamp[timeStampSize];
  1433 + const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
  1434 +
  1435 +#ifdef _MSC_VER
  1436 + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  1437 +#else
  1438 + std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
  1439 +#endif
  1440 + return std::string(timeStamp);
  1441 + }
  1442 + };
  1443 +}
  1444 +#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  1445 +
  1446 +#ifdef _MSC_VER
  1447 +#pragma warning(pop)
  1448 +#endif
  1449 +
  1450 +// end catch_tostring.h
  1451 +#include <iosfwd>
  1452 +
  1453 +#ifdef _MSC_VER
  1454 +#pragma warning(push)
  1455 +#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
  1456 +#pragma warning(disable:4018) // more "signed/unsigned mismatch"
  1457 +#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
  1458 +#pragma warning(disable:4180) // qualifier applied to function type has no meaning
  1459 +#endif
  1460 +
  1461 +namespace Catch {
  1462 +
  1463 + struct ITransientExpression {
  1464 + auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
  1465 + auto getResult() const -> bool { return m_result; }
  1466 + virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
  1467 +
  1468 + ITransientExpression( bool isBinaryExpression, bool result )
  1469 + : m_isBinaryExpression( isBinaryExpression ),
  1470 + m_result( result )
  1471 + {}
  1472 +
  1473 + // We don't actually need a virtual destructor, but many static analysers
  1474 + // complain if it's not here :-(
  1475 + virtual ~ITransientExpression();
  1476 +
  1477 + bool m_isBinaryExpression;
  1478 + bool m_result;
  1479 +
  1480 + };
  1481 +
  1482 + void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
  1483 +
  1484 + template<typename LhsT, typename RhsT>
  1485 + class BinaryExpr : public ITransientExpression {
  1486 + LhsT m_lhs;
  1487 + StringRef m_op;
  1488 + RhsT m_rhs;
  1489 +
  1490 + void streamReconstructedExpression( std::ostream &os ) const override {
  1491 + formatReconstructedExpression
  1492 + ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
  1493 + }
  1494 +
  1495 + public:
  1496 + BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
  1497 + : ITransientExpression{ true, comparisonResult },
  1498 + m_lhs( lhs ),
  1499 + m_op( op ),
  1500 + m_rhs( rhs )
  1501 + {}
  1502 + };
  1503 +
  1504 + template<typename LhsT>
  1505 + class UnaryExpr : public ITransientExpression {
  1506 + LhsT m_lhs;
  1507 +
  1508 + void streamReconstructedExpression( std::ostream &os ) const override {
  1509 + os << Catch::Detail::stringify( m_lhs );
  1510 + }
  1511 +
  1512 + public:
  1513 + explicit UnaryExpr( LhsT lhs )
  1514 + : ITransientExpression{ false, lhs ? true : false },
  1515 + m_lhs( lhs )
  1516 + {}
  1517 + };
  1518 +
  1519 + // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
  1520 + template<typename LhsT, typename RhsT>
  1521 + auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
  1522 + template<typename T>
  1523 + auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
  1524 + template<typename T>
  1525 + auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
  1526 + template<typename T>
  1527 + auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
  1528 + template<typename T>
  1529 + auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
  1530 +
  1531 + template<typename LhsT, typename RhsT>
  1532 + auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
  1533 + template<typename T>
  1534 + auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
  1535 + template<typename T>
  1536 + auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
  1537 + template<typename T>
  1538 + auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
  1539 + template<typename T>
  1540 + auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
  1541 +
  1542 + template<typename LhsT>
  1543 + class ExprLhs {
  1544 + LhsT m_lhs;
  1545 + public:
  1546 + explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
  1547 +
  1548 + template<typename RhsT>
  1549 + auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1550 + return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
  1551 + }
  1552 + auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
  1553 + return { m_lhs == rhs, m_lhs, "==", rhs };
  1554 + }
  1555 +
  1556 + template<typename RhsT>
  1557 + auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1558 + return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
  1559 + }
  1560 + auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
  1561 + return { m_lhs != rhs, m_lhs, "!=", rhs };
  1562 + }
  1563 +
  1564 + template<typename RhsT>
  1565 + auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1566 + return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
  1567 + }
  1568 + template<typename RhsT>
  1569 + auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1570 + return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
  1571 + }
  1572 + template<typename RhsT>
  1573 + auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1574 + return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
  1575 + }
  1576 + template<typename RhsT>
  1577 + auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1578 + return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
  1579 + }
  1580 +
  1581 + auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
  1582 + return UnaryExpr<LhsT>{ m_lhs };
  1583 + }
  1584 + };
  1585 +
  1586 + void handleExpression( ITransientExpression const& expr );
  1587 +
  1588 + template<typename T>
  1589 + void handleExpression( ExprLhs<T> const& expr ) {
  1590 + handleExpression( expr.makeUnaryExpr() );
  1591 + }
  1592 +
  1593 + struct Decomposer {
  1594 + template<typename T>
  1595 + auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
  1596 + return ExprLhs<T const&>{ lhs };
  1597 + }
  1598 +
  1599 + auto operator <=( bool value ) -> ExprLhs<bool> {
  1600 + return ExprLhs<bool>{ value };
  1601 + }
  1602 + };
  1603 +
  1604 +} // end namespace Catch
  1605 +
  1606 +#ifdef _MSC_VER
  1607 +#pragma warning(pop)
  1608 +#endif
  1609 +
  1610 +// end catch_decomposer.h
  1611 +// start catch_interfaces_capture.h
  1612 +
  1613 +#include <string>
  1614 +
  1615 +namespace Catch {
  1616 +
  1617 + class AssertionResult;
  1618 + struct AssertionInfo;
  1619 + struct SectionInfo;
  1620 + struct SectionEndInfo;
  1621 + struct MessageInfo;
  1622 + struct Counts;
  1623 + struct BenchmarkInfo;
  1624 + struct BenchmarkStats;
  1625 + struct AssertionReaction;
  1626 + struct SourceLineInfo;
  1627 +
  1628 + struct ITransientExpression;
  1629 + struct IGeneratorTracker;
  1630 +
  1631 + struct IResultCapture {
  1632 +
  1633 + virtual ~IResultCapture();
  1634 +
  1635 + virtual bool sectionStarted( SectionInfo const& sectionInfo,
  1636 + Counts& assertions ) = 0;
  1637 + virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
  1638 + virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
  1639 +
  1640 + virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
  1641 +
  1642 + virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
  1643 + virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
  1644 +
  1645 + virtual void pushScopedMessage( MessageInfo const& message ) = 0;
  1646 + virtual void popScopedMessage( MessageInfo const& message ) = 0;
  1647 +
  1648 + virtual void handleFatalErrorCondition( StringRef message ) = 0;
  1649 +
  1650 + virtual void handleExpr
  1651 + ( AssertionInfo const& info,
  1652 + ITransientExpression const& expr,
  1653 + AssertionReaction& reaction ) = 0;
  1654 + virtual void handleMessage
  1655 + ( AssertionInfo const& info,
  1656 + ResultWas::OfType resultType,
  1657 + StringRef const& message,
  1658 + AssertionReaction& reaction ) = 0;
  1659 + virtual void handleUnexpectedExceptionNotThrown
  1660 + ( AssertionInfo const& info,
  1661 + AssertionReaction& reaction ) = 0;
  1662 + virtual void handleUnexpectedInflightException
  1663 + ( AssertionInfo const& info,
  1664 + std::string const& message,
  1665 + AssertionReaction& reaction ) = 0;
  1666 + virtual void handleIncomplete
  1667 + ( AssertionInfo const& info ) = 0;
  1668 + virtual void handleNonExpr
  1669 + ( AssertionInfo const &info,
  1670 + ResultWas::OfType resultType,
  1671 + AssertionReaction &reaction ) = 0;
  1672 +
  1673 + virtual bool lastAssertionPassed() = 0;
  1674 + virtual void assertionPassed() = 0;
  1675 +
  1676 + // Deprecated, do not use:
  1677 + virtual std::string getCurrentTestName() const = 0;
  1678 + virtual const AssertionResult* getLastResult() const = 0;
  1679 + virtual void exceptionEarlyReported() = 0;
  1680 + };
  1681 +
  1682 + IResultCapture& getResultCapture();
  1683 +}
  1684 +
  1685 +// end catch_interfaces_capture.h
  1686 +namespace Catch {
  1687 +
  1688 + struct TestFailureException{};
  1689 + struct AssertionResultData;
  1690 + struct IResultCapture;
  1691 + class RunContext;
  1692 +
  1693 + class LazyExpression {
  1694 + friend class AssertionHandler;
  1695 + friend struct AssertionStats;
  1696 + friend class RunContext;
  1697 +
  1698 + ITransientExpression const* m_transientExpression = nullptr;
  1699 + bool m_isNegated;
  1700 + public:
  1701 + LazyExpression( bool isNegated );
  1702 + LazyExpression( LazyExpression const& other );
  1703 + LazyExpression& operator = ( LazyExpression const& ) = delete;
  1704 +
  1705 + explicit operator bool() const;
  1706 +
  1707 + friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
  1708 + };
  1709 +
  1710 + struct AssertionReaction {
  1711 + bool shouldDebugBreak = false;
  1712 + bool shouldThrow = false;
  1713 + };
  1714 +
  1715 + class AssertionHandler {
  1716 + AssertionInfo m_assertionInfo;
  1717 + AssertionReaction m_reaction;
  1718 + bool m_completed = false;
  1719 + IResultCapture& m_resultCapture;
  1720 +
  1721 + public:
  1722 + AssertionHandler
  1723 + ( StringRef const& macroName,
  1724 + SourceLineInfo const& lineInfo,
  1725 + StringRef capturedExpression,
  1726 + ResultDisposition::Flags resultDisposition );
  1727 + ~AssertionHandler() {
  1728