llvm-journey

LLVM Journey
git clone git://0xff.ir/g/llvm-journey.git
Log | Files | Refs | README | LICENSE

catch.hpp (650013B)


      1 /*
      2  *  Catch v2.13.0
      3  *  Generated: 2020-07-12 20:07:49.015950
      4  *  ----------------------------------------------------------
      5  *  This file has been merged from multiple headers. Please don't edit it directly
      6  *  Copyright (c) 2020 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 13
     18 #define CATCH_VERSION_PATCH 0
     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      // Because REQUIREs trigger GCC's -Wparentheses, and because still
     40      // supported version of g++ have only buggy support for _Pragmas,
     41      // Wparentheses have to be suppressed globally.
     42 #    pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details
     43 
     44 #    pragma GCC diagnostic push
     45 #    pragma GCC diagnostic ignored "-Wunused-variable"
     46 #    pragma GCC diagnostic ignored "-Wpadded"
     47 #endif
     48 // end catch_suppress_warnings.h
     49 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
     50 #  define CATCH_IMPL
     51 #  define CATCH_CONFIG_ALL_PARTS
     52 #endif
     53 
     54 // In the impl file, we want to have access to all parts of the headers
     55 // Can also be used to sanely support PCHs
     56 #if defined(CATCH_CONFIG_ALL_PARTS)
     57 #  define CATCH_CONFIG_EXTERNAL_INTERFACES
     58 #  if defined(CATCH_CONFIG_DISABLE_MATCHERS)
     59 #    undef CATCH_CONFIG_DISABLE_MATCHERS
     60 #  endif
     61 #  if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
     62 #    define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
     63 #  endif
     64 #endif
     65 
     66 #if !defined(CATCH_CONFIG_IMPL_ONLY)
     67 // start catch_platform.h
     68 
     69 #ifdef __APPLE__
     70 # include <TargetConditionals.h>
     71 # if TARGET_OS_OSX == 1
     72 #  define CATCH_PLATFORM_MAC
     73 # elif TARGET_OS_IPHONE == 1
     74 #  define CATCH_PLATFORM_IPHONE
     75 # endif
     76 
     77 #elif defined(linux) || defined(__linux) || defined(__linux__)
     78 #  define CATCH_PLATFORM_LINUX
     79 
     80 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
     81 #  define CATCH_PLATFORM_WINDOWS
     82 #endif
     83 
     84 // end catch_platform.h
     85 
     86 #ifdef CATCH_IMPL
     87 #  ifndef CLARA_CONFIG_MAIN
     88 #    define CLARA_CONFIG_MAIN_NOT_DEFINED
     89 #    define CLARA_CONFIG_MAIN
     90 #  endif
     91 #endif
     92 
     93 // start catch_user_interfaces.h
     94 
     95 namespace Catch {
     96     unsigned int rngSeed();
     97 }
     98 
     99 // end catch_user_interfaces.h
    100 // start catch_tag_alias_autoregistrar.h
    101 
    102 // start catch_common.h
    103 
    104 // start catch_compiler_capabilities.h
    105 
    106 // Detect a number of compiler features - by compiler
    107 // The following features are defined:
    108 //
    109 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
    110 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
    111 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
    112 // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
    113 // ****************
    114 // Note to maintainers: if new toggles are added please document them
    115 // in configuration.md, too
    116 // ****************
    117 
    118 // In general each macro has a _NO_<feature name> form
    119 // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
    120 // Many features, at point of detection, define an _INTERNAL_ macro, so they
    121 // can be combined, en-mass, with the _NO_ forms later.
    122 
    123 #ifdef __cplusplus
    124 
    125 #  if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
    126 #    define CATCH_CPP14_OR_GREATER
    127 #  endif
    128 
    129 #  if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
    130 #    define CATCH_CPP17_OR_GREATER
    131 #  endif
    132 
    133 #endif
    134 
    135 #if defined(__cpp_lib_uncaught_exceptions)
    136 #  define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
    137 #endif
    138 
    139 // We have to avoid both ICC and Clang, because they try to mask themselves
    140 // as gcc, and we want only GCC in this block
    141 #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC)
    142 #    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
    143 #    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "GCC diagnostic pop" )
    144 
    145 #    define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
    146 
    147 #endif
    148 
    149 #if defined(__clang__)
    150 
    151 #    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
    152 #    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "clang diagnostic pop" )
    153 
    154 // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
    155 // which results in calls to destructors being emitted for each temporary,
    156 // without a matching initialization. In practice, this can result in something
    157 // like `std::string::~string` being called on an uninitialized value.
    158 //
    159 // For example, this code will likely segfault under IBM XL:
    160 // ```
    161 // REQUIRE(std::string("12") + "34" == "1234")
    162 // ```
    163 //
    164 // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
    165 #  if !defined(__ibmxl__)
    166 #    define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
    167 #  endif
    168 
    169 #    define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
    170          _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
    171          _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
    172 
    173 #    define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
    174          _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
    175 
    176 #    define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
    177          _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
    178 
    179 #    define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
    180          _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
    181 
    182 #    define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
    183          _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
    184 
    185 #endif // __clang__
    186 
    187 ////////////////////////////////////////////////////////////////////////////////
    188 // Assume that non-Windows platforms support posix signals by default
    189 #if !defined(CATCH_PLATFORM_WINDOWS)
    190     #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
    191 #endif
    192 
    193 ////////////////////////////////////////////////////////////////////////////////
    194 // We know some environments not to support full POSIX signals
    195 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
    196     #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
    197 #endif
    198 
    199 #ifdef __OS400__
    200 #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
    201 #       define CATCH_CONFIG_COLOUR_NONE
    202 #endif
    203 
    204 ////////////////////////////////////////////////////////////////////////////////
    205 // Android somehow still does not support std::to_string
    206 #if defined(__ANDROID__)
    207 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
    208 #    define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
    209 #endif
    210 
    211 ////////////////////////////////////////////////////////////////////////////////
    212 // Not all Windows environments support SEH properly
    213 #if defined(__MINGW32__)
    214 #    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
    215 #endif
    216 
    217 ////////////////////////////////////////////////////////////////////////////////
    218 // PS4
    219 #if defined(__ORBIS__)
    220 #    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
    221 #endif
    222 
    223 ////////////////////////////////////////////////////////////////////////////////
    224 // Cygwin
    225 #ifdef __CYGWIN__
    226 
    227 // Required for some versions of Cygwin to declare gettimeofday
    228 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
    229 #   define _BSD_SOURCE
    230 // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
    231 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
    232 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
    233            && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
    234 
    235 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
    236 
    237 # endif
    238 #endif // __CYGWIN__
    239 
    240 ////////////////////////////////////////////////////////////////////////////////
    241 // Visual C++
    242 #if defined(_MSC_VER)
    243 
    244 #  define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
    245 #  define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  __pragma( warning(pop) )
    246 
    247 #  if _MSC_VER >= 1900 // Visual Studio 2015 or newer
    248 #    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
    249 #  endif
    250 
    251 // Universal Windows platform does not support SEH
    252 // Or console colours (or console at all...)
    253 #  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
    254 #    define CATCH_CONFIG_COLOUR_NONE
    255 #  else
    256 #    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
    257 #  endif
    258 
    259 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
    260 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
    261 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
    262 #  if !defined(__clang__) // Handle Clang masquerading for msvc
    263 #    if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
    264 #      define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    265 #    endif // MSVC_TRADITIONAL
    266 #  endif // __clang__
    267 
    268 #endif // _MSC_VER
    269 
    270 #if defined(_REENTRANT) || defined(_MSC_VER)
    271 // Enable async processing, as -pthread is specified or no additional linking is required
    272 # define CATCH_INTERNAL_CONFIG_USE_ASYNC
    273 #endif // _MSC_VER
    274 
    275 ////////////////////////////////////////////////////////////////////////////////
    276 // Check if we are compiled with -fno-exceptions or equivalent
    277 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
    278 #  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
    279 #endif
    280 
    281 ////////////////////////////////////////////////////////////////////////////////
    282 // DJGPP
    283 #ifdef __DJGPP__
    284 #  define CATCH_INTERNAL_CONFIG_NO_WCHAR
    285 #endif // __DJGPP__
    286 
    287 ////////////////////////////////////////////////////////////////////////////////
    288 // Embarcadero C++Build
    289 #if defined(__BORLANDC__)
    290     #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
    291 #endif
    292 
    293 ////////////////////////////////////////////////////////////////////////////////
    294 
    295 // Use of __COUNTER__ is suppressed during code analysis in
    296 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
    297 // handled by it.
    298 // Otherwise all supported compilers support COUNTER macro,
    299 // but user still might want to turn it off
    300 #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
    301     #define CATCH_INTERNAL_CONFIG_COUNTER
    302 #endif
    303 
    304 ////////////////////////////////////////////////////////////////////////////////
    305 
    306 // RTX is a special version of Windows that is real time.
    307 // This means that it is detected as Windows, but does not provide
    308 // the same set of capabilities as real Windows does.
    309 #if defined(UNDER_RTSS) || defined(RTX64_BUILD)
    310     #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
    311     #define CATCH_INTERNAL_CONFIG_NO_ASYNC
    312     #define CATCH_CONFIG_COLOUR_NONE
    313 #endif
    314 
    315 #if !defined(_GLIBCXX_USE_C99_MATH_TR1)
    316 #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
    317 #endif
    318 
    319 // Various stdlib support checks that require __has_include
    320 #if defined(__has_include)
    321   // Check if string_view is available and usable
    322   #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
    323   #    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
    324   #endif
    325 
    326   // Check if optional is available and usable
    327   #  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
    328   #    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
    329   #  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
    330 
    331   // Check if byte is available and usable
    332   #  if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
    333   #    define CATCH_INTERNAL_CONFIG_CPP17_BYTE
    334   #  endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
    335 
    336   // Check if variant is available and usable
    337   #  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
    338   #    if defined(__clang__) && (__clang_major__ < 8)
    339          // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
    340          // fix should be in clang 8, workaround in libstdc++ 8.2
    341   #      include <ciso646>
    342   #      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
    343   #        define CATCH_CONFIG_NO_CPP17_VARIANT
    344   #      else
    345   #        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
    346   #      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
    347   #    else
    348   #      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
    349   #    endif // defined(__clang__) && (__clang_major__ < 8)
    350   #  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
    351 #endif // defined(__has_include)
    352 
    353 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
    354 #   define CATCH_CONFIG_COUNTER
    355 #endif
    356 #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)
    357 #   define CATCH_CONFIG_WINDOWS_SEH
    358 #endif
    359 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
    360 #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)
    361 #   define CATCH_CONFIG_POSIX_SIGNALS
    362 #endif
    363 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
    364 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
    365 #   define CATCH_CONFIG_WCHAR
    366 #endif
    367 
    368 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
    369 #    define CATCH_CONFIG_CPP11_TO_STRING
    370 #endif
    371 
    372 #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
    373 #  define CATCH_CONFIG_CPP17_OPTIONAL
    374 #endif
    375 
    376 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
    377 #  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
    378 #endif
    379 
    380 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
    381 #  define CATCH_CONFIG_CPP17_STRING_VIEW
    382 #endif
    383 
    384 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
    385 #  define CATCH_CONFIG_CPP17_VARIANT
    386 #endif
    387 
    388 #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
    389 #  define CATCH_CONFIG_CPP17_BYTE
    390 #endif
    391 
    392 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
    393 #  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
    394 #endif
    395 
    396 #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)
    397 #  define CATCH_CONFIG_NEW_CAPTURE
    398 #endif
    399 
    400 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
    401 #  define CATCH_CONFIG_DISABLE_EXCEPTIONS
    402 #endif
    403 
    404 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
    405 #  define CATCH_CONFIG_POLYFILL_ISNAN
    406 #endif
    407 
    408 #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC)  && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
    409 #  define CATCH_CONFIG_USE_ASYNC
    410 #endif
    411 
    412 #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
    413 #  define CATCH_CONFIG_ANDROID_LOGWRITE
    414 #endif
    415 
    416 #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
    417 #  define CATCH_CONFIG_GLOBAL_NEXTAFTER
    418 #endif
    419 
    420 // Even if we do not think the compiler has that warning, we still have
    421 // to provide a macro that can be used by the code.
    422 #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
    423 #   define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
    424 #endif
    425 #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
    426 #   define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
    427 #endif
    428 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
    429 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
    430 #endif
    431 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
    432 #   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
    433 #endif
    434 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
    435 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
    436 #endif
    437 #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
    438 #   define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
    439 #endif
    440 
    441 // The goal of this macro is to avoid evaluation of the arguments, but
    442 // still have the compiler warn on problems inside...
    443 #if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)
    444 #   define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
    445 #endif
    446 
    447 #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
    448 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
    449 #elif defined(__clang__) && (__clang_major__ < 5)
    450 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
    451 #endif
    452 
    453 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
    454 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
    455 #endif
    456 
    457 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
    458 #define CATCH_TRY if ((true))
    459 #define CATCH_CATCH_ALL if ((false))
    460 #define CATCH_CATCH_ANON(type) if ((false))
    461 #else
    462 #define CATCH_TRY try
    463 #define CATCH_CATCH_ALL catch (...)
    464 #define CATCH_CATCH_ANON(type) catch (type)
    465 #endif
    466 
    467 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
    468 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    469 #endif
    470 
    471 // end catch_compiler_capabilities.h
    472 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
    473 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
    474 #ifdef CATCH_CONFIG_COUNTER
    475 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
    476 #else
    477 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
    478 #endif
    479 
    480 #include <iosfwd>
    481 #include <string>
    482 #include <cstdint>
    483 
    484 // We need a dummy global operator<< so we can bring it into Catch namespace later
    485 struct Catch_global_namespace_dummy {};
    486 std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
    487 
    488 namespace Catch {
    489 
    490     struct CaseSensitive { enum Choice {
    491         Yes,
    492         No
    493     }; };
    494 
    495     class NonCopyable {
    496         NonCopyable( NonCopyable const& )              = delete;
    497         NonCopyable( NonCopyable && )                  = delete;
    498         NonCopyable& operator = ( NonCopyable const& ) = delete;
    499         NonCopyable& operator = ( NonCopyable && )     = delete;
    500 
    501     protected:
    502         NonCopyable();
    503         virtual ~NonCopyable();
    504     };
    505 
    506     struct SourceLineInfo {
    507 
    508         SourceLineInfo() = delete;
    509         SourceLineInfo( char const* _file, std::size_t _line ) noexcept
    510         :   file( _file ),
    511             line( _line )
    512         {}
    513 
    514         SourceLineInfo( SourceLineInfo const& other )            = default;
    515         SourceLineInfo& operator = ( SourceLineInfo const& )     = default;
    516         SourceLineInfo( SourceLineInfo&& )              noexcept = default;
    517         SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
    518 
    519         bool empty() const noexcept { return file[0] == '\0'; }
    520         bool operator == ( SourceLineInfo const& other ) const noexcept;
    521         bool operator < ( SourceLineInfo const& other ) const noexcept;
    522 
    523         char const* file;
    524         std::size_t line;
    525     };
    526 
    527     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
    528 
    529     // Bring in operator<< from global namespace into Catch namespace
    530     // This is necessary because the overload of operator<< above makes
    531     // lookup stop at namespace Catch
    532     using ::operator<<;
    533 
    534     // Use this in variadic streaming macros to allow
    535     //    >> +StreamEndStop
    536     // as well as
    537     //    >> stuff +StreamEndStop
    538     struct StreamEndStop {
    539         std::string operator+() const;
    540     };
    541     template<typename T>
    542     T const& operator + ( T const& value, StreamEndStop ) {
    543         return value;
    544     }
    545 }
    546 
    547 #define CATCH_INTERNAL_LINEINFO \
    548     ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
    549 
    550 // end catch_common.h
    551 namespace Catch {
    552 
    553     struct RegistrarForTagAliases {
    554         RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
    555     };
    556 
    557 } // end namespace Catch
    558 
    559 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
    560     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
    561     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
    562     namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
    563     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
    564 
    565 // end catch_tag_alias_autoregistrar.h
    566 // start catch_test_registry.h
    567 
    568 // start catch_interfaces_testcase.h
    569 
    570 #include <vector>
    571 
    572 namespace Catch {
    573 
    574     class TestSpec;
    575 
    576     struct ITestInvoker {
    577         virtual void invoke () const = 0;
    578         virtual ~ITestInvoker();
    579     };
    580 
    581     class TestCase;
    582     struct IConfig;
    583 
    584     struct ITestCaseRegistry {
    585         virtual ~ITestCaseRegistry();
    586         virtual std::vector<TestCase> const& getAllTests() const = 0;
    587         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
    588     };
    589 
    590     bool isThrowSafe( TestCase const& testCase, IConfig const& config );
    591     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
    592     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
    593     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
    594 
    595 }
    596 
    597 // end catch_interfaces_testcase.h
    598 // start catch_stringref.h
    599 
    600 #include <cstddef>
    601 #include <string>
    602 #include <iosfwd>
    603 #include <cassert>
    604 
    605 namespace Catch {
    606 
    607     /// A non-owning string class (similar to the forthcoming std::string_view)
    608     /// Note that, because a StringRef may be a substring of another string,
    609     /// it may not be null terminated.
    610     class StringRef {
    611     public:
    612         using size_type = std::size_t;
    613         using const_iterator = const char*;
    614 
    615     private:
    616         static constexpr char const* const s_empty = "";
    617 
    618         char const* m_start = s_empty;
    619         size_type m_size = 0;
    620 
    621     public: // construction
    622         constexpr StringRef() noexcept = default;
    623 
    624         StringRef( char const* rawChars ) noexcept;
    625 
    626         constexpr StringRef( char const* rawChars, size_type size ) noexcept
    627         :   m_start( rawChars ),
    628             m_size( size )
    629         {}
    630 
    631         StringRef( std::string const& stdString ) noexcept
    632         :   m_start( stdString.c_str() ),
    633             m_size( stdString.size() )
    634         {}
    635 
    636         explicit operator std::string() const {
    637             return std::string(m_start, m_size);
    638         }
    639 
    640     public: // operators
    641         auto operator == ( StringRef const& other ) const noexcept -> bool;
    642         auto operator != (StringRef const& other) const noexcept -> bool {
    643             return !(*this == other);
    644         }
    645 
    646         auto operator[] ( size_type index ) const noexcept -> char {
    647             assert(index < m_size);
    648             return m_start[index];
    649         }
    650 
    651     public: // named queries
    652         constexpr auto empty() const noexcept -> bool {
    653             return m_size == 0;
    654         }
    655         constexpr auto size() const noexcept -> size_type {
    656             return m_size;
    657         }
    658 
    659         // Returns the current start pointer. If the StringRef is not
    660         // null-terminated, throws std::domain_exception
    661         auto c_str() const -> char const*;
    662 
    663     public: // substrings and searches
    664         // Returns a substring of [start, start + length).
    665         // If start + length > size(), then the substring is [start, size()).
    666         // If start > size(), then the substring is empty.
    667         auto substr( size_type start, size_type length ) const noexcept -> StringRef;
    668 
    669         // Returns the current start pointer. May not be null-terminated.
    670         auto data() const noexcept -> char const*;
    671 
    672         constexpr auto isNullTerminated() const noexcept -> bool {
    673             return m_start[m_size] == '\0';
    674         }
    675 
    676     public: // iterators
    677         constexpr const_iterator begin() const { return m_start; }
    678         constexpr const_iterator end() const { return m_start + m_size; }
    679     };
    680 
    681     auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
    682     auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
    683 
    684     constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
    685         return StringRef( rawChars, size );
    686     }
    687 } // namespace Catch
    688 
    689 constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
    690     return Catch::StringRef( rawChars, size );
    691 }
    692 
    693 // end catch_stringref.h
    694 // start catch_preprocessor.hpp
    695 
    696 
    697 #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
    698 #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
    699 #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
    700 #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
    701 #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
    702 #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
    703 
    704 #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    705 #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
    706 // MSVC needs more evaluations
    707 #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
    708 #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
    709 #else
    710 #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL5(__VA_ARGS__)
    711 #endif
    712 
    713 #define CATCH_REC_END(...)
    714 #define CATCH_REC_OUT
    715 
    716 #define CATCH_EMPTY()
    717 #define CATCH_DEFER(id) id CATCH_EMPTY()
    718 
    719 #define CATCH_REC_GET_END2() 0, CATCH_REC_END
    720 #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
    721 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
    722 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
    723 #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
    724 #define CATCH_REC_NEXT(test, next)  CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
    725 
    726 #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
    727 #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
    728 #define CATCH_REC_LIST2(f, x, peek, ...)   f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
    729 
    730 #define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
    731 #define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ )
    732 #define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...)   f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
    733 
    734 // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
    735 // and passes userdata as the first parameter to each invocation,
    736 // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
    737 #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
    738 
    739 #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
    740 
    741 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
    742 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
    743 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
    744 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
    745 #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
    746 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    747 #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
    748 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
    749 #else
    750 // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
    751 #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
    752 #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
    753 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
    754 #endif
    755 
    756 #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
    757 #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
    758 
    759 #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
    760 
    761 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    762 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
    763 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
    764 #else
    765 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
    766 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
    767 #endif
    768 
    769 #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
    770     CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
    771 
    772 #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
    773 #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
    774 #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
    775 #define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
    776 #define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
    777 #define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
    778 #define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)
    779 #define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
    780 #define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
    781 #define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
    782 #define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
    783 
    784 #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
    785 
    786 #define INTERNAL_CATCH_TYPE_GEN\
    787     template<typename...> struct TypeList {};\
    788     template<typename...Ts>\
    789     constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
    790     template<template<typename...> class...> struct TemplateTypeList{};\
    791     template<template<typename...> class...Cs>\
    792     constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
    793     template<typename...>\
    794     struct append;\
    795     template<typename...>\
    796     struct rewrap;\
    797     template<template<typename...> class, typename...>\
    798     struct create;\
    799     template<template<typename...> class, typename>\
    800     struct convert;\
    801     \
    802     template<typename T> \
    803     struct append<T> { using type = T; };\
    804     template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
    805     struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
    806     template< template<typename...> class L1, typename...E1, typename...Rest>\
    807     struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
    808     \
    809     template< template<typename...> class Container, template<typename...> class List, typename...elems>\
    810     struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
    811     template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
    812     struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
    813     \
    814     template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
    815     struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
    816     template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
    817     struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
    818 
    819 #define INTERNAL_CATCH_NTTP_1(signature, ...)\
    820     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
    821     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    822     constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
    823     template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
    824     template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
    825     constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
    826     \
    827     template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    828     struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
    829     template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
    830     struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
    831     template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
    832     struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
    833 
    834 #define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
    835 #define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
    836     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    837     static void TestName()
    838 #define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
    839     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    840     static void TestName()
    841 
    842 #define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
    843 #define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
    844     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    845     static void TestName()
    846 #define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
    847     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    848     static void TestName()
    849 
    850 #define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
    851     template<typename Type>\
    852     void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
    853     {\
    854         Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
    855     }
    856 
    857 #define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
    858     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    859     void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
    860     {\
    861         Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
    862     }
    863 
    864 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
    865     template<typename Type>\
    866     void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
    867     {\
    868         Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
    869     }
    870 
    871 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
    872     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    873     void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
    874     {\
    875         Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
    876     }
    877 
    878 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
    879 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
    880     template<typename TestType> \
    881     struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
    882         void test();\
    883     }
    884 
    885 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
    886     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
    887     struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
    888         void test();\
    889     }
    890 
    891 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
    892 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
    893     template<typename TestType> \
    894     void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
    895 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
    896     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
    897     void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
    898 
    899 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    900 #define INTERNAL_CATCH_NTTP_0
    901 #define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0)
    902 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)
    903 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)
    904 #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)
    905 #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)
    906 #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)
    907 #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)
    908 #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)
    909 #else
    910 #define INTERNAL_CATCH_NTTP_0(signature)
    911 #define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__))
    912 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
    913 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
    914 #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
    915 #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
    916 #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
    917 #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
    918 #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
    919 #endif
    920 
    921 // end catch_preprocessor.hpp
    922 // start catch_meta.hpp
    923 
    924 
    925 #include <type_traits>
    926 
    927 namespace Catch {
    928     template<typename T>
    929     struct always_false : std::false_type {};
    930 
    931     template <typename> struct true_given : std::true_type {};
    932     struct is_callable_tester {
    933         template <typename Fun, typename... Args>
    934         true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
    935         template <typename...>
    936         std::false_type static test(...);
    937     };
    938 
    939     template <typename T>
    940     struct is_callable;
    941 
    942     template <typename Fun, typename... Args>
    943     struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
    944 
    945 #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
    946     // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
    947     // replaced with std::invoke_result here.
    948     template <typename Func, typename... U>
    949     using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
    950 #else
    951     // Keep ::type here because we still support C++11
    952     template <typename Func, typename... U>
    953     using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;
    954 #endif
    955 
    956 } // namespace Catch
    957 
    958 namespace mpl_{
    959     struct na;
    960 }
    961 
    962 // end catch_meta.hpp
    963 namespace Catch {
    964 
    965 template<typename C>
    966 class TestInvokerAsMethod : public ITestInvoker {
    967     void (C::*m_testAsMethod)();
    968 public:
    969     TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
    970 
    971     void invoke() const override {
    972         C obj;
    973         (obj.*m_testAsMethod)();
    974     }
    975 };
    976 
    977 auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
    978 
    979 template<typename C>
    980 auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
    981     return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
    982 }
    983 
    984 struct NameAndTags {
    985     NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
    986     StringRef name;
    987     StringRef tags;
    988 };
    989 
    990 struct AutoReg : NonCopyable {
    991     AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
    992     ~AutoReg();
    993 };
    994 
    995 } // end namespace Catch
    996 
    997 #if defined(CATCH_CONFIG_DISABLE)
    998     #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
    999         static void TestName()
   1000     #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
   1001         namespace{                        \
   1002             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
   1003                 void test();              \
   1004             };                            \
   1005         }                                 \
   1006         void TestName::test()
   1007     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... )  \
   1008         INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
   1009     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... )    \
   1010         namespace{                                                                                  \
   1011             namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                      \
   1012             INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
   1013         }                                                                                           \
   1014         }                                                                                           \
   1015         INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
   1016 
   1017     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1018         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
   1019             INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
   1020     #else
   1021         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
   1022             INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
   1023     #endif
   1024 
   1025     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1026         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
   1027             INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
   1028     #else
   1029         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
   1030             INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
   1031     #endif
   1032 
   1033     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1034         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
   1035             INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
   1036     #else
   1037         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
   1038             INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
   1039     #endif
   1040 
   1041     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1042         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
   1043             INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
   1044     #else
   1045         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
   1046             INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
   1047     #endif
   1048 #endif
   1049 
   1050     ///////////////////////////////////////////////////////////////////////////////
   1051     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
   1052         static void TestName(); \
   1053         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1054         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1055         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
   1056         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   1057         static void TestName()
   1058     #define INTERNAL_CATCH_TESTCASE( ... ) \
   1059         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
   1060 
   1061     ///////////////////////////////////////////////////////////////////////////////
   1062     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
   1063         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1064         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1065         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
   1066         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   1067 
   1068     ///////////////////////////////////////////////////////////////////////////////
   1069     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
   1070         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1071         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1072         namespace{ \
   1073             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
   1074                 void test(); \
   1075             }; \
   1076             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
   1077         } \
   1078         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   1079         void TestName::test()
   1080     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
   1081         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
   1082 
   1083     ///////////////////////////////////////////////////////////////////////////////
   1084     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
   1085         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1086         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1087         Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
   1088         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   1089 
   1090     ///////////////////////////////////////////////////////////////////////////////
   1091     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
   1092         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1093         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1094         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
   1095         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
   1096         INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
   1097         namespace {\
   1098         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
   1099             INTERNAL_CATCH_TYPE_GEN\
   1100             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
   1101             INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
   1102             template<typename...Types> \
   1103             struct TestName{\
   1104                 TestName(){\
   1105                     int index = 0;                                    \
   1106                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
   1107                     using expander = int[];\
   1108                     (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
   1109                 }\
   1110             };\
   1111             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
   1112             TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
   1113             return 0;\
   1114         }();\
   1115         }\
   1116         }\
   1117         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   1118         INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
   1119 
   1120 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1121     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
   1122         INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ )
   1123 #else
   1124     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
   1125         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
   1126 #endif
   1127 
   1128 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1129     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
   1130         INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ )
   1131 #else
   1132     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
   1133         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
   1134 #endif
   1135 
   1136     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
   1137         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                      \
   1138         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \
   1139         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                \
   1140         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS              \
   1141         template<typename TestType> static void TestFuncName();       \
   1142         namespace {\
   1143         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                     \
   1144             INTERNAL_CATCH_TYPE_GEN                                                  \
   1145             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))         \
   1146             template<typename... Types>                               \
   1147             struct TestName {                                         \
   1148                 void reg_tests() {                                          \
   1149                     int index = 0;                                    \
   1150                     using expander = int[];                           \
   1151                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
   1152                     constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
   1153                     constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
   1154                     (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\
   1155                 }                                                     \
   1156             };                                                        \
   1157             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
   1158                 using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
   1159                 TestInit t;                                           \
   1160                 t.reg_tests();                                        \
   1161                 return 0;                                             \
   1162             }();                                                      \
   1163         }                                                             \
   1164         }                                                             \
   1165         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
   1166         template<typename TestType>                                   \
   1167         static void TestFuncName()
   1168 
   1169 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1170     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
   1171         INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__)
   1172 #else
   1173     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
   1174         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T, __VA_ARGS__ ) )
   1175 #endif
   1176 
   1177 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1178     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
   1179         INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__)
   1180 #else
   1181     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
   1182         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) )
   1183 #endif
   1184 
   1185     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
   1186         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1187         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1188         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
   1189         template<typename TestType> static void TestFunc();       \
   1190         namespace {\
   1191         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
   1192         INTERNAL_CATCH_TYPE_GEN\
   1193         template<typename... Types>                               \
   1194         struct TestName {                                         \
   1195             void reg_tests() {                                          \
   1196                 int index = 0;                                    \
   1197                 using expander = int[];                           \
   1198                 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */\
   1199             }                                                     \
   1200         };\
   1201         static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
   1202                 using TestInit = typename convert<TestName, TmplList>::type; \
   1203                 TestInit t;                                           \
   1204                 t.reg_tests();                                        \
   1205                 return 0;                                             \
   1206             }();                                                      \
   1207         }}\
   1208         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
   1209         template<typename TestType>                                   \
   1210         static void TestFunc()
   1211 
   1212     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
   1213         INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList )
   1214 
   1215     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
   1216         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1217         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1218         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
   1219         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
   1220         namespace {\
   1221         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
   1222             INTERNAL_CATCH_TYPE_GEN\
   1223             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
   1224             INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
   1225             INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
   1226             template<typename...Types> \
   1227             struct TestNameClass{\
   1228                 TestNameClass(){\
   1229                     int index = 0;                                    \
   1230                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
   1231                     using expander = int[];\
   1232                     (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
   1233                 }\
   1234             };\
   1235             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
   1236                 TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
   1237                 return 0;\
   1238         }();\
   1239         }\
   1240         }\
   1241         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   1242         INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
   1243 
   1244 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1245     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
   1246         INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
   1247 #else
   1248     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
   1249         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
   1250 #endif
   1251 
   1252 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1253     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
   1254         INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
   1255 #else
   1256     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
   1257         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
   1258 #endif
   1259 
   1260     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
   1261         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1262         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1263         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
   1264         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
   1265         template<typename TestType> \
   1266             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
   1267                 void test();\
   1268             };\
   1269         namespace {\
   1270         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
   1271             INTERNAL_CATCH_TYPE_GEN                  \
   1272             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
   1273             template<typename...Types>\
   1274             struct TestNameClass{\
   1275                 void reg_tests(){\
   1276                     int index = 0;\
   1277                     using expander = int[];\
   1278                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
   1279                     constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
   1280                     constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
   1281                     (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \
   1282                 }\
   1283             };\
   1284             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
   1285                 using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\
   1286                 TestInit t;\
   1287                 t.reg_tests();\
   1288                 return 0;\
   1289             }(); \
   1290         }\
   1291         }\
   1292         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   1293         template<typename TestType> \
   1294         void TestName<TestType>::test()
   1295 
   1296 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1297     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
   1298         INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
   1299 #else
   1300     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
   1301         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )
   1302 #endif
   1303 
   1304 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1305     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
   1306         INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
   1307 #else
   1308     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
   1309         INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
   1310 #endif
   1311 
   1312     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
   1313         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1314         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1315         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
   1316         template<typename TestType> \
   1317         struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
   1318             void test();\
   1319         };\
   1320         namespace {\
   1321         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
   1322             INTERNAL_CATCH_TYPE_GEN\
   1323             template<typename...Types>\
   1324             struct TestNameClass{\
   1325                 void reg_tests(){\
   1326                     int index = 0;\
   1327                     using expander = int[];\
   1328                     (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */ \
   1329                 }\
   1330             };\
   1331             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
   1332                 using TestInit = typename convert<TestNameClass, TmplList>::type;\
   1333                 TestInit t;\
   1334                 t.reg_tests();\
   1335                 return 0;\
   1336             }(); \
   1337         }}\
   1338         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   1339         template<typename TestType> \
   1340         void TestName<TestType>::test()
   1341 
   1342 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
   1343         INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, TmplList )
   1344 
   1345 // end catch_test_registry.h
   1346 // start catch_capture.hpp
   1347 
   1348 // start catch_assertionhandler.h
   1349 
   1350 // start catch_assertioninfo.h
   1351 
   1352 // start catch_result_type.h
   1353 
   1354 namespace Catch {
   1355 
   1356     // ResultWas::OfType enum
   1357     struct ResultWas { enum OfType {
   1358         Unknown = -1,
   1359         Ok = 0,
   1360         Info = 1,
   1361         Warning = 2,
   1362 
   1363         FailureBit = 0x10,
   1364 
   1365         ExpressionFailed = FailureBit | 1,
   1366         ExplicitFailure = FailureBit | 2,
   1367 
   1368         Exception = 0x100 | FailureBit,
   1369 
   1370         ThrewException = Exception | 1,
   1371         DidntThrowException = Exception | 2,
   1372 
   1373         FatalErrorCondition = 0x200 | FailureBit
   1374 
   1375     }; };
   1376 
   1377     bool isOk( ResultWas::OfType resultType );
   1378     bool isJustInfo( int flags );
   1379 
   1380     // ResultDisposition::Flags enum
   1381     struct ResultDisposition { enum Flags {
   1382         Normal = 0x01,
   1383 
   1384         ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
   1385         FalseTest = 0x04,           // Prefix expression with !
   1386         SuppressFail = 0x08         // Failures are reported but do not fail the test
   1387     }; };
   1388 
   1389     ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
   1390 
   1391     bool shouldContinueOnFailure( int flags );
   1392     inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
   1393     bool shouldSuppressFailure( int flags );
   1394 
   1395 } // end namespace Catch
   1396 
   1397 // end catch_result_type.h
   1398 namespace Catch {
   1399 
   1400     struct AssertionInfo
   1401     {
   1402         StringRef macroName;
   1403         SourceLineInfo lineInfo;
   1404         StringRef capturedExpression;
   1405         ResultDisposition::Flags resultDisposition;
   1406 
   1407         // We want to delete this constructor but a compiler bug in 4.8 means
   1408         // the struct is then treated as non-aggregate
   1409         //AssertionInfo() = delete;
   1410     };
   1411 
   1412 } // end namespace Catch
   1413 
   1414 // end catch_assertioninfo.h
   1415 // start catch_decomposer.h
   1416 
   1417 // start catch_tostring.h
   1418 
   1419 #include <vector>
   1420 #include <cstddef>
   1421 #include <type_traits>
   1422 #include <string>
   1423 // start catch_stream.h
   1424 
   1425 #include <iosfwd>
   1426 #include <cstddef>
   1427 #include <ostream>
   1428 
   1429 namespace Catch {
   1430 
   1431     std::ostream& cout();
   1432     std::ostream& cerr();
   1433     std::ostream& clog();
   1434 
   1435     class StringRef;
   1436 
   1437     struct IStream {
   1438         virtual ~IStream();
   1439         virtual std::ostream& stream() const = 0;
   1440     };
   1441 
   1442     auto makeStream( StringRef const &filename ) -> IStream const*;
   1443 
   1444     class ReusableStringStream : NonCopyable {
   1445         std::size_t m_index;
   1446         std::ostream* m_oss;
   1447     public:
   1448         ReusableStringStream();
   1449         ~ReusableStringStream();
   1450 
   1451         auto str() const -> std::string;
   1452 
   1453         template<typename T>
   1454         auto operator << ( T const& value ) -> ReusableStringStream& {
   1455             *m_oss << value;
   1456             return *this;
   1457         }
   1458         auto get() -> std::ostream& { return *m_oss; }
   1459     };
   1460 }
   1461 
   1462 // end catch_stream.h
   1463 // start catch_interfaces_enum_values_registry.h
   1464 
   1465 #include <vector>
   1466 
   1467 namespace Catch {
   1468 
   1469     namespace Detail {
   1470         struct EnumInfo {
   1471             StringRef m_name;
   1472             std::vector<std::pair<int, StringRef>> m_values;
   1473 
   1474             ~EnumInfo();
   1475 
   1476             StringRef lookup( int value ) const;
   1477         };
   1478     } // namespace Detail
   1479 
   1480     struct IMutableEnumValuesRegistry {
   1481         virtual ~IMutableEnumValuesRegistry();
   1482 
   1483         virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
   1484 
   1485         template<typename E>
   1486         Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
   1487             static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
   1488             std::vector<int> intValues;
   1489             intValues.reserve( values.size() );
   1490             for( auto enumValue : values )
   1491                 intValues.push_back( static_cast<int>( enumValue ) );
   1492             return registerEnum( enumName, allEnums, intValues );
   1493         }
   1494     };
   1495 
   1496 } // Catch
   1497 
   1498 // end catch_interfaces_enum_values_registry.h
   1499 
   1500 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
   1501 #include <string_view>
   1502 #endif
   1503 
   1504 #ifdef __OBJC__
   1505 // start catch_objc_arc.hpp
   1506 
   1507 #import <Foundation/Foundation.h>
   1508 
   1509 #ifdef __has_feature
   1510 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
   1511 #else
   1512 #define CATCH_ARC_ENABLED 0
   1513 #endif
   1514 
   1515 void arcSafeRelease( NSObject* obj );
   1516 id performOptionalSelector( id obj, SEL sel );
   1517 
   1518 #if !CATCH_ARC_ENABLED
   1519 inline void arcSafeRelease( NSObject* obj ) {
   1520     [obj release];
   1521 }
   1522 inline id performOptionalSelector( id obj, SEL sel ) {
   1523     if( [obj respondsToSelector: sel] )
   1524         return [obj performSelector: sel];
   1525     return nil;
   1526 }
   1527 #define CATCH_UNSAFE_UNRETAINED
   1528 #define CATCH_ARC_STRONG
   1529 #else
   1530 inline void arcSafeRelease( NSObject* ){}
   1531 inline id performOptionalSelector( id obj, SEL sel ) {
   1532 #ifdef __clang__
   1533 #pragma clang diagnostic push
   1534 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
   1535 #endif
   1536     if( [obj respondsToSelector: sel] )
   1537         return [obj performSelector: sel];
   1538 #ifdef __clang__
   1539 #pragma clang diagnostic pop
   1540 #endif
   1541     return nil;
   1542 }
   1543 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
   1544 #define CATCH_ARC_STRONG __strong
   1545 #endif
   1546 
   1547 // end catch_objc_arc.hpp
   1548 #endif
   1549 
   1550 #ifdef _MSC_VER
   1551 #pragma warning(push)
   1552 #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
   1553 #endif
   1554 
   1555 namespace Catch {
   1556     namespace Detail {
   1557 
   1558         extern const std::string unprintableString;
   1559 
   1560         std::string rawMemoryToString( const void *object, std::size_t size );
   1561 
   1562         template<typename T>
   1563         std::string rawMemoryToString( const T& object ) {
   1564           return rawMemoryToString( &object, sizeof(object) );
   1565         }
   1566 
   1567         template<typename T>
   1568         class IsStreamInsertable {
   1569             template<typename Stream, typename U>
   1570             static auto test(int)
   1571                 -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
   1572 
   1573             template<typename, typename>
   1574             static auto test(...)->std::false_type;
   1575 
   1576         public:
   1577             static const bool value = decltype(test<std::ostream, const T&>(0))::value;
   1578         };
   1579 
   1580         template<typename E>
   1581         std::string convertUnknownEnumToString( E e );
   1582 
   1583         template<typename T>
   1584         typename std::enable_if<
   1585             !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
   1586         std::string>::type convertUnstreamable( T const& ) {
   1587             return Detail::unprintableString;
   1588         }
   1589         template<typename T>
   1590         typename std::enable_if<
   1591             !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
   1592          std::string>::type convertUnstreamable(T const& ex) {
   1593             return ex.what();
   1594         }
   1595 
   1596         template<typename T>
   1597         typename std::enable_if<
   1598             std::is_enum<T>::value
   1599         , std::string>::type convertUnstreamable( T const& value ) {
   1600             return convertUnknownEnumToString( value );
   1601         }
   1602 
   1603 #if defined(_MANAGED)
   1604         //! Convert a CLR string to a utf8 std::string
   1605         template<typename T>
   1606         std::string clrReferenceToString( T^ ref ) {
   1607             if (ref == nullptr)
   1608                 return std::string("null");
   1609             auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
   1610             cli::pin_ptr<System::Byte> p = &bytes[0];
   1611             return std::string(reinterpret_cast<char const *>(p), bytes->Length);
   1612         }
   1613 #endif
   1614 
   1615     } // namespace Detail
   1616 
   1617     // If we decide for C++14, change these to enable_if_ts
   1618     template <typename T, typename = void>
   1619     struct StringMaker {
   1620         template <typename Fake = T>
   1621         static
   1622         typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
   1623             convert(const Fake& value) {
   1624                 ReusableStringStream rss;
   1625                 // NB: call using the function-like syntax to avoid ambiguity with
   1626                 // user-defined templated operator<< under clang.
   1627                 rss.operator<<(value);
   1628                 return rss.str();
   1629         }
   1630 
   1631         template <typename Fake = T>
   1632         static
   1633         typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
   1634             convert( const Fake& value ) {
   1635 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
   1636             return Detail::convertUnstreamable(value);
   1637 #else
   1638             return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
   1639 #endif
   1640         }
   1641     };
   1642 
   1643     namespace Detail {
   1644 
   1645         // This function dispatches all stringification requests inside of Catch.
   1646         // Should be preferably called fully qualified, like ::Catch::Detail::stringify
   1647         template <typename T>
   1648         std::string stringify(const T& e) {
   1649             return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
   1650         }
   1651 
   1652         template<typename E>
   1653         std::string convertUnknownEnumToString( E e ) {
   1654             return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
   1655         }
   1656 
   1657 #if defined(_MANAGED)
   1658         template <typename T>
   1659         std::string stringify( T^ e ) {
   1660             return ::Catch::StringMaker<T^>::convert(e);
   1661         }
   1662 #endif
   1663 
   1664     } // namespace Detail
   1665 
   1666     // Some predefined specializations
   1667 
   1668     template<>
   1669     struct StringMaker<std::string> {
   1670         static std::string convert(const std::string& str);
   1671     };
   1672 
   1673 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
   1674     template<>
   1675     struct StringMaker<std::string_view> {
   1676         static std::string convert(std::string_view str);
   1677     };
   1678 #endif
   1679 
   1680     template<>
   1681     struct StringMaker<char const *> {
   1682         static std::string convert(char const * str);
   1683     };
   1684     template<>
   1685     struct StringMaker<char *> {
   1686         static std::string convert(char * str);
   1687     };
   1688 
   1689 #ifdef CATCH_CONFIG_WCHAR
   1690     template<>
   1691     struct StringMaker<std::wstring> {
   1692         static std::string convert(const std::wstring& wstr);
   1693     };
   1694 
   1695 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
   1696     template<>
   1697     struct StringMaker<std::wstring_view> {
   1698         static std::string convert(std::wstring_view str);
   1699     };
   1700 # endif
   1701 
   1702     template<>
   1703     struct StringMaker<wchar_t const *> {
   1704         static std::string convert(wchar_t const * str);
   1705     };
   1706     template<>
   1707     struct StringMaker<wchar_t *> {
   1708         static std::string convert(wchar_t * str);
   1709     };
   1710 #endif
   1711 
   1712     // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
   1713     //      while keeping string semantics?
   1714     template<int SZ>
   1715     struct StringMaker<char[SZ]> {
   1716         static std::string convert(char const* str) {
   1717             return ::Catch::Detail::stringify(std::string{ str });
   1718         }
   1719     };
   1720     template<int SZ>
   1721     struct StringMaker<signed char[SZ]> {
   1722         static std::string convert(signed char const* str) {
   1723             return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
   1724         }
   1725     };
   1726     template<int SZ>
   1727     struct StringMaker<unsigned char[SZ]> {
   1728         static std::string convert(unsigned char const* str) {
   1729             return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
   1730         }
   1731     };
   1732 
   1733 #if defined(CATCH_CONFIG_CPP17_BYTE)
   1734     template<>
   1735     struct StringMaker<std::byte> {
   1736         static std::string convert(std::byte value);
   1737     };
   1738 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
   1739     template<>
   1740     struct StringMaker<int> {
   1741         static std::string convert(int value);
   1742     };
   1743     template<>
   1744     struct StringMaker<long> {
   1745         static std::string convert(long value);
   1746     };
   1747     template<>
   1748     struct StringMaker<long long> {
   1749         static std::string convert(long long value);
   1750     };
   1751     template<>
   1752     struct StringMaker<unsigned int> {
   1753         static std::string convert(unsigned int value);
   1754     };
   1755     template<>
   1756     struct StringMaker<unsigned long> {
   1757         static std::string convert(unsigned long value);
   1758     };
   1759     template<>
   1760     struct StringMaker<unsigned long long> {
   1761         static std::string convert(unsigned long long value);
   1762     };
   1763 
   1764     template<>
   1765     struct StringMaker<bool> {
   1766         static std::string convert(bool b);
   1767     };
   1768 
   1769     template<>
   1770     struct StringMaker<char> {
   1771         static std::string convert(char c);
   1772     };
   1773     template<>
   1774     struct StringMaker<signed char> {
   1775         static std::string convert(signed char c);
   1776     };
   1777     template<>
   1778     struct StringMaker<unsigned char> {
   1779         static std::string convert(unsigned char c);
   1780     };
   1781 
   1782     template<>
   1783     struct StringMaker<std::nullptr_t> {
   1784         static std::string convert(std::nullptr_t);
   1785     };
   1786 
   1787     template<>
   1788     struct StringMaker<float> {
   1789         static std::string convert(float value);
   1790         static int precision;
   1791     };
   1792 
   1793     template<>
   1794     struct StringMaker<double> {
   1795         static std::string convert(double value);
   1796         static int precision;
   1797     };
   1798 
   1799     template <typename T>
   1800     struct StringMaker<T*> {
   1801         template <typename U>
   1802         static std::string convert(U* p) {
   1803             if (p) {
   1804                 return ::Catch::Detail::rawMemoryToString(p);
   1805             } else {
   1806                 return "nullptr";
   1807             }
   1808         }
   1809     };
   1810 
   1811     template <typename R, typename C>
   1812     struct StringMaker<R C::*> {
   1813         static std::string convert(R C::* p) {
   1814             if (p) {
   1815                 return ::Catch::Detail::rawMemoryToString(p);
   1816             } else {
   1817                 return "nullptr";
   1818             }
   1819         }
   1820     };
   1821 
   1822 #if defined(_MANAGED)
   1823     template <typename T>
   1824     struct StringMaker<T^> {
   1825         static std::string convert( T^ ref ) {
   1826             return ::Catch::Detail::clrReferenceToString(ref);
   1827         }
   1828     };
   1829 #endif
   1830 
   1831     namespace Detail {
   1832         template<typename InputIterator>
   1833         std::string rangeToString(InputIterator first, InputIterator last) {
   1834             ReusableStringStream rss;
   1835             rss << "{ ";
   1836             if (first != last) {
   1837                 rss << ::Catch::Detail::stringify(*first);
   1838                 for (++first; first != last; ++first)
   1839                     rss << ", " << ::Catch::Detail::stringify(*first);
   1840             }
   1841             rss << " }";
   1842             return rss.str();
   1843         }
   1844     }
   1845 
   1846 #ifdef __OBJC__
   1847     template<>
   1848     struct StringMaker<NSString*> {
   1849         static std::string convert(NSString * nsstring) {
   1850             if (!nsstring)
   1851                 return "nil";
   1852             return std::string("@") + [nsstring UTF8String];
   1853         }
   1854     };
   1855     template<>
   1856     struct StringMaker<NSObject*> {
   1857         static std::string convert(NSObject* nsObject) {
   1858             return ::Catch::Detail::stringify([nsObject description]);
   1859         }
   1860 
   1861     };
   1862     namespace Detail {
   1863         inline std::string stringify( NSString* nsstring ) {
   1864             return StringMaker<NSString*>::convert( nsstring );
   1865         }
   1866 
   1867     } // namespace Detail
   1868 #endif // __OBJC__
   1869 
   1870 } // namespace Catch
   1871 
   1872 //////////////////////////////////////////////////////
   1873 // Separate std-lib types stringification, so it can be selectively enabled
   1874 // This means that we do not bring in
   1875 
   1876 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
   1877 #  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
   1878 #  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
   1879 #  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
   1880 #  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
   1881 #  define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
   1882 #endif
   1883 
   1884 // Separate std::pair specialization
   1885 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
   1886 #include <utility>
   1887 namespace Catch {
   1888     template<typename T1, typename T2>
   1889     struct StringMaker<std::pair<T1, T2> > {
   1890         static std::string convert(const std::pair<T1, T2>& pair) {
   1891             ReusableStringStream rss;
   1892             rss << "{ "
   1893                 << ::Catch::Detail::stringify(pair.first)
   1894                 << ", "
   1895                 << ::Catch::Detail::stringify(pair.second)
   1896                 << " }";
   1897             return rss.str();
   1898         }
   1899     };
   1900 }
   1901 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
   1902 
   1903 #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
   1904 #include <optional>
   1905 namespace Catch {
   1906     template<typename T>
   1907     struct StringMaker<std::optional<T> > {
   1908         static std::string convert(const std::optional<T>& optional) {
   1909             ReusableStringStream rss;
   1910             if (optional.has_value()) {
   1911                 rss << ::Catch::Detail::stringify(*optional);
   1912             } else {
   1913                 rss << "{ }";
   1914             }
   1915             return rss.str();
   1916         }
   1917     };
   1918 }
   1919 #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
   1920 
   1921 // Separate std::tuple specialization
   1922 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
   1923 #include <tuple>
   1924 namespace Catch {
   1925     namespace Detail {
   1926         template<
   1927             typename Tuple,
   1928             std::size_t N = 0,
   1929             bool = (N < std::tuple_size<Tuple>::value)
   1930             >
   1931             struct TupleElementPrinter {
   1932             static void print(const Tuple& tuple, std::ostream& os) {
   1933                 os << (N ? ", " : " ")
   1934                     << ::Catch::Detail::stringify(std::get<N>(tuple));
   1935                 TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
   1936             }
   1937         };
   1938 
   1939         template<
   1940             typename Tuple,
   1941             std::size_t N
   1942         >
   1943             struct TupleElementPrinter<Tuple, N, false> {
   1944             static void print(const Tuple&, std::ostream&) {}
   1945         };
   1946 
   1947     }
   1948 
   1949     template<typename ...Types>
   1950     struct StringMaker<std::tuple<Types...>> {
   1951         static std::string convert(const std::tuple<Types...>& tuple) {
   1952             ReusableStringStream rss;
   1953             rss << '{';
   1954             Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
   1955             rss << " }";
   1956             return rss.str();
   1957         }
   1958     };
   1959 }
   1960 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
   1961 
   1962 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
   1963 #include <variant>
   1964 namespace Catch {
   1965     template<>
   1966     struct StringMaker<std::monostate> {
   1967         static std::string convert(const std::monostate&) {
   1968             return "{ }";
   1969         }
   1970     };
   1971 
   1972     template<typename... Elements>
   1973     struct StringMaker<std::variant<Elements...>> {
   1974         static std::string convert(const std::variant<Elements...>& variant) {
   1975             if (variant.valueless_by_exception()) {
   1976                 return "{valueless variant}";
   1977             } else {
   1978                 return std::visit(
   1979                     [](const auto& value) {
   1980                         return ::Catch::Detail::stringify(value);
   1981                     },
   1982                     variant
   1983                 );
   1984             }
   1985         }
   1986     };
   1987 }
   1988 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
   1989 
   1990 namespace Catch {
   1991     // Import begin/ end from std here
   1992     using std::begin;
   1993     using std::end;
   1994 
   1995     namespace detail {
   1996         template <typename...>
   1997         struct void_type {
   1998             using type = void;
   1999         };
   2000 
   2001         template <typename T, typename = void>
   2002         struct is_range_impl : std::false_type {
   2003         };
   2004 
   2005         template <typename T>
   2006         struct is_range_impl<T, typename void_type<decltype(begin(std::declval<T>()))>::type> : std::true_type {
   2007         };
   2008     } // namespace detail
   2009 
   2010     template <typename T>
   2011     struct is_range : detail::is_range_impl<T> {
   2012     };
   2013 
   2014 #if defined(_MANAGED) // Managed types are never ranges
   2015     template <typename T>
   2016     struct is_range<T^> {
   2017         static const bool value = false;
   2018     };
   2019 #endif
   2020 
   2021     template<typename Range>
   2022     std::string rangeToString( Range const& range ) {
   2023         return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
   2024     }
   2025 
   2026     // Handle vector<bool> specially
   2027     template<typename Allocator>
   2028     std::string rangeToString( std::vector<bool, Allocator> const& v ) {
   2029         ReusableStringStream rss;
   2030         rss << "{ ";
   2031         bool first = true;
   2032         for( bool b : v ) {
   2033             if( first )
   2034                 first = false;
   2035             else
   2036                 rss << ", ";
   2037             rss << ::Catch::Detail::stringify( b );
   2038         }
   2039         rss << " }";
   2040         return rss.str();
   2041     }
   2042 
   2043     template<typename R>
   2044     struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
   2045         static std::string convert( R const& range ) {
   2046             return rangeToString( range );
   2047         }
   2048     };
   2049 
   2050     template <typename T, int SZ>
   2051     struct StringMaker<T[SZ]> {
   2052         static std::string convert(T const(&arr)[SZ]) {
   2053             return rangeToString(arr);
   2054         }
   2055     };
   2056 
   2057 } // namespace Catch
   2058 
   2059 // Separate std::chrono::duration specialization
   2060 #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
   2061 #include <ctime>
   2062 #include <ratio>
   2063 #include <chrono>
   2064 
   2065 namespace Catch {
   2066 
   2067 template <class Ratio>
   2068 struct ratio_string {
   2069     static std::string symbol();
   2070 };
   2071 
   2072 template <class Ratio>
   2073 std::string ratio_string<Ratio>::symbol() {
   2074     Catch::ReusableStringStream rss;
   2075     rss << '[' << Ratio::num << '/'
   2076         << Ratio::den << ']';
   2077     return rss.str();
   2078 }
   2079 template <>
   2080 struct ratio_string<std::atto> {
   2081     static std::string symbol();
   2082 };
   2083 template <>
   2084 struct ratio_string<std::femto> {
   2085     static std::string symbol();
   2086 };
   2087 template <>
   2088 struct ratio_string<std::pico> {
   2089     static std::string symbol();
   2090 };
   2091 template <>
   2092 struct ratio_string<std::nano> {
   2093     static std::string symbol();
   2094 };
   2095 template <>
   2096 struct ratio_string<std::micro> {
   2097     static std::string symbol();
   2098 };
   2099 template <>
   2100 struct ratio_string<std::milli> {
   2101     static std::string symbol();
   2102 };
   2103 
   2104     ////////////
   2105     // std::chrono::duration specializations
   2106     template<typename Value, typename Ratio>
   2107     struct StringMaker<std::chrono::duration<Value, Ratio>> {
   2108         static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
   2109             ReusableStringStream rss;
   2110             rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
   2111             return rss.str();
   2112         }
   2113     };
   2114     template<typename Value>
   2115     struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
   2116         static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
   2117             ReusableStringStream rss;
   2118             rss << duration.count() << " s";
   2119             return rss.str();
   2120         }
   2121     };
   2122     template<typename Value>
   2123     struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
   2124         static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
   2125             ReusableStringStream rss;
   2126             rss << duration.count() << " m";
   2127             return rss.str();
   2128         }
   2129     };
   2130     template<typename Value>
   2131     struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
   2132         static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
   2133             ReusableStringStream rss;
   2134             rss << duration.count() << " h";
   2135             return rss.str();
   2136         }
   2137     };
   2138 
   2139     ////////////
   2140     // std::chrono::time_point specialization
   2141     // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
   2142     template<typename Clock, typename Duration>
   2143     struct StringMaker<std::chrono::time_point<Clock, Duration>> {
   2144         static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
   2145             return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
   2146         }
   2147     };
   2148     // std::chrono::time_point<system_clock> specialization
   2149     template<typename Duration>
   2150     struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
   2151         static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
   2152             auto converted = std::chrono::system_clock::to_time_t(time_point);
   2153 
   2154 #ifdef _MSC_VER
   2155             std::tm timeInfo = {};
   2156             gmtime_s(&timeInfo, &converted);
   2157 #else
   2158             std::tm* timeInfo = std::gmtime(&converted);
   2159 #endif
   2160 
   2161             auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
   2162             char timeStamp[timeStampSize];
   2163             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
   2164 
   2165 #ifdef _MSC_VER
   2166             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
   2167 #else
   2168             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
   2169 #endif
   2170             return std::string(timeStamp);
   2171         }
   2172     };
   2173 }
   2174 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
   2175 
   2176 #define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
   2177 namespace Catch { \
   2178     template<> struct StringMaker<enumName> { \
   2179         static std::string convert( enumName value ) { \
   2180             static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
   2181             return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
   2182         } \
   2183     }; \
   2184 }
   2185 
   2186 #define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
   2187 
   2188 #ifdef _MSC_VER
   2189 #pragma warning(pop)
   2190 #endif
   2191 
   2192 // end catch_tostring.h
   2193 #include <iosfwd>
   2194 
   2195 #ifdef _MSC_VER
   2196 #pragma warning(push)
   2197 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
   2198 #pragma warning(disable:4018) // more "signed/unsigned mismatch"
   2199 #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
   2200 #pragma warning(disable:4180) // qualifier applied to function type has no meaning
   2201 #pragma warning(disable:4800) // Forcing result to true or false
   2202 #endif
   2203 
   2204 namespace Catch {
   2205 
   2206     struct ITransientExpression {
   2207         auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
   2208         auto getResult() const -> bool { return m_result; }
   2209         virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
   2210 
   2211         ITransientExpression( bool isBinaryExpression, bool result )
   2212         :   m_isBinaryExpression( isBinaryExpression ),
   2213             m_result( result )
   2214         {}
   2215 
   2216         // We don't actually need a virtual destructor, but many static analysers
   2217         // complain if it's not here :-(
   2218         virtual ~ITransientExpression();
   2219 
   2220         bool m_isBinaryExpression;
   2221         bool m_result;
   2222 
   2223     };
   2224 
   2225     void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
   2226 
   2227     template<typename LhsT, typename RhsT>
   2228     class BinaryExpr  : public ITransientExpression {
   2229         LhsT m_lhs;
   2230         StringRef m_op;
   2231         RhsT m_rhs;
   2232 
   2233         void streamReconstructedExpression( std::ostream &os ) const override {
   2234             formatReconstructedExpression
   2235                     ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
   2236         }
   2237 
   2238     public:
   2239         BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
   2240         :   ITransientExpression{ true, comparisonResult },
   2241             m_lhs( lhs ),
   2242             m_op( op ),
   2243             m_rhs( rhs )
   2244         {}
   2245 
   2246         template<typename T>
   2247         auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2248             static_assert(always_false<T>::value,
   2249             "chained comparisons are not supported inside assertions, "
   2250             "wrap the expression inside parentheses, or decompose it");
   2251         }
   2252 
   2253         template<typename T>
   2254         auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2255             static_assert(always_false<T>::value,
   2256             "chained comparisons are not supported inside assertions, "
   2257             "wrap the expression inside parentheses, or decompose it");
   2258         }
   2259 
   2260         template<typename T>
   2261         auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2262             static_assert(always_false<T>::value,
   2263             "chained comparisons are not supported inside assertions, "
   2264             "wrap the expression inside parentheses, or decompose it");
   2265         }
   2266 
   2267         template<typename T>
   2268         auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2269             static_assert(always_false<T>::value,
   2270             "chained comparisons are not supported inside assertions, "
   2271             "wrap the expression inside parentheses, or decompose it");
   2272         }
   2273 
   2274         template<typename T>
   2275         auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2276             static_assert(always_false<T>::value,
   2277             "chained comparisons are not supported inside assertions, "
   2278             "wrap the expression inside parentheses, or decompose it");
   2279         }
   2280 
   2281         template<typename T>
   2282         auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2283             static_assert(always_false<T>::value,
   2284             "chained comparisons are not supported inside assertions, "
   2285             "wrap the expression inside parentheses, or decompose it");
   2286         }
   2287 
   2288         template<typename T>
   2289         auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2290             static_assert(always_false<T>::value,
   2291             "chained comparisons are not supported inside assertions, "
   2292             "wrap the expression inside parentheses, or decompose it");
   2293         }
   2294 
   2295         template<typename T>
   2296         auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2297             static_assert(always_false<T>::value,
   2298             "chained comparisons are not supported inside assertions, "
   2299             "wrap the expression inside parentheses, or decompose it");
   2300         }
   2301     };
   2302 
   2303     template<typename LhsT>
   2304     class UnaryExpr : public ITransientExpression {
   2305         LhsT m_lhs;
   2306 
   2307         void streamReconstructedExpression( std::ostream &os ) const override {
   2308             os << Catch::Detail::stringify( m_lhs );
   2309         }
   2310 
   2311     public:
   2312         explicit UnaryExpr( LhsT lhs )
   2313         :   ITransientExpression{ false, static_cast<bool>(lhs) },
   2314             m_lhs( lhs )
   2315         {}
   2316     };
   2317 
   2318     // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
   2319     template<typename LhsT, typename RhsT>
   2320     auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
   2321     template<typename T>
   2322     auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
   2323     template<typename T>
   2324     auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
   2325     template<typename T>
   2326     auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
   2327     template<typename T>
   2328     auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
   2329 
   2330     template<typename LhsT, typename RhsT>
   2331     auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
   2332     template<typename T>
   2333     auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
   2334     template<typename T>
   2335     auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
   2336     template<typename T>
   2337     auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
   2338     template<typename T>
   2339     auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
   2340 
   2341     template<typename LhsT>
   2342     class ExprLhs {
   2343         LhsT m_lhs;
   2344     public:
   2345         explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
   2346 
   2347         template<typename RhsT>
   2348         auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
   2349             return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
   2350         }
   2351         auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
   2352             return { m_lhs == rhs, m_lhs, "==", rhs };
   2353         }
   2354 
   2355         template<typename RhsT>
   2356         auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
   2357             return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
   2358         }
   2359         auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
   2360             return { m_lhs != rhs, m_lhs, "!=", rhs };
   2361         }
   2362 
   2363         template<typename RhsT>
   2364         auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
   2365             return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
   2366         }
   2367         template<typename RhsT>
   2368         auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
   2369             return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
   2370         }
   2371         template<typename RhsT>
   2372         auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
   2373             return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
   2374         }
   2375         template<typename RhsT>
   2376         auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
   2377             return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
   2378         }
   2379         template <typename RhsT>
   2380         auto operator | (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
   2381             return { static_cast<bool>(m_lhs | rhs), m_lhs, "|", rhs };
   2382         }
   2383         template <typename RhsT>
   2384         auto operator & (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
   2385             return { static_cast<bool>(m_lhs & rhs), m_lhs, "&", rhs };
   2386         }
   2387         template <typename RhsT>
   2388         auto operator ^ (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
   2389             return { static_cast<bool>(m_lhs ^ rhs), m_lhs, "^", rhs };
   2390         }
   2391 
   2392         template<typename RhsT>
   2393         auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
   2394             static_assert(always_false<RhsT>::value,
   2395             "operator&& is not supported inside assertions, "
   2396             "wrap the expression inside parentheses, or decompose it");
   2397         }
   2398 
   2399         template<typename RhsT>
   2400         auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
   2401             static_assert(always_false<RhsT>::value,
   2402             "operator|| is not supported inside assertions, "
   2403             "wrap the expression inside parentheses, or decompose it");
   2404         }
   2405 
   2406         auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
   2407             return UnaryExpr<LhsT>{ m_lhs };
   2408         }
   2409     };
   2410 
   2411     void handleExpression( ITransientExpression const& expr );
   2412 
   2413     template<typename T>
   2414     void handleExpression( ExprLhs<T> const& expr ) {
   2415         handleExpression( expr.makeUnaryExpr() );
   2416     }
   2417 
   2418     struct Decomposer {
   2419         template<typename T>
   2420         auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
   2421             return ExprLhs<T const&>{ lhs };
   2422         }
   2423 
   2424         auto operator <=( bool value ) -> ExprLhs<bool> {
   2425             return ExprLhs<bool>{ value };
   2426         }
   2427     };
   2428 
   2429 } // end namespace Catch
   2430 
   2431 #ifdef _MSC_VER
   2432 #pragma warning(pop)
   2433 #endif
   2434 
   2435 // end catch_decomposer.h
   2436 // start catch_interfaces_capture.h
   2437 
   2438 #include <string>
   2439 #include <chrono>
   2440 
   2441 namespace Catch {
   2442 
   2443     class AssertionResult;
   2444     struct AssertionInfo;
   2445     struct SectionInfo;
   2446     struct SectionEndInfo;
   2447     struct MessageInfo;
   2448     struct MessageBuilder;
   2449     struct Counts;
   2450     struct AssertionReaction;
   2451     struct SourceLineInfo;
   2452 
   2453     struct ITransientExpression;
   2454     struct IGeneratorTracker;
   2455 
   2456 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   2457     struct BenchmarkInfo;
   2458     template <typename Duration = std::chrono::duration<double, std::nano>>
   2459     struct BenchmarkStats;
   2460 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   2461 
   2462     struct IResultCapture {
   2463 
   2464         virtual ~IResultCapture();
   2465 
   2466         virtual bool sectionStarted(    SectionInfo const& sectionInfo,
   2467                                         Counts& assertions ) = 0;
   2468         virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
   2469         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
   2470 
   2471         virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
   2472 
   2473 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   2474         virtual void benchmarkPreparing( std::string const& name ) = 0;
   2475         virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
   2476         virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
   2477         virtual void benchmarkFailed( std::string const& error ) = 0;
   2478 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   2479 
   2480         virtual void pushScopedMessage( MessageInfo const& message ) = 0;
   2481         virtual void popScopedMessage( MessageInfo const& message ) = 0;
   2482 
   2483         virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
   2484 
   2485         virtual void handleFatalErrorCondition( StringRef message ) = 0;
   2486 
   2487         virtual void handleExpr
   2488                 (   AssertionInfo const& info,
   2489                     ITransientExpression const& expr,
   2490                     AssertionReaction& reaction ) = 0;
   2491         virtual void handleMessage
   2492                 (   AssertionInfo const& info,
   2493                     ResultWas::OfType resultType,
   2494                     StringRef const& message,
   2495                     AssertionReaction& reaction ) = 0;
   2496         virtual void handleUnexpectedExceptionNotThrown
   2497                 (   AssertionInfo const& info,
   2498                     AssertionReaction& reaction ) = 0;
   2499         virtual void handleUnexpectedInflightException
   2500                 (   AssertionInfo const& info,
   2501                     std::string const& message,
   2502                     AssertionReaction& reaction ) = 0;
   2503         virtual void handleIncomplete
   2504                 (   AssertionInfo const& info ) = 0;
   2505         virtual void handleNonExpr
   2506                 (   AssertionInfo const &info,
   2507                     ResultWas::OfType resultType,
   2508                     AssertionReaction &reaction ) = 0;
   2509 
   2510         virtual bool lastAssertionPassed() = 0;
   2511         virtual void assertionPassed() = 0;
   2512 
   2513         // Deprecated, do not use:
   2514         virtual std::string getCurrentTestName() const = 0;
   2515         virtual const AssertionResult* getLastResult() const = 0;
   2516         virtual void exceptionEarlyReported() = 0;
   2517     };
   2518 
   2519     IResultCapture& getResultCapture();
   2520 }
   2521 
   2522 // end catch_interfaces_capture.h
   2523 namespace Catch {
   2524 
   2525     struct TestFailureException{};
   2526     struct AssertionResultData;
   2527     struct IResultCapture;
   2528     class RunContext;
   2529 
   2530     class LazyExpression {
   2531         friend class AssertionHandler;
   2532         friend struct AssertionStats;
   2533         friend class RunContext;
   2534 
   2535         ITransientExpression const* m_transientExpression = nullptr;
   2536         bool m_isNegated;
   2537     public:
   2538         LazyExpression( bool isNegated );
   2539         LazyExpression( LazyExpression const& other );
   2540         LazyExpression& operator = ( LazyExpression const& ) = delete;
   2541 
   2542         explicit operator bool() const;
   2543 
   2544         friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
   2545     };
   2546 
   2547     struct AssertionReaction {
   2548         bool shouldDebugBreak = false;
   2549         bool shouldThrow = false;
   2550     };
   2551 
   2552     class AssertionHandler {
   2553         AssertionInfo m_assertionInfo;
   2554         AssertionReaction m_reaction;
   2555         bool m_completed = false;
   2556         IResultCapture& m_resultCapture;
   2557 
   2558     public:
   2559         AssertionHandler
   2560             (   StringRef const& macroName,
   2561                 SourceLineInfo const& lineInfo,
   2562                 StringRef capturedExpression,
   2563                 ResultDisposition::Flags resultDisposition );
   2564         ~AssertionHandler() {
   2565             if ( !m_completed ) {
   2566                 m_resultCapture.handleIncomplete( m_assertionInfo );
   2567             }
   2568         }
   2569 
   2570         template<typename T>
   2571         void handleExpr( ExprLhs<T> const& expr ) {
   2572             handleExpr( expr.makeUnaryExpr() );
   2573         }
   2574         void handleExpr( ITransientExpression const& expr );
   2575 
   2576         void handleMessage(ResultWas::OfType resultType, StringRef const& message);
   2577 
   2578         void handleExceptionThrownAsExpected();
   2579         void handleUnexpectedExceptionNotThrown();
   2580         void handleExceptionNotThrownAsExpected();
   2581         void handleThrowingCallSkipped();
   2582         void handleUnexpectedInflightException();
   2583 
   2584         void complete();
   2585         void setCompleted();
   2586 
   2587         // query
   2588         auto allowThrows() const -> bool;
   2589     };
   2590 
   2591     void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
   2592 
   2593 } // namespace Catch
   2594 
   2595 // end catch_assertionhandler.h
   2596 // start catch_message.h
   2597 
   2598 #include <string>
   2599 #include <vector>
   2600 
   2601 namespace Catch {
   2602 
   2603     struct MessageInfo {
   2604         MessageInfo(    StringRef const& _macroName,
   2605                         SourceLineInfo const& _lineInfo,
   2606                         ResultWas::OfType _type );
   2607 
   2608         StringRef macroName;
   2609         std::string message;
   2610         SourceLineInfo lineInfo;
   2611         ResultWas::OfType type;
   2612         unsigned int sequence;
   2613 
   2614         bool operator == ( MessageInfo const& other ) const;
   2615         bool operator < ( MessageInfo const& other ) const;
   2616     private:
   2617         static unsigned int globalCount;
   2618     };
   2619 
   2620     struct MessageStream {
   2621 
   2622         template<typename T>
   2623         MessageStream& operator << ( T const& value ) {
   2624             m_stream << value;
   2625             return *this;
   2626         }
   2627 
   2628         ReusableStringStream m_stream;
   2629     };
   2630 
   2631     struct MessageBuilder : MessageStream {
   2632         MessageBuilder( StringRef const& macroName,
   2633                         SourceLineInfo const& lineInfo,
   2634                         ResultWas::OfType type );
   2635 
   2636         template<typename T>
   2637         MessageBuilder& operator << ( T const& value ) {
   2638             m_stream << value;
   2639             return *this;
   2640         }
   2641 
   2642         MessageInfo m_info;
   2643     };
   2644 
   2645     class ScopedMessage {
   2646     public:
   2647         explicit ScopedMessage( MessageBuilder const& builder );
   2648         ScopedMessage( ScopedMessage& duplicate ) = delete;
   2649         ScopedMessage( ScopedMessage&& old );
   2650         ~ScopedMessage();
   2651 
   2652         MessageInfo m_info;
   2653         bool m_moved;
   2654     };
   2655 
   2656     class Capturer {
   2657         std::vector<MessageInfo> m_messages;
   2658         IResultCapture& m_resultCapture = getResultCapture();
   2659         size_t m_captured = 0;
   2660     public:
   2661         Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
   2662         ~Capturer();
   2663 
   2664         void captureValue( size_t index, std::string const& value );
   2665 
   2666         template<typename T>
   2667         void captureValues( size_t index, T const& value ) {
   2668             captureValue( index, Catch::Detail::stringify( value ) );
   2669         }
   2670 
   2671         template<typename T, typename... Ts>
   2672         void captureValues( size_t index, T const& value, Ts const&... values ) {
   2673             captureValue( index, Catch::Detail::stringify(value) );
   2674             captureValues( index+1, values... );
   2675         }
   2676     };
   2677 
   2678 } // end namespace Catch
   2679 
   2680 // end catch_message.h
   2681 #if !defined(CATCH_CONFIG_DISABLE)
   2682 
   2683 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
   2684   #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
   2685 #else
   2686   #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
   2687 #endif
   2688 
   2689 #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
   2690 
   2691 ///////////////////////////////////////////////////////////////////////////////
   2692 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
   2693 // macros.
   2694 #define INTERNAL_CATCH_TRY
   2695 #define INTERNAL_CATCH_CATCH( capturer )
   2696 
   2697 #else // CATCH_CONFIG_FAST_COMPILE
   2698 
   2699 #define INTERNAL_CATCH_TRY try
   2700 #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
   2701 
   2702 #endif
   2703 
   2704 #define INTERNAL_CATCH_REACT( handler ) handler.complete();
   2705 
   2706 ///////////////////////////////////////////////////////////////////////////////
   2707 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
   2708     do { \
   2709         CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \
   2710         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
   2711         INTERNAL_CATCH_TRY { \
   2712             CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   2713             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
   2714             catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
   2715             CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   2716         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
   2717         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   2718     } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) )
   2719 
   2720 ///////////////////////////////////////////////////////////////////////////////
   2721 #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
   2722     INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
   2723     if( Catch::getResultCapture().lastAssertionPassed() )
   2724 
   2725 ///////////////////////////////////////////////////////////////////////////////
   2726 #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
   2727     INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
   2728     if( !Catch::getResultCapture().lastAssertionPassed() )
   2729 
   2730 ///////////////////////////////////////////////////////////////////////////////
   2731 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
   2732     do { \
   2733         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
   2734         try { \
   2735             static_cast<void>(__VA_ARGS__); \
   2736             catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
   2737         } \
   2738         catch( ... ) { \
   2739             catchAssertionHandler.handleUnexpectedInflightException(); \
   2740         } \
   2741         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   2742     } while( false )
   2743 
   2744 ///////////////////////////////////////////////////////////////////////////////
   2745 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
   2746     do { \
   2747         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
   2748         if( catchAssertionHandler.allowThrows() ) \
   2749             try { \
   2750                 static_cast<void>(__VA_ARGS__); \
   2751                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
   2752             } \
   2753             catch( ... ) { \
   2754                 catchAssertionHandler.handleExceptionThrownAsExpected(); \
   2755             } \
   2756         else \
   2757             catchAssertionHandler.handleThrowingCallSkipped(); \
   2758         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   2759     } while( false )
   2760 
   2761 ///////////////////////////////////////////////////////////////////////////////
   2762 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
   2763     do { \
   2764         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
   2765         if( catchAssertionHandler.allowThrows() ) \
   2766             try { \
   2767                 static_cast<void>(expr); \
   2768                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
   2769             } \
   2770             catch( exceptionType const& ) { \
   2771                 catchAssertionHandler.handleExceptionThrownAsExpected(); \
   2772             } \
   2773             catch( ... ) { \
   2774                 catchAssertionHandler.handleUnexpectedInflightException(); \
   2775             } \
   2776         else \
   2777             catchAssertionHandler.handleThrowingCallSkipped(); \
   2778         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   2779     } while( false )
   2780 
   2781 ///////////////////////////////////////////////////////////////////////////////
   2782 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
   2783     do { \
   2784         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
   2785         catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
   2786         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   2787     } while( false )
   2788 
   2789 ///////////////////////////////////////////////////////////////////////////////
   2790 #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
   2791     auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
   2792     varName.captureValues( 0, __VA_ARGS__ )
   2793 
   2794 ///////////////////////////////////////////////////////////////////////////////
   2795 #define INTERNAL_CATCH_INFO( macroName, log ) \
   2796     Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
   2797 
   2798 ///////////////////////////////////////////////////////////////////////////////
   2799 #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
   2800     Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
   2801 
   2802 ///////////////////////////////////////////////////////////////////////////////
   2803 // Although this is matcher-based, it can be used with just a string
   2804 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
   2805     do { \
   2806         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
   2807         if( catchAssertionHandler.allowThrows() ) \
   2808             try { \
   2809                 static_cast<void>(__VA_ARGS__); \
   2810                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
   2811             } \
   2812             catch( ... ) { \
   2813                 Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
   2814             } \
   2815         else \
   2816             catchAssertionHandler.handleThrowingCallSkipped(); \
   2817         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   2818     } while( false )
   2819 
   2820 #endif // CATCH_CONFIG_DISABLE
   2821 
   2822 // end catch_capture.hpp
   2823 // start catch_section.h
   2824 
   2825 // start catch_section_info.h
   2826 
   2827 // start catch_totals.h
   2828 
   2829 #include <cstddef>
   2830 
   2831 namespace Catch {
   2832 
   2833     struct Counts {
   2834         Counts operator - ( Counts const& other ) const;
   2835         Counts& operator += ( Counts const& other );
   2836 
   2837         std::size_t total() const;
   2838         bool allPassed() const;
   2839         bool allOk() const;
   2840 
   2841         std::size_t passed = 0;
   2842         std::size_t failed = 0;
   2843         std::size_t failedButOk = 0;
   2844     };
   2845 
   2846     struct Totals {
   2847 
   2848         Totals operator - ( Totals const& other ) const;
   2849         Totals& operator += ( Totals const& other );
   2850 
   2851         Totals delta( Totals const& prevTotals ) const;
   2852 
   2853         int error = 0;
   2854         Counts assertions;
   2855         Counts testCases;
   2856     };
   2857 }
   2858 
   2859 // end catch_totals.h
   2860 #include <string>
   2861 
   2862 namespace Catch {
   2863 
   2864     struct SectionInfo {
   2865         SectionInfo
   2866             (   SourceLineInfo const& _lineInfo,
   2867                 std::string const& _name );
   2868 
   2869         // Deprecated
   2870         SectionInfo
   2871             (   SourceLineInfo const& _lineInfo,
   2872                 std::string const& _name,
   2873                 std::string const& ) : SectionInfo( _lineInfo, _name ) {}
   2874 
   2875         std::string name;
   2876         std::string description; // !Deprecated: this will always be empty
   2877         SourceLineInfo lineInfo;
   2878     };
   2879 
   2880     struct SectionEndInfo {
   2881         SectionInfo sectionInfo;
   2882         Counts prevAssertions;
   2883         double durationInSeconds;
   2884     };
   2885 
   2886 } // end namespace Catch
   2887 
   2888 // end catch_section_info.h
   2889 // start catch_timer.h
   2890 
   2891 #include <cstdint>
   2892 
   2893 namespace Catch {
   2894 
   2895     auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
   2896     auto getEstimatedClockResolution() -> uint64_t;
   2897 
   2898     class Timer {
   2899         uint64_t m_nanoseconds = 0;
   2900     public:
   2901         void start();
   2902         auto getElapsedNanoseconds() const -> uint64_t;
   2903         auto getElapsedMicroseconds() const -> uint64_t;
   2904         auto getElapsedMilliseconds() const -> unsigned int;
   2905         auto getElapsedSeconds() const -> double;
   2906     };
   2907 
   2908 } // namespace Catch
   2909 
   2910 // end catch_timer.h
   2911 #include <string>
   2912 
   2913 namespace Catch {
   2914 
   2915     class Section : NonCopyable {
   2916     public:
   2917         Section( SectionInfo const& info );
   2918         ~Section();
   2919 
   2920         // This indicates whether the section should be executed or not
   2921         explicit operator bool() const;
   2922 
   2923     private:
   2924         SectionInfo m_info;
   2925 
   2926         std::string m_name;
   2927         Counts m_assertions;
   2928         bool m_sectionIncluded;
   2929         Timer m_timer;
   2930     };
   2931 
   2932 } // end namespace Catch
   2933 
   2934 #define INTERNAL_CATCH_SECTION( ... ) \
   2935     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   2936     CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
   2937     if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
   2938     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   2939 
   2940 #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
   2941     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   2942     CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
   2943     if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
   2944     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   2945 
   2946 // end catch_section.h
   2947 // start catch_interfaces_exception.h
   2948 
   2949 // start catch_interfaces_registry_hub.h
   2950 
   2951 #include <string>
   2952 #include <memory>
   2953 
   2954 namespace Catch {
   2955 
   2956     class TestCase;
   2957     struct ITestCaseRegistry;
   2958     struct IExceptionTranslatorRegistry;
   2959     struct IExceptionTranslator;
   2960     struct IReporterRegistry;
   2961     struct IReporterFactory;
   2962     struct ITagAliasRegistry;
   2963     struct IMutableEnumValuesRegistry;
   2964 
   2965     class StartupExceptionRegistry;
   2966 
   2967     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
   2968 
   2969     struct IRegistryHub {
   2970         virtual ~IRegistryHub();
   2971 
   2972         virtual IReporterRegistry const& getReporterRegistry() const = 0;
   2973         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
   2974         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
   2975         virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
   2976 
   2977         virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
   2978     };
   2979 
   2980     struct IMutableRegistryHub {
   2981         virtual ~IMutableRegistryHub();
   2982         virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
   2983         virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
   2984         virtual void registerTest( TestCase const& testInfo ) = 0;
   2985         virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
   2986         virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
   2987         virtual void registerStartupException() noexcept = 0;
   2988         virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
   2989     };
   2990 
   2991     IRegistryHub const& getRegistryHub();
   2992     IMutableRegistryHub& getMutableRegistryHub();
   2993     void cleanUp();
   2994     std::string translateActiveException();
   2995 
   2996 }
   2997 
   2998 // end catch_interfaces_registry_hub.h
   2999 #if defined(CATCH_CONFIG_DISABLE)
   3000     #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
   3001         static std::string translatorName( signature )
   3002 #endif
   3003 
   3004 #include <exception>
   3005 #include <string>
   3006 #include <vector>
   3007 
   3008 namespace Catch {
   3009     using exceptionTranslateFunction = std::string(*)();
   3010 
   3011     struct IExceptionTranslator;
   3012     using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
   3013 
   3014     struct IExceptionTranslator {
   3015         virtual ~IExceptionTranslator();
   3016         virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
   3017     };
   3018 
   3019     struct IExceptionTranslatorRegistry {
   3020         virtual ~IExceptionTranslatorRegistry();
   3021 
   3022         virtual std::string translateActiveException() const = 0;
   3023     };
   3024 
   3025     class ExceptionTranslatorRegistrar {
   3026         template<typename T>
   3027         class ExceptionTranslator : public IExceptionTranslator {
   3028         public:
   3029 
   3030             ExceptionTranslator( std::string(*translateFunction)( T& ) )
   3031             : m_translateFunction( translateFunction )
   3032             {}
   3033 
   3034             std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
   3035 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
   3036                 return "";
   3037 #else
   3038                 try {
   3039                     if( it == itEnd )
   3040                         std::rethrow_exception(std::current_exception());
   3041                     else
   3042                         return (*it)->translate( it+1, itEnd );
   3043                 }
   3044                 catch( T& ex ) {
   3045                     return m_translateFunction( ex );
   3046                 }
   3047 #endif
   3048             }
   3049 
   3050         protected:
   3051             std::string(*m_translateFunction)( T& );
   3052         };
   3053 
   3054     public:
   3055         template<typename T>
   3056         ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
   3057             getMutableRegistryHub().registerTranslator
   3058                 ( new ExceptionTranslator<T>( translateFunction ) );
   3059         }
   3060     };
   3061 }
   3062 
   3063 ///////////////////////////////////////////////////////////////////////////////
   3064 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
   3065     static std::string translatorName( signature ); \
   3066     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   3067     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   3068     namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
   3069     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   3070     static std::string translatorName( signature )
   3071 
   3072 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
   3073 
   3074 // end catch_interfaces_exception.h
   3075 // start catch_approx.h
   3076 
   3077 #include <type_traits>
   3078 
   3079 namespace Catch {
   3080 namespace Detail {
   3081 
   3082     class Approx {
   3083     private:
   3084         bool equalityComparisonImpl(double other) const;
   3085         // Validates the new margin (margin >= 0)
   3086         // out-of-line to avoid including stdexcept in the header
   3087         void setMargin(double margin);
   3088         // Validates the new epsilon (0 < epsilon < 1)
   3089         // out-of-line to avoid including stdexcept in the header
   3090         void setEpsilon(double epsilon);
   3091 
   3092     public:
   3093         explicit Approx ( double value );
   3094 
   3095         static Approx custom();
   3096 
   3097         Approx operator-() const;
   3098 
   3099         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3100         Approx operator()( T const& value ) {
   3101             Approx approx( static_cast<double>(value) );
   3102             approx.m_epsilon = m_epsilon;
   3103             approx.m_margin = m_margin;
   3104             approx.m_scale = m_scale;
   3105             return approx;
   3106         }
   3107 
   3108         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3109         explicit Approx( T const& value ): Approx(static_cast<double>(value))
   3110         {}
   3111 
   3112         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3113         friend bool operator == ( const T& lhs, Approx const& rhs ) {
   3114             auto lhs_v = static_cast<double>(lhs);
   3115             return rhs.equalityComparisonImpl(lhs_v);
   3116         }
   3117 
   3118         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3119         friend bool operator == ( Approx const& lhs, const T& rhs ) {
   3120             return operator==( rhs, lhs );
   3121         }
   3122 
   3123         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3124         friend bool operator != ( T const& lhs, Approx const& rhs ) {
   3125             return !operator==( lhs, rhs );
   3126         }
   3127 
   3128         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3129         friend bool operator != ( Approx const& lhs, T const& rhs ) {
   3130             return !operator==( rhs, lhs );
   3131         }
   3132 
   3133         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3134         friend bool operator <= ( T const& lhs, Approx const& rhs ) {
   3135             return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
   3136         }
   3137 
   3138         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3139         friend bool operator <= ( Approx const& lhs, T const& rhs ) {
   3140             return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
   3141         }
   3142 
   3143         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3144         friend bool operator >= ( T const& lhs, Approx const& rhs ) {
   3145             return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
   3146         }
   3147 
   3148         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3149         friend bool operator >= ( Approx const& lhs, T const& rhs ) {
   3150             return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
   3151         }
   3152 
   3153         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3154         Approx& epsilon( T const& newEpsilon ) {
   3155             double epsilonAsDouble = static_cast<double>(newEpsilon);
   3156             setEpsilon(epsilonAsDouble);
   3157             return *this;
   3158         }
   3159 
   3160         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3161         Approx& margin( T const& newMargin ) {
   3162             double marginAsDouble = static_cast<double>(newMargin);
   3163             setMargin(marginAsDouble);
   3164             return *this;
   3165         }
   3166 
   3167         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3168         Approx& scale( T const& newScale ) {
   3169             m_scale = static_cast<double>(newScale);
   3170             return *this;
   3171         }
   3172 
   3173         std::string toString() const;
   3174 
   3175     private:
   3176         double m_epsilon;
   3177         double m_margin;
   3178         double m_scale;
   3179         double m_value;
   3180     };
   3181 } // end namespace Detail
   3182 
   3183 namespace literals {
   3184     Detail::Approx operator "" _a(long double val);
   3185     Detail::Approx operator "" _a(unsigned long long val);
   3186 } // end namespace literals
   3187 
   3188 template<>
   3189 struct StringMaker<Catch::Detail::Approx> {
   3190     static std::string convert(Catch::Detail::Approx const& value);
   3191 };
   3192 
   3193 } // end namespace Catch
   3194 
   3195 // end catch_approx.h
   3196 // start catch_string_manip.h
   3197 
   3198 #include <string>
   3199 #include <iosfwd>
   3200 #include <vector>
   3201 
   3202 namespace Catch {
   3203 
   3204     bool startsWith( std::string const& s, std::string const& prefix );
   3205     bool startsWith( std::string const& s, char prefix );
   3206     bool endsWith( std::string const& s, std::string const& suffix );
   3207     bool endsWith( std::string const& s, char suffix );
   3208     bool contains( std::string const& s, std::string const& infix );
   3209     void toLowerInPlace( std::string& s );
   3210     std::string toLower( std::string const& s );
   3211     //! Returns a new string without whitespace at the start/end
   3212     std::string trim( std::string const& str );
   3213     //! Returns a substring of the original ref without whitespace. Beware lifetimes!
   3214     StringRef trim(StringRef ref);
   3215 
   3216     // !!! Be aware, returns refs into original string - make sure original string outlives them
   3217     std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
   3218     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
   3219 
   3220     struct pluralise {
   3221         pluralise( std::size_t count, std::string const& label );
   3222 
   3223         friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
   3224 
   3225         std::size_t m_count;
   3226         std::string m_label;
   3227     };
   3228 }
   3229 
   3230 // end catch_string_manip.h
   3231 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
   3232 // start catch_capture_matchers.h
   3233 
   3234 // start catch_matchers.h
   3235 
   3236 #include <string>
   3237 #include <vector>
   3238 
   3239 namespace Catch {
   3240 namespace Matchers {
   3241     namespace Impl {
   3242 
   3243         template<typename ArgT> struct MatchAllOf;
   3244         template<typename ArgT> struct MatchAnyOf;
   3245         template<typename ArgT> struct MatchNotOf;
   3246 
   3247         class MatcherUntypedBase {
   3248         public:
   3249             MatcherUntypedBase() = default;
   3250             MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
   3251             MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
   3252             std::string toString() const;
   3253 
   3254         protected:
   3255             virtual ~MatcherUntypedBase();
   3256             virtual std::string describe() const = 0;
   3257             mutable std::string m_cachedToString;
   3258         };
   3259 
   3260 #ifdef __clang__
   3261 #    pragma clang diagnostic push
   3262 #    pragma clang diagnostic ignored "-Wnon-virtual-dtor"
   3263 #endif
   3264 
   3265         template<typename ObjectT>
   3266         struct MatcherMethod {
   3267             virtual bool match( ObjectT const& arg ) const = 0;
   3268         };
   3269 
   3270 #if defined(__OBJC__)
   3271         // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
   3272         // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
   3273         template<>
   3274         struct MatcherMethod<NSString*> {
   3275             virtual bool match( NSString* arg ) const = 0;
   3276         };
   3277 #endif
   3278 
   3279 #ifdef __clang__
   3280 #    pragma clang diagnostic pop
   3281 #endif
   3282 
   3283         template<typename T>
   3284         struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
   3285 
   3286             MatchAllOf<T> operator && ( MatcherBase const& other ) const;
   3287             MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
   3288             MatchNotOf<T> operator ! () const;
   3289         };
   3290 
   3291         template<typename ArgT>
   3292         struct MatchAllOf : MatcherBase<ArgT> {
   3293             bool match( ArgT const& arg ) const override {
   3294                 for( auto matcher : m_matchers ) {
   3295                     if (!matcher->match(arg))
   3296                         return false;
   3297                 }
   3298                 return true;
   3299             }
   3300             std::string describe() const override {
   3301                 std::string description;
   3302                 description.reserve( 4 + m_matchers.size()*32 );
   3303                 description += "( ";
   3304                 bool first = true;
   3305                 for( auto matcher : m_matchers ) {
   3306                     if( first )
   3307                         first = false;
   3308                     else
   3309                         description += " and ";
   3310                     description += matcher->toString();
   3311                 }
   3312                 description += " )";
   3313                 return description;
   3314             }
   3315 
   3316             MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {
   3317                 auto copy(*this);
   3318                 copy.m_matchers.push_back( &other );
   3319                 return copy;
   3320             }
   3321 
   3322             std::vector<MatcherBase<ArgT> const*> m_matchers;
   3323         };
   3324         template<typename ArgT>
   3325         struct MatchAnyOf : MatcherBase<ArgT> {
   3326 
   3327             bool match( ArgT const& arg ) const override {
   3328                 for( auto matcher : m_matchers ) {
   3329                     if (matcher->match(arg))
   3330                         return true;
   3331                 }
   3332                 return false;
   3333             }
   3334             std::string describe() const override {
   3335                 std::string description;
   3336                 description.reserve( 4 + m_matchers.size()*32 );
   3337                 description += "( ";
   3338                 bool first = true;
   3339                 for( auto matcher : m_matchers ) {
   3340                     if( first )
   3341                         first = false;
   3342                     else
   3343                         description += " or ";
   3344                     description += matcher->toString();
   3345                 }
   3346                 description += " )";
   3347                 return description;
   3348             }
   3349 
   3350             MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {
   3351                 auto copy(*this);
   3352                 copy.m_matchers.push_back( &other );
   3353                 return copy;
   3354             }
   3355 
   3356             std::vector<MatcherBase<ArgT> const*> m_matchers;
   3357         };
   3358 
   3359         template<typename ArgT>
   3360         struct MatchNotOf : MatcherBase<ArgT> {
   3361 
   3362             MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
   3363 
   3364             bool match( ArgT const& arg ) const override {
   3365                 return !m_underlyingMatcher.match( arg );
   3366             }
   3367 
   3368             std::string describe() const override {
   3369                 return "not " + m_underlyingMatcher.toString();
   3370             }
   3371             MatcherBase<ArgT> const& m_underlyingMatcher;
   3372         };
   3373 
   3374         template<typename T>
   3375         MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {
   3376             return MatchAllOf<T>() && *this && other;
   3377         }
   3378         template<typename T>
   3379         MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
   3380             return MatchAnyOf<T>() || *this || other;
   3381         }
   3382         template<typename T>
   3383         MatchNotOf<T> MatcherBase<T>::operator ! () const {
   3384             return MatchNotOf<T>( *this );
   3385         }
   3386 
   3387     } // namespace Impl
   3388 
   3389 } // namespace Matchers
   3390 
   3391 using namespace Matchers;
   3392 using Matchers::Impl::MatcherBase;
   3393 
   3394 } // namespace Catch
   3395 
   3396 // end catch_matchers.h
   3397 // start catch_matchers_exception.hpp
   3398 
   3399 namespace Catch {
   3400 namespace Matchers {
   3401 namespace Exception {
   3402 
   3403 class ExceptionMessageMatcher : public MatcherBase<std::exception> {
   3404     std::string m_message;
   3405 public:
   3406 
   3407     ExceptionMessageMatcher(std::string const& message):
   3408         m_message(message)
   3409     {}
   3410 
   3411     bool match(std::exception const& ex) const override;
   3412 
   3413     std::string describe() const override;
   3414 };
   3415 
   3416 } // namespace Exception
   3417 
   3418 Exception::ExceptionMessageMatcher Message(std::string const& message);
   3419 
   3420 } // namespace Matchers
   3421 } // namespace Catch
   3422 
   3423 // end catch_matchers_exception.hpp
   3424 // start catch_matchers_floating.h
   3425 
   3426 namespace Catch {
   3427 namespace Matchers {
   3428 
   3429     namespace Floating {
   3430 
   3431         enum class FloatingPointKind : uint8_t;
   3432 
   3433         struct WithinAbsMatcher : MatcherBase<double> {
   3434             WithinAbsMatcher(double target, double margin);
   3435             bool match(double const& matchee) const override;
   3436             std::string describe() const override;
   3437         private:
   3438             double m_target;
   3439             double m_margin;
   3440         };
   3441 
   3442         struct WithinUlpsMatcher : MatcherBase<double> {
   3443             WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
   3444             bool match(double const& matchee) const override;
   3445             std::string describe() const override;
   3446         private:
   3447             double m_target;
   3448             uint64_t m_ulps;
   3449             FloatingPointKind m_type;
   3450         };
   3451 
   3452         // Given IEEE-754 format for floats and doubles, we can assume
   3453         // that float -> double promotion is lossless. Given this, we can
   3454         // assume that if we do the standard relative comparison of
   3455         // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
   3456         // the same result if we do this for floats, as if we do this for
   3457         // doubles that were promoted from floats.
   3458         struct WithinRelMatcher : MatcherBase<double> {
   3459             WithinRelMatcher(double target, double epsilon);
   3460             bool match(double const& matchee) const override;
   3461             std::string describe() const override;
   3462         private:
   3463             double m_target;
   3464             double m_epsilon;
   3465         };
   3466 
   3467     } // namespace Floating
   3468 
   3469     // The following functions create the actual matcher objects.
   3470     // This allows the types to be inferred
   3471     Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
   3472     Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
   3473     Floating::WithinAbsMatcher WithinAbs(double target, double margin);
   3474     Floating::WithinRelMatcher WithinRel(double target, double eps);
   3475     // defaults epsilon to 100*numeric_limits<double>::epsilon()
   3476     Floating::WithinRelMatcher WithinRel(double target);
   3477     Floating::WithinRelMatcher WithinRel(float target, float eps);
   3478     // defaults epsilon to 100*numeric_limits<float>::epsilon()
   3479     Floating::WithinRelMatcher WithinRel(float target);
   3480 
   3481 } // namespace Matchers
   3482 } // namespace Catch
   3483 
   3484 // end catch_matchers_floating.h
   3485 // start catch_matchers_generic.hpp
   3486 
   3487 #include <functional>
   3488 #include <string>
   3489 
   3490 namespace Catch {
   3491 namespace Matchers {
   3492 namespace Generic {
   3493 
   3494 namespace Detail {
   3495     std::string finalizeDescription(const std::string& desc);
   3496 }
   3497 
   3498 template <typename T>
   3499 class PredicateMatcher : public MatcherBase<T> {
   3500     std::function<bool(T const&)> m_predicate;
   3501     std::string m_description;
   3502 public:
   3503 
   3504     PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
   3505         :m_predicate(std::move(elem)),
   3506         m_description(Detail::finalizeDescription(descr))
   3507     {}
   3508 
   3509     bool match( T const& item ) const override {
   3510         return m_predicate(item);
   3511     }
   3512 
   3513     std::string describe() const override {
   3514         return m_description;
   3515     }
   3516 };
   3517 
   3518 } // namespace Generic
   3519 
   3520     // The following functions create the actual matcher objects.
   3521     // The user has to explicitly specify type to the function, because
   3522     // inferring std::function<bool(T const&)> is hard (but possible) and
   3523     // requires a lot of TMP.
   3524     template<typename T>
   3525     Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
   3526         return Generic::PredicateMatcher<T>(predicate, description);
   3527     }
   3528 
   3529 } // namespace Matchers
   3530 } // namespace Catch
   3531 
   3532 // end catch_matchers_generic.hpp
   3533 // start catch_matchers_string.h
   3534 
   3535 #include <string>
   3536 
   3537 namespace Catch {
   3538 namespace Matchers {
   3539 
   3540     namespace StdString {
   3541 
   3542         struct CasedString
   3543         {
   3544             CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
   3545             std::string adjustString( std::string const& str ) const;
   3546             std::string caseSensitivitySuffix() const;
   3547 
   3548             CaseSensitive::Choice m_caseSensitivity;
   3549             std::string m_str;
   3550         };
   3551 
   3552         struct StringMatcherBase : MatcherBase<std::string> {
   3553             StringMatcherBase( std::string const& operation, CasedString const& comparator );
   3554             std::string describe() const override;
   3555 
   3556             CasedString m_comparator;
   3557             std::string m_operation;
   3558         };
   3559 
   3560         struct EqualsMatcher : StringMatcherBase {
   3561             EqualsMatcher( CasedString const& comparator );
   3562             bool match( std::string const& source ) const override;
   3563         };
   3564         struct ContainsMatcher : StringMatcherBase {
   3565             ContainsMatcher( CasedString const& comparator );
   3566             bool match( std::string const& source ) const override;
   3567         };
   3568         struct StartsWithMatcher : StringMatcherBase {
   3569             StartsWithMatcher( CasedString const& comparator );
   3570             bool match( std::string const& source ) const override;
   3571         };
   3572         struct EndsWithMatcher : StringMatcherBase {
   3573             EndsWithMatcher( CasedString const& comparator );
   3574             bool match( std::string const& source ) const override;
   3575         };
   3576 
   3577         struct RegexMatcher : MatcherBase<std::string> {
   3578             RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
   3579             bool match( std::string const& matchee ) const override;
   3580             std::string describe() const override;
   3581 
   3582         private:
   3583             std::string m_regex;
   3584             CaseSensitive::Choice m_caseSensitivity;
   3585         };
   3586 
   3587     } // namespace StdString
   3588 
   3589     // The following functions create the actual matcher objects.
   3590     // This allows the types to be inferred
   3591 
   3592     StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
   3593     StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
   3594     StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
   3595     StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
   3596     StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
   3597 
   3598 } // namespace Matchers
   3599 } // namespace Catch
   3600 
   3601 // end catch_matchers_string.h
   3602 // start catch_matchers_vector.h
   3603 
   3604 #include <algorithm>
   3605 
   3606 namespace Catch {
   3607 namespace Matchers {
   3608 
   3609     namespace Vector {
   3610         template<typename T, typename Alloc>
   3611         struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
   3612 
   3613             ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
   3614 
   3615             bool match(std::vector<T, Alloc> const &v) const override {
   3616                 for (auto const& el : v) {
   3617                     if (el == m_comparator) {
   3618                         return true;
   3619                     }
   3620                 }
   3621                 return false;
   3622             }
   3623 
   3624             std::string describe() const override {
   3625                 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
   3626             }
   3627 
   3628             T const& m_comparator;
   3629         };
   3630 
   3631         template<typename T, typename AllocComp, typename AllocMatch>
   3632         struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
   3633 
   3634             ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
   3635 
   3636             bool match(std::vector<T, AllocMatch> const &v) const override {
   3637                 // !TBD: see note in EqualsMatcher
   3638                 if (m_comparator.size() > v.size())
   3639                     return false;
   3640                 for (auto const& comparator : m_comparator) {
   3641                     auto present = false;
   3642                     for (const auto& el : v) {
   3643                         if (el == comparator) {
   3644                             present = true;
   3645                             break;
   3646                         }
   3647                     }
   3648                     if (!present) {
   3649                         return false;
   3650                     }
   3651                 }
   3652                 return true;
   3653             }
   3654             std::string describe() const override {
   3655                 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
   3656             }
   3657 
   3658             std::vector<T, AllocComp> const& m_comparator;
   3659         };
   3660 
   3661         template<typename T, typename AllocComp, typename AllocMatch>
   3662         struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
   3663 
   3664             EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
   3665 
   3666             bool match(std::vector<T, AllocMatch> const &v) const override {
   3667                 // !TBD: This currently works if all elements can be compared using !=
   3668                 // - a more general approach would be via a compare template that defaults
   3669                 // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc
   3670                 // - then just call that directly
   3671                 if (m_comparator.size() != v.size())
   3672                     return false;
   3673                 for (std::size_t i = 0; i < v.size(); ++i)
   3674                     if (m_comparator[i] != v[i])
   3675                         return false;
   3676                 return true;
   3677             }
   3678             std::string describe() const override {
   3679                 return "Equals: " + ::Catch::Detail::stringify( m_comparator );
   3680             }
   3681             std::vector<T, AllocComp> const& m_comparator;
   3682         };
   3683 
   3684         template<typename T, typename AllocComp, typename AllocMatch>
   3685         struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
   3686 
   3687             ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator( comparator ) {}
   3688 
   3689             bool match(std::vector<T, AllocMatch> const &v) const override {
   3690                 if (m_comparator.size() != v.size())
   3691                     return false;
   3692                 for (std::size_t i = 0; i < v.size(); ++i)
   3693                     if (m_comparator[i] != approx(v[i]))
   3694                         return false;
   3695                 return true;
   3696             }
   3697             std::string describe() const override {
   3698                 return "is approx: " + ::Catch::Detail::stringify( m_comparator );
   3699             }
   3700             template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3701             ApproxMatcher& epsilon( T const& newEpsilon ) {
   3702                 approx.epsilon(newEpsilon);
   3703                 return *this;
   3704             }
   3705             template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3706             ApproxMatcher& margin( T const& newMargin ) {
   3707                 approx.margin(newMargin);
   3708                 return *this;
   3709             }
   3710             template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3711             ApproxMatcher& scale( T const& newScale ) {
   3712                 approx.scale(newScale);
   3713                 return *this;
   3714             }
   3715 
   3716             std::vector<T, AllocComp> const& m_comparator;
   3717             mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
   3718         };
   3719 
   3720         template<typename T, typename AllocComp, typename AllocMatch>
   3721         struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
   3722             UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) : m_target(target) {}
   3723             bool match(std::vector<T, AllocMatch> const& vec) const override {
   3724                 if (m_target.size() != vec.size()) {
   3725                     return false;
   3726                 }
   3727                 return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
   3728             }
   3729 
   3730             std::string describe() const override {
   3731                 return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
   3732             }
   3733         private:
   3734             std::vector<T, AllocComp> const& m_target;
   3735         };
   3736 
   3737     } // namespace Vector
   3738 
   3739     // The following functions create the actual matcher objects.
   3740     // This allows the types to be inferred
   3741 
   3742     template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
   3743     Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {
   3744         return Vector::ContainsMatcher<T, AllocComp, AllocMatch>( comparator );
   3745     }
   3746 
   3747     template<typename T, typename Alloc = std::allocator<T>>
   3748     Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) {
   3749         return Vector::ContainsElementMatcher<T, Alloc>( comparator );
   3750     }
   3751 
   3752     template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
   3753     Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {
   3754         return Vector::EqualsMatcher<T, AllocComp, AllocMatch>( comparator );
   3755     }
   3756 
   3757     template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
   3758     Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {
   3759         return Vector::ApproxMatcher<T, AllocComp, AllocMatch>( comparator );
   3760     }
   3761 
   3762     template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
   3763     Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) {
   3764         return Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch>( target );
   3765     }
   3766 
   3767 } // namespace Matchers
   3768 } // namespace Catch
   3769 
   3770 // end catch_matchers_vector.h
   3771 namespace Catch {
   3772 
   3773     template<typename ArgT, typename MatcherT>
   3774     class MatchExpr : public ITransientExpression {
   3775         ArgT const& m_arg;
   3776         MatcherT m_matcher;
   3777         StringRef m_matcherString;
   3778     public:
   3779         MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
   3780         :   ITransientExpression{ true, matcher.match( arg ) },
   3781             m_arg( arg ),
   3782             m_matcher( matcher ),
   3783             m_matcherString( matcherString )
   3784         {}
   3785 
   3786         void streamReconstructedExpression( std::ostream &os ) const override {
   3787             auto matcherAsString = m_matcher.toString();
   3788             os << Catch::Detail::stringify( m_arg ) << ' ';
   3789             if( matcherAsString == Detail::unprintableString )
   3790                 os << m_matcherString;
   3791             else
   3792                 os << matcherAsString;
   3793         }
   3794     };
   3795 
   3796     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
   3797 
   3798     void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );
   3799 
   3800     template<typename ArgT, typename MatcherT>
   3801     auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {
   3802         return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
   3803     }
   3804 
   3805 } // namespace Catch
   3806 
   3807 ///////////////////////////////////////////////////////////////////////////////
   3808 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
   3809     do { \
   3810         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
   3811         INTERNAL_CATCH_TRY { \
   3812             catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
   3813         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
   3814         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   3815     } while( false )
   3816 
   3817 ///////////////////////////////////////////////////////////////////////////////
   3818 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
   3819     do { \
   3820         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
   3821         if( catchAssertionHandler.allowThrows() ) \
   3822             try { \
   3823                 static_cast<void>(__VA_ARGS__ ); \
   3824                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
   3825             } \
   3826             catch( exceptionType const& ex ) { \
   3827                 catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
   3828             } \
   3829             catch( ... ) { \
   3830                 catchAssertionHandler.handleUnexpectedInflightException(); \
   3831             } \
   3832         else \
   3833             catchAssertionHandler.handleThrowingCallSkipped(); \
   3834         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   3835     } while( false )
   3836 
   3837 // end catch_capture_matchers.h
   3838 #endif
   3839 // start catch_generators.hpp
   3840 
   3841 // start catch_interfaces_generatortracker.h
   3842 
   3843 
   3844 #include <memory>
   3845 
   3846 namespace Catch {
   3847 
   3848     namespace Generators {
   3849         class GeneratorUntypedBase {
   3850         public:
   3851             GeneratorUntypedBase() = default;
   3852             virtual ~GeneratorUntypedBase();
   3853             // Attempts to move the generator to the next element
   3854              //
   3855              // Returns true iff the move succeeded (and a valid element
   3856              // can be retrieved).
   3857             virtual bool next() = 0;
   3858         };
   3859         using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
   3860 
   3861     } // namespace Generators
   3862 
   3863     struct IGeneratorTracker {
   3864         virtual ~IGeneratorTracker();
   3865         virtual auto hasGenerator() const -> bool = 0;
   3866         virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
   3867         virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
   3868     };
   3869 
   3870 } // namespace Catch
   3871 
   3872 // end catch_interfaces_generatortracker.h
   3873 // start catch_enforce.h
   3874 
   3875 #include <exception>
   3876 
   3877 namespace Catch {
   3878 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
   3879     template <typename Ex>
   3880     [[noreturn]]
   3881     void throw_exception(Ex const& e) {
   3882         throw e;
   3883     }
   3884 #else // ^^ Exceptions are enabled //  Exceptions are disabled vv
   3885     [[noreturn]]
   3886     void throw_exception(std::exception const& e);
   3887 #endif
   3888 
   3889     [[noreturn]]
   3890     void throw_logic_error(std::string const& msg);
   3891     [[noreturn]]
   3892     void throw_domain_error(std::string const& msg);
   3893     [[noreturn]]
   3894     void throw_runtime_error(std::string const& msg);
   3895 
   3896 } // namespace Catch;
   3897 
   3898 #define CATCH_MAKE_MSG(...) \
   3899     (Catch::ReusableStringStream() << __VA_ARGS__).str()
   3900 
   3901 #define CATCH_INTERNAL_ERROR(...) \
   3902     Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
   3903 
   3904 #define CATCH_ERROR(...) \
   3905     Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
   3906 
   3907 #define CATCH_RUNTIME_ERROR(...) \
   3908     Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
   3909 
   3910 #define CATCH_ENFORCE( condition, ... ) \
   3911     do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
   3912 
   3913 // end catch_enforce.h
   3914 #include <memory>
   3915 #include <vector>
   3916 #include <cassert>
   3917 
   3918 #include <utility>
   3919 #include <exception>
   3920 
   3921 namespace Catch {
   3922 
   3923 class GeneratorException : public std::exception {
   3924     const char* const m_msg = "";
   3925 
   3926 public:
   3927     GeneratorException(const char* msg):
   3928         m_msg(msg)
   3929     {}
   3930 
   3931     const char* what() const noexcept override final;
   3932 };
   3933 
   3934 namespace Generators {
   3935 
   3936     // !TBD move this into its own location?
   3937     namespace pf{
   3938         template<typename T, typename... Args>
   3939         std::unique_ptr<T> make_unique( Args&&... args ) {
   3940             return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
   3941         }
   3942     }
   3943 
   3944     template<typename T>
   3945     struct IGenerator : GeneratorUntypedBase {
   3946         virtual ~IGenerator() = default;
   3947 
   3948         // Returns the current element of the generator
   3949         //
   3950         // \Precondition The generator is either freshly constructed,
   3951         // or the last call to `next()` returned true
   3952         virtual T const& get() const = 0;
   3953         using type = T;
   3954     };
   3955 
   3956     template<typename T>
   3957     class SingleValueGenerator final : public IGenerator<T> {
   3958         T m_value;
   3959     public:
   3960         SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
   3961 
   3962         T const& get() const override {
   3963             return m_value;
   3964         }
   3965         bool next() override {
   3966             return false;
   3967         }
   3968     };
   3969 
   3970     template<typename T>
   3971     class FixedValuesGenerator final : public IGenerator<T> {
   3972         static_assert(!std::is_same<T, bool>::value,
   3973             "FixedValuesGenerator does not support bools because of std::vector<bool>"
   3974             "specialization, use SingleValue Generator instead.");
   3975         std::vector<T> m_values;
   3976         size_t m_idx = 0;
   3977     public:
   3978         FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
   3979 
   3980         T const& get() const override {
   3981             return m_values[m_idx];
   3982         }
   3983         bool next() override {
   3984             ++m_idx;
   3985             return m_idx < m_values.size();
   3986         }
   3987     };
   3988 
   3989     template <typename T>
   3990     class GeneratorWrapper final {
   3991         std::unique_ptr<IGenerator<T>> m_generator;
   3992     public:
   3993         GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
   3994             m_generator(std::move(generator))
   3995         {}
   3996         T const& get() const {
   3997             return m_generator->get();
   3998         }
   3999         bool next() {
   4000             return m_generator->next();
   4001         }
   4002     };
   4003 
   4004     template <typename T>
   4005     GeneratorWrapper<T> value(T&& value) {
   4006         return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
   4007     }
   4008     template <typename T>
   4009     GeneratorWrapper<T> values(std::initializer_list<T> values) {
   4010         return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
   4011     }
   4012 
   4013     template<typename T>
   4014     class Generators : public IGenerator<T> {
   4015         std::vector<GeneratorWrapper<T>> m_generators;
   4016         size_t m_current = 0;
   4017 
   4018         void populate(GeneratorWrapper<T>&& generator) {
   4019             m_generators.emplace_back(std::move(generator));
   4020         }
   4021         void populate(T&& val) {
   4022             m_generators.emplace_back(value(std::forward<T>(val)));
   4023         }
   4024         template<typename U>
   4025         void populate(U&& val) {
   4026             populate(T(std::forward<U>(val)));
   4027         }
   4028         template<typename U, typename... Gs>
   4029         void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
   4030             populate(std::forward<U>(valueOrGenerator));
   4031             populate(std::forward<Gs>(moreGenerators)...);
   4032         }
   4033 
   4034     public:
   4035         template <typename... Gs>
   4036         Generators(Gs &&... moreGenerators) {
   4037             m_generators.reserve(sizeof...(Gs));
   4038             populate(std::forward<Gs>(moreGenerators)...);
   4039         }
   4040 
   4041         T const& get() const override {
   4042             return m_generators[m_current].get();
   4043         }
   4044 
   4045         bool next() override {
   4046             if (m_current >= m_generators.size()) {
   4047                 return false;
   4048             }
   4049             const bool current_status = m_generators[m_current].next();
   4050             if (!current_status) {
   4051                 ++m_current;
   4052             }
   4053             return m_current < m_generators.size();
   4054         }
   4055     };
   4056 
   4057     template<typename... Ts>
   4058     GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {
   4059         return values<std::tuple<Ts...>>( tuples );
   4060     }
   4061 
   4062     // Tag type to signal that a generator sequence should convert arguments to a specific type
   4063     template <typename T>
   4064     struct as {};
   4065 
   4066     template<typename T, typename... Gs>
   4067     auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {
   4068         return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
   4069     }
   4070     template<typename T>
   4071     auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {
   4072         return Generators<T>(std::move(generator));
   4073     }
   4074     template<typename T, typename... Gs>
   4075     auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {
   4076         return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
   4077     }
   4078     template<typename T, typename U, typename... Gs>
   4079     auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {
   4080         return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
   4081     }
   4082 
   4083     auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
   4084 
   4085     template<typename L>
   4086     // Note: The type after -> is weird, because VS2015 cannot parse
   4087     //       the expression used in the typedef inside, when it is in
   4088     //       return type. Yeah.
   4089     auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
   4090         using UnderlyingType = typename decltype(generatorExpression())::type;
   4091 
   4092         IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );
   4093         if (!tracker.hasGenerator()) {
   4094             tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
   4095         }
   4096 
   4097         auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
   4098         return generator.get();
   4099     }
   4100 
   4101 } // namespace Generators
   4102 } // namespace Catch
   4103 
   4104 #define GENERATE( ... ) \
   4105     Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
   4106                                  CATCH_INTERNAL_LINEINFO, \
   4107                                  [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
   4108 #define GENERATE_COPY( ... ) \
   4109     Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
   4110                                  CATCH_INTERNAL_LINEINFO, \
   4111                                  [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
   4112 #define GENERATE_REF( ... ) \
   4113     Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
   4114                                  CATCH_INTERNAL_LINEINFO, \
   4115                                  [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
   4116 
   4117 // end catch_generators.hpp
   4118 // start catch_generators_generic.hpp
   4119 
   4120 namespace Catch {
   4121 namespace Generators {
   4122 
   4123     template <typename T>
   4124     class TakeGenerator : public IGenerator<T> {
   4125         GeneratorWrapper<T> m_generator;
   4126         size_t m_returned = 0;
   4127         size_t m_target;
   4128     public:
   4129         TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
   4130             m_generator(std::move(generator)),
   4131             m_target(target)
   4132         {
   4133             assert(target != 0 && "Empty generators are not allowed");
   4134         }
   4135         T const& get() const override {
   4136             return m_generator.get();
   4137         }
   4138         bool next() override {
   4139             ++m_returned;
   4140             if (m_returned >= m_target) {
   4141                 return false;
   4142             }
   4143 
   4144             const auto success = m_generator.next();
   4145             // If the underlying generator does not contain enough values
   4146             // then we cut short as well
   4147             if (!success) {
   4148                 m_returned = m_target;
   4149             }
   4150             return success;
   4151         }
   4152     };
   4153 
   4154     template <typename T>
   4155     GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
   4156         return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
   4157     }
   4158 
   4159     template <typename T, typename Predicate>
   4160     class FilterGenerator : public IGenerator<T> {
   4161         GeneratorWrapper<T> m_generator;
   4162         Predicate m_predicate;
   4163     public:
   4164         template <typename P = Predicate>
   4165         FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
   4166             m_generator(std::move(generator)),
   4167             m_predicate(std::forward<P>(pred))
   4168         {
   4169             if (!m_predicate(m_generator.get())) {
   4170                 // It might happen that there are no values that pass the
   4171                 // filter. In that case we throw an exception.
   4172                 auto has_initial_value = next();
   4173                 if (!has_initial_value) {
   4174                     Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
   4175                 }
   4176             }
   4177         }
   4178 
   4179         T const& get() const override {
   4180             return m_generator.get();
   4181         }
   4182 
   4183         bool next() override {
   4184             bool success = m_generator.next();
   4185             if (!success) {
   4186                 return false;
   4187             }
   4188             while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
   4189             return success;
   4190         }
   4191     };
   4192 
   4193     template <typename T, typename Predicate>
   4194     GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
   4195         return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
   4196     }
   4197 
   4198     template <typename T>
   4199     class RepeatGenerator : public IGenerator<T> {
   4200         static_assert(!std::is_same<T, bool>::value,
   4201             "RepeatGenerator currently does not support bools"
   4202             "because of std::vector<bool> specialization");
   4203         GeneratorWrapper<T> m_generator;
   4204         mutable std::vector<T> m_returned;
   4205         size_t m_target_repeats;
   4206         size_t m_current_repeat = 0;
   4207         size_t m_repeat_index = 0;
   4208     public:
   4209         RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
   4210             m_generator(std::move(generator)),
   4211             m_target_repeats(repeats)
   4212         {
   4213             assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
   4214         }
   4215 
   4216         T const& get() const override {
   4217             if (m_current_repeat == 0) {
   4218                 m_returned.push_back(m_generator.get());
   4219                 return m_returned.back();
   4220             }
   4221             return m_returned[m_repeat_index];
   4222         }
   4223 
   4224         bool next() override {
   4225             // There are 2 basic cases:
   4226             // 1) We are still reading the generator
   4227             // 2) We are reading our own cache
   4228 
   4229             // In the first case, we need to poke the underlying generator.
   4230             // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
   4231             if (m_current_repeat == 0) {
   4232                 const auto success = m_generator.next();
   4233                 if (!success) {
   4234                     ++m_current_repeat;
   4235                 }
   4236                 return m_current_repeat < m_target_repeats;
   4237             }
   4238 
   4239             // In the second case, we need to move indices forward and check that we haven't run up against the end
   4240             ++m_repeat_index;
   4241             if (m_repeat_index == m_returned.size()) {
   4242                 m_repeat_index = 0;
   4243                 ++m_current_repeat;
   4244             }
   4245             return m_current_repeat < m_target_repeats;
   4246         }
   4247     };
   4248 
   4249     template <typename T>
   4250     GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
   4251         return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
   4252     }
   4253 
   4254     template <typename T, typename U, typename Func>
   4255     class MapGenerator : public IGenerator<T> {
   4256         // TBD: provide static assert for mapping function, for friendly error message
   4257         GeneratorWrapper<U> m_generator;
   4258         Func m_function;
   4259         // To avoid returning dangling reference, we have to save the values
   4260         T m_cache;
   4261     public:
   4262         template <typename F2 = Func>
   4263         MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
   4264             m_generator(std::move(generator)),
   4265             m_function(std::forward<F2>(function)),
   4266             m_cache(m_function(m_generator.get()))
   4267         {}
   4268 
   4269         T const& get() const override {
   4270             return m_cache;
   4271         }
   4272         bool next() override {
   4273             const auto success = m_generator.next();
   4274             if (success) {
   4275                 m_cache = m_function(m_generator.get());
   4276             }
   4277             return success;
   4278         }
   4279     };
   4280 
   4281     template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
   4282     GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
   4283         return GeneratorWrapper<T>(
   4284             pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
   4285         );
   4286     }
   4287 
   4288     template <typename T, typename U, typename Func>
   4289     GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
   4290         return GeneratorWrapper<T>(
   4291             pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
   4292         );
   4293     }
   4294 
   4295     template <typename T>
   4296     class ChunkGenerator final : public IGenerator<std::vector<T>> {
   4297         std::vector<T> m_chunk;
   4298         size_t m_chunk_size;
   4299         GeneratorWrapper<T> m_generator;
   4300         bool m_used_up = false;
   4301     public:
   4302         ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
   4303             m_chunk_size(size), m_generator(std::move(generator))
   4304         {
   4305             m_chunk.reserve(m_chunk_size);
   4306             if (m_chunk_size != 0) {
   4307                 m_chunk.push_back(m_generator.get());
   4308                 for (size_t i = 1; i < m_chunk_size; ++i) {
   4309                     if (!m_generator.next()) {
   4310                         Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
   4311                     }
   4312                     m_chunk.push_back(m_generator.get());
   4313                 }
   4314             }
   4315         }
   4316         std::vector<T> const& get() const override {
   4317             return m_chunk;
   4318         }
   4319         bool next() override {
   4320             m_chunk.clear();
   4321             for (size_t idx = 0; idx < m_chunk_size; ++idx) {
   4322                 if (!m_generator.next()) {
   4323                     return false;
   4324                 }
   4325                 m_chunk.push_back(m_generator.get());
   4326             }
   4327             return true;
   4328         }
   4329     };
   4330 
   4331     template <typename T>
   4332     GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {
   4333         return GeneratorWrapper<std::vector<T>>(
   4334             pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
   4335         );
   4336     }
   4337 
   4338 } // namespace Generators
   4339 } // namespace Catch
   4340 
   4341 // end catch_generators_generic.hpp
   4342 // start catch_generators_specific.hpp
   4343 
   4344 // start catch_context.h
   4345 
   4346 #include <memory>
   4347 
   4348 namespace Catch {
   4349 
   4350     struct IResultCapture;
   4351     struct IRunner;
   4352     struct IConfig;
   4353     struct IMutableContext;
   4354 
   4355     using IConfigPtr = std::shared_ptr<IConfig const>;
   4356 
   4357     struct IContext
   4358     {
   4359         virtual ~IContext();
   4360 
   4361         virtual IResultCapture* getResultCapture() = 0;
   4362         virtual IRunner* getRunner() = 0;
   4363         virtual IConfigPtr const& getConfig() const = 0;
   4364     };
   4365 
   4366     struct IMutableContext : IContext
   4367     {
   4368         virtual ~IMutableContext();
   4369         virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
   4370         virtual void setRunner( IRunner* runner ) = 0;
   4371         virtual void setConfig( IConfigPtr const& config ) = 0;
   4372 
   4373     private:
   4374         static IMutableContext *currentContext;
   4375         friend IMutableContext& getCurrentMutableContext();
   4376         friend void cleanUpContext();
   4377         static void createContext();
   4378     };
   4379 
   4380     inline IMutableContext& getCurrentMutableContext()
   4381     {
   4382         if( !IMutableContext::currentContext )
   4383             IMutableContext::createContext();
   4384         // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
   4385         return *IMutableContext::currentContext;
   4386     }
   4387 
   4388     inline IContext& getCurrentContext()
   4389     {
   4390         return getCurrentMutableContext();
   4391     }
   4392 
   4393     void cleanUpContext();
   4394 
   4395     class SimplePcg32;
   4396     SimplePcg32& rng();
   4397 }
   4398 
   4399 // end catch_context.h
   4400 // start catch_interfaces_config.h
   4401 
   4402 // start catch_option.hpp
   4403 
   4404 namespace Catch {
   4405 
   4406     // An optional type
   4407     template<typename T>
   4408     class Option {
   4409     public:
   4410         Option() : nullableValue( nullptr ) {}
   4411         Option( T const& _value )
   4412         : nullableValue( new( storage ) T( _value ) )
   4413         {}
   4414         Option( Option const& _other )
   4415         : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
   4416         {}
   4417 
   4418         ~Option() {
   4419             reset();
   4420         }
   4421 
   4422         Option& operator= ( Option const& _other ) {
   4423             if( &_other != this ) {
   4424                 reset();
   4425                 if( _other )
   4426                     nullableValue = new( storage ) T( *_other );
   4427             }
   4428             return *this;
   4429         }
   4430         Option& operator = ( T const& _value ) {
   4431             reset();
   4432             nullableValue = new( storage ) T( _value );
   4433             return *this;
   4434         }
   4435 
   4436         void reset() {
   4437             if( nullableValue )
   4438                 nullableValue->~T();
   4439             nullableValue = nullptr;
   4440         }
   4441 
   4442         T& operator*() { return *nullableValue; }
   4443         T const& operator*() const { return *nullableValue; }
   4444         T* operator->() { return nullableValue; }
   4445         const T* operator->() const { return nullableValue; }
   4446 
   4447         T valueOr( T const& defaultValue ) const {
   4448             return nullableValue ? *nullableValue : defaultValue;
   4449         }
   4450 
   4451         bool some() const { return nullableValue != nullptr; }
   4452         bool none() const { return nullableValue == nullptr; }
   4453 
   4454         bool operator !() const { return nullableValue == nullptr; }
   4455         explicit operator bool() const {
   4456             return some();
   4457         }
   4458 
   4459     private:
   4460         T *nullableValue;
   4461         alignas(alignof(T)) char storage[sizeof(T)];
   4462     };
   4463 
   4464 } // end namespace Catch
   4465 
   4466 // end catch_option.hpp
   4467 #include <chrono>
   4468 #include <iosfwd>
   4469 #include <string>
   4470 #include <vector>
   4471 #include <memory>
   4472 
   4473 namespace Catch {
   4474 
   4475     enum class Verbosity {
   4476         Quiet = 0,
   4477         Normal,
   4478         High
   4479     };
   4480 
   4481     struct WarnAbout { enum What {
   4482         Nothing = 0x00,
   4483         NoAssertions = 0x01,
   4484         NoTests = 0x02
   4485     }; };
   4486 
   4487     struct ShowDurations { enum OrNot {
   4488         DefaultForReporter,
   4489         Always,
   4490         Never
   4491     }; };
   4492     struct RunTests { enum InWhatOrder {
   4493         InDeclarationOrder,
   4494         InLexicographicalOrder,
   4495         InRandomOrder
   4496     }; };
   4497     struct UseColour { enum YesOrNo {
   4498         Auto,
   4499         Yes,
   4500         No
   4501     }; };
   4502     struct WaitForKeypress { enum When {
   4503         Never,
   4504         BeforeStart = 1,
   4505         BeforeExit = 2,
   4506         BeforeStartAndExit = BeforeStart | BeforeExit
   4507     }; };
   4508 
   4509     class TestSpec;
   4510 
   4511     struct IConfig : NonCopyable {
   4512 
   4513         virtual ~IConfig();
   4514 
   4515         virtual bool allowThrows() const = 0;
   4516         virtual std::ostream& stream() const = 0;
   4517         virtual std::string name() const = 0;
   4518         virtual bool includeSuccessfulResults() const = 0;
   4519         virtual bool shouldDebugBreak() const = 0;
   4520         virtual bool warnAboutMissingAssertions() const = 0;
   4521         virtual bool warnAboutNoTests() const = 0;
   4522         virtual int abortAfter() const = 0;
   4523         virtual bool showInvisibles() const = 0;
   4524         virtual ShowDurations::OrNot showDurations() const = 0;
   4525         virtual double minDuration() const = 0;
   4526         virtual TestSpec const& testSpec() const = 0;
   4527         virtual bool hasTestFilters() const = 0;
   4528         virtual std::vector<std::string> const& getTestsOrTags() const = 0;
   4529         virtual RunTests::InWhatOrder runOrder() const = 0;
   4530         virtual unsigned int rngSeed() const = 0;
   4531         virtual UseColour::YesOrNo useColour() const = 0;
   4532         virtual std::vector<std::string> const& getSectionsToRun() const = 0;
   4533         virtual Verbosity verbosity() const = 0;
   4534 
   4535         virtual bool benchmarkNoAnalysis() const = 0;
   4536         virtual int benchmarkSamples() const = 0;
   4537         virtual double benchmarkConfidenceInterval() const = 0;
   4538         virtual unsigned int benchmarkResamples() const = 0;
   4539         virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
   4540     };
   4541 
   4542     using IConfigPtr = std::shared_ptr<IConfig const>;
   4543 }
   4544 
   4545 // end catch_interfaces_config.h
   4546 // start catch_random_number_generator.h
   4547 
   4548 #include <cstdint>
   4549 
   4550 namespace Catch {
   4551 
   4552     // This is a simple implementation of C++11 Uniform Random Number
   4553     // Generator. It does not provide all operators, because Catch2
   4554     // does not use it, but it should behave as expected inside stdlib's
   4555     // distributions.
   4556     // The implementation is based on the PCG family (http://pcg-random.org)
   4557     class SimplePcg32 {
   4558         using state_type = std::uint64_t;
   4559     public:
   4560         using result_type = std::uint32_t;
   4561         static constexpr result_type (min)() {
   4562             return 0;
   4563         }
   4564         static constexpr result_type (max)() {
   4565             return static_cast<result_type>(-1);
   4566         }
   4567 
   4568         // Provide some default initial state for the default constructor
   4569         SimplePcg32():SimplePcg32(0xed743cc4U) {}
   4570 
   4571         explicit SimplePcg32(result_type seed_);
   4572 
   4573         void seed(result_type seed_);
   4574         void discard(uint64_t skip);
   4575 
   4576         result_type operator()();
   4577 
   4578     private:
   4579         friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
   4580         friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
   4581 
   4582         // In theory we also need operator<< and operator>>
   4583         // In practice we do not use them, so we will skip them for now
   4584 
   4585         std::uint64_t m_state;
   4586         // This part of the state determines which "stream" of the numbers
   4587         // is chosen -- we take it as a constant for Catch2, so we only
   4588         // need to deal with seeding the main state.
   4589         // Picked by reading 8 bytes from `/dev/random` :-)
   4590         static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
   4591     };
   4592 
   4593 } // end namespace Catch
   4594 
   4595 // end catch_random_number_generator.h
   4596 #include <random>
   4597 
   4598 namespace Catch {
   4599 namespace Generators {
   4600 
   4601 template <typename Float>
   4602 class RandomFloatingGenerator final : public IGenerator<Float> {
   4603     Catch::SimplePcg32& m_rng;
   4604     std::uniform_real_distribution<Float> m_dist;
   4605     Float m_current_number;
   4606 public:
   4607 
   4608     RandomFloatingGenerator(Float a, Float b):
   4609         m_rng(rng()),
   4610         m_dist(a, b) {
   4611         static_cast<void>(next());
   4612     }
   4613 
   4614     Float const& get() const override {
   4615         return m_current_number;
   4616     }
   4617     bool next() override {
   4618         m_current_number = m_dist(m_rng);
   4619         return true;
   4620     }
   4621 };
   4622 
   4623 template <typename Integer>
   4624 class RandomIntegerGenerator final : public IGenerator<Integer> {
   4625     Catch::SimplePcg32& m_rng;
   4626     std::uniform_int_distribution<Integer> m_dist;
   4627     Integer m_current_number;
   4628 public:
   4629 
   4630     RandomIntegerGenerator(Integer a, Integer b):
   4631         m_rng(rng()),
   4632         m_dist(a, b) {
   4633         static_cast<void>(next());
   4634     }
   4635 
   4636     Integer const& get() const override {
   4637         return m_current_number;
   4638     }
   4639     bool next() override {
   4640         m_current_number = m_dist(m_rng);
   4641         return true;
   4642     }
   4643 };
   4644 
   4645 // TODO: Ideally this would be also constrained against the various char types,
   4646 //       but I don't expect users to run into that in practice.
   4647 template <typename T>
   4648 typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
   4649 GeneratorWrapper<T>>::type
   4650 random(T a, T b) {
   4651     return GeneratorWrapper<T>(
   4652         pf::make_unique<RandomIntegerGenerator<T>>(a, b)
   4653     );
   4654 }
   4655 
   4656 template <typename T>
   4657 typename std::enable_if<std::is_floating_point<T>::value,
   4658 GeneratorWrapper<T>>::type
   4659 random(T a, T b) {
   4660     return GeneratorWrapper<T>(
   4661         pf::make_unique<RandomFloatingGenerator<T>>(a, b)
   4662     );
   4663 }
   4664 
   4665 template <typename T>
   4666 class RangeGenerator final : public IGenerator<T> {
   4667     T m_current;
   4668     T m_end;
   4669     T m_step;
   4670     bool m_positive;
   4671 
   4672 public:
   4673     RangeGenerator(T const& start, T const& end, T const& step):
   4674         m_current(start),
   4675         m_end(end),
   4676         m_step(step),
   4677         m_positive(m_step > T(0))
   4678     {
   4679         assert(m_current != m_end && "Range start and end cannot be equal");
   4680         assert(m_step != T(0) && "Step size cannot be zero");
   4681         assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
   4682     }
   4683 
   4684     RangeGenerator(T const& start, T const& end):
   4685         RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
   4686     {}
   4687 
   4688     T const& get() const override {
   4689         return m_current;
   4690     }
   4691 
   4692     bool next() override {
   4693         m_current += m_step;
   4694         return (m_positive) ? (m_current < m_end) : (m_current > m_end);
   4695     }
   4696 };
   4697 
   4698 template <typename T>
   4699 GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
   4700     static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
   4701     return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
   4702 }
   4703 
   4704 template <typename T>
   4705 GeneratorWrapper<T> range(T const& start, T const& end) {
   4706     static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
   4707     return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
   4708 }
   4709 
   4710 template <typename T>
   4711 class IteratorGenerator final : public IGenerator<T> {
   4712     static_assert(!std::is_same<T, bool>::value,
   4713         "IteratorGenerator currently does not support bools"
   4714         "because of std::vector<bool> specialization");
   4715 
   4716     std::vector<T> m_elems;
   4717     size_t m_current = 0;
   4718 public:
   4719     template <typename InputIterator, typename InputSentinel>
   4720     IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
   4721         if (m_elems.empty()) {
   4722             Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
   4723         }
   4724     }
   4725 
   4726     T const& get() const override {
   4727         return m_elems[m_current];
   4728     }
   4729 
   4730     bool next() override {
   4731         ++m_current;
   4732         return m_current != m_elems.size();
   4733     }
   4734 };
   4735 
   4736 template <typename InputIterator,
   4737           typename InputSentinel,
   4738           typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
   4739 GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
   4740     return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
   4741 }
   4742 
   4743 template <typename Container,
   4744           typename ResultType = typename Container::value_type>
   4745 GeneratorWrapper<ResultType> from_range(Container const& cnt) {
   4746     return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
   4747 }
   4748 
   4749 } // namespace Generators
   4750 } // namespace Catch
   4751 
   4752 // end catch_generators_specific.hpp
   4753 
   4754 // These files are included here so the single_include script doesn't put them
   4755 // in the conditionally compiled sections
   4756 // start catch_test_case_info.h
   4757 
   4758 #include <string>
   4759 #include <vector>
   4760 #include <memory>
   4761 
   4762 #ifdef __clang__
   4763 #pragma clang diagnostic push
   4764 #pragma clang diagnostic ignored "-Wpadded"
   4765 #endif
   4766 
   4767 namespace Catch {
   4768 
   4769     struct ITestInvoker;
   4770 
   4771     struct TestCaseInfo {
   4772         enum SpecialProperties{
   4773             None = 0,
   4774             IsHidden = 1 << 1,
   4775             ShouldFail = 1 << 2,
   4776             MayFail = 1 << 3,
   4777             Throws = 1 << 4,
   4778             NonPortable = 1 << 5,
   4779             Benchmark = 1 << 6
   4780         };
   4781 
   4782         TestCaseInfo(   std::string const& _name,
   4783                         std::string const& _className,
   4784                         std::string const& _description,
   4785                         std::vector<std::string> const& _tags,
   4786                         SourceLineInfo const& _lineInfo );
   4787 
   4788         friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
   4789 
   4790         bool isHidden() const;
   4791         bool throws() const;
   4792         bool okToFail() const;
   4793         bool expectedToFail() const;
   4794 
   4795         std::string tagsAsString() const;
   4796 
   4797         std::string name;
   4798         std::string className;
   4799         std::string description;
   4800         std::vector<std::string> tags;
   4801         std::vector<std::string> lcaseTags;
   4802         SourceLineInfo lineInfo;
   4803         SpecialProperties properties;
   4804     };
   4805 
   4806     class TestCase : public TestCaseInfo {
   4807     public:
   4808 
   4809         TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
   4810 
   4811         TestCase withName( std::string const& _newName ) const;
   4812 
   4813         void invoke() const;
   4814 
   4815         TestCaseInfo const& getTestCaseInfo() const;
   4816 
   4817         bool operator == ( TestCase const& other ) const;
   4818         bool operator < ( TestCase const& other ) const;
   4819 
   4820     private:
   4821         std::shared_ptr<ITestInvoker> test;
   4822     };
   4823 
   4824     TestCase makeTestCase(  ITestInvoker* testCase,
   4825                             std::string const& className,
   4826                             NameAndTags const& nameAndTags,
   4827                             SourceLineInfo const& lineInfo );
   4828 }
   4829 
   4830 #ifdef __clang__
   4831 #pragma clang diagnostic pop
   4832 #endif
   4833 
   4834 // end catch_test_case_info.h
   4835 // start catch_interfaces_runner.h
   4836 
   4837 namespace Catch {
   4838 
   4839     struct IRunner {
   4840         virtual ~IRunner();
   4841         virtual bool aborting() const = 0;
   4842     };
   4843 }
   4844 
   4845 // end catch_interfaces_runner.h
   4846 
   4847 #ifdef __OBJC__
   4848 // start catch_objc.hpp
   4849 
   4850 #import <objc/runtime.h>
   4851 
   4852 #include <string>
   4853 
   4854 // NB. Any general catch headers included here must be included
   4855 // in catch.hpp first to make sure they are included by the single
   4856 // header for non obj-usage
   4857 
   4858 ///////////////////////////////////////////////////////////////////////////////
   4859 // This protocol is really only here for (self) documenting purposes, since
   4860 // all its methods are optional.
   4861 @protocol OcFixture
   4862 
   4863 @optional
   4864 
   4865 -(void) setUp;
   4866 -(void) tearDown;
   4867 
   4868 @end
   4869 
   4870 namespace Catch {
   4871 
   4872     class OcMethod : public ITestInvoker {
   4873 
   4874     public:
   4875         OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
   4876 
   4877         virtual void invoke() const {
   4878             id obj = [[m_cls alloc] init];
   4879 
   4880             performOptionalSelector( obj, @selector(setUp)  );
   4881             performOptionalSelector( obj, m_sel );
   4882             performOptionalSelector( obj, @selector(tearDown)  );
   4883 
   4884             arcSafeRelease( obj );
   4885         }
   4886     private:
   4887         virtual ~OcMethod() {}
   4888 
   4889         Class m_cls;
   4890         SEL m_sel;
   4891     };
   4892 
   4893     namespace Detail{
   4894 
   4895         inline std::string getAnnotation(   Class cls,
   4896                                             std::string const& annotationName,
   4897                                             std::string const& testCaseName ) {
   4898             NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
   4899             SEL sel = NSSelectorFromString( selStr );
   4900             arcSafeRelease( selStr );
   4901             id value = performOptionalSelector( cls, sel );
   4902             if( value )
   4903                 return [(NSString*)value UTF8String];
   4904             return "";
   4905         }
   4906     }
   4907 
   4908     inline std::size_t registerTestMethods() {
   4909         std::size_t noTestMethods = 0;
   4910         int noClasses = objc_getClassList( nullptr, 0 );
   4911 
   4912         Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
   4913         objc_getClassList( classes, noClasses );
   4914 
   4915         for( int c = 0; c < noClasses; c++ ) {
   4916             Class cls = classes[c];
   4917             {
   4918                 u_int count;
   4919                 Method* methods = class_copyMethodList( cls, &count );
   4920                 for( u_int m = 0; m < count ; m++ ) {
   4921                     SEL selector = method_getName(methods[m]);
   4922                     std::string methodName = sel_getName(selector);
   4923                     if( startsWith( methodName, "Catch_TestCase_" ) ) {
   4924                         std::string testCaseName = methodName.substr( 15 );
   4925                         std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
   4926                         std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
   4927                         const char* className = class_getName( cls );
   4928 
   4929                         getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
   4930                         noTestMethods++;
   4931                     }
   4932                 }
   4933                 free(methods);
   4934             }
   4935         }
   4936         return noTestMethods;
   4937     }
   4938 
   4939 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
   4940 
   4941     namespace Matchers {
   4942         namespace Impl {
   4943         namespace NSStringMatchers {
   4944 
   4945             struct StringHolder : MatcherBase<NSString*>{
   4946                 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
   4947                 StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
   4948                 StringHolder() {
   4949                     arcSafeRelease( m_substr );
   4950                 }
   4951 
   4952                 bool match( NSString* str ) const override {
   4953                     return false;
   4954                 }
   4955 
   4956                 NSString* CATCH_ARC_STRONG m_substr;
   4957             };
   4958 
   4959             struct Equals : StringHolder {
   4960                 Equals( NSString* substr ) : StringHolder( substr ){}
   4961 
   4962                 bool match( NSString* str ) const override {
   4963                     return  (str != nil || m_substr == nil ) &&
   4964                             [str isEqualToString:m_substr];
   4965                 }
   4966 
   4967                 std::string describe() const override {
   4968                     return "equals string: " + Catch::Detail::stringify( m_substr );
   4969                 }
   4970             };
   4971 
   4972             struct Contains : StringHolder {
   4973                 Contains( NSString* substr ) : StringHolder( substr ){}
   4974 
   4975                 bool match( NSString* str ) const override {
   4976                     return  (str != nil || m_substr == nil ) &&
   4977                             [str rangeOfString:m_substr].location != NSNotFound;
   4978                 }
   4979 
   4980                 std::string describe() const override {
   4981                     return "contains string: " + Catch::Detail::stringify( m_substr );
   4982                 }
   4983             };
   4984 
   4985             struct StartsWith : StringHolder {
   4986                 StartsWith( NSString* substr ) : StringHolder( substr ){}
   4987 
   4988                 bool match( NSString* str ) const override {
   4989                     return  (str != nil || m_substr == nil ) &&
   4990                             [str rangeOfString:m_substr].location == 0;
   4991                 }
   4992 
   4993                 std::string describe() const override {
   4994                     return "starts with: " + Catch::Detail::stringify( m_substr );
   4995                 }
   4996             };
   4997             struct EndsWith : StringHolder {
   4998                 EndsWith( NSString* substr ) : StringHolder( substr ){}
   4999 
   5000                 bool match( NSString* str ) const override {
   5001                     return  (str != nil || m_substr == nil ) &&
   5002                             [str rangeOfString:m_substr].location == [str length] - [m_substr length];
   5003                 }
   5004 
   5005                 std::string describe() const override {
   5006                     return "ends with: " + Catch::Detail::stringify( m_substr );
   5007                 }
   5008             };
   5009 
   5010         } // namespace NSStringMatchers
   5011         } // namespace Impl
   5012 
   5013         inline Impl::NSStringMatchers::Equals
   5014             Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
   5015 
   5016         inline Impl::NSStringMatchers::Contains
   5017             Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
   5018 
   5019         inline Impl::NSStringMatchers::StartsWith
   5020             StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
   5021 
   5022         inline Impl::NSStringMatchers::EndsWith
   5023             EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
   5024 
   5025     } // namespace Matchers
   5026 
   5027     using namespace Matchers;
   5028 
   5029 #endif // CATCH_CONFIG_DISABLE_MATCHERS
   5030 
   5031 } // namespace Catch
   5032 
   5033 ///////////////////////////////////////////////////////////////////////////////
   5034 #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
   5035 #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
   5036 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
   5037 { \
   5038 return @ name; \
   5039 } \
   5040 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
   5041 { \
   5042 return @ desc; \
   5043 } \
   5044 -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
   5045 
   5046 #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
   5047 
   5048 // end catch_objc.hpp
   5049 #endif
   5050 
   5051 // Benchmarking needs the externally-facing parts of reporters to work
   5052 #if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   5053 // start catch_external_interfaces.h
   5054 
   5055 // start catch_reporter_bases.hpp
   5056 
   5057 // start catch_interfaces_reporter.h
   5058 
   5059 // start catch_config.hpp
   5060 
   5061 // start catch_test_spec_parser.h
   5062 
   5063 #ifdef __clang__
   5064 #pragma clang diagnostic push
   5065 #pragma clang diagnostic ignored "-Wpadded"
   5066 #endif
   5067 
   5068 // start catch_test_spec.h
   5069 
   5070 #ifdef __clang__
   5071 #pragma clang diagnostic push
   5072 #pragma clang diagnostic ignored "-Wpadded"
   5073 #endif
   5074 
   5075 // start catch_wildcard_pattern.h
   5076 
   5077 namespace Catch
   5078 {
   5079     class WildcardPattern {
   5080         enum WildcardPosition {
   5081             NoWildcard = 0,
   5082             WildcardAtStart = 1,
   5083             WildcardAtEnd = 2,
   5084             WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
   5085         };
   5086 
   5087     public:
   5088 
   5089         WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
   5090         virtual ~WildcardPattern() = default;
   5091         virtual bool matches( std::string const& str ) const;
   5092 
   5093     private:
   5094         std::string normaliseString( std::string const& str ) const;
   5095         CaseSensitive::Choice m_caseSensitivity;
   5096         WildcardPosition m_wildcard = NoWildcard;
   5097         std::string m_pattern;
   5098     };
   5099 }
   5100 
   5101 // end catch_wildcard_pattern.h
   5102 #include <string>
   5103 #include <vector>
   5104 #include <memory>
   5105 
   5106 namespace Catch {
   5107 
   5108     struct IConfig;
   5109 
   5110     class TestSpec {
   5111         class Pattern {
   5112         public:
   5113             explicit Pattern( std::string const& name );
   5114             virtual ~Pattern();
   5115             virtual bool matches( TestCaseInfo const& testCase ) const = 0;
   5116             std::string const& name() const;
   5117         private:
   5118             std::string const m_name;
   5119         };
   5120         using PatternPtr = std::shared_ptr<Pattern>;
   5121 
   5122         class NamePattern : public Pattern {
   5123         public:
   5124             explicit NamePattern( std::string const& name, std::string const& filterString );
   5125             bool matches( TestCaseInfo const& testCase ) const override;
   5126         private:
   5127             WildcardPattern m_wildcardPattern;
   5128         };
   5129 
   5130         class TagPattern : public Pattern {
   5131         public:
   5132             explicit TagPattern( std::string const& tag, std::string const& filterString );
   5133             bool matches( TestCaseInfo const& testCase ) const override;
   5134         private:
   5135             std::string m_tag;
   5136         };
   5137 
   5138         class ExcludedPattern : public Pattern {
   5139         public:
   5140             explicit ExcludedPattern( PatternPtr const& underlyingPattern );
   5141             bool matches( TestCaseInfo const& testCase ) const override;
   5142         private:
   5143             PatternPtr m_underlyingPattern;
   5144         };
   5145 
   5146         struct Filter {
   5147             std::vector<PatternPtr> m_patterns;
   5148 
   5149             bool matches( TestCaseInfo const& testCase ) const;
   5150             std::string name() const;
   5151         };
   5152 
   5153     public:
   5154         struct FilterMatch {
   5155             std::string name;
   5156             std::vector<TestCase const*> tests;
   5157         };
   5158         using Matches = std::vector<FilterMatch>;
   5159         using vectorStrings = std::vector<std::string>;
   5160 
   5161         bool hasFilters() const;
   5162         bool matches( TestCaseInfo const& testCase ) const;
   5163         Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;
   5164         const vectorStrings & getInvalidArgs() const;
   5165 
   5166     private:
   5167         std::vector<Filter> m_filters;
   5168         std::vector<std::string> m_invalidArgs;
   5169         friend class TestSpecParser;
   5170     };
   5171 }
   5172 
   5173 #ifdef __clang__
   5174 #pragma clang diagnostic pop
   5175 #endif
   5176 
   5177 // end catch_test_spec.h
   5178 // start catch_interfaces_tag_alias_registry.h
   5179 
   5180 #include <string>
   5181 
   5182 namespace Catch {
   5183 
   5184     struct TagAlias;
   5185 
   5186     struct ITagAliasRegistry {
   5187         virtual ~ITagAliasRegistry();
   5188         // Nullptr if not present
   5189         virtual TagAlias const* find( std::string const& alias ) const = 0;
   5190         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
   5191 
   5192         static ITagAliasRegistry const& get();
   5193     };
   5194 
   5195 } // end namespace Catch
   5196 
   5197 // end catch_interfaces_tag_alias_registry.h
   5198 namespace Catch {
   5199 
   5200     class TestSpecParser {
   5201         enum Mode{ None, Name, QuotedName, Tag, EscapedName };
   5202         Mode m_mode = None;
   5203         Mode lastMode = None;
   5204         bool m_exclusion = false;
   5205         std::size_t m_pos = 0;
   5206         std::size_t m_realPatternPos = 0;
   5207         std::string m_arg;
   5208         std::string m_substring;
   5209         std::string m_patternName;
   5210         std::vector<std::size_t> m_escapeChars;
   5211         TestSpec::Filter m_currentFilter;
   5212         TestSpec m_testSpec;
   5213         ITagAliasRegistry const* m_tagAliases = nullptr;
   5214 
   5215     public:
   5216         TestSpecParser( ITagAliasRegistry const& tagAliases );
   5217 
   5218         TestSpecParser& parse( std::string const& arg );
   5219         TestSpec testSpec();
   5220 
   5221     private:
   5222         bool visitChar( char c );
   5223         void startNewMode( Mode mode );
   5224         bool processNoneChar( char c );
   5225         void processNameChar( char c );
   5226         bool processOtherChar( char c );
   5227         void endMode();
   5228         void escape();
   5229         bool isControlChar( char c ) const;
   5230         void saveLastMode();
   5231         void revertBackToLastMode();
   5232         void addFilter();
   5233         bool separate();
   5234 
   5235         // Handles common preprocessing of the pattern for name/tag patterns
   5236         std::string preprocessPattern();
   5237         // Adds the current pattern as a test name
   5238         void addNamePattern();
   5239         // Adds the current pattern as a tag
   5240         void addTagPattern();
   5241 
   5242         inline void addCharToPattern(char c) {
   5243             m_substring += c;
   5244             m_patternName += c;
   5245             m_realPatternPos++;
   5246         }
   5247 
   5248     };
   5249     TestSpec parseTestSpec( std::string const& arg );
   5250 
   5251 } // namespace Catch
   5252 
   5253 #ifdef __clang__
   5254 #pragma clang diagnostic pop
   5255 #endif
   5256 
   5257 // end catch_test_spec_parser.h
   5258 // Libstdc++ doesn't like incomplete classes for unique_ptr
   5259 
   5260 #include <memory>
   5261 #include <vector>
   5262 #include <string>
   5263 
   5264 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
   5265 #define CATCH_CONFIG_CONSOLE_WIDTH 80
   5266 #endif
   5267 
   5268 namespace Catch {
   5269 
   5270     struct IStream;
   5271 
   5272     struct ConfigData {
   5273         bool listTests = false;
   5274         bool listTags = false;
   5275         bool listReporters = false;
   5276         bool listTestNamesOnly = false;
   5277 
   5278         bool showSuccessfulTests = false;
   5279         bool shouldDebugBreak = false;
   5280         bool noThrow = false;
   5281         bool showHelp = false;
   5282         bool showInvisibles = false;
   5283         bool filenamesAsTags = false;
   5284         bool libIdentify = false;
   5285 
   5286         int abortAfter = -1;
   5287         unsigned int rngSeed = 0;
   5288 
   5289         bool benchmarkNoAnalysis = false;
   5290         unsigned int benchmarkSamples = 100;
   5291         double benchmarkConfidenceInterval = 0.95;
   5292         unsigned int benchmarkResamples = 100000;
   5293         std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
   5294 
   5295         Verbosity verbosity = Verbosity::Normal;
   5296         WarnAbout::What warnings = WarnAbout::Nothing;
   5297         ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
   5298         double minDuration = -1;
   5299         RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
   5300         UseColour::YesOrNo useColour = UseColour::Auto;
   5301         WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
   5302 
   5303         std::string outputFilename;
   5304         std::string name;
   5305         std::string processName;
   5306 #ifndef CATCH_CONFIG_DEFAULT_REPORTER
   5307 #define CATCH_CONFIG_DEFAULT_REPORTER "console"
   5308 #endif
   5309         std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
   5310 #undef CATCH_CONFIG_DEFAULT_REPORTER
   5311 
   5312         std::vector<std::string> testsOrTags;
   5313         std::vector<std::string> sectionsToRun;
   5314     };
   5315 
   5316     class Config : public IConfig {
   5317     public:
   5318 
   5319         Config() = default;
   5320         Config( ConfigData const& data );
   5321         virtual ~Config() = default;
   5322 
   5323         std::string const& getFilename() const;
   5324 
   5325         bool listTests() const;
   5326         bool listTestNamesOnly() const;
   5327         bool listTags() const;
   5328         bool listReporters() const;
   5329 
   5330         std::string getProcessName() const;
   5331         std::string const& getReporterName() const;
   5332 
   5333         std::vector<std::string> const& getTestsOrTags() const override;
   5334         std::vector<std::string> const& getSectionsToRun() const override;
   5335 
   5336         TestSpec const& testSpec() const override;
   5337         bool hasTestFilters() const override;
   5338 
   5339         bool showHelp() const;
   5340 
   5341         // IConfig interface
   5342         bool allowThrows() const override;
   5343         std::ostream& stream() const override;
   5344         std::string name() const override;
   5345         bool includeSuccessfulResults() const override;
   5346         bool warnAboutMissingAssertions() const override;
   5347         bool warnAboutNoTests() const override;
   5348         ShowDurations::OrNot showDurations() const override;
   5349         double minDuration() const override;
   5350         RunTests::InWhatOrder runOrder() const override;
   5351         unsigned int rngSeed() const override;
   5352         UseColour::YesOrNo useColour() const override;
   5353         bool shouldDebugBreak() const override;
   5354         int abortAfter() const override;
   5355         bool showInvisibles() const override;
   5356         Verbosity verbosity() const override;
   5357         bool benchmarkNoAnalysis() const override;
   5358         int benchmarkSamples() const override;
   5359         double benchmarkConfidenceInterval() const override;
   5360         unsigned int benchmarkResamples() const override;
   5361         std::chrono::milliseconds benchmarkWarmupTime() const override;
   5362 
   5363     private:
   5364 
   5365         IStream const* openStream();
   5366         ConfigData m_data;
   5367 
   5368         std::unique_ptr<IStream const> m_stream;
   5369         TestSpec m_testSpec;
   5370         bool m_hasTestFilters = false;
   5371     };
   5372 
   5373 } // end namespace Catch
   5374 
   5375 // end catch_config.hpp
   5376 // start catch_assertionresult.h
   5377 
   5378 #include <string>
   5379 
   5380 namespace Catch {
   5381 
   5382     struct AssertionResultData
   5383     {
   5384         AssertionResultData() = delete;
   5385 
   5386         AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
   5387 
   5388         std::string message;
   5389         mutable std::string reconstructedExpression;
   5390         LazyExpression lazyExpression;
   5391         ResultWas::OfType resultType;
   5392 
   5393         std::string reconstructExpression() const;
   5394     };
   5395 
   5396     class AssertionResult {
   5397     public:
   5398         AssertionResult() = delete;
   5399         AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
   5400 
   5401         bool isOk() const;
   5402         bool succeeded() const;
   5403         ResultWas::OfType getResultType() const;
   5404         bool hasExpression() const;
   5405         bool hasMessage() const;
   5406         std::string getExpression() const;
   5407         std::string getExpressionInMacro() const;
   5408         bool hasExpandedExpression() const;
   5409         std::string getExpandedExpression() const;
   5410         std::string getMessage() const;
   5411         SourceLineInfo getSourceInfo() const;
   5412         StringRef getTestMacroName() const;
   5413 
   5414     //protected:
   5415         AssertionInfo m_info;
   5416         AssertionResultData m_resultData;
   5417     };
   5418 
   5419 } // end namespace Catch
   5420 
   5421 // end catch_assertionresult.h
   5422 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   5423 // start catch_estimate.hpp
   5424 
   5425  // Statistics estimates
   5426 
   5427 
   5428 namespace Catch {
   5429     namespace Benchmark {
   5430         template <typename Duration>
   5431         struct Estimate {
   5432             Duration point;
   5433             Duration lower_bound;
   5434             Duration upper_bound;
   5435             double confidence_interval;
   5436 
   5437             template <typename Duration2>
   5438             operator Estimate<Duration2>() const {
   5439                 return { point, lower_bound, upper_bound, confidence_interval };
   5440             }
   5441         };
   5442     } // namespace Benchmark
   5443 } // namespace Catch
   5444 
   5445 // end catch_estimate.hpp
   5446 // start catch_outlier_classification.hpp
   5447 
   5448 // Outlier information
   5449 
   5450 namespace Catch {
   5451     namespace Benchmark {
   5452         struct OutlierClassification {
   5453             int samples_seen = 0;
   5454             int low_severe = 0;     // more than 3 times IQR below Q1
   5455             int low_mild = 0;       // 1.5 to 3 times IQR below Q1
   5456             int high_mild = 0;      // 1.5 to 3 times IQR above Q3
   5457             int high_severe = 0;    // more than 3 times IQR above Q3
   5458 
   5459             int total() const {
   5460                 return low_severe + low_mild + high_mild + high_severe;
   5461             }
   5462         };
   5463     } // namespace Benchmark
   5464 } // namespace Catch
   5465 
   5466 // end catch_outlier_classification.hpp
   5467 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   5468 
   5469 #include <string>
   5470 #include <iosfwd>
   5471 #include <map>
   5472 #include <set>
   5473 #include <memory>
   5474 #include <algorithm>
   5475 
   5476 namespace Catch {
   5477 
   5478     struct ReporterConfig {
   5479         explicit ReporterConfig( IConfigPtr const& _fullConfig );
   5480 
   5481         ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
   5482 
   5483         std::ostream& stream() const;
   5484         IConfigPtr fullConfig() const;
   5485 
   5486     private:
   5487         std::ostream* m_stream;
   5488         IConfigPtr m_fullConfig;
   5489     };
   5490 
   5491     struct ReporterPreferences {
   5492         bool shouldRedirectStdOut = false;
   5493         bool shouldReportAllAssertions = false;
   5494     };
   5495 
   5496     template<typename T>
   5497     struct LazyStat : Option<T> {
   5498         LazyStat& operator=( T const& _value ) {
   5499             Option<T>::operator=( _value );
   5500             used = false;
   5501             return *this;
   5502         }
   5503         void reset() {
   5504             Option<T>::reset();
   5505             used = false;
   5506         }
   5507         bool used = false;
   5508     };
   5509 
   5510     struct TestRunInfo {
   5511         TestRunInfo( std::string const& _name );
   5512         std::string name;
   5513     };
   5514     struct GroupInfo {
   5515         GroupInfo(  std::string const& _name,
   5516                     std::size_t _groupIndex,
   5517                     std::size_t _groupsCount );
   5518 
   5519         std::string name;
   5520         std::size_t groupIndex;
   5521         std::size_t groupsCounts;
   5522     };
   5523 
   5524     struct AssertionStats {
   5525         AssertionStats( AssertionResult const& _assertionResult,
   5526                         std::vector<MessageInfo> const& _infoMessages,
   5527                         Totals const& _totals );
   5528 
   5529         AssertionStats( AssertionStats const& )              = default;
   5530         AssertionStats( AssertionStats && )                  = default;
   5531         AssertionStats& operator = ( AssertionStats const& ) = delete;
   5532         AssertionStats& operator = ( AssertionStats && )     = delete;
   5533         virtual ~AssertionStats();
   5534 
   5535         AssertionResult assertionResult;
   5536         std::vector<MessageInfo> infoMessages;
   5537         Totals totals;
   5538     };
   5539 
   5540     struct SectionStats {
   5541         SectionStats(   SectionInfo const& _sectionInfo,
   5542                         Counts const& _assertions,
   5543                         double _durationInSeconds,
   5544                         bool _missingAssertions );
   5545         SectionStats( SectionStats const& )              = default;
   5546         SectionStats( SectionStats && )                  = default;
   5547         SectionStats& operator = ( SectionStats const& ) = default;
   5548         SectionStats& operator = ( SectionStats && )     = default;
   5549         virtual ~SectionStats();
   5550 
   5551         SectionInfo sectionInfo;
   5552         Counts assertions;
   5553         double durationInSeconds;
   5554         bool missingAssertions;
   5555     };
   5556 
   5557     struct TestCaseStats {
   5558         TestCaseStats(  TestCaseInfo const& _testInfo,
   5559                         Totals const& _totals,
   5560                         std::string const& _stdOut,
   5561                         std::string const& _stdErr,
   5562                         bool _aborting );
   5563 
   5564         TestCaseStats( TestCaseStats const& )              = default;
   5565         TestCaseStats( TestCaseStats && )                  = default;
   5566         TestCaseStats& operator = ( TestCaseStats const& ) = default;
   5567         TestCaseStats& operator = ( TestCaseStats && )     = default;
   5568         virtual ~TestCaseStats();
   5569 
   5570         TestCaseInfo testInfo;
   5571         Totals totals;
   5572         std::string stdOut;
   5573         std::string stdErr;
   5574         bool aborting;
   5575     };
   5576 
   5577     struct TestGroupStats {
   5578         TestGroupStats( GroupInfo const& _groupInfo,
   5579                         Totals const& _totals,
   5580                         bool _aborting );
   5581         TestGroupStats( GroupInfo const& _groupInfo );
   5582 
   5583         TestGroupStats( TestGroupStats const& )              = default;
   5584         TestGroupStats( TestGroupStats && )                  = default;
   5585         TestGroupStats& operator = ( TestGroupStats const& ) = default;
   5586         TestGroupStats& operator = ( TestGroupStats && )     = default;
   5587         virtual ~TestGroupStats();
   5588 
   5589         GroupInfo groupInfo;
   5590         Totals totals;
   5591         bool aborting;
   5592     };
   5593 
   5594     struct TestRunStats {
   5595         TestRunStats(   TestRunInfo const& _runInfo,
   5596                         Totals const& _totals,
   5597                         bool _aborting );
   5598 
   5599         TestRunStats( TestRunStats const& )              = default;
   5600         TestRunStats( TestRunStats && )                  = default;
   5601         TestRunStats& operator = ( TestRunStats const& ) = default;
   5602         TestRunStats& operator = ( TestRunStats && )     = default;
   5603         virtual ~TestRunStats();
   5604 
   5605         TestRunInfo runInfo;
   5606         Totals totals;
   5607         bool aborting;
   5608     };
   5609 
   5610 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   5611     struct BenchmarkInfo {
   5612         std::string name;
   5613         double estimatedDuration;
   5614         int iterations;
   5615         int samples;
   5616         unsigned int resamples;
   5617         double clockResolution;
   5618         double clockCost;
   5619     };
   5620 
   5621     template <class Duration>
   5622     struct BenchmarkStats {
   5623         BenchmarkInfo info;
   5624 
   5625         std::vector<Duration> samples;
   5626         Benchmark::Estimate<Duration> mean;
   5627         Benchmark::Estimate<Duration> standardDeviation;
   5628         Benchmark::OutlierClassification outliers;
   5629         double outlierVariance;
   5630 
   5631         template <typename Duration2>
   5632         operator BenchmarkStats<Duration2>() const {
   5633             std::vector<Duration2> samples2;
   5634             samples2.reserve(samples.size());
   5635             std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
   5636             return {
   5637                 info,
   5638                 std::move(samples2),
   5639                 mean,
   5640                 standardDeviation,
   5641                 outliers,
   5642                 outlierVariance,
   5643             };
   5644         }
   5645     };
   5646 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   5647 
   5648     struct IStreamingReporter {
   5649         virtual ~IStreamingReporter() = default;
   5650 
   5651         // Implementing class must also provide the following static methods:
   5652         // static std::string getDescription();
   5653         // static std::set<Verbosity> getSupportedVerbosities()
   5654 
   5655         virtual ReporterPreferences getPreferences() const = 0;
   5656 
   5657         virtual void noMatchingTestCases( std::string const& spec ) = 0;
   5658 
   5659         virtual void reportInvalidArguments(std::string const&) {}
   5660 
   5661         virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
   5662         virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
   5663 
   5664         virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
   5665         virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
   5666 
   5667 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   5668         virtual void benchmarkPreparing( std::string const& ) {}
   5669         virtual void benchmarkStarting( BenchmarkInfo const& ) {}
   5670         virtual void benchmarkEnded( BenchmarkStats<> const& ) {}
   5671         virtual void benchmarkFailed( std::string const& ) {}
   5672 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   5673 
   5674         virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
   5675 
   5676         // The return value indicates if the messages buffer should be cleared:
   5677         virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
   5678 
   5679         virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
   5680         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
   5681         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
   5682         virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
   5683 
   5684         virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
   5685 
   5686         // Default empty implementation provided
   5687         virtual void fatalErrorEncountered( StringRef name );
   5688 
   5689         virtual bool isMulti() const;
   5690     };
   5691     using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
   5692 
   5693     struct IReporterFactory {
   5694         virtual ~IReporterFactory();
   5695         virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
   5696         virtual std::string getDescription() const = 0;
   5697     };
   5698     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
   5699 
   5700     struct IReporterRegistry {
   5701         using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
   5702         using Listeners = std::vector<IReporterFactoryPtr>;
   5703 
   5704         virtual ~IReporterRegistry();
   5705         virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
   5706         virtual FactoryMap const& getFactories() const = 0;
   5707         virtual Listeners const& getListeners() const = 0;
   5708     };
   5709 
   5710 } // end namespace Catch
   5711 
   5712 // end catch_interfaces_reporter.h
   5713 #include <algorithm>
   5714 #include <cstring>
   5715 #include <cfloat>
   5716 #include <cstdio>
   5717 #include <cassert>
   5718 #include <memory>
   5719 #include <ostream>
   5720 
   5721 namespace Catch {
   5722     void prepareExpandedExpression(AssertionResult& result);
   5723 
   5724     // Returns double formatted as %.3f (format expected on output)
   5725     std::string getFormattedDuration( double duration );
   5726 
   5727     //! Should the reporter show
   5728     bool shouldShowDuration( IConfig const& config, double duration );
   5729 
   5730     std::string serializeFilters( std::vector<std::string> const& container );
   5731 
   5732     template<typename DerivedT>
   5733     struct StreamingReporterBase : IStreamingReporter {
   5734 
   5735         StreamingReporterBase( ReporterConfig const& _config )
   5736         :   m_config( _config.fullConfig() ),
   5737             stream( _config.stream() )
   5738         {
   5739             m_reporterPrefs.shouldRedirectStdOut = false;
   5740             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
   5741                 CATCH_ERROR( "Verbosity level not supported by this reporter" );
   5742         }
   5743 
   5744         ReporterPreferences getPreferences() const override {
   5745             return m_reporterPrefs;
   5746         }
   5747 
   5748         static std::set<Verbosity> getSupportedVerbosities() {
   5749             return { Verbosity::Normal };
   5750         }
   5751 
   5752         ~StreamingReporterBase() override = default;
   5753 
   5754         void noMatchingTestCases(std::string const&) override {}
   5755 
   5756         void reportInvalidArguments(std::string const&) override {}
   5757 
   5758         void testRunStarting(TestRunInfo const& _testRunInfo) override {
   5759             currentTestRunInfo = _testRunInfo;
   5760         }
   5761 
   5762         void testGroupStarting(GroupInfo const& _groupInfo) override {
   5763             currentGroupInfo = _groupInfo;
   5764         }
   5765 
   5766         void testCaseStarting(TestCaseInfo const& _testInfo) override  {
   5767             currentTestCaseInfo = _testInfo;
   5768         }
   5769         void sectionStarting(SectionInfo const& _sectionInfo) override {
   5770             m_sectionStack.push_back(_sectionInfo);
   5771         }
   5772 
   5773         void sectionEnded(SectionStats const& /* _sectionStats */) override {
   5774             m_sectionStack.pop_back();
   5775         }
   5776         void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
   5777             currentTestCaseInfo.reset();
   5778         }
   5779         void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
   5780             currentGroupInfo.reset();
   5781         }
   5782         void testRunEnded(TestRunStats const& /* _testRunStats */) override {
   5783             currentTestCaseInfo.reset();
   5784             currentGroupInfo.reset();
   5785             currentTestRunInfo.reset();
   5786         }
   5787 
   5788         void skipTest(TestCaseInfo const&) override {
   5789             // Don't do anything with this by default.
   5790             // It can optionally be overridden in the derived class.
   5791         }
   5792 
   5793         IConfigPtr m_config;
   5794         std::ostream& stream;
   5795 
   5796         LazyStat<TestRunInfo> currentTestRunInfo;
   5797         LazyStat<GroupInfo> currentGroupInfo;
   5798         LazyStat<TestCaseInfo> currentTestCaseInfo;
   5799 
   5800         std::vector<SectionInfo> m_sectionStack;
   5801         ReporterPreferences m_reporterPrefs;
   5802     };
   5803 
   5804     template<typename DerivedT>
   5805     struct CumulativeReporterBase : IStreamingReporter {
   5806         template<typename T, typename ChildNodeT>
   5807         struct Node {
   5808             explicit Node( T const& _value ) : value( _value ) {}
   5809             virtual ~Node() {}
   5810 
   5811             using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
   5812             T value;
   5813             ChildNodes children;
   5814         };
   5815         struct SectionNode {
   5816             explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
   5817             virtual ~SectionNode() = default;
   5818 
   5819             bool operator == (SectionNode const& other) const {
   5820                 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
   5821             }
   5822             bool operator == (std::shared_ptr<SectionNode> const& other) const {
   5823                 return operator==(*other);
   5824             }
   5825 
   5826             SectionStats stats;
   5827             using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
   5828             using Assertions = std::vector<AssertionStats>;
   5829             ChildSections childSections;
   5830             Assertions assertions;
   5831             std::string stdOut;
   5832             std::string stdErr;
   5833         };
   5834 
   5835         struct BySectionInfo {
   5836             BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
   5837             BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
   5838             bool operator() (std::shared_ptr<SectionNode> const& node) const {
   5839                 return ((node->stats.sectionInfo.name == m_other.name) &&
   5840                         (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
   5841             }
   5842             void operator=(BySectionInfo const&) = delete;
   5843 
   5844         private:
   5845             SectionInfo const& m_other;
   5846         };
   5847 
   5848         using TestCaseNode = Node<TestCaseStats, SectionNode>;
   5849         using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
   5850         using TestRunNode = Node<TestRunStats, TestGroupNode>;
   5851 
   5852         CumulativeReporterBase( ReporterConfig const& _config )
   5853         :   m_config( _config.fullConfig() ),
   5854             stream( _config.stream() )
   5855         {
   5856             m_reporterPrefs.shouldRedirectStdOut = false;
   5857             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
   5858                 CATCH_ERROR( "Verbosity level not supported by this reporter" );
   5859         }
   5860         ~CumulativeReporterBase() override = default;
   5861 
   5862         ReporterPreferences getPreferences() const override {
   5863             return m_reporterPrefs;
   5864         }
   5865 
   5866         static std::set<Verbosity> getSupportedVerbosities() {
   5867             return { Verbosity::Normal };
   5868         }
   5869 
   5870         void testRunStarting( TestRunInfo const& ) override {}
   5871         void testGroupStarting( GroupInfo const& ) override {}
   5872 
   5873         void testCaseStarting( TestCaseInfo const& ) override {}
   5874 
   5875         void sectionStarting( SectionInfo const& sectionInfo ) override {
   5876             SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
   5877             std::shared_ptr<SectionNode> node;
   5878             if( m_sectionStack.empty() ) {
   5879                 if( !m_rootSection )
   5880                     m_rootSection = std::make_shared<SectionNode>( incompleteStats );
   5881                 node = m_rootSection;
   5882             }
   5883             else {
   5884                 SectionNode& parentNode = *m_sectionStack.back();
   5885                 auto it =
   5886                     std::find_if(   parentNode.childSections.begin(),
   5887                                     parentNode.childSections.end(),
   5888                                     BySectionInfo( sectionInfo ) );
   5889                 if( it == parentNode.childSections.end() ) {
   5890                     node = std::make_shared<SectionNode>( incompleteStats );
   5891                     parentNode.childSections.push_back( node );
   5892                 }
   5893                 else
   5894                     node = *it;
   5895             }
   5896             m_sectionStack.push_back( node );
   5897             m_deepestSection = std::move(node);
   5898         }
   5899 
   5900         void assertionStarting(AssertionInfo const&) override {}
   5901 
   5902         bool assertionEnded(AssertionStats const& assertionStats) override {
   5903             assert(!m_sectionStack.empty());
   5904             // AssertionResult holds a pointer to a temporary DecomposedExpression,
   5905             // which getExpandedExpression() calls to build the expression string.
   5906             // Our section stack copy of the assertionResult will likely outlive the
   5907             // temporary, so it must be expanded or discarded now to avoid calling
   5908             // a destroyed object later.
   5909             prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
   5910             SectionNode& sectionNode = *m_sectionStack.back();
   5911             sectionNode.assertions.push_back(assertionStats);
   5912             return true;
   5913         }
   5914         void sectionEnded(SectionStats const& sectionStats) override {
   5915             assert(!m_sectionStack.empty());
   5916             SectionNode& node = *m_sectionStack.back();
   5917             node.stats = sectionStats;
   5918             m_sectionStack.pop_back();
   5919         }
   5920         void testCaseEnded(TestCaseStats const& testCaseStats) override {
   5921             auto node = std::make_shared<TestCaseNode>(testCaseStats);
   5922             assert(m_sectionStack.size() == 0);
   5923             node->children.push_back(m_rootSection);
   5924             m_testCases.push_back(node);
   5925             m_rootSection.reset();
   5926 
   5927             assert(m_deepestSection);
   5928             m_deepestSection->stdOut = testCaseStats.stdOut;
   5929             m_deepestSection->stdErr = testCaseStats.stdErr;
   5930         }
   5931         void testGroupEnded(TestGroupStats const& testGroupStats) override {
   5932             auto node = std::make_shared<TestGroupNode>(testGroupStats);
   5933             node->children.swap(m_testCases);
   5934             m_testGroups.push_back(node);
   5935         }
   5936         void testRunEnded(TestRunStats const& testRunStats) override {
   5937             auto node = std::make_shared<TestRunNode>(testRunStats);
   5938             node->children.swap(m_testGroups);
   5939             m_testRuns.push_back(node);
   5940             testRunEndedCumulative();
   5941         }
   5942         virtual void testRunEndedCumulative() = 0;
   5943 
   5944         void skipTest(TestCaseInfo const&) override {}
   5945 
   5946         IConfigPtr m_config;
   5947         std::ostream& stream;
   5948         std::vector<AssertionStats> m_assertions;
   5949         std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
   5950         std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
   5951         std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
   5952 
   5953         std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
   5954 
   5955         std::shared_ptr<SectionNode> m_rootSection;
   5956         std::shared_ptr<SectionNode> m_deepestSection;
   5957         std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
   5958         ReporterPreferences m_reporterPrefs;
   5959     };
   5960 
   5961     template<char C>
   5962     char const* getLineOfChars() {
   5963         static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
   5964         if( !*line ) {
   5965             std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
   5966             line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
   5967         }
   5968         return line;
   5969     }
   5970 
   5971     struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
   5972         TestEventListenerBase( ReporterConfig const& _config );
   5973 
   5974         static std::set<Verbosity> getSupportedVerbosities();
   5975 
   5976         void assertionStarting(AssertionInfo const&) override;
   5977         bool assertionEnded(AssertionStats const&) override;
   5978     };
   5979 
   5980 } // end namespace Catch
   5981 
   5982 // end catch_reporter_bases.hpp
   5983 // start catch_console_colour.h
   5984 
   5985 namespace Catch {
   5986 
   5987     struct Colour {
   5988         enum Code {
   5989             None = 0,
   5990 
   5991             White,
   5992             Red,
   5993             Green,
   5994             Blue,
   5995             Cyan,
   5996             Yellow,
   5997             Grey,
   5998 
   5999             Bright = 0x10,
   6000 
   6001             BrightRed = Bright | Red,
   6002             BrightGreen = Bright | Green,
   6003             LightGrey = Bright | Grey,
   6004             BrightWhite = Bright | White,
   6005             BrightYellow = Bright | Yellow,
   6006 
   6007             // By intention
   6008             FileName = LightGrey,
   6009             Warning = BrightYellow,
   6010             ResultError = BrightRed,
   6011             ResultSuccess = BrightGreen,
   6012             ResultExpectedFailure = Warning,
   6013 
   6014             Error = BrightRed,
   6015             Success = Green,
   6016 
   6017             OriginalExpression = Cyan,
   6018             ReconstructedExpression = BrightYellow,
   6019 
   6020             SecondaryText = LightGrey,
   6021             Headers = White
   6022         };
   6023 
   6024         // Use constructed object for RAII guard
   6025         Colour( Code _colourCode );
   6026         Colour( Colour&& other ) noexcept;
   6027         Colour& operator=( Colour&& other ) noexcept;
   6028         ~Colour();
   6029 
   6030         // Use static method for one-shot changes
   6031         static void use( Code _colourCode );
   6032 
   6033     private:
   6034         bool m_moved = false;
   6035     };
   6036 
   6037     std::ostream& operator << ( std::ostream& os, Colour const& );
   6038 
   6039 } // end namespace Catch
   6040 
   6041 // end catch_console_colour.h
   6042 // start catch_reporter_registrars.hpp
   6043 
   6044 
   6045 namespace Catch {
   6046 
   6047     template<typename T>
   6048     class ReporterRegistrar {
   6049 
   6050         class ReporterFactory : public IReporterFactory {
   6051 
   6052             IStreamingReporterPtr create( ReporterConfig const& config ) const override {
   6053                 return std::unique_ptr<T>( new T( config ) );
   6054             }
   6055 
   6056             std::string getDescription() const override {
   6057                 return T::getDescription();
   6058             }
   6059         };
   6060 
   6061     public:
   6062 
   6063         explicit ReporterRegistrar( std::string const& name ) {
   6064             getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
   6065         }
   6066     };
   6067 
   6068     template<typename T>
   6069     class ListenerRegistrar {
   6070 
   6071         class ListenerFactory : public IReporterFactory {
   6072 
   6073             IStreamingReporterPtr create( ReporterConfig const& config ) const override {
   6074                 return std::unique_ptr<T>( new T( config ) );
   6075             }
   6076             std::string getDescription() const override {
   6077                 return std::string();
   6078             }
   6079         };
   6080 
   6081     public:
   6082 
   6083         ListenerRegistrar() {
   6084             getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
   6085         }
   6086     };
   6087 }
   6088 
   6089 #if !defined(CATCH_CONFIG_DISABLE)
   6090 
   6091 #define CATCH_REGISTER_REPORTER( name, reporterType ) \
   6092     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION         \
   6093     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \
   6094     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
   6095     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   6096 
   6097 #define CATCH_REGISTER_LISTENER( listenerType ) \
   6098     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION   \
   6099     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS    \
   6100     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
   6101     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   6102 #else // CATCH_CONFIG_DISABLE
   6103 
   6104 #define CATCH_REGISTER_REPORTER(name, reporterType)
   6105 #define CATCH_REGISTER_LISTENER(listenerType)
   6106 
   6107 #endif // CATCH_CONFIG_DISABLE
   6108 
   6109 // end catch_reporter_registrars.hpp
   6110 // Allow users to base their work off existing reporters
   6111 // start catch_reporter_compact.h
   6112 
   6113 namespace Catch {
   6114 
   6115     struct CompactReporter : StreamingReporterBase<CompactReporter> {
   6116 
   6117         using StreamingReporterBase::StreamingReporterBase;
   6118 
   6119         ~CompactReporter() override;
   6120 
   6121         static std::string getDescription();
   6122 
   6123         void noMatchingTestCases(std::string const& spec) override;
   6124 
   6125         void assertionStarting(AssertionInfo const&) override;
   6126 
   6127         bool assertionEnded(AssertionStats const& _assertionStats) override;
   6128 
   6129         void sectionEnded(SectionStats const& _sectionStats) override;
   6130 
   6131         void testRunEnded(TestRunStats const& _testRunStats) override;
   6132 
   6133     };
   6134 
   6135 } // end namespace Catch
   6136 
   6137 // end catch_reporter_compact.h
   6138 // start catch_reporter_console.h
   6139 
   6140 #if defined(_MSC_VER)
   6141 #pragma warning(push)
   6142 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
   6143                               // Note that 4062 (not all labels are handled
   6144                               // and default is missing) is enabled
   6145 #endif
   6146 
   6147 namespace Catch {
   6148     // Fwd decls
   6149     struct SummaryColumn;
   6150     class TablePrinter;
   6151 
   6152     struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
   6153         std::unique_ptr<TablePrinter> m_tablePrinter;
   6154 
   6155         ConsoleReporter(ReporterConfig const& config);
   6156         ~ConsoleReporter() override;
   6157         static std::string getDescription();
   6158 
   6159         void noMatchingTestCases(std::string const& spec) override;
   6160 
   6161         void reportInvalidArguments(std::string const&arg) override;
   6162 
   6163         void assertionStarting(AssertionInfo const&) override;
   6164 
   6165         bool assertionEnded(AssertionStats const& _assertionStats) override;
   6166 
   6167         void sectionStarting(SectionInfo const& _sectionInfo) override;
   6168         void sectionEnded(SectionStats const& _sectionStats) override;
   6169 
   6170 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   6171         void benchmarkPreparing(std::string const& name) override;
   6172         void benchmarkStarting(BenchmarkInfo const& info) override;
   6173         void benchmarkEnded(BenchmarkStats<> const& stats) override;
   6174         void benchmarkFailed(std::string const& error) override;
   6175 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   6176 
   6177         void testCaseEnded(TestCaseStats const& _testCaseStats) override;
   6178         void testGroupEnded(TestGroupStats const& _testGroupStats) override;
   6179         void testRunEnded(TestRunStats const& _testRunStats) override;
   6180         void testRunStarting(TestRunInfo const& _testRunInfo) override;
   6181     private:
   6182 
   6183         void lazyPrint();
   6184 
   6185         void lazyPrintWithoutClosingBenchmarkTable();
   6186         void lazyPrintRunInfo();
   6187         void lazyPrintGroupInfo();
   6188         void printTestCaseAndSectionHeader();
   6189 
   6190         void printClosedHeader(std::string const& _name);
   6191         void printOpenHeader(std::string const& _name);
   6192 
   6193         // if string has a : in first line will set indent to follow it on
   6194         // subsequent lines
   6195         void printHeaderString(std::string const& _string, std::size_t indent = 0);
   6196 
   6197         void printTotals(Totals const& totals);
   6198         void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
   6199 
   6200         void printTotalsDivider(Totals const& totals);
   6201         void printSummaryDivider();
   6202         void printTestFilters();
   6203 
   6204     private:
   6205         bool m_headerPrinted = false;
   6206     };
   6207 
   6208 } // end namespace Catch
   6209 
   6210 #if defined(_MSC_VER)
   6211 #pragma warning(pop)
   6212 #endif
   6213 
   6214 // end catch_reporter_console.h
   6215 // start catch_reporter_junit.h
   6216 
   6217 // start catch_xmlwriter.h
   6218 
   6219 #include <vector>
   6220 
   6221 namespace Catch {
   6222     enum class XmlFormatting {
   6223         None = 0x00,
   6224         Indent = 0x01,
   6225         Newline = 0x02,
   6226     };
   6227 
   6228     XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs);
   6229     XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs);
   6230 
   6231     class XmlEncode {
   6232     public:
   6233         enum ForWhat { ForTextNodes, ForAttributes };
   6234 
   6235         XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
   6236 
   6237         void encodeTo( std::ostream& os ) const;
   6238 
   6239         friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
   6240 
   6241     private:
   6242         std::string m_str;
   6243         ForWhat m_forWhat;
   6244     };
   6245 
   6246     class XmlWriter {
   6247     public:
   6248 
   6249         class ScopedElement {
   6250         public:
   6251             ScopedElement( XmlWriter* writer, XmlFormatting fmt );
   6252 
   6253             ScopedElement( ScopedElement&& other ) noexcept;
   6254             ScopedElement& operator=( ScopedElement&& other ) noexcept;
   6255 
   6256             ~ScopedElement();
   6257 
   6258             ScopedElement& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent );
   6259 
   6260             template<typename T>
   6261             ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
   6262                 m_writer->writeAttribute( name, attribute );
   6263                 return *this;
   6264             }
   6265 
   6266         private:
   6267             mutable XmlWriter* m_writer = nullptr;
   6268             XmlFormatting m_fmt;
   6269         };
   6270 
   6271         XmlWriter( std::ostream& os = Catch::cout() );
   6272         ~XmlWriter();
   6273 
   6274         XmlWriter( XmlWriter const& ) = delete;
   6275         XmlWriter& operator=( XmlWriter const& ) = delete;
   6276 
   6277         XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
   6278 
   6279         ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
   6280 
   6281         XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
   6282 
   6283         XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
   6284 
   6285         XmlWriter& writeAttribute( std::string const& name, bool attribute );
   6286 
   6287         template<typename T>
   6288         XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
   6289             ReusableStringStream rss;
   6290             rss << attribute;
   6291             return writeAttribute( name, rss.str() );
   6292         }
   6293 
   6294         XmlWriter& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
   6295 
   6296         XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
   6297 
   6298         void writeStylesheetRef( std::string const& url );
   6299 
   6300         XmlWriter& writeBlankLine();
   6301 
   6302         void ensureTagClosed();
   6303 
   6304     private:
   6305 
   6306         void applyFormatting(XmlFormatting fmt);
   6307 
   6308         void writeDeclaration();
   6309 
   6310         void newlineIfNecessary();
   6311 
   6312         bool m_tagIsOpen = false;
   6313         bool m_needsNewline = false;
   6314         std::vector<std::string> m_tags;
   6315         std::string m_indent;
   6316         std::ostream& m_os;
   6317     };
   6318 
   6319 }
   6320 
   6321 // end catch_xmlwriter.h
   6322 namespace Catch {
   6323 
   6324     class JunitReporter : public CumulativeReporterBase<JunitReporter> {
   6325     public:
   6326         JunitReporter(ReporterConfig const& _config);
   6327 
   6328         ~JunitReporter() override;
   6329 
   6330         static std::string getDescription();
   6331 
   6332         void noMatchingTestCases(std::string const& /*spec*/) override;
   6333 
   6334         void testRunStarting(TestRunInfo const& runInfo) override;
   6335 
   6336         void testGroupStarting(GroupInfo const& groupInfo) override;
   6337 
   6338         void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
   6339         bool assertionEnded(AssertionStats const& assertionStats) override;
   6340 
   6341         void testCaseEnded(TestCaseStats const& testCaseStats) override;
   6342 
   6343         void testGroupEnded(TestGroupStats const& testGroupStats) override;
   6344 
   6345         void testRunEndedCumulative() override;
   6346 
   6347         void writeGroup(TestGroupNode const& groupNode, double suiteTime);
   6348 
   6349         void writeTestCase(TestCaseNode const& testCaseNode);
   6350 
   6351         void writeSection(std::string const& className,
   6352                           std::string const& rootName,
   6353                           SectionNode const& sectionNode);
   6354 
   6355         void writeAssertions(SectionNode const& sectionNode);
   6356         void writeAssertion(AssertionStats const& stats);
   6357 
   6358         XmlWriter xml;
   6359         Timer suiteTimer;
   6360         std::string stdOutForSuite;
   6361         std::string stdErrForSuite;
   6362         unsigned int unexpectedExceptions = 0;
   6363         bool m_okToFail = false;
   6364     };
   6365 
   6366 } // end namespace Catch
   6367 
   6368 // end catch_reporter_junit.h
   6369 // start catch_reporter_xml.h
   6370 
   6371 namespace Catch {
   6372     class XmlReporter : public StreamingReporterBase<XmlReporter> {
   6373     public:
   6374         XmlReporter(ReporterConfig const& _config);
   6375 
   6376         ~XmlReporter() override;
   6377 
   6378         static std::string getDescription();
   6379 
   6380         virtual std::string getStylesheetRef() const;
   6381 
   6382         void writeSourceInfo(SourceLineInfo const& sourceInfo);
   6383 
   6384     public: // StreamingReporterBase
   6385 
   6386         void noMatchingTestCases(std::string const& s) override;
   6387 
   6388         void testRunStarting(TestRunInfo const& testInfo) override;
   6389 
   6390         void testGroupStarting(GroupInfo const& groupInfo) override;
   6391 
   6392         void testCaseStarting(TestCaseInfo const& testInfo) override;
   6393 
   6394         void sectionStarting(SectionInfo const& sectionInfo) override;
   6395 
   6396         void assertionStarting(AssertionInfo const&) override;
   6397 
   6398         bool assertionEnded(AssertionStats const& assertionStats) override;
   6399 
   6400         void sectionEnded(SectionStats const& sectionStats) override;
   6401 
   6402         void testCaseEnded(TestCaseStats const& testCaseStats) override;
   6403 
   6404         void testGroupEnded(TestGroupStats const& testGroupStats) override;
   6405 
   6406         void testRunEnded(TestRunStats const& testRunStats) override;
   6407 
   6408 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   6409         void benchmarkPreparing(std::string const& name) override;
   6410         void benchmarkStarting(BenchmarkInfo const&) override;
   6411         void benchmarkEnded(BenchmarkStats<> const&) override;
   6412         void benchmarkFailed(std::string const&) override;
   6413 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   6414 
   6415     private:
   6416         Timer m_testCaseTimer;
   6417         XmlWriter m_xml;
   6418         int m_sectionDepth = 0;
   6419     };
   6420 
   6421 } // end namespace Catch
   6422 
   6423 // end catch_reporter_xml.h
   6424 
   6425 // end catch_external_interfaces.h
   6426 #endif
   6427 
   6428 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   6429 // start catch_benchmarking_all.hpp
   6430 
   6431 // A proxy header that includes all of the benchmarking headers to allow
   6432 // concise include of the benchmarking features. You should prefer the
   6433 // individual includes in standard use.
   6434 
   6435 // start catch_benchmark.hpp
   6436 
   6437  // Benchmark
   6438 
   6439 // start catch_chronometer.hpp
   6440 
   6441 // User-facing chronometer
   6442 
   6443 
   6444 // start catch_clock.hpp
   6445 
   6446 // Clocks
   6447 
   6448 
   6449 #include <chrono>
   6450 #include <ratio>
   6451 
   6452 namespace Catch {
   6453     namespace Benchmark {
   6454         template <typename Clock>
   6455         using ClockDuration = typename Clock::duration;
   6456         template <typename Clock>
   6457         using FloatDuration = std::chrono::duration<double, typename Clock::period>;
   6458 
   6459         template <typename Clock>
   6460         using TimePoint = typename Clock::time_point;
   6461 
   6462         using default_clock = std::chrono::steady_clock;
   6463 
   6464         template <typename Clock>
   6465         struct now {
   6466             TimePoint<Clock> operator()() const {
   6467                 return Clock::now();
   6468             }
   6469         };
   6470 
   6471         using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
   6472     } // namespace Benchmark
   6473 } // namespace Catch
   6474 
   6475 // end catch_clock.hpp
   6476 // start catch_optimizer.hpp
   6477 
   6478  // Hinting the optimizer
   6479 
   6480 
   6481 #if defined(_MSC_VER)
   6482 #   include <atomic> // atomic_thread_fence
   6483 #endif
   6484 
   6485 namespace Catch {
   6486     namespace Benchmark {
   6487 #if defined(__GNUC__) || defined(__clang__)
   6488         template <typename T>
   6489         inline void keep_memory(T* p) {
   6490             asm volatile("" : : "g"(p) : "memory");
   6491         }
   6492         inline void keep_memory() {
   6493             asm volatile("" : : : "memory");
   6494         }
   6495 
   6496         namespace Detail {
   6497             inline void optimizer_barrier() { keep_memory(); }
   6498         } // namespace Detail
   6499 #elif defined(_MSC_VER)
   6500 
   6501 #pragma optimize("", off)
   6502         template <typename T>
   6503         inline void keep_memory(T* p) {
   6504             // thanks @milleniumbug
   6505             *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
   6506         }
   6507         // TODO equivalent keep_memory()
   6508 #pragma optimize("", on)
   6509 
   6510         namespace Detail {
   6511             inline void optimizer_barrier() {
   6512                 std::atomic_thread_fence(std::memory_order_seq_cst);
   6513             }
   6514         } // namespace Detail
   6515 
   6516 #endif
   6517 
   6518         template <typename T>
   6519         inline void deoptimize_value(T&& x) {
   6520             keep_memory(&x);
   6521         }
   6522 
   6523         template <typename Fn, typename... Args>
   6524         inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
   6525             deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));
   6526         }
   6527 
   6528         template <typename Fn, typename... Args>
   6529         inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
   6530             std::forward<Fn>(fn) (std::forward<Args...>(args...));
   6531         }
   6532     } // namespace Benchmark
   6533 } // namespace Catch
   6534 
   6535 // end catch_optimizer.hpp
   6536 // start catch_complete_invoke.hpp
   6537 
   6538 // Invoke with a special case for void
   6539 
   6540 
   6541 #include <type_traits>
   6542 #include <utility>
   6543 
   6544 namespace Catch {
   6545     namespace Benchmark {
   6546         namespace Detail {
   6547             template <typename T>
   6548             struct CompleteType { using type = T; };
   6549             template <>
   6550             struct CompleteType<void> { struct type {}; };
   6551 
   6552             template <typename T>
   6553             using CompleteType_t = typename CompleteType<T>::type;
   6554 
   6555             template <typename Result>
   6556             struct CompleteInvoker {
   6557                 template <typename Fun, typename... Args>
   6558                 static Result invoke(Fun&& fun, Args&&... args) {
   6559                     return std::forward<Fun>(fun)(std::forward<Args>(args)...);
   6560                 }
   6561             };
   6562             template <>
   6563             struct CompleteInvoker<void> {
   6564                 template <typename Fun, typename... Args>
   6565                 static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
   6566                     std::forward<Fun>(fun)(std::forward<Args>(args)...);
   6567                     return {};
   6568                 }
   6569             };
   6570 
   6571             // invoke and not return void :(
   6572             template <typename Fun, typename... Args>
   6573             CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) {
   6574                 return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
   6575             }
   6576 
   6577             const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
   6578         } // namespace Detail
   6579 
   6580         template <typename Fun>
   6581         Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun) {
   6582             CATCH_TRY{
   6583                 return Detail::complete_invoke(std::forward<Fun>(fun));
   6584             } CATCH_CATCH_ALL{
   6585                 getResultCapture().benchmarkFailed(translateActiveException());
   6586                 CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
   6587             }
   6588         }
   6589     } // namespace Benchmark
   6590 } // namespace Catch
   6591 
   6592 // end catch_complete_invoke.hpp
   6593 namespace Catch {
   6594     namespace Benchmark {
   6595         namespace Detail {
   6596             struct ChronometerConcept {
   6597                 virtual void start() = 0;
   6598                 virtual void finish() = 0;
   6599                 virtual ~ChronometerConcept() = default;
   6600             };
   6601             template <typename Clock>
   6602             struct ChronometerModel final : public ChronometerConcept {
   6603                 void start() override { started = Clock::now(); }
   6604                 void finish() override { finished = Clock::now(); }
   6605 
   6606                 ClockDuration<Clock> elapsed() const { return finished - started; }
   6607 
   6608                 TimePoint<Clock> started;
   6609                 TimePoint<Clock> finished;
   6610             };
   6611         } // namespace Detail
   6612 
   6613         struct Chronometer {
   6614         public:
   6615             template <typename Fun>
   6616             void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
   6617 
   6618             int runs() const { return k; }
   6619 
   6620             Chronometer(Detail::ChronometerConcept& meter, int k)
   6621                 : impl(&meter)
   6622                 , k(k) {}
   6623 
   6624         private:
   6625             template <typename Fun>
   6626             void measure(Fun&& fun, std::false_type) {
   6627                 measure([&fun](int) { return fun(); }, std::true_type());
   6628             }
   6629 
   6630             template <typename Fun>
   6631             void measure(Fun&& fun, std::true_type) {
   6632                 Detail::optimizer_barrier();
   6633                 impl->start();
   6634                 for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);
   6635                 impl->finish();
   6636                 Detail::optimizer_barrier();
   6637             }
   6638 
   6639             Detail::ChronometerConcept* impl;
   6640             int k;
   6641         };
   6642     } // namespace Benchmark
   6643 } // namespace Catch
   6644 
   6645 // end catch_chronometer.hpp
   6646 // start catch_environment.hpp
   6647 
   6648 // Environment information
   6649 
   6650 
   6651 namespace Catch {
   6652     namespace Benchmark {
   6653         template <typename Duration>
   6654         struct EnvironmentEstimate {
   6655             Duration mean;
   6656             OutlierClassification outliers;
   6657 
   6658             template <typename Duration2>
   6659             operator EnvironmentEstimate<Duration2>() const {
   6660                 return { mean, outliers };
   6661             }
   6662         };
   6663         template <typename Clock>
   6664         struct Environment {
   6665             using clock_type = Clock;
   6666             EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
   6667             EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
   6668         };
   6669     } // namespace Benchmark
   6670 } // namespace Catch
   6671 
   6672 // end catch_environment.hpp
   6673 // start catch_execution_plan.hpp
   6674 
   6675  // Execution plan
   6676 
   6677 
   6678 // start catch_benchmark_function.hpp
   6679 
   6680  // Dumb std::function implementation for consistent call overhead
   6681 
   6682 
   6683 #include <cassert>
   6684 #include <type_traits>
   6685 #include <utility>
   6686 #include <memory>
   6687 
   6688 namespace Catch {
   6689     namespace Benchmark {
   6690         namespace Detail {
   6691             template <typename T>
   6692             using Decay = typename std::decay<T>::type;
   6693             template <typename T, typename U>
   6694             struct is_related
   6695                 : std::is_same<Decay<T>, Decay<U>> {};
   6696 
   6697             /// We need to reinvent std::function because every piece of code that might add overhead
   6698             /// in a measurement context needs to have consistent performance characteristics so that we
   6699             /// can account for it in the measurement.
   6700             /// Implementations of std::function with optimizations that aren't always applicable, like
   6701             /// small buffer optimizations, are not uncommon.
   6702             /// This is effectively an implementation of std::function without any such optimizations;
   6703             /// it may be slow, but it is consistently slow.
   6704             struct BenchmarkFunction {
   6705             private:
   6706                 struct callable {
   6707                     virtual void call(Chronometer meter) const = 0;
   6708                     virtual callable* clone() const = 0;
   6709                     virtual ~callable() = default;
   6710                 };
   6711                 template <typename Fun>
   6712                 struct model : public callable {
   6713                     model(Fun&& fun) : fun(std::move(fun)) {}
   6714                     model(Fun const& fun) : fun(fun) {}
   6715 
   6716                     model<Fun>* clone() const override { return new model<Fun>(*this); }
   6717 
   6718                     void call(Chronometer meter) const override {
   6719                         call(meter, is_callable<Fun(Chronometer)>());
   6720                     }
   6721                     void call(Chronometer meter, std::true_type) const {
   6722                         fun(meter);
   6723                     }
   6724                     void call(Chronometer meter, std::false_type) const {
   6725                         meter.measure(fun);
   6726                     }
   6727 
   6728                     Fun fun;
   6729                 };
   6730 
   6731                 struct do_nothing { void operator()() const {} };
   6732 
   6733                 template <typename T>
   6734                 BenchmarkFunction(model<T>* c) : f(c) {}
   6735 
   6736             public:
   6737                 BenchmarkFunction()
   6738                     : f(new model<do_nothing>{ {} }) {}
   6739 
   6740                 template <typename Fun,
   6741                     typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
   6742                     BenchmarkFunction(Fun&& fun)
   6743                     : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}
   6744 
   6745                 BenchmarkFunction(BenchmarkFunction&& that)
   6746                     : f(std::move(that.f)) {}
   6747 
   6748                 BenchmarkFunction(BenchmarkFunction const& that)
   6749                     : f(that.f->clone()) {}
   6750 
   6751                 BenchmarkFunction& operator=(BenchmarkFunction&& that) {
   6752                     f = std::move(that.f);
   6753                     return *this;
   6754                 }
   6755 
   6756                 BenchmarkFunction& operator=(BenchmarkFunction const& that) {
   6757                     f.reset(that.f->clone());
   6758                     return *this;
   6759                 }
   6760 
   6761                 void operator()(Chronometer meter) const { f->call(meter); }
   6762 
   6763             private:
   6764                 std::unique_ptr<callable> f;
   6765             };
   6766         } // namespace Detail
   6767     } // namespace Benchmark
   6768 } // namespace Catch
   6769 
   6770 // end catch_benchmark_function.hpp
   6771 // start catch_repeat.hpp
   6772 
   6773 // repeat algorithm
   6774 
   6775 
   6776 #include <type_traits>
   6777 #include <utility>
   6778 
   6779 namespace Catch {
   6780     namespace Benchmark {
   6781         namespace Detail {
   6782             template <typename Fun>
   6783             struct repeater {
   6784                 void operator()(int k) const {
   6785                     for (int i = 0; i < k; ++i) {
   6786                         fun();
   6787                     }
   6788                 }
   6789                 Fun fun;
   6790             };
   6791             template <typename Fun>
   6792             repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {
   6793                 return { std::forward<Fun>(fun) };
   6794             }
   6795         } // namespace Detail
   6796     } // namespace Benchmark
   6797 } // namespace Catch
   6798 
   6799 // end catch_repeat.hpp
   6800 // start catch_run_for_at_least.hpp
   6801 
   6802 // Run a function for a minimum amount of time
   6803 
   6804 
   6805 // start catch_measure.hpp
   6806 
   6807 // Measure
   6808 
   6809 
   6810 // start catch_timing.hpp
   6811 
   6812 // Timing
   6813 
   6814 
   6815 #include <tuple>
   6816 #include <type_traits>
   6817 
   6818 namespace Catch {
   6819     namespace Benchmark {
   6820         template <typename Duration, typename Result>
   6821         struct Timing {
   6822             Duration elapsed;
   6823             Result result;
   6824             int iterations;
   6825         };
   6826         template <typename Clock, typename Func, typename... Args>
   6827         using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;
   6828     } // namespace Benchmark
   6829 } // namespace Catch
   6830 
   6831 // end catch_timing.hpp
   6832 #include <utility>
   6833 
   6834 namespace Catch {
   6835     namespace Benchmark {
   6836         namespace Detail {
   6837             template <typename Clock, typename Fun, typename... Args>
   6838             TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) {
   6839                 auto start = Clock::now();
   6840                 auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
   6841                 auto end = Clock::now();
   6842                 auto delta = end - start;
   6843                 return { delta, std::forward<decltype(r)>(r), 1 };
   6844             }
   6845         } // namespace Detail
   6846     } // namespace Benchmark
   6847 } // namespace Catch
   6848 
   6849 // end catch_measure.hpp
   6850 #include <utility>
   6851 #include <type_traits>
   6852 
   6853 namespace Catch {
   6854     namespace Benchmark {
   6855         namespace Detail {
   6856             template <typename Clock, typename Fun>
   6857             TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {
   6858                 return Detail::measure<Clock>(fun, iters);
   6859             }
   6860             template <typename Clock, typename Fun>
   6861             TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {
   6862                 Detail::ChronometerModel<Clock> meter;
   6863                 auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
   6864 
   6865                 return { meter.elapsed(), std::move(result), iters };
   6866             }
   6867 
   6868             template <typename Clock, typename Fun>
   6869             using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
   6870 
   6871             struct optimized_away_error : std::exception {
   6872                 const char* what() const noexcept override {
   6873                     return "could not measure benchmark, maybe it was optimized away";
   6874                 }
   6875             };
   6876 
   6877             template <typename Clock, typename Fun>
   6878             TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
   6879                 auto iters = seed;
   6880                 while (iters < (1 << 30)) {
   6881                     auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
   6882 
   6883                     if (Timing.elapsed >= how_long) {
   6884                         return { Timing.elapsed, std::move(Timing.result), iters };
   6885                     }
   6886                     iters *= 2;
   6887                 }
   6888                 throw optimized_away_error{};
   6889             }
   6890         } // namespace Detail
   6891     } // namespace Benchmark
   6892 } // namespace Catch
   6893 
   6894 // end catch_run_for_at_least.hpp
   6895 #include <algorithm>
   6896 
   6897 namespace Catch {
   6898     namespace Benchmark {
   6899         template <typename Duration>
   6900         struct ExecutionPlan {
   6901             int iterations_per_sample;
   6902             Duration estimated_duration;
   6903             Detail::BenchmarkFunction benchmark;
   6904             Duration warmup_time;
   6905             int warmup_iterations;
   6906 
   6907             template <typename Duration2>
   6908             operator ExecutionPlan<Duration2>() const {
   6909                 return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
   6910             }
   6911 
   6912             template <typename Clock>
   6913             std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
   6914                 // warmup a bit
   6915                 Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
   6916 
   6917                 std::vector<FloatDuration<Clock>> times;
   6918                 times.reserve(cfg.benchmarkSamples());
   6919                 std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
   6920                     Detail::ChronometerModel<Clock> model;
   6921                     this->benchmark(Chronometer(model, iterations_per_sample));
   6922                     auto sample_time = model.elapsed() - env.clock_cost.mean;
   6923                     if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
   6924                     return sample_time / iterations_per_sample;
   6925                 });
   6926                 return times;
   6927             }
   6928         };
   6929     } // namespace Benchmark
   6930 } // namespace Catch
   6931 
   6932 // end catch_execution_plan.hpp
   6933 // start catch_estimate_clock.hpp
   6934 
   6935  // Environment measurement
   6936 
   6937 
   6938 // start catch_stats.hpp
   6939 
   6940 // Statistical analysis tools
   6941 
   6942 
   6943 #include <algorithm>
   6944 #include <functional>
   6945 #include <vector>
   6946 #include <iterator>
   6947 #include <numeric>
   6948 #include <tuple>
   6949 #include <cmath>
   6950 #include <utility>
   6951 #include <cstddef>
   6952 #include <random>
   6953 
   6954 namespace Catch {
   6955     namespace Benchmark {
   6956         namespace Detail {
   6957             using sample = std::vector<double>;
   6958 
   6959             double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
   6960 
   6961             template <typename Iterator>
   6962             OutlierClassification classify_outliers(Iterator first, Iterator last) {
   6963                 std::vector<double> copy(first, last);
   6964 
   6965                 auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
   6966                 auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
   6967                 auto iqr = q3 - q1;
   6968                 auto los = q1 - (iqr * 3.);
   6969                 auto lom = q1 - (iqr * 1.5);
   6970                 auto him = q3 + (iqr * 1.5);
   6971                 auto his = q3 + (iqr * 3.);
   6972 
   6973                 OutlierClassification o;
   6974                 for (; first != last; ++first) {
   6975                     auto&& t = *first;
   6976                     if (t < los) ++o.low_severe;
   6977                     else if (t < lom) ++o.low_mild;
   6978                     else if (t > his) ++o.high_severe;
   6979                     else if (t > him) ++o.high_mild;
   6980                     ++o.samples_seen;
   6981                 }
   6982                 return o;
   6983             }
   6984 
   6985             template <typename Iterator>
   6986             double mean(Iterator first, Iterator last) {
   6987                 auto count = last - first;
   6988                 double sum = std::accumulate(first, last, 0.);
   6989                 return sum / count;
   6990             }
   6991 
   6992             template <typename URng, typename Iterator, typename Estimator>
   6993             sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {
   6994                 auto n = last - first;
   6995                 std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
   6996 
   6997                 sample out;
   6998                 out.reserve(resamples);
   6999                 std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
   7000                     std::vector<double> resampled;
   7001                     resampled.reserve(n);
   7002                     std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
   7003                     return estimator(resampled.begin(), resampled.end());
   7004                 });
   7005                 std::sort(out.begin(), out.end());
   7006                 return out;
   7007             }
   7008 
   7009             template <typename Estimator, typename Iterator>
   7010             sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
   7011                 auto n = last - first;
   7012                 auto second = std::next(first);
   7013                 sample results;
   7014                 results.reserve(n);
   7015 
   7016                 for (auto it = first; it != last; ++it) {
   7017                     std::iter_swap(it, first);
   7018                     results.push_back(estimator(second, last));
   7019                 }
   7020 
   7021                 return results;
   7022             }
   7023 
   7024             inline double normal_cdf(double x) {
   7025                 return std::erfc(-x / std::sqrt(2.0)) / 2.0;
   7026             }
   7027 
   7028             double erfc_inv(double x);
   7029 
   7030             double normal_quantile(double p);
   7031 
   7032             template <typename Iterator, typename Estimator>
   7033             Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
   7034                 auto n_samples = last - first;
   7035 
   7036                 double point = estimator(first, last);
   7037                 // Degenerate case with a single sample
   7038                 if (n_samples == 1) return { point, point, point, confidence_level };
   7039 
   7040                 sample jack = jackknife(estimator, first, last);
   7041                 double jack_mean = mean(jack.begin(), jack.end());
   7042                 double sum_squares, sum_cubes;
   7043                 std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {
   7044                     auto d = jack_mean - x;
   7045                     auto d2 = d * d;
   7046                     auto d3 = d2 * d;
   7047                     return { sqcb.first + d2, sqcb.second + d3 };
   7048                 });
   7049 
   7050                 double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
   7051                 int n = static_cast<int>(resample.size());
   7052                 double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
   7053                 // degenerate case with uniform samples
   7054                 if (prob_n == 0) return { point, point, point, confidence_level };
   7055 
   7056                 double bias = normal_quantile(prob_n);
   7057                 double z1 = normal_quantile((1. - confidence_level) / 2.);
   7058 
   7059                 auto cumn = [n](double x) -> int {
   7060                     return std::lround(normal_cdf(x) * n); };
   7061                 auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
   7062                 double b1 = bias + z1;
   7063                 double b2 = bias - z1;
   7064                 double a1 = a(b1);
   7065                 double a2 = a(b2);
   7066                 auto lo = std::max(cumn(a1), 0);
   7067                 auto hi = std::min(cumn(a2), n - 1);
   7068 
   7069                 return { point, resample[lo], resample[hi], confidence_level };
   7070             }
   7071 
   7072             double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
   7073 
   7074             struct bootstrap_analysis {
   7075                 Estimate<double> mean;
   7076                 Estimate<double> standard_deviation;
   7077                 double outlier_variance;
   7078             };
   7079 
   7080             bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
   7081         } // namespace Detail
   7082     } // namespace Benchmark
   7083 } // namespace Catch
   7084 
   7085 // end catch_stats.hpp
   7086 #include <algorithm>
   7087 #include <iterator>
   7088 #include <tuple>
   7089 #include <vector>
   7090 #include <cmath>
   7091 
   7092 namespace Catch {
   7093     namespace Benchmark {
   7094         namespace Detail {
   7095             template <typename Clock>
   7096             std::vector<double> resolution(int k) {
   7097                 std::vector<TimePoint<Clock>> times;
   7098                 times.reserve(k + 1);
   7099                 std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
   7100 
   7101                 std::vector<double> deltas;
   7102                 deltas.reserve(k);
   7103                 std::transform(std::next(times.begin()), times.end(), times.begin(),
   7104                     std::back_inserter(deltas),
   7105                     [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
   7106 
   7107                 return deltas;
   7108             }
   7109 
   7110             const auto warmup_iterations = 10000;
   7111             const auto warmup_time = std::chrono::milliseconds(100);
   7112             const auto minimum_ticks = 1000;
   7113             const auto warmup_seed = 10000;
   7114             const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
   7115             const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
   7116             const auto clock_cost_estimation_tick_limit = 100000;
   7117             const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
   7118             const auto clock_cost_estimation_iterations = 10000;
   7119 
   7120             template <typename Clock>
   7121             int warmup() {
   7122                 return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)
   7123                     .iterations;
   7124             }
   7125             template <typename Clock>
   7126             EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
   7127                 auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
   7128                     .result;
   7129                 return {
   7130                     FloatDuration<Clock>(mean(r.begin(), r.end())),
   7131                     classify_outliers(r.begin(), r.end()),
   7132                 };
   7133             }
   7134             template <typename Clock>
   7135             EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
   7136                 auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
   7137                 auto time_clock = [](int k) {
   7138                     return Detail::measure<Clock>([k] {
   7139                         for (int i = 0; i < k; ++i) {
   7140                             volatile auto ignored = Clock::now();
   7141                             (void)ignored;
   7142                         }
   7143                     }).elapsed;
   7144                 };
   7145                 time_clock(1);
   7146                 int iters = clock_cost_estimation_iterations;
   7147                 auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
   7148                 std::vector<double> times;
   7149                 int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
   7150                 times.reserve(nsamples);
   7151                 std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
   7152                     return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
   7153                 });
   7154                 return {
   7155                     FloatDuration<Clock>(mean(times.begin(), times.end())),
   7156                     classify_outliers(times.begin(), times.end()),
   7157                 };
   7158             }
   7159 
   7160             template <typename Clock>
   7161             Environment<FloatDuration<Clock>> measure_environment() {
   7162                 static Environment<FloatDuration<Clock>>* env = nullptr;
   7163                 if (env) {
   7164                     return *env;
   7165                 }
   7166 
   7167                 auto iters = Detail::warmup<Clock>();
   7168                 auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
   7169                 auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
   7170 
   7171                 env = new Environment<FloatDuration<Clock>>{ resolution, cost };
   7172                 return *env;
   7173             }
   7174         } // namespace Detail
   7175     } // namespace Benchmark
   7176 } // namespace Catch
   7177 
   7178 // end catch_estimate_clock.hpp
   7179 // start catch_analyse.hpp
   7180 
   7181  // Run and analyse one benchmark
   7182 
   7183 
   7184 // start catch_sample_analysis.hpp
   7185 
   7186 // Benchmark results
   7187 
   7188 
   7189 #include <algorithm>
   7190 #include <vector>
   7191 #include <string>
   7192 #include <iterator>
   7193 
   7194 namespace Catch {
   7195     namespace Benchmark {
   7196         template <typename Duration>
   7197         struct SampleAnalysis {
   7198             std::vector<Duration> samples;
   7199             Estimate<Duration> mean;
   7200             Estimate<Duration> standard_deviation;
   7201             OutlierClassification outliers;
   7202             double outlier_variance;
   7203 
   7204             template <typename Duration2>
   7205             operator SampleAnalysis<Duration2>() const {
   7206                 std::vector<Duration2> samples2;
   7207                 samples2.reserve(samples.size());
   7208                 std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
   7209                 return {
   7210                     std::move(samples2),
   7211                     mean,
   7212                     standard_deviation,
   7213                     outliers,
   7214                     outlier_variance,
   7215                 };
   7216             }
   7217         };
   7218     } // namespace Benchmark
   7219 } // namespace Catch
   7220 
   7221 // end catch_sample_analysis.hpp
   7222 #include <algorithm>
   7223 #include <iterator>
   7224 #include <vector>
   7225 
   7226 namespace Catch {
   7227     namespace Benchmark {
   7228         namespace Detail {
   7229             template <typename Duration, typename Iterator>
   7230             SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
   7231                 if (!cfg.benchmarkNoAnalysis()) {
   7232                     std::vector<double> samples;
   7233                     samples.reserve(last - first);
   7234                     std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
   7235 
   7236                     auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
   7237                     auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
   7238 
   7239                     auto wrap_estimate = [](Estimate<double> e) {
   7240                         return Estimate<Duration> {
   7241                             Duration(e.point),
   7242                                 Duration(e.lower_bound),
   7243                                 Duration(e.upper_bound),
   7244                                 e.confidence_interval,
   7245                         };
   7246                     };
   7247                     std::vector<Duration> samples2;
   7248                     samples2.reserve(samples.size());
   7249                     std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
   7250                     return {
   7251                         std::move(samples2),
   7252                         wrap_estimate(analysis.mean),
   7253                         wrap_estimate(analysis.standard_deviation),
   7254                         outliers,
   7255                         analysis.outlier_variance,
   7256                     };
   7257                 } else {
   7258                     std::vector<Duration> samples;
   7259                     samples.reserve(last - first);
   7260 
   7261                     Duration mean = Duration(0);
   7262                     int i = 0;
   7263                     for (auto it = first; it < last; ++it, ++i) {
   7264                         samples.push_back(Duration(*it));
   7265                         mean += Duration(*it);
   7266                     }
   7267                     mean /= i;
   7268 
   7269                     return {
   7270                         std::move(samples),
   7271                         Estimate<Duration>{mean, mean, mean, 0.0},
   7272                         Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
   7273                         OutlierClassification{},
   7274                         0.0
   7275                     };
   7276                 }
   7277             }
   7278         } // namespace Detail
   7279     } // namespace Benchmark
   7280 } // namespace Catch
   7281 
   7282 // end catch_analyse.hpp
   7283 #include <algorithm>
   7284 #include <functional>
   7285 #include <string>
   7286 #include <vector>
   7287 #include <cmath>
   7288 
   7289 namespace Catch {
   7290     namespace Benchmark {
   7291         struct Benchmark {
   7292             Benchmark(std::string &&name)
   7293                 : name(std::move(name)) {}
   7294 
   7295             template <class FUN>
   7296             Benchmark(std::string &&name, FUN &&func)
   7297                 : fun(std::move(func)), name(std::move(name)) {}
   7298 
   7299             template <typename Clock>
   7300             ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
   7301                 auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
   7302                 auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
   7303                 auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
   7304                 int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
   7305                 return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };
   7306             }
   7307 
   7308             template <typename Clock = default_clock>
   7309             void run() {
   7310                 IConfigPtr cfg = getCurrentContext().getConfig();
   7311 
   7312                 auto env = Detail::measure_environment<Clock>();
   7313 
   7314                 getResultCapture().benchmarkPreparing(name);
   7315                 CATCH_TRY{
   7316                     auto plan = user_code([&] {
   7317                         return prepare<Clock>(*cfg, env);
   7318                     });
   7319 
   7320                     BenchmarkInfo info {
   7321                         name,
   7322                         plan.estimated_duration.count(),
   7323                         plan.iterations_per_sample,
   7324                         cfg->benchmarkSamples(),
   7325                         cfg->benchmarkResamples(),
   7326                         env.clock_resolution.mean.count(),
   7327                         env.clock_cost.mean.count()
   7328                     };
   7329 
   7330                     getResultCapture().benchmarkStarting(info);
   7331 
   7332                     auto samples = user_code([&] {
   7333                         return plan.template run<Clock>(*cfg, env);
   7334                     });
   7335 
   7336                     auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
   7337                     BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
   7338                     getResultCapture().benchmarkEnded(stats);
   7339 
   7340                 } CATCH_CATCH_ALL{
   7341                     if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
   7342                         std::rethrow_exception(std::current_exception());
   7343                 }
   7344             }
   7345 
   7346             // sets lambda to be used in fun *and* executes benchmark!
   7347             template <typename Fun,
   7348                 typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
   7349                 Benchmark & operator=(Fun func) {
   7350                 fun = Detail::BenchmarkFunction(func);
   7351                 run();
   7352                 return *this;
   7353             }
   7354 
   7355             explicit operator bool() {
   7356                 return true;
   7357             }
   7358 
   7359         private:
   7360             Detail::BenchmarkFunction fun;
   7361             std::string name;
   7362         };
   7363     }
   7364 } // namespace Catch
   7365 
   7366 #define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
   7367 #define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
   7368 
   7369 #define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
   7370     if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
   7371         BenchmarkName = [&](int benchmarkIndex)
   7372 
   7373 #define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
   7374     if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
   7375         BenchmarkName = [&]
   7376 
   7377 // end catch_benchmark.hpp
   7378 // start catch_constructor.hpp
   7379 
   7380 // Constructor and destructor helpers
   7381 
   7382 
   7383 #include <type_traits>
   7384 
   7385 namespace Catch {
   7386     namespace Benchmark {
   7387         namespace Detail {
   7388             template <typename T, bool Destruct>
   7389             struct ObjectStorage
   7390             {
   7391                 using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
   7392 
   7393                 ObjectStorage() : data() {}
   7394 
   7395                 ObjectStorage(const ObjectStorage& other)
   7396                 {
   7397                     new(&data) T(other.stored_object());
   7398                 }
   7399 
   7400                 ObjectStorage(ObjectStorage&& other)
   7401                 {
   7402                     new(&data) T(std::move(other.stored_object()));
   7403                 }
   7404 
   7405                 ~ObjectStorage() { destruct_on_exit<T>(); }
   7406 
   7407                 template <typename... Args>
   7408                 void construct(Args&&... args)
   7409                 {
   7410                     new (&data) T(std::forward<Args>(args)...);
   7411                 }
   7412 
   7413                 template <bool AllowManualDestruction = !Destruct>
   7414                 typename std::enable_if<AllowManualDestruction>::type destruct()
   7415                 {
   7416                     stored_object().~T();
   7417                 }
   7418 
   7419             private:
   7420                 // If this is a constructor benchmark, destruct the underlying object
   7421                 template <typename U>
   7422                 void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
   7423                 // Otherwise, don't
   7424                 template <typename U>
   7425                 void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
   7426 
   7427                 T& stored_object() {
   7428                     return *static_cast<T*>(static_cast<void*>(&data));
   7429                 }
   7430 
   7431                 T const& stored_object() const {
   7432                     return *static_cast<T*>(static_cast<void*>(&data));
   7433                 }
   7434 
   7435                 TStorage data;
   7436             };
   7437         }
   7438 
   7439         template <typename T>
   7440         using storage_for = Detail::ObjectStorage<T, true>;
   7441 
   7442         template <typename T>
   7443         using destructable_object = Detail::ObjectStorage<T, false>;
   7444     }
   7445 }
   7446 
   7447 // end catch_constructor.hpp
   7448 // end catch_benchmarking_all.hpp
   7449 #endif
   7450 
   7451 #endif // ! CATCH_CONFIG_IMPL_ONLY
   7452 
   7453 #ifdef CATCH_IMPL
   7454 // start catch_impl.hpp
   7455 
   7456 #ifdef __clang__
   7457 #pragma clang diagnostic push
   7458 #pragma clang diagnostic ignored "-Wweak-vtables"
   7459 #endif
   7460 
   7461 // Keep these here for external reporters
   7462 // start catch_test_case_tracker.h
   7463 
   7464 #include <string>
   7465 #include <vector>
   7466 #include <memory>
   7467 
   7468 namespace Catch {
   7469 namespace TestCaseTracking {
   7470 
   7471     struct NameAndLocation {
   7472         std::string name;
   7473         SourceLineInfo location;
   7474 
   7475         NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
   7476         friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
   7477             return lhs.name == rhs.name
   7478                 && lhs.location == rhs.location;
   7479         }
   7480     };
   7481 
   7482     class ITracker;
   7483 
   7484     using ITrackerPtr = std::shared_ptr<ITracker>;
   7485 
   7486     class  ITracker {
   7487         NameAndLocation m_nameAndLocation;
   7488 
   7489     public:
   7490         ITracker(NameAndLocation const& nameAndLoc) :
   7491             m_nameAndLocation(nameAndLoc)
   7492         {}
   7493 
   7494         // static queries
   7495         NameAndLocation const& nameAndLocation() const {
   7496             return m_nameAndLocation;
   7497         }
   7498 
   7499         virtual ~ITracker();
   7500 
   7501         // dynamic queries
   7502         virtual bool isComplete() const = 0; // Successfully completed or failed
   7503         virtual bool isSuccessfullyCompleted() const = 0;
   7504         virtual bool isOpen() const = 0; // Started but not complete
   7505         virtual bool hasChildren() const = 0;
   7506         virtual bool hasStarted() const = 0;
   7507 
   7508         virtual ITracker& parent() = 0;
   7509 
   7510         // actions
   7511         virtual void close() = 0; // Successfully complete
   7512         virtual void fail() = 0;
   7513         virtual void markAsNeedingAnotherRun() = 0;
   7514 
   7515         virtual void addChild( ITrackerPtr const& child ) = 0;
   7516         virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
   7517         virtual void openChild() = 0;
   7518 
   7519         // Debug/ checking
   7520         virtual bool isSectionTracker() const = 0;
   7521         virtual bool isGeneratorTracker() const = 0;
   7522     };
   7523 
   7524     class TrackerContext {
   7525 
   7526         enum RunState {
   7527             NotStarted,
   7528             Executing,
   7529             CompletedCycle
   7530         };
   7531 
   7532         ITrackerPtr m_rootTracker;
   7533         ITracker* m_currentTracker = nullptr;
   7534         RunState m_runState = NotStarted;
   7535 
   7536     public:
   7537 
   7538         ITracker& startRun();
   7539         void endRun();
   7540 
   7541         void startCycle();
   7542         void completeCycle();
   7543 
   7544         bool completedCycle() const;
   7545         ITracker& currentTracker();
   7546         void setCurrentTracker( ITracker* tracker );
   7547     };
   7548 
   7549     class TrackerBase : public ITracker {
   7550     protected:
   7551         enum CycleState {
   7552             NotStarted,
   7553             Executing,
   7554             ExecutingChildren,
   7555             NeedsAnotherRun,
   7556             CompletedSuccessfully,
   7557             Failed
   7558         };
   7559 
   7560         using Children = std::vector<ITrackerPtr>;
   7561         TrackerContext& m_ctx;
   7562         ITracker* m_parent;
   7563         Children m_children;
   7564         CycleState m_runState = NotStarted;
   7565 
   7566     public:
   7567         TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
   7568 
   7569         bool isComplete() const override;
   7570         bool isSuccessfullyCompleted() const override;
   7571         bool isOpen() const override;
   7572         bool hasChildren() const override;
   7573         bool hasStarted() const override {
   7574             return m_runState != NotStarted;
   7575         }
   7576 
   7577         void addChild( ITrackerPtr const& child ) override;
   7578 
   7579         ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
   7580         ITracker& parent() override;
   7581 
   7582         void openChild() override;
   7583 
   7584         bool isSectionTracker() const override;
   7585         bool isGeneratorTracker() const override;
   7586 
   7587         void open();
   7588 
   7589         void close() override;
   7590         void fail() override;
   7591         void markAsNeedingAnotherRun() override;
   7592 
   7593     private:
   7594         void moveToParent();
   7595         void moveToThis();
   7596     };
   7597 
   7598     class SectionTracker : public TrackerBase {
   7599         std::vector<std::string> m_filters;
   7600         std::string m_trimmed_name;
   7601     public:
   7602         SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
   7603 
   7604         bool isSectionTracker() const override;
   7605 
   7606         bool isComplete() const override;
   7607 
   7608         static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
   7609 
   7610         void tryOpen();
   7611 
   7612         void addInitialFilters( std::vector<std::string> const& filters );
   7613         void addNextFilters( std::vector<std::string> const& filters );
   7614     };
   7615 
   7616 } // namespace TestCaseTracking
   7617 
   7618 using TestCaseTracking::ITracker;
   7619 using TestCaseTracking::TrackerContext;
   7620 using TestCaseTracking::SectionTracker;
   7621 
   7622 } // namespace Catch
   7623 
   7624 // end catch_test_case_tracker.h
   7625 
   7626 // start catch_leak_detector.h
   7627 
   7628 namespace Catch {
   7629 
   7630     struct LeakDetector {
   7631         LeakDetector();
   7632         ~LeakDetector();
   7633     };
   7634 
   7635 }
   7636 // end catch_leak_detector.h
   7637 // Cpp files will be included in the single-header file here
   7638 // start catch_stats.cpp
   7639 
   7640 // Statistical analysis tools
   7641 
   7642 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   7643 
   7644 #include <cassert>
   7645 #include <random>
   7646 
   7647 #if defined(CATCH_CONFIG_USE_ASYNC)
   7648 #include <future>
   7649 #endif
   7650 
   7651 namespace {
   7652     double erf_inv(double x) {
   7653         // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
   7654         double w, p;
   7655 
   7656         w = -log((1.0 - x) * (1.0 + x));
   7657 
   7658         if (w < 6.250000) {
   7659             w = w - 3.125000;
   7660             p = -3.6444120640178196996e-21;
   7661             p = -1.685059138182016589e-19 + p * w;
   7662             p = 1.2858480715256400167e-18 + p * w;
   7663             p = 1.115787767802518096e-17 + p * w;
   7664             p = -1.333171662854620906e-16 + p * w;
   7665             p = 2.0972767875968561637e-17 + p * w;
   7666             p = 6.6376381343583238325e-15 + p * w;
   7667             p = -4.0545662729752068639e-14 + p * w;
   7668             p = -8.1519341976054721522e-14 + p * w;
   7669             p = 2.6335093153082322977e-12 + p * w;
   7670             p = -1.2975133253453532498e-11 + p * w;
   7671             p = -5.4154120542946279317e-11 + p * w;
   7672             p = 1.051212273321532285e-09 + p * w;
   7673             p = -4.1126339803469836976e-09 + p * w;
   7674             p = -2.9070369957882005086e-08 + p * w;
   7675             p = 4.2347877827932403518e-07 + p * w;
   7676             p = -1.3654692000834678645e-06 + p * w;
   7677             p = -1.3882523362786468719e-05 + p * w;
   7678             p = 0.0001867342080340571352 + p * w;
   7679             p = -0.00074070253416626697512 + p * w;
   7680             p = -0.0060336708714301490533 + p * w;
   7681             p = 0.24015818242558961693 + p * w;
   7682             p = 1.6536545626831027356 + p * w;
   7683         } else if (w < 16.000000) {
   7684             w = sqrt(w) - 3.250000;
   7685             p = 2.2137376921775787049e-09;
   7686             p = 9.0756561938885390979e-08 + p * w;
   7687             p = -2.7517406297064545428e-07 + p * w;
   7688             p = 1.8239629214389227755e-08 + p * w;
   7689             p = 1.5027403968909827627e-06 + p * w;
   7690             p = -4.013867526981545969e-06 + p * w;
   7691             p = 2.9234449089955446044e-06 + p * w;
   7692             p = 1.2475304481671778723e-05 + p * w;
   7693             p = -4.7318229009055733981e-05 + p * w;
   7694             p = 6.8284851459573175448e-05 + p * w;
   7695             p = 2.4031110387097893999e-05 + p * w;
   7696             p = -0.0003550375203628474796 + p * w;
   7697             p = 0.00095328937973738049703 + p * w;
   7698             p = -0.0016882755560235047313 + p * w;
   7699             p = 0.0024914420961078508066 + p * w;
   7700             p = -0.0037512085075692412107 + p * w;
   7701             p = 0.005370914553590063617 + p * w;
   7702             p = 1.0052589676941592334 + p * w;
   7703             p = 3.0838856104922207635 + p * w;
   7704         } else {
   7705             w = sqrt(w) - 5.000000;
   7706             p = -2.7109920616438573243e-11;
   7707             p = -2.5556418169965252055e-10 + p * w;
   7708             p = 1.5076572693500548083e-09 + p * w;
   7709             p = -3.7894654401267369937e-09 + p * w;
   7710             p = 7.6157012080783393804e-09 + p * w;
   7711             p = -1.4960026627149240478e-08 + p * w;
   7712             p = 2.9147953450901080826e-08 + p * w;
   7713             p = -6.7711997758452339498e-08 + p * w;
   7714             p = 2.2900482228026654717e-07 + p * w;
   7715             p = -9.9298272942317002539e-07 + p * w;
   7716             p = 4.5260625972231537039e-06 + p * w;
   7717             p = -1.9681778105531670567e-05 + p * w;
   7718             p = 7.5995277030017761139e-05 + p * w;
   7719             p = -0.00021503011930044477347 + p * w;
   7720             p = -0.00013871931833623122026 + p * w;
   7721             p = 1.0103004648645343977 + p * w;
   7722             p = 4.8499064014085844221 + p * w;
   7723         }
   7724         return p * x;
   7725     }
   7726 
   7727     double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
   7728         auto m = Catch::Benchmark::Detail::mean(first, last);
   7729         double variance = std::accumulate(first, last, 0., [m](double a, double b) {
   7730             double diff = b - m;
   7731             return a + diff * diff;
   7732             }) / (last - first);
   7733             return std::sqrt(variance);
   7734     }
   7735 
   7736 }
   7737 
   7738 namespace Catch {
   7739     namespace Benchmark {
   7740         namespace Detail {
   7741 
   7742             double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
   7743                 auto count = last - first;
   7744                 double idx = (count - 1) * k / static_cast<double>(q);
   7745                 int j = static_cast<int>(idx);
   7746                 double g = idx - j;
   7747                 std::nth_element(first, first + j, last);
   7748                 auto xj = first[j];
   7749                 if (g == 0) return xj;
   7750 
   7751                 auto xj1 = *std::min_element(first + (j + 1), last);
   7752                 return xj + g * (xj1 - xj);
   7753             }
   7754 
   7755             double erfc_inv(double x) {
   7756                 return erf_inv(1.0 - x);
   7757             }
   7758 
   7759             double normal_quantile(double p) {
   7760                 static const double ROOT_TWO = std::sqrt(2.0);
   7761 
   7762                 double result = 0.0;
   7763                 assert(p >= 0 && p <= 1);
   7764                 if (p < 0 || p > 1) {
   7765                     return result;
   7766                 }
   7767 
   7768                 result = -erfc_inv(2.0 * p);
   7769                 // result *= normal distribution standard deviation (1.0) * sqrt(2)
   7770                 result *= /*sd * */ ROOT_TWO;
   7771                 // result += normal disttribution mean (0)
   7772                 return result;
   7773             }
   7774 
   7775             double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
   7776                 double sb = stddev.point;
   7777                 double mn = mean.point / n;
   7778                 double mg_min = mn / 2.;
   7779                 double sg = std::min(mg_min / 4., sb / std::sqrt(n));
   7780                 double sg2 = sg * sg;
   7781                 double sb2 = sb * sb;
   7782 
   7783                 auto c_max = [n, mn, sb2, sg2](double x) -> double {
   7784                     double k = mn - x;
   7785                     double d = k * k;
   7786                     double nd = n * d;
   7787                     double k0 = -n * nd;
   7788                     double k1 = sb2 - n * sg2 + nd;
   7789                     double det = k1 * k1 - 4 * sg2 * k0;
   7790                     return (int)(-2. * k0 / (k1 + std::sqrt(det)));
   7791                 };
   7792 
   7793                 auto var_out = [n, sb2, sg2](double c) {
   7794                     double nc = n - c;
   7795                     return (nc / n) * (sb2 - nc * sg2);
   7796                 };
   7797 
   7798                 return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2;
   7799             }
   7800 
   7801             bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
   7802                 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
   7803                 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
   7804                 static std::random_device entropy;
   7805                 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   7806 
   7807                 auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
   7808 
   7809                 auto mean = &Detail::mean<std::vector<double>::iterator>;
   7810                 auto stddev = &standard_deviation;
   7811 
   7812 #if defined(CATCH_CONFIG_USE_ASYNC)
   7813                 auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
   7814                     auto seed = entropy();
   7815                     return std::async(std::launch::async, [=] {
   7816                         std::mt19937 rng(seed);
   7817                         auto resampled = resample(rng, n_resamples, first, last, f);
   7818                         return bootstrap(confidence_level, first, last, resampled, f);
   7819                     });
   7820                 };
   7821 
   7822                 auto mean_future = Estimate(mean);
   7823                 auto stddev_future = Estimate(stddev);
   7824 
   7825                 auto mean_estimate = mean_future.get();
   7826                 auto stddev_estimate = stddev_future.get();
   7827 #else
   7828                 auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
   7829                     auto seed = entropy();
   7830                     std::mt19937 rng(seed);
   7831                     auto resampled = resample(rng, n_resamples, first, last, f);
   7832                     return bootstrap(confidence_level, first, last, resampled, f);
   7833                 };
   7834 
   7835                 auto mean_estimate = Estimate(mean);
   7836                 auto stddev_estimate = Estimate(stddev);
   7837 #endif // CATCH_USE_ASYNC
   7838 
   7839                 double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
   7840 
   7841                 return { mean_estimate, stddev_estimate, outlier_variance };
   7842             }
   7843         } // namespace Detail
   7844     } // namespace Benchmark
   7845 } // namespace Catch
   7846 
   7847 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   7848 // end catch_stats.cpp
   7849 // start catch_approx.cpp
   7850 
   7851 #include <cmath>
   7852 #include <limits>
   7853 
   7854 namespace {
   7855 
   7856 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
   7857 // But without the subtraction to allow for INFINITY in comparison
   7858 bool marginComparison(double lhs, double rhs, double margin) {
   7859     return (lhs + margin >= rhs) && (rhs + margin >= lhs);
   7860 }
   7861 
   7862 }
   7863 
   7864 namespace Catch {
   7865 namespace Detail {
   7866 
   7867     Approx::Approx ( double value )
   7868     :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
   7869         m_margin( 0.0 ),
   7870         m_scale( 0.0 ),
   7871         m_value( value )
   7872     {}
   7873 
   7874     Approx Approx::custom() {
   7875         return Approx( 0 );
   7876     }
   7877 
   7878     Approx Approx::operator-() const {
   7879         auto temp(*this);
   7880         temp.m_value = -temp.m_value;
   7881         return temp;
   7882     }
   7883 
   7884     std::string Approx::toString() const {
   7885         ReusableStringStream rss;
   7886         rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
   7887         return rss.str();
   7888     }
   7889 
   7890     bool Approx::equalityComparisonImpl(const double other) const {
   7891         // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
   7892         // Thanks to Richard Harris for his help refining the scaled margin value
   7893         return marginComparison(m_value, other, m_margin)
   7894             || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
   7895     }
   7896 
   7897     void Approx::setMargin(double newMargin) {
   7898         CATCH_ENFORCE(newMargin >= 0,
   7899             "Invalid Approx::margin: " << newMargin << '.'
   7900             << " Approx::Margin has to be non-negative.");
   7901         m_margin = newMargin;
   7902     }
   7903 
   7904     void Approx::setEpsilon(double newEpsilon) {
   7905         CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
   7906             "Invalid Approx::epsilon: " << newEpsilon << '.'
   7907             << " Approx::epsilon has to be in [0, 1]");
   7908         m_epsilon = newEpsilon;
   7909     }
   7910 
   7911 } // end namespace Detail
   7912 
   7913 namespace literals {
   7914     Detail::Approx operator "" _a(long double val) {
   7915         return Detail::Approx(val);
   7916     }
   7917     Detail::Approx operator "" _a(unsigned long long val) {
   7918         return Detail::Approx(val);
   7919     }
   7920 } // end namespace literals
   7921 
   7922 std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
   7923     return value.toString();
   7924 }
   7925 
   7926 } // end namespace Catch
   7927 // end catch_approx.cpp
   7928 // start catch_assertionhandler.cpp
   7929 
   7930 // start catch_debugger.h
   7931 
   7932 namespace Catch {
   7933     bool isDebuggerActive();
   7934 }
   7935 
   7936 #ifdef CATCH_PLATFORM_MAC
   7937 
   7938     #if defined(__i386__) || defined(__x86_64__)
   7939         #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
   7940     #elif defined(__aarch64__)
   7941         #define CATCH_TRAP()  __asm__(".inst 0xd4200000")
   7942     #endif
   7943 
   7944 #elif defined(CATCH_PLATFORM_IPHONE)
   7945 
   7946     // use inline assembler
   7947     #if defined(__i386__) || defined(__x86_64__)
   7948         #define CATCH_TRAP()  __asm__("int $3")
   7949     #elif defined(__aarch64__)
   7950         #define CATCH_TRAP()  __asm__(".inst 0xd4200000")
   7951     #elif defined(__arm__) && !defined(__thumb__)
   7952         #define CATCH_TRAP()  __asm__(".inst 0xe7f001f0")
   7953     #elif defined(__arm__) &&  defined(__thumb__)
   7954         #define CATCH_TRAP()  __asm__(".inst 0xde01")
   7955     #endif
   7956 
   7957 #elif defined(CATCH_PLATFORM_LINUX)
   7958     // If we can use inline assembler, do it because this allows us to break
   7959     // directly at the location of the failing check instead of breaking inside
   7960     // raise() called from it, i.e. one stack frame below.
   7961     #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
   7962         #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
   7963     #else // Fall back to the generic way.
   7964         #include <signal.h>
   7965 
   7966         #define CATCH_TRAP() raise(SIGTRAP)
   7967     #endif
   7968 #elif defined(_MSC_VER)
   7969     #define CATCH_TRAP() __debugbreak()
   7970 #elif defined(__MINGW32__)
   7971     extern "C" __declspec(dllimport) void __stdcall DebugBreak();
   7972     #define CATCH_TRAP() DebugBreak()
   7973 #endif
   7974 
   7975 #ifndef CATCH_BREAK_INTO_DEBUGGER
   7976     #ifdef CATCH_TRAP
   7977         #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
   7978     #else
   7979         #define CATCH_BREAK_INTO_DEBUGGER() []{}()
   7980     #endif
   7981 #endif
   7982 
   7983 // end catch_debugger.h
   7984 // start catch_run_context.h
   7985 
   7986 // start catch_fatal_condition.h
   7987 
   7988 // start catch_windows_h_proxy.h
   7989 
   7990 
   7991 #if defined(CATCH_PLATFORM_WINDOWS)
   7992 
   7993 #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
   7994 #  define CATCH_DEFINED_NOMINMAX
   7995 #  define NOMINMAX
   7996 #endif
   7997 #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
   7998 #  define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
   7999 #  define WIN32_LEAN_AND_MEAN
   8000 #endif
   8001 
   8002 #ifdef __AFXDLL
   8003 #include <AfxWin.h>
   8004 #else
   8005 #include <windows.h>
   8006 #endif
   8007 
   8008 #ifdef CATCH_DEFINED_NOMINMAX
   8009 #  undef NOMINMAX
   8010 #endif
   8011 #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
   8012 #  undef WIN32_LEAN_AND_MEAN
   8013 #endif
   8014 
   8015 #endif // defined(CATCH_PLATFORM_WINDOWS)
   8016 
   8017 // end catch_windows_h_proxy.h
   8018 #if defined( CATCH_CONFIG_WINDOWS_SEH )
   8019 
   8020 namespace Catch {
   8021 
   8022     struct FatalConditionHandler {
   8023 
   8024         static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
   8025         FatalConditionHandler();
   8026         static void reset();
   8027         ~FatalConditionHandler();
   8028 
   8029     private:
   8030         static bool isSet;
   8031         static ULONG guaranteeSize;
   8032         static PVOID exceptionHandlerHandle;
   8033     };
   8034 
   8035 } // namespace Catch
   8036 
   8037 #elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
   8038 
   8039 #include <signal.h>
   8040 
   8041 namespace Catch {
   8042 
   8043     struct FatalConditionHandler {
   8044 
   8045         static bool isSet;
   8046         static struct sigaction oldSigActions[];
   8047         static stack_t oldSigStack;
   8048         static char altStackMem[];
   8049 
   8050         static void handleSignal( int sig );
   8051 
   8052         FatalConditionHandler();
   8053         ~FatalConditionHandler();
   8054         static void reset();
   8055     };
   8056 
   8057 } // namespace Catch
   8058 
   8059 #else
   8060 
   8061 namespace Catch {
   8062     struct FatalConditionHandler {
   8063         void reset();
   8064     };
   8065 }
   8066 
   8067 #endif
   8068 
   8069 // end catch_fatal_condition.h
   8070 #include <string>
   8071 
   8072 namespace Catch {
   8073 
   8074     struct IMutableContext;
   8075 
   8076     ///////////////////////////////////////////////////////////////////////////
   8077 
   8078     class RunContext : public IResultCapture, public IRunner {
   8079 
   8080     public:
   8081         RunContext( RunContext const& ) = delete;
   8082         RunContext& operator =( RunContext const& ) = delete;
   8083 
   8084         explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
   8085 
   8086         ~RunContext() override;
   8087 
   8088         void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
   8089         void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
   8090 
   8091         Totals runTest(TestCase const& testCase);
   8092 
   8093         IConfigPtr config() const;
   8094         IStreamingReporter& reporter() const;
   8095 
   8096     public: // IResultCapture
   8097 
   8098         // Assertion handlers
   8099         void handleExpr
   8100                 (   AssertionInfo const& info,
   8101                     ITransientExpression const& expr,
   8102                     AssertionReaction& reaction ) override;
   8103         void handleMessage
   8104                 (   AssertionInfo const& info,
   8105                     ResultWas::OfType resultType,
   8106                     StringRef const& message,
   8107                     AssertionReaction& reaction ) override;
   8108         void handleUnexpectedExceptionNotThrown
   8109                 (   AssertionInfo const& info,
   8110                     AssertionReaction& reaction ) override;
   8111         void handleUnexpectedInflightException
   8112                 (   AssertionInfo const& info,
   8113                     std::string const& message,
   8114                     AssertionReaction& reaction ) override;
   8115         void handleIncomplete
   8116                 (   AssertionInfo const& info ) override;
   8117         void handleNonExpr
   8118                 (   AssertionInfo const &info,
   8119                     ResultWas::OfType resultType,
   8120                     AssertionReaction &reaction ) override;
   8121 
   8122         bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
   8123 
   8124         void sectionEnded( SectionEndInfo const& endInfo ) override;
   8125         void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
   8126 
   8127         auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
   8128 
   8129 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   8130         void benchmarkPreparing( std::string const& name ) override;
   8131         void benchmarkStarting( BenchmarkInfo const& info ) override;
   8132         void benchmarkEnded( BenchmarkStats<> const& stats ) override;
   8133         void benchmarkFailed( std::string const& error ) override;
   8134 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   8135 
   8136         void pushScopedMessage( MessageInfo const& message ) override;
   8137         void popScopedMessage( MessageInfo const& message ) override;
   8138 
   8139         void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
   8140 
   8141         std::string getCurrentTestName() const override;
   8142 
   8143         const AssertionResult* getLastResult() const override;
   8144 
   8145         void exceptionEarlyReported() override;
   8146 
   8147         void handleFatalErrorCondition( StringRef message ) override;
   8148 
   8149         bool lastAssertionPassed() override;
   8150 
   8151         void assertionPassed() override;
   8152 
   8153     public:
   8154         // !TBD We need to do this another way!
   8155         bool aborting() const final;
   8156 
   8157     private:
   8158 
   8159         void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
   8160         void invokeActiveTestCase();
   8161 
   8162         void resetAssertionInfo();
   8163         bool testForMissingAssertions( Counts& assertions );
   8164 
   8165         void assertionEnded( AssertionResult const& result );
   8166         void reportExpr
   8167                 (   AssertionInfo const &info,
   8168                     ResultWas::OfType resultType,
   8169                     ITransientExpression const *expr,
   8170                     bool negated );
   8171 
   8172         void populateReaction( AssertionReaction& reaction );
   8173 
   8174     private:
   8175 
   8176         void handleUnfinishedSections();
   8177 
   8178         TestRunInfo m_runInfo;
   8179         IMutableContext& m_context;
   8180         TestCase const* m_activeTestCase = nullptr;
   8181         ITracker* m_testCaseTracker = nullptr;
   8182         Option<AssertionResult> m_lastResult;
   8183 
   8184         IConfigPtr m_config;
   8185         Totals m_totals;
   8186         IStreamingReporterPtr m_reporter;
   8187         std::vector<MessageInfo> m_messages;
   8188         std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
   8189         AssertionInfo m_lastAssertionInfo;
   8190         std::vector<SectionEndInfo> m_unfinishedSections;
   8191         std::vector<ITracker*> m_activeSections;
   8192         TrackerContext m_trackerContext;
   8193         bool m_lastAssertionPassed = false;
   8194         bool m_shouldReportUnexpected = true;
   8195         bool m_includeSuccessfulResults;
   8196     };
   8197 
   8198     void seedRng(IConfig const& config);
   8199     unsigned int rngSeed();
   8200 } // end namespace Catch
   8201 
   8202 // end catch_run_context.h
   8203 namespace Catch {
   8204 
   8205     namespace {
   8206         auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
   8207             expr.streamReconstructedExpression( os );
   8208             return os;
   8209         }
   8210     }
   8211 
   8212     LazyExpression::LazyExpression( bool isNegated )
   8213     :   m_isNegated( isNegated )
   8214     {}
   8215 
   8216     LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
   8217 
   8218     LazyExpression::operator bool() const {
   8219         return m_transientExpression != nullptr;
   8220     }
   8221 
   8222     auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
   8223         if( lazyExpr.m_isNegated )
   8224             os << "!";
   8225 
   8226         if( lazyExpr ) {
   8227             if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
   8228                 os << "(" << *lazyExpr.m_transientExpression << ")";
   8229             else
   8230                 os << *lazyExpr.m_transientExpression;
   8231         }
   8232         else {
   8233             os << "{** error - unchecked empty expression requested **}";
   8234         }
   8235         return os;
   8236     }
   8237 
   8238     AssertionHandler::AssertionHandler
   8239         (   StringRef const& macroName,
   8240             SourceLineInfo const& lineInfo,
   8241             StringRef capturedExpression,
   8242             ResultDisposition::Flags resultDisposition )
   8243     :   m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
   8244         m_resultCapture( getResultCapture() )
   8245     {}
   8246 
   8247     void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
   8248         m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
   8249     }
   8250     void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
   8251         m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
   8252     }
   8253 
   8254     auto AssertionHandler::allowThrows() const -> bool {
   8255         return getCurrentContext().getConfig()->allowThrows();
   8256     }
   8257 
   8258     void AssertionHandler::complete() {
   8259         setCompleted();
   8260         if( m_reaction.shouldDebugBreak ) {
   8261 
   8262             // If you find your debugger stopping you here then go one level up on the
   8263             // call-stack for the code that caused it (typically a failed assertion)
   8264 
   8265             // (To go back to the test and change execution, jump over the throw, next)
   8266             CATCH_BREAK_INTO_DEBUGGER();
   8267         }
   8268         if (m_reaction.shouldThrow) {
   8269 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
   8270             throw Catch::TestFailureException();
   8271 #else
   8272             CATCH_ERROR( "Test failure requires aborting test!" );
   8273 #endif
   8274         }
   8275     }
   8276     void AssertionHandler::setCompleted() {
   8277         m_completed = true;
   8278     }
   8279 
   8280     void AssertionHandler::handleUnexpectedInflightException() {
   8281         m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
   8282     }
   8283 
   8284     void AssertionHandler::handleExceptionThrownAsExpected() {
   8285         m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
   8286     }
   8287     void AssertionHandler::handleExceptionNotThrownAsExpected() {
   8288         m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
   8289     }
   8290 
   8291     void AssertionHandler::handleUnexpectedExceptionNotThrown() {
   8292         m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
   8293     }
   8294 
   8295     void AssertionHandler::handleThrowingCallSkipped() {
   8296         m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
   8297     }
   8298 
   8299     // This is the overload that takes a string and infers the Equals matcher from it
   8300     // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
   8301     void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString  ) {
   8302         handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
   8303     }
   8304 
   8305 } // namespace Catch
   8306 // end catch_assertionhandler.cpp
   8307 // start catch_assertionresult.cpp
   8308 
   8309 namespace Catch {
   8310     AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
   8311         lazyExpression(_lazyExpression),
   8312         resultType(_resultType) {}
   8313 
   8314     std::string AssertionResultData::reconstructExpression() const {
   8315 
   8316         if( reconstructedExpression.empty() ) {
   8317             if( lazyExpression ) {
   8318                 ReusableStringStream rss;
   8319                 rss << lazyExpression;
   8320                 reconstructedExpression = rss.str();
   8321             }
   8322         }
   8323         return reconstructedExpression;
   8324     }
   8325 
   8326     AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
   8327     :   m_info( info ),
   8328         m_resultData( data )
   8329     {}
   8330 
   8331     // Result was a success
   8332     bool AssertionResult::succeeded() const {
   8333         return Catch::isOk( m_resultData.resultType );
   8334     }
   8335 
   8336     // Result was a success, or failure is suppressed
   8337     bool AssertionResult::isOk() const {
   8338         return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
   8339     }
   8340 
   8341     ResultWas::OfType AssertionResult::getResultType() const {
   8342         return m_resultData.resultType;
   8343     }
   8344 
   8345     bool AssertionResult::hasExpression() const {
   8346         return !m_info.capturedExpression.empty();
   8347     }
   8348 
   8349     bool AssertionResult::hasMessage() const {
   8350         return !m_resultData.message.empty();
   8351     }
   8352 
   8353     std::string AssertionResult::getExpression() const {
   8354         // Possibly overallocating by 3 characters should be basically free
   8355         std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);
   8356         if (isFalseTest(m_info.resultDisposition)) {
   8357             expr += "!(";
   8358         }
   8359         expr += m_info.capturedExpression;
   8360         if (isFalseTest(m_info.resultDisposition)) {
   8361             expr += ')';
   8362         }
   8363         return expr;
   8364     }
   8365 
   8366     std::string AssertionResult::getExpressionInMacro() const {
   8367         std::string expr;
   8368         if( m_info.macroName.empty() )
   8369             expr = static_cast<std::string>(m_info.capturedExpression);
   8370         else {
   8371             expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
   8372             expr += m_info.macroName;
   8373             expr += "( ";
   8374             expr += m_info.capturedExpression;
   8375             expr += " )";
   8376         }
   8377         return expr;
   8378     }
   8379 
   8380     bool AssertionResult::hasExpandedExpression() const {
   8381         return hasExpression() && getExpandedExpression() != getExpression();
   8382     }
   8383 
   8384     std::string AssertionResult::getExpandedExpression() const {
   8385         std::string expr = m_resultData.reconstructExpression();
   8386         return expr.empty()
   8387                 ? getExpression()
   8388                 : expr;
   8389     }
   8390 
   8391     std::string AssertionResult::getMessage() const {
   8392         return m_resultData.message;
   8393     }
   8394     SourceLineInfo AssertionResult::getSourceInfo() const {
   8395         return m_info.lineInfo;
   8396     }
   8397 
   8398     StringRef AssertionResult::getTestMacroName() const {
   8399         return m_info.macroName;
   8400     }
   8401 
   8402 } // end namespace Catch
   8403 // end catch_assertionresult.cpp
   8404 // start catch_capture_matchers.cpp
   8405 
   8406 namespace Catch {
   8407 
   8408     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
   8409 
   8410     // This is the general overload that takes a any string matcher
   8411     // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
   8412     // the Equals matcher (so the header does not mention matchers)
   8413     void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  ) {
   8414         std::string exceptionMessage = Catch::translateActiveException();
   8415         MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
   8416         handler.handleExpr( expr );
   8417     }
   8418 
   8419 } // namespace Catch
   8420 // end catch_capture_matchers.cpp
   8421 // start catch_commandline.cpp
   8422 
   8423 // start catch_commandline.h
   8424 
   8425 // start catch_clara.h
   8426 
   8427 // Use Catch's value for console width (store Clara's off to the side, if present)
   8428 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
   8429 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
   8430 #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
   8431 #endif
   8432 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
   8433 
   8434 #ifdef __clang__
   8435 #pragma clang diagnostic push
   8436 #pragma clang diagnostic ignored "-Wweak-vtables"
   8437 #pragma clang diagnostic ignored "-Wexit-time-destructors"
   8438 #pragma clang diagnostic ignored "-Wshadow"
   8439 #endif
   8440 
   8441 // start clara.hpp
   8442 // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
   8443 //
   8444 // Distributed under the Boost Software License, Version 1.0. (See accompanying
   8445 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
   8446 //
   8447 // See https://github.com/philsquared/Clara for more details
   8448 
   8449 // Clara v1.1.5
   8450 
   8451 
   8452 #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
   8453 #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
   8454 #endif
   8455 
   8456 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
   8457 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
   8458 #endif
   8459 
   8460 #ifndef CLARA_CONFIG_OPTIONAL_TYPE
   8461 #ifdef __has_include
   8462 #if __has_include(<optional>) && __cplusplus >= 201703L
   8463 #include <optional>
   8464 #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
   8465 #endif
   8466 #endif
   8467 #endif
   8468 
   8469 // ----------- #included from clara_textflow.hpp -----------
   8470 
   8471 // TextFlowCpp
   8472 //
   8473 // A single-header library for wrapping and laying out basic text, by Phil Nash
   8474 //
   8475 // Distributed under the Boost Software License, Version 1.0. (See accompanying
   8476 // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
   8477 //
   8478 // This project is hosted at https://github.com/philsquared/textflowcpp
   8479 
   8480 
   8481 #include <cassert>
   8482 #include <ostream>
   8483 #include <sstream>
   8484 #include <vector>
   8485 
   8486 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
   8487 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
   8488 #endif
   8489 
   8490 namespace Catch {
   8491 namespace clara {
   8492 namespace TextFlow {
   8493 
   8494 inline auto isWhitespace(char c) -> bool {
   8495 	static std::string chars = " \t\n\r";
   8496 	return chars.find(c) != std::string::npos;
   8497 }
   8498 inline auto isBreakableBefore(char c) -> bool {
   8499 	static std::string chars = "[({<|";
   8500 	return chars.find(c) != std::string::npos;
   8501 }
   8502 inline auto isBreakableAfter(char c) -> bool {
   8503 	static std::string chars = "])}>.,:;*+-=&/\\";
   8504 	return chars.find(c) != std::string::npos;
   8505 }
   8506 
   8507 class Columns;
   8508 
   8509 class Column {
   8510 	std::vector<std::string> m_strings;
   8511 	size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
   8512 	size_t m_indent = 0;
   8513 	size_t m_initialIndent = std::string::npos;
   8514 
   8515 public:
   8516 	class iterator {
   8517 		friend Column;
   8518 
   8519 		Column const& m_column;
   8520 		size_t m_stringIndex = 0;
   8521 		size_t m_pos = 0;
   8522 
   8523 		size_t m_len = 0;
   8524 		size_t m_end = 0;
   8525 		bool m_suffix = false;
   8526 
   8527 		iterator(Column const& column, size_t stringIndex)
   8528 			: m_column(column),
   8529 			m_stringIndex(stringIndex) {}
   8530 
   8531 		auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
   8532 
   8533 		auto isBoundary(size_t at) const -> bool {
   8534 			assert(at > 0);
   8535 			assert(at <= line().size());
   8536 
   8537 			return at == line().size() ||
   8538 				(isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
   8539 				isBreakableBefore(line()[at]) ||
   8540 				isBreakableAfter(line()[at - 1]);
   8541 		}
   8542 
   8543 		void calcLength() {
   8544 			assert(m_stringIndex < m_column.m_strings.size());
   8545 
   8546 			m_suffix = false;
   8547 			auto width = m_column.m_width - indent();
   8548 			m_end = m_pos;
   8549 			if (line()[m_pos] == '\n') {
   8550 				++m_end;
   8551 			}
   8552 			while (m_end < line().size() && line()[m_end] != '\n')
   8553 				++m_end;
   8554 
   8555 			if (m_end < m_pos + width) {
   8556 				m_len = m_end - m_pos;
   8557 			} else {
   8558 				size_t len = width;
   8559 				while (len > 0 && !isBoundary(m_pos + len))
   8560 					--len;
   8561 				while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
   8562 					--len;
   8563 
   8564 				if (len > 0) {
   8565 					m_len = len;
   8566 				} else {
   8567 					m_suffix = true;
   8568 					m_len = width - 1;
   8569 				}
   8570 			}
   8571 		}
   8572 
   8573 		auto indent() const -> size_t {
   8574 			auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
   8575 			return initial == std::string::npos ? m_column.m_indent : initial;
   8576 		}
   8577 
   8578 		auto addIndentAndSuffix(std::string const &plain) const -> std::string {
   8579 			return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
   8580 		}
   8581 
   8582 	public:
   8583 		using difference_type = std::ptrdiff_t;
   8584 		using value_type = std::string;
   8585 		using pointer = value_type * ;
   8586 		using reference = value_type & ;
   8587 		using iterator_category = std::forward_iterator_tag;
   8588 
   8589 		explicit iterator(Column const& column) : m_column(column) {
   8590 			assert(m_column.m_width > m_column.m_indent);
   8591 			assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
   8592 			calcLength();
   8593 			if (m_len == 0)
   8594 				m_stringIndex++; // Empty string
   8595 		}
   8596 
   8597 		auto operator *() const -> std::string {
   8598 			assert(m_stringIndex < m_column.m_strings.size());
   8599 			assert(m_pos <= m_end);
   8600 			return addIndentAndSuffix(line().substr(m_pos, m_len));
   8601 		}
   8602 
   8603 		auto operator ++() -> iterator& {
   8604 			m_pos += m_len;
   8605 			if (m_pos < line().size() && line()[m_pos] == '\n')
   8606 				m_pos += 1;
   8607 			else
   8608 				while (m_pos < line().size() && isWhitespace(line()[m_pos]))
   8609 					++m_pos;
   8610 
   8611 			if (m_pos == line().size()) {
   8612 				m_pos = 0;
   8613 				++m_stringIndex;
   8614 			}
   8615 			if (m_stringIndex < m_column.m_strings.size())
   8616 				calcLength();
   8617 			return *this;
   8618 		}
   8619 		auto operator ++(int) -> iterator {
   8620 			iterator prev(*this);
   8621 			operator++();
   8622 			return prev;
   8623 		}
   8624 
   8625 		auto operator ==(iterator const& other) const -> bool {
   8626 			return
   8627 				m_pos == other.m_pos &&
   8628 				m_stringIndex == other.m_stringIndex &&
   8629 				&m_column == &other.m_column;
   8630 		}
   8631 		auto operator !=(iterator const& other) const -> bool {
   8632 			return !operator==(other);
   8633 		}
   8634 	};
   8635 	using const_iterator = iterator;
   8636 
   8637 	explicit Column(std::string const& text) { m_strings.push_back(text); }
   8638 
   8639 	auto width(size_t newWidth) -> Column& {
   8640 		assert(newWidth > 0);
   8641 		m_width = newWidth;
   8642 		return *this;
   8643 	}
   8644 	auto indent(size_t newIndent) -> Column& {
   8645 		m_indent = newIndent;
   8646 		return *this;
   8647 	}
   8648 	auto initialIndent(size_t newIndent) -> Column& {
   8649 		m_initialIndent = newIndent;
   8650 		return *this;
   8651 	}
   8652 
   8653 	auto width() const -> size_t { return m_width; }
   8654 	auto begin() const -> iterator { return iterator(*this); }
   8655 	auto end() const -> iterator { return { *this, m_strings.size() }; }
   8656 
   8657 	inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
   8658 		bool first = true;
   8659 		for (auto line : col) {
   8660 			if (first)
   8661 				first = false;
   8662 			else
   8663 				os << "\n";
   8664 			os << line;
   8665 		}
   8666 		return os;
   8667 	}
   8668 
   8669 	auto operator + (Column const& other)->Columns;
   8670 
   8671 	auto toString() const -> std::string {
   8672 		std::ostringstream oss;
   8673 		oss << *this;
   8674 		return oss.str();
   8675 	}
   8676 };
   8677 
   8678 class Spacer : public Column {
   8679 
   8680 public:
   8681 	explicit Spacer(size_t spaceWidth) : Column("") {
   8682 		width(spaceWidth);
   8683 	}
   8684 };
   8685 
   8686 class Columns {
   8687 	std::vector<Column> m_columns;
   8688 
   8689 public:
   8690 
   8691 	class iterator {
   8692 		friend Columns;
   8693 		struct EndTag {};
   8694 
   8695 		std::vector<Column> const& m_columns;
   8696 		std::vector<Column::iterator> m_iterators;
   8697 		size_t m_activeIterators;
   8698 
   8699 		iterator(Columns const& columns, EndTag)
   8700 			: m_columns(columns.m_columns),
   8701 			m_activeIterators(0) {
   8702 			m_iterators.reserve(m_columns.size());
   8703 
   8704 			for (auto const& col : m_columns)
   8705 				m_iterators.push_back(col.end());
   8706 		}
   8707 
   8708 	public:
   8709 		using difference_type = std::ptrdiff_t;
   8710 		using value_type = std::string;
   8711 		using pointer = value_type * ;
   8712 		using reference = value_type & ;
   8713 		using iterator_category = std::forward_iterator_tag;
   8714 
   8715 		explicit iterator(Columns const& columns)
   8716 			: m_columns(columns.m_columns),
   8717 			m_activeIterators(m_columns.size()) {
   8718 			m_iterators.reserve(m_columns.size());
   8719 
   8720 			for (auto const& col : m_columns)
   8721 				m_iterators.push_back(col.begin());
   8722 		}
   8723 
   8724 		auto operator ==(iterator const& other) const -> bool {
   8725 			return m_iterators == other.m_iterators;
   8726 		}
   8727 		auto operator !=(iterator const& other) const -> bool {
   8728 			return m_iterators != other.m_iterators;
   8729 		}
   8730 		auto operator *() const -> std::string {
   8731 			std::string row, padding;
   8732 
   8733 			for (size_t i = 0; i < m_columns.size(); ++i) {
   8734 				auto width = m_columns[i].width();
   8735 				if (m_iterators[i] != m_columns[i].end()) {
   8736 					std::string col = *m_iterators[i];
   8737 					row += padding + col;
   8738 					if (col.size() < width)
   8739 						padding = std::string(width - col.size(), ' ');
   8740 					else
   8741 						padding = "";
   8742 				} else {
   8743 					padding += std::string(width, ' ');
   8744 				}
   8745 			}
   8746 			return row;
   8747 		}
   8748 		auto operator ++() -> iterator& {
   8749 			for (size_t i = 0; i < m_columns.size(); ++i) {
   8750 				if (m_iterators[i] != m_columns[i].end())
   8751 					++m_iterators[i];
   8752 			}
   8753 			return *this;
   8754 		}
   8755 		auto operator ++(int) -> iterator {
   8756 			iterator prev(*this);
   8757 			operator++();
   8758 			return prev;
   8759 		}
   8760 	};
   8761 	using const_iterator = iterator;
   8762 
   8763 	auto begin() const -> iterator { return iterator(*this); }
   8764 	auto end() const -> iterator { return { *this, iterator::EndTag() }; }
   8765 
   8766 	auto operator += (Column const& col) -> Columns& {
   8767 		m_columns.push_back(col);
   8768 		return *this;
   8769 	}
   8770 	auto operator + (Column const& col) -> Columns {
   8771 		Columns combined = *this;
   8772 		combined += col;
   8773 		return combined;
   8774 	}
   8775 
   8776 	inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
   8777 
   8778 		bool first = true;
   8779 		for (auto line : cols) {
   8780 			if (first)
   8781 				first = false;
   8782 			else
   8783 				os << "\n";
   8784 			os << line;
   8785 		}
   8786 		return os;
   8787 	}
   8788 
   8789 	auto toString() const -> std::string {
   8790 		std::ostringstream oss;
   8791 		oss << *this;
   8792 		return oss.str();
   8793 	}
   8794 };
   8795 
   8796 inline auto Column::operator + (Column const& other) -> Columns {
   8797 	Columns cols;
   8798 	cols += *this;
   8799 	cols += other;
   8800 	return cols;
   8801 }
   8802 }
   8803 
   8804 }
   8805 }
   8806 
   8807 // ----------- end of #include from clara_textflow.hpp -----------
   8808 // ........... back in clara.hpp
   8809 
   8810 #include <cctype>
   8811 #include <string>
   8812 #include <memory>
   8813 #include <set>
   8814 #include <algorithm>
   8815 
   8816 #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
   8817 #define CATCH_PLATFORM_WINDOWS
   8818 #endif
   8819 
   8820 namespace Catch { namespace clara {
   8821 namespace detail {
   8822 
   8823     // Traits for extracting arg and return type of lambdas (for single argument lambdas)
   8824     template<typename L>
   8825     struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
   8826 
   8827     template<typename ClassT, typename ReturnT, typename... Args>
   8828     struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
   8829         static const bool isValid = false;
   8830     };
   8831 
   8832     template<typename ClassT, typename ReturnT, typename ArgT>
   8833     struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
   8834         static const bool isValid = true;
   8835         using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
   8836         using ReturnType = ReturnT;
   8837     };
   8838 
   8839     class TokenStream;
   8840 
   8841     // Transport for raw args (copied from main args, or supplied via init list for testing)
   8842     class Args {
   8843         friend TokenStream;
   8844         std::string m_exeName;
   8845         std::vector<std::string> m_args;
   8846 
   8847     public:
   8848         Args( int argc, char const* const* argv )
   8849             : m_exeName(argv[0]),
   8850               m_args(argv + 1, argv + argc) {}
   8851 
   8852         Args( std::initializer_list<std::string> args )
   8853         :   m_exeName( *args.begin() ),
   8854             m_args( args.begin()+1, args.end() )
   8855         {}
   8856 
   8857         auto exeName() const -> std::string {
   8858             return m_exeName;
   8859         }
   8860     };
   8861 
   8862     // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
   8863     // may encode an option + its argument if the : or = form is used
   8864     enum class TokenType {
   8865         Option, Argument
   8866     };
   8867     struct Token {
   8868         TokenType type;
   8869         std::string token;
   8870     };
   8871 
   8872     inline auto isOptPrefix( char c ) -> bool {
   8873         return c == '-'
   8874 #ifdef CATCH_PLATFORM_WINDOWS
   8875             || c == '/'
   8876 #endif
   8877         ;
   8878     }
   8879 
   8880     // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
   8881     class TokenStream {
   8882         using Iterator = std::vector<std::string>::const_iterator;
   8883         Iterator it;
   8884         Iterator itEnd;
   8885         std::vector<Token> m_tokenBuffer;
   8886 
   8887         void loadBuffer() {
   8888             m_tokenBuffer.resize( 0 );
   8889 
   8890             // Skip any empty strings
   8891             while( it != itEnd && it->empty() )
   8892                 ++it;
   8893 
   8894             if( it != itEnd ) {
   8895                 auto const &next = *it;
   8896                 if( isOptPrefix( next[0] ) ) {
   8897                     auto delimiterPos = next.find_first_of( " :=" );
   8898                     if( delimiterPos != std::string::npos ) {
   8899                         m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
   8900                         m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
   8901                     } else {
   8902                         if( next[1] != '-' && next.size() > 2 ) {
   8903                             std::string opt = "- ";
   8904                             for( size_t i = 1; i < next.size(); ++i ) {
   8905                                 opt[1] = next[i];
   8906                                 m_tokenBuffer.push_back( { TokenType::Option, opt } );
   8907                             }
   8908                         } else {
   8909                             m_tokenBuffer.push_back( { TokenType::Option, next } );
   8910                         }
   8911                     }
   8912                 } else {
   8913                     m_tokenBuffer.push_back( { TokenType::Argument, next } );
   8914                 }
   8915             }
   8916         }
   8917 
   8918     public:
   8919         explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
   8920 
   8921         TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
   8922             loadBuffer();
   8923         }
   8924 
   8925         explicit operator bool() const {
   8926             return !m_tokenBuffer.empty() || it != itEnd;
   8927         }
   8928 
   8929         auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
   8930 
   8931         auto operator*() const -> Token {
   8932             assert( !m_tokenBuffer.empty() );
   8933             return m_tokenBuffer.front();
   8934         }
   8935 
   8936         auto operator->() const -> Token const * {
   8937             assert( !m_tokenBuffer.empty() );
   8938             return &m_tokenBuffer.front();
   8939         }
   8940 
   8941         auto operator++() -> TokenStream & {
   8942             if( m_tokenBuffer.size() >= 2 ) {
   8943                 m_tokenBuffer.erase( m_tokenBuffer.begin() );
   8944             } else {
   8945                 if( it != itEnd )
   8946                     ++it;
   8947                 loadBuffer();
   8948             }
   8949             return *this;
   8950         }
   8951     };
   8952 
   8953     class ResultBase {
   8954     public:
   8955         enum Type {
   8956             Ok, LogicError, RuntimeError
   8957         };
   8958 
   8959     protected:
   8960         ResultBase( Type type ) : m_type( type ) {}
   8961         virtual ~ResultBase() = default;
   8962 
   8963         virtual void enforceOk() const = 0;
   8964 
   8965         Type m_type;
   8966     };
   8967 
   8968     template<typename T>
   8969     class ResultValueBase : public ResultBase {
   8970     public:
   8971         auto value() const -> T const & {
   8972             enforceOk();
   8973             return m_value;
   8974         }
   8975 
   8976     protected:
   8977         ResultValueBase( Type type ) : ResultBase( type ) {}
   8978 
   8979         ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
   8980             if( m_type == ResultBase::Ok )
   8981                 new( &m_value ) T( other.m_value );
   8982         }
   8983 
   8984         ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
   8985             new( &m_value ) T( value );
   8986         }
   8987 
   8988         auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
   8989             if( m_type == ResultBase::Ok )
   8990                 m_value.~T();
   8991             ResultBase::operator=(other);
   8992             if( m_type == ResultBase::Ok )
   8993                 new( &m_value ) T( other.m_value );
   8994             return *this;
   8995         }
   8996 
   8997         ~ResultValueBase() override {
   8998             if( m_type == Ok )
   8999                 m_value.~T();
   9000         }
   9001 
   9002         union {
   9003             T m_value;
   9004         };
   9005     };
   9006 
   9007     template<>
   9008     class ResultValueBase<void> : public ResultBase {
   9009     protected:
   9010         using ResultBase::ResultBase;
   9011     };
   9012 
   9013     template<typename T = void>
   9014     class BasicResult : public ResultValueBase<T> {
   9015     public:
   9016         template<typename U>
   9017         explicit BasicResult( BasicResult<U> const &other )
   9018         :   ResultValueBase<T>( other.type() ),
   9019             m_errorMessage( other.errorMessage() )
   9020         {
   9021             assert( type() != ResultBase::Ok );
   9022         }
   9023 
   9024         template<typename U>
   9025         static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
   9026         static auto ok() -> BasicResult { return { ResultBase::Ok }; }
   9027         static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
   9028         static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
   9029 
   9030         explicit operator bool() const { return m_type == ResultBase::Ok; }
   9031         auto type() const -> ResultBase::Type { return m_type; }
   9032         auto errorMessage() const -> std::string { return m_errorMessage; }
   9033 
   9034     protected:
   9035         void enforceOk() const override {
   9036 
   9037             // Errors shouldn't reach this point, but if they do
   9038             // the actual error message will be in m_errorMessage
   9039             assert( m_type != ResultBase::LogicError );
   9040             assert( m_type != ResultBase::RuntimeError );
   9041             if( m_type != ResultBase::Ok )
   9042                 std::abort();
   9043         }
   9044 
   9045         std::string m_errorMessage; // Only populated if resultType is an error
   9046 
   9047         BasicResult( ResultBase::Type type, std::string const &message )
   9048         :   ResultValueBase<T>(type),
   9049             m_errorMessage(message)
   9050         {
   9051             assert( m_type != ResultBase::Ok );
   9052         }
   9053 
   9054         using ResultValueBase<T>::ResultValueBase;
   9055         using ResultBase::m_type;
   9056     };
   9057 
   9058     enum class ParseResultType {
   9059         Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
   9060     };
   9061 
   9062     class ParseState {
   9063     public:
   9064 
   9065         ParseState( ParseResultType type, TokenStream const &remainingTokens )
   9066         : m_type(type),
   9067           m_remainingTokens( remainingTokens )
   9068         {}
   9069 
   9070         auto type() const -> ParseResultType { return m_type; }
   9071         auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
   9072 
   9073     private:
   9074         ParseResultType m_type;
   9075         TokenStream m_remainingTokens;
   9076     };
   9077 
   9078     using Result = BasicResult<void>;
   9079     using ParserResult = BasicResult<ParseResultType>;
   9080     using InternalParseResult = BasicResult<ParseState>;
   9081 
   9082     struct HelpColumns {
   9083         std::string left;
   9084         std::string right;
   9085     };
   9086 
   9087     template<typename T>
   9088     inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
   9089         std::stringstream ss;
   9090         ss << source;
   9091         ss >> target;
   9092         if( ss.fail() )
   9093             return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
   9094         else
   9095             return ParserResult::ok( ParseResultType::Matched );
   9096     }
   9097     inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
   9098         target = source;
   9099         return ParserResult::ok( ParseResultType::Matched );
   9100     }
   9101     inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
   9102         std::string srcLC = source;
   9103         std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower(c) ); } );
   9104         if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
   9105             target = true;
   9106         else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
   9107             target = false;
   9108         else
   9109             return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
   9110         return ParserResult::ok( ParseResultType::Matched );
   9111     }
   9112 #ifdef CLARA_CONFIG_OPTIONAL_TYPE
   9113     template<typename T>
   9114     inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
   9115         T temp;
   9116         auto result = convertInto( source, temp );
   9117         if( result )
   9118             target = std::move(temp);
   9119         return result;
   9120     }
   9121 #endif // CLARA_CONFIG_OPTIONAL_TYPE
   9122 
   9123     struct NonCopyable {
   9124         NonCopyable() = default;
   9125         NonCopyable( NonCopyable const & ) = delete;
   9126         NonCopyable( NonCopyable && ) = delete;
   9127         NonCopyable &operator=( NonCopyable const & ) = delete;
   9128         NonCopyable &operator=( NonCopyable && ) = delete;
   9129     };
   9130 
   9131     struct BoundRef : NonCopyable {
   9132         virtual ~BoundRef() = default;
   9133         virtual auto isContainer() const -> bool { return false; }
   9134         virtual auto isFlag() const -> bool { return false; }
   9135     };
   9136     struct BoundValueRefBase : BoundRef {
   9137         virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
   9138     };
   9139     struct BoundFlagRefBase : BoundRef {
   9140         virtual auto setFlag( bool flag ) -> ParserResult = 0;
   9141         virtual auto isFlag() const -> bool { return true; }
   9142     };
   9143 
   9144     template<typename T>
   9145     struct BoundValueRef : BoundValueRefBase {
   9146         T &m_ref;
   9147 
   9148         explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
   9149 
   9150         auto setValue( std::string const &arg ) -> ParserResult override {
   9151             return convertInto( arg, m_ref );
   9152         }
   9153     };
   9154 
   9155     template<typename T>
   9156     struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
   9157         std::vector<T> &m_ref;
   9158 
   9159         explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
   9160 
   9161         auto isContainer() const -> bool override { return true; }
   9162 
   9163         auto setValue( std::string const &arg ) -> ParserResult override {
   9164             T temp;
   9165             auto result = convertInto( arg, temp );
   9166             if( result )
   9167                 m_ref.push_back( temp );
   9168             return result;
   9169         }
   9170     };
   9171 
   9172     struct BoundFlagRef : BoundFlagRefBase {
   9173         bool &m_ref;
   9174 
   9175         explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
   9176 
   9177         auto setFlag( bool flag ) -> ParserResult override {
   9178             m_ref = flag;
   9179             return ParserResult::ok( ParseResultType::Matched );
   9180         }
   9181     };
   9182 
   9183     template<typename ReturnType>
   9184     struct LambdaInvoker {
   9185         static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
   9186 
   9187         template<typename L, typename ArgType>
   9188         static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
   9189             return lambda( arg );
   9190         }
   9191     };
   9192 
   9193     template<>
   9194     struct LambdaInvoker<void> {
   9195         template<typename L, typename ArgType>
   9196         static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
   9197             lambda( arg );
   9198             return ParserResult::ok( ParseResultType::Matched );
   9199         }
   9200     };
   9201 
   9202     template<typename ArgType, typename L>
   9203     inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
   9204         ArgType temp{};
   9205         auto result = convertInto( arg, temp );
   9206         return !result
   9207            ? result
   9208            : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
   9209     }
   9210 
   9211     template<typename L>
   9212     struct BoundLambda : BoundValueRefBase {
   9213         L m_lambda;
   9214 
   9215         static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
   9216         explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
   9217 
   9218         auto setValue( std::string const &arg ) -> ParserResult override {
   9219             return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
   9220         }
   9221     };
   9222 
   9223     template<typename L>
   9224     struct BoundFlagLambda : BoundFlagRefBase {
   9225         L m_lambda;
   9226 
   9227         static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
   9228         static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
   9229 
   9230         explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
   9231 
   9232         auto setFlag( bool flag ) -> ParserResult override {
   9233             return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
   9234         }
   9235     };
   9236 
   9237     enum class Optionality { Optional, Required };
   9238 
   9239     struct Parser;
   9240 
   9241     class ParserBase {
   9242     public:
   9243         virtual ~ParserBase() = default;
   9244         virtual auto validate() const -> Result { return Result::ok(); }
   9245         virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult  = 0;
   9246         virtual auto cardinality() const -> size_t { return 1; }
   9247 
   9248         auto parse( Args const &args ) const -> InternalParseResult {
   9249             return parse( args.exeName(), TokenStream( args ) );
   9250         }
   9251     };
   9252 
   9253     template<typename DerivedT>
   9254     class ComposableParserImpl : public ParserBase {
   9255     public:
   9256         template<typename T>
   9257         auto operator|( T const &other ) const -> Parser;
   9258 
   9259 		template<typename T>
   9260         auto operator+( T const &other ) const -> Parser;
   9261     };
   9262 
   9263     // Common code and state for Args and Opts
   9264     template<typename DerivedT>
   9265     class ParserRefImpl : public ComposableParserImpl<DerivedT> {
   9266     protected:
   9267         Optionality m_optionality = Optionality::Optional;
   9268         std::shared_ptr<BoundRef> m_ref;
   9269         std::string m_hint;
   9270         std::string m_description;
   9271 
   9272         explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
   9273 
   9274     public:
   9275         template<typename T>
   9276         ParserRefImpl( T &ref, std::string const &hint )
   9277         :   m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
   9278             m_hint( hint )
   9279         {}
   9280 
   9281         template<typename LambdaT>
   9282         ParserRefImpl( LambdaT const &ref, std::string const &hint )
   9283         :   m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
   9284             m_hint(hint)
   9285         {}
   9286 
   9287         auto operator()( std::string const &description ) -> DerivedT & {
   9288             m_description = description;
   9289             return static_cast<DerivedT &>( *this );
   9290         }
   9291 
   9292         auto optional() -> DerivedT & {
   9293             m_optionality = Optionality::Optional;
   9294             return static_cast<DerivedT &>( *this );
   9295         };
   9296 
   9297         auto required() -> DerivedT & {
   9298             m_optionality = Optionality::Required;
   9299             return static_cast<DerivedT &>( *this );
   9300         };
   9301 
   9302         auto isOptional() const -> bool {
   9303             return m_optionality == Optionality::Optional;
   9304         }
   9305 
   9306         auto cardinality() const -> size_t override {
   9307             if( m_ref->isContainer() )
   9308                 return 0;
   9309             else
   9310                 return 1;
   9311         }
   9312 
   9313         auto hint() const -> std::string { return m_hint; }
   9314     };
   9315 
   9316     class ExeName : public ComposableParserImpl<ExeName> {
   9317         std::shared_ptr<std::string> m_name;
   9318         std::shared_ptr<BoundValueRefBase> m_ref;
   9319 
   9320         template<typename LambdaT>
   9321         static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
   9322             return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
   9323         }
   9324 
   9325     public:
   9326         ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
   9327 
   9328         explicit ExeName( std::string &ref ) : ExeName() {
   9329             m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
   9330         }
   9331 
   9332         template<typename LambdaT>
   9333         explicit ExeName( LambdaT const& lambda ) : ExeName() {
   9334             m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
   9335         }
   9336 
   9337         // The exe name is not parsed out of the normal tokens, but is handled specially
   9338         auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
   9339             return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
   9340         }
   9341 
   9342         auto name() const -> std::string { return *m_name; }
   9343         auto set( std::string const& newName ) -> ParserResult {
   9344 
   9345             auto lastSlash = newName.find_last_of( "\\/" );
   9346             auto filename = ( lastSlash == std::string::npos )
   9347                     ? newName
   9348                     : newName.substr( lastSlash+1 );
   9349 
   9350             *m_name = filename;
   9351             if( m_ref )
   9352                 return m_ref->setValue( filename );
   9353             else
   9354                 return ParserResult::ok( ParseResultType::Matched );
   9355         }
   9356     };
   9357 
   9358     class Arg : public ParserRefImpl<Arg> {
   9359     public:
   9360         using ParserRefImpl::ParserRefImpl;
   9361 
   9362         auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
   9363             auto validationResult = validate();
   9364             if( !validationResult )
   9365                 return InternalParseResult( validationResult );
   9366 
   9367             auto remainingTokens = tokens;
   9368             auto const &token = *remainingTokens;
   9369             if( token.type != TokenType::Argument )
   9370                 return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
   9371 
   9372             assert( !m_ref->isFlag() );
   9373             auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
   9374 
   9375             auto result = valueRef->setValue( remainingTokens->token );
   9376             if( !result )
   9377                 return InternalParseResult( result );
   9378             else
   9379                 return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
   9380         }
   9381     };
   9382 
   9383     inline auto normaliseOpt( std::string const &optName ) -> std::string {
   9384 #ifdef CATCH_PLATFORM_WINDOWS
   9385         if( optName[0] == '/' )
   9386             return "-" + optName.substr( 1 );
   9387         else
   9388 #endif
   9389             return optName;
   9390     }
   9391 
   9392     class Opt : public ParserRefImpl<Opt> {
   9393     protected:
   9394         std::vector<std::string> m_optNames;
   9395 
   9396     public:
   9397         template<typename LambdaT>
   9398         explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
   9399 
   9400         explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
   9401 
   9402         template<typename LambdaT>
   9403         Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
   9404 
   9405         template<typename T>
   9406         Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
   9407 
   9408         auto operator[]( std::string const &optName ) -> Opt & {
   9409             m_optNames.push_back( optName );
   9410             return *this;
   9411         }
   9412 
   9413         auto getHelpColumns() const -> std::vector<HelpColumns> {
   9414             std::ostringstream oss;
   9415             bool first = true;
   9416             for( auto const &opt : m_optNames ) {
   9417                 if (first)
   9418                     first = false;
   9419                 else
   9420                     oss << ", ";
   9421                 oss << opt;
   9422             }
   9423             if( !m_hint.empty() )
   9424                 oss << " <" << m_hint << ">";
   9425             return { { oss.str(), m_description } };
   9426         }
   9427 
   9428         auto isMatch( std::string const &optToken ) const -> bool {
   9429             auto normalisedToken = normaliseOpt( optToken );
   9430             for( auto const &name : m_optNames ) {
   9431                 if( normaliseOpt( name ) == normalisedToken )
   9432                     return true;
   9433             }
   9434             return false;
   9435         }
   9436 
   9437         using ParserBase::parse;
   9438 
   9439         auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
   9440             auto validationResult = validate();
   9441             if( !validationResult )
   9442                 return InternalParseResult( validationResult );
   9443 
   9444             auto remainingTokens = tokens;
   9445             if( remainingTokens && remainingTokens->type == TokenType::Option ) {
   9446                 auto const &token = *remainingTokens;
   9447                 if( isMatch(token.token ) ) {
   9448                     if( m_ref->isFlag() ) {
   9449                         auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
   9450                         auto result = flagRef->setFlag( true );
   9451                         if( !result )
   9452                             return InternalParseResult( result );
   9453                         if( result.value() == ParseResultType::ShortCircuitAll )
   9454                             return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
   9455                     } else {
   9456                         auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
   9457                         ++remainingTokens;
   9458                         if( !remainingTokens )
   9459                             return InternalParseResult::runtimeError( "Expected argument following " + token.token );
   9460                         auto const &argToken = *remainingTokens;
   9461                         if( argToken.type != TokenType::Argument )
   9462                             return InternalParseResult::runtimeError( "Expected argument following " + token.token );
   9463                         auto result = valueRef->setValue( argToken.token );
   9464                         if( !result )
   9465                             return InternalParseResult( result );
   9466                         if( result.value() == ParseResultType::ShortCircuitAll )
   9467                             return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
   9468                     }
   9469                     return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
   9470                 }
   9471             }
   9472             return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
   9473         }
   9474 
   9475         auto validate() const -> Result override {
   9476             if( m_optNames.empty() )
   9477                 return Result::logicError( "No options supplied to Opt" );
   9478             for( auto const &name : m_optNames ) {
   9479                 if( name.empty() )
   9480                     return Result::logicError( "Option name cannot be empty" );
   9481 #ifdef CATCH_PLATFORM_WINDOWS
   9482                 if( name[0] != '-' && name[0] != '/' )
   9483                     return Result::logicError( "Option name must begin with '-' or '/'" );
   9484 #else
   9485                 if( name[0] != '-' )
   9486                     return Result::logicError( "Option name must begin with '-'" );
   9487 #endif
   9488             }
   9489             return ParserRefImpl::validate();
   9490         }
   9491     };
   9492 
   9493     struct Help : Opt {
   9494         Help( bool &showHelpFlag )
   9495         :   Opt([&]( bool flag ) {
   9496                 showHelpFlag = flag;
   9497                 return ParserResult::ok( ParseResultType::ShortCircuitAll );
   9498             })
   9499         {
   9500             static_cast<Opt &>( *this )
   9501                     ("display usage information")
   9502                     ["-?"]["-h"]["--help"]
   9503                     .optional();
   9504         }
   9505     };
   9506 
   9507     struct Parser : ParserBase {
   9508 
   9509         mutable ExeName m_exeName;
   9510         std::vector<Opt> m_options;
   9511         std::vector<Arg> m_args;
   9512 
   9513         auto operator|=( ExeName const &exeName ) -> Parser & {
   9514             m_exeName = exeName;
   9515             return *this;
   9516         }
   9517 
   9518         auto operator|=( Arg const &arg ) -> Parser & {
   9519             m_args.push_back(arg);
   9520             return *this;
   9521         }
   9522 
   9523         auto operator|=( Opt const &opt ) -> Parser & {
   9524             m_options.push_back(opt);
   9525             return *this;
   9526         }
   9527 
   9528         auto operator|=( Parser const &other ) -> Parser & {
   9529             m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
   9530             m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
   9531             return *this;
   9532         }
   9533 
   9534         template<typename T>
   9535         auto operator|( T const &other ) const -> Parser {
   9536             return Parser( *this ) |= other;
   9537         }
   9538 
   9539         // Forward deprecated interface with '+' instead of '|'
   9540         template<typename T>
   9541         auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
   9542         template<typename T>
   9543         auto operator+( T const &other ) const -> Parser { return operator|( other ); }
   9544 
   9545         auto getHelpColumns() const -> std::vector<HelpColumns> {
   9546             std::vector<HelpColumns> cols;
   9547             for (auto const &o : m_options) {
   9548                 auto childCols = o.getHelpColumns();
   9549                 cols.insert( cols.end(), childCols.begin(), childCols.end() );
   9550             }
   9551             return cols;
   9552         }
   9553 
   9554         void writeToStream( std::ostream &os ) const {
   9555             if (!m_exeName.name().empty()) {
   9556                 os << "usage:\n" << "  " << m_exeName.name() << " ";
   9557                 bool required = true, first = true;
   9558                 for( auto const &arg : m_args ) {
   9559                     if (first)
   9560                         first = false;
   9561                     else
   9562                         os << " ";
   9563                     if( arg.isOptional() && required ) {
   9564                         os << "[";
   9565                         required = false;
   9566                     }
   9567                     os << "<" << arg.hint() << ">";
   9568                     if( arg.cardinality() == 0 )
   9569                         os << " ... ";
   9570                 }
   9571                 if( !required )
   9572                     os << "]";
   9573                 if( !m_options.empty() )
   9574                     os << " options";
   9575                 os << "\n\nwhere options are:" << std::endl;
   9576             }
   9577 
   9578             auto rows = getHelpColumns();
   9579             size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
   9580             size_t optWidth = 0;
   9581             for( auto const &cols : rows )
   9582                 optWidth = (std::max)(optWidth, cols.left.size() + 2);
   9583 
   9584             optWidth = (std::min)(optWidth, consoleWidth/2);
   9585 
   9586             for( auto const &cols : rows ) {
   9587                 auto row =
   9588                         TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
   9589                         TextFlow::Spacer(4) +
   9590                         TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
   9591                 os << row << std::endl;
   9592             }
   9593         }
   9594 
   9595         friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
   9596             parser.writeToStream( os );
   9597             return os;
   9598         }
   9599 
   9600         auto validate() const -> Result override {
   9601             for( auto const &opt : m_options ) {
   9602                 auto result = opt.validate();
   9603                 if( !result )
   9604                     return result;
   9605             }
   9606             for( auto const &arg : m_args ) {
   9607                 auto result = arg.validate();
   9608                 if( !result )
   9609                     return result;
   9610             }
   9611             return Result::ok();
   9612         }
   9613 
   9614         using ParserBase::parse;
   9615 
   9616         auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
   9617 
   9618             struct ParserInfo {
   9619                 ParserBase const* parser = nullptr;
   9620                 size_t count = 0;
   9621             };
   9622             const size_t totalParsers = m_options.size() + m_args.size();
   9623             assert( totalParsers < 512 );
   9624             // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
   9625             ParserInfo parseInfos[512];
   9626 
   9627             {
   9628                 size_t i = 0;
   9629                 for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
   9630                 for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
   9631             }
   9632 
   9633             m_exeName.set( exeName );
   9634 
   9635             auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
   9636             while( result.value().remainingTokens() ) {
   9637                 bool tokenParsed = false;
   9638 
   9639                 for( size_t i = 0; i < totalParsers; ++i ) {
   9640                     auto&  parseInfo = parseInfos[i];
   9641                     if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
   9642                         result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
   9643                         if (!result)
   9644                             return result;
   9645                         if (result.value().type() != ParseResultType::NoMatch) {
   9646                             tokenParsed = true;
   9647                             ++parseInfo.count;
   9648                             break;
   9649                         }
   9650                     }
   9651                 }
   9652 
   9653                 if( result.value().type() == ParseResultType::ShortCircuitAll )
   9654                     return result;
   9655                 if( !tokenParsed )
   9656                     return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
   9657             }
   9658             // !TBD Check missing required options
   9659             return result;
   9660         }
   9661     };
   9662 
   9663     template<typename DerivedT>
   9664     template<typename T>
   9665     auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
   9666         return Parser() | static_cast<DerivedT const &>( *this ) | other;
   9667     }
   9668 } // namespace detail
   9669 
   9670 // A Combined parser
   9671 using detail::Parser;
   9672 
   9673 // A parser for options
   9674 using detail::Opt;
   9675 
   9676 // A parser for arguments
   9677 using detail::Arg;
   9678 
   9679 // Wrapper for argc, argv from main()
   9680 using detail::Args;
   9681 
   9682 // Specifies the name of the executable
   9683 using detail::ExeName;
   9684 
   9685 // Convenience wrapper for option parser that specifies the help option
   9686 using detail::Help;
   9687 
   9688 // enum of result types from a parse
   9689 using detail::ParseResultType;
   9690 
   9691 // Result type for parser operation
   9692 using detail::ParserResult;
   9693 
   9694 }} // namespace Catch::clara
   9695 
   9696 // end clara.hpp
   9697 #ifdef __clang__
   9698 #pragma clang diagnostic pop
   9699 #endif
   9700 
   9701 // Restore Clara's value for console width, if present
   9702 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
   9703 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
   9704 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
   9705 #endif
   9706 
   9707 // end catch_clara.h
   9708 namespace Catch {
   9709 
   9710     clara::Parser makeCommandLineParser( ConfigData& config );
   9711 
   9712 } // end namespace Catch
   9713 
   9714 // end catch_commandline.h
   9715 #include <fstream>
   9716 #include <ctime>
   9717 
   9718 namespace Catch {
   9719 
   9720     clara::Parser makeCommandLineParser( ConfigData& config ) {
   9721 
   9722         using namespace clara;
   9723 
   9724         auto const setWarning = [&]( std::string const& warning ) {
   9725                 auto warningSet = [&]() {
   9726                     if( warning == "NoAssertions" )
   9727                         return WarnAbout::NoAssertions;
   9728 
   9729                     if ( warning == "NoTests" )
   9730                         return WarnAbout::NoTests;
   9731 
   9732                     return WarnAbout::Nothing;
   9733                 }();
   9734 
   9735                 if (warningSet == WarnAbout::Nothing)
   9736                     return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
   9737                 config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
   9738                 return ParserResult::ok( ParseResultType::Matched );
   9739             };
   9740         auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
   9741                 std::ifstream f( filename.c_str() );
   9742                 if( !f.is_open() )
   9743                     return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
   9744 
   9745                 std::string line;
   9746                 while( std::getline( f, line ) ) {
   9747                     line = trim(line);
   9748                     if( !line.empty() && !startsWith( line, '#' ) ) {
   9749                         if( !startsWith( line, '"' ) )
   9750                             line = '"' + line + '"';
   9751                         config.testsOrTags.push_back( line );
   9752                         config.testsOrTags.emplace_back( "," );
   9753                     }
   9754                 }
   9755                 //Remove comma in the end
   9756                 if(!config.testsOrTags.empty())
   9757                     config.testsOrTags.erase( config.testsOrTags.end()-1 );
   9758 
   9759                 return ParserResult::ok( ParseResultType::Matched );
   9760             };
   9761         auto const setTestOrder = [&]( std::string const& order ) {
   9762                 if( startsWith( "declared", order ) )
   9763                     config.runOrder = RunTests::InDeclarationOrder;
   9764                 else if( startsWith( "lexical", order ) )
   9765                     config.runOrder = RunTests::InLexicographicalOrder;
   9766                 else if( startsWith( "random", order ) )
   9767                     config.runOrder = RunTests::InRandomOrder;
   9768                 else
   9769                     return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
   9770                 return ParserResult::ok( ParseResultType::Matched );
   9771             };
   9772         auto const setRngSeed = [&]( std::string const& seed ) {
   9773                 if( seed != "time" )
   9774                     return clara::detail::convertInto( seed, config.rngSeed );
   9775                 config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
   9776                 return ParserResult::ok( ParseResultType::Matched );
   9777             };
   9778         auto const setColourUsage = [&]( std::string const& useColour ) {
   9779                     auto mode = toLower( useColour );
   9780 
   9781                     if( mode == "yes" )
   9782                         config.useColour = UseColour::Yes;
   9783                     else if( mode == "no" )
   9784                         config.useColour = UseColour::No;
   9785                     else if( mode == "auto" )
   9786                         config.useColour = UseColour::Auto;
   9787                     else
   9788                         return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
   9789                 return ParserResult::ok( ParseResultType::Matched );
   9790             };
   9791         auto const setWaitForKeypress = [&]( std::string const& keypress ) {
   9792                 auto keypressLc = toLower( keypress );
   9793                 if (keypressLc == "never")
   9794                     config.waitForKeypress = WaitForKeypress::Never;
   9795                 else if( keypressLc == "start" )
   9796                     config.waitForKeypress = WaitForKeypress::BeforeStart;
   9797                 else if( keypressLc == "exit" )
   9798                     config.waitForKeypress = WaitForKeypress::BeforeExit;
   9799                 else if( keypressLc == "both" )
   9800                     config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
   9801                 else
   9802                     return ParserResult::runtimeError( "keypress argument must be one of: never, start, exit or both. '" + keypress + "' not recognised" );
   9803             return ParserResult::ok( ParseResultType::Matched );
   9804             };
   9805         auto const setVerbosity = [&]( std::string const& verbosity ) {
   9806             auto lcVerbosity = toLower( verbosity );
   9807             if( lcVerbosity == "quiet" )
   9808                 config.verbosity = Verbosity::Quiet;
   9809             else if( lcVerbosity == "normal" )
   9810                 config.verbosity = Verbosity::Normal;
   9811             else if( lcVerbosity == "high" )
   9812                 config.verbosity = Verbosity::High;
   9813             else
   9814                 return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
   9815             return ParserResult::ok( ParseResultType::Matched );
   9816         };
   9817         auto const setReporter = [&]( std::string const& reporter ) {
   9818             IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
   9819 
   9820             auto lcReporter = toLower( reporter );
   9821             auto result = factories.find( lcReporter );
   9822 
   9823             if( factories.end() != result )
   9824                 config.reporterName = lcReporter;
   9825             else
   9826                 return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
   9827             return ParserResult::ok( ParseResultType::Matched );
   9828         };
   9829 
   9830         auto cli
   9831             = ExeName( config.processName )
   9832             | Help( config.showHelp )
   9833             | Opt( config.listTests )
   9834                 ["-l"]["--list-tests"]
   9835                 ( "list all/matching test cases" )
   9836             | Opt( config.listTags )
   9837                 ["-t"]["--list-tags"]
   9838                 ( "list all/matching tags" )
   9839             | Opt( config.showSuccessfulTests )
   9840                 ["-s"]["--success"]
   9841                 ( "include successful tests in output" )
   9842             | Opt( config.shouldDebugBreak )
   9843                 ["-b"]["--break"]
   9844                 ( "break into debugger on failure" )
   9845             | Opt( config.noThrow )
   9846                 ["-e"]["--nothrow"]
   9847                 ( "skip exception tests" )
   9848             | Opt( config.showInvisibles )
   9849                 ["-i"]["--invisibles"]
   9850                 ( "show invisibles (tabs, newlines)" )
   9851             | Opt( config.outputFilename, "filename" )
   9852                 ["-o"]["--out"]
   9853                 ( "output filename" )
   9854             | Opt( setReporter, "name" )
   9855                 ["-r"]["--reporter"]
   9856                 ( "reporter to use (defaults to console)" )
   9857             | Opt( config.name, "name" )
   9858                 ["-n"]["--name"]
   9859                 ( "suite name" )
   9860             | Opt( [&]( bool ){ config.abortAfter = 1; } )
   9861                 ["-a"]["--abort"]
   9862                 ( "abort at first failure" )
   9863             | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
   9864                 ["-x"]["--abortx"]
   9865                 ( "abort after x failures" )
   9866             | Opt( setWarning, "warning name" )
   9867                 ["-w"]["--warn"]
   9868                 ( "enable warnings" )
   9869             | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
   9870                 ["-d"]["--durations"]
   9871                 ( "show test durations" )
   9872             | Opt( config.minDuration, "seconds" )
   9873                 ["-D"]["--min-duration"]
   9874                 ( "show test durations for tests taking at least the given number of seconds" )
   9875             | Opt( loadTestNamesFromFile, "filename" )
   9876                 ["-f"]["--input-file"]
   9877                 ( "load test names to run from a file" )
   9878             | Opt( config.filenamesAsTags )
   9879                 ["-#"]["--filenames-as-tags"]
   9880                 ( "adds a tag for the filename" )
   9881             | Opt( config.sectionsToRun, "section name" )
   9882                 ["-c"]["--section"]
   9883                 ( "specify section to run" )
   9884             | Opt( setVerbosity, "quiet|normal|high" )
   9885                 ["-v"]["--verbosity"]
   9886                 ( "set output verbosity" )
   9887             | Opt( config.listTestNamesOnly )
   9888                 ["--list-test-names-only"]
   9889                 ( "list all/matching test cases names only" )
   9890             | Opt( config.listReporters )
   9891                 ["--list-reporters"]
   9892                 ( "list all reporters" )
   9893             | Opt( setTestOrder, "decl|lex|rand" )
   9894                 ["--order"]
   9895                 ( "test case order (defaults to decl)" )
   9896             | Opt( setRngSeed, "'time'|number" )
   9897                 ["--rng-seed"]
   9898                 ( "set a specific seed for random numbers" )
   9899             | Opt( setColourUsage, "yes|no" )
   9900                 ["--use-colour"]
   9901                 ( "should output be colourised" )
   9902             | Opt( config.libIdentify )
   9903                 ["--libidentify"]
   9904                 ( "report name and version according to libidentify standard" )
   9905             | Opt( setWaitForKeypress, "never|start|exit|both" )
   9906                 ["--wait-for-keypress"]
   9907                 ( "waits for a keypress before exiting" )
   9908             | Opt( config.benchmarkSamples, "samples" )
   9909                 ["--benchmark-samples"]
   9910                 ( "number of samples to collect (default: 100)" )
   9911             | Opt( config.benchmarkResamples, "resamples" )
   9912                 ["--benchmark-resamples"]
   9913                 ( "number of resamples for the bootstrap (default: 100000)" )
   9914             | Opt( config.benchmarkConfidenceInterval, "confidence interval" )
   9915                 ["--benchmark-confidence-interval"]
   9916                 ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" )
   9917             | Opt( config.benchmarkNoAnalysis )
   9918                 ["--benchmark-no-analysis"]
   9919                 ( "perform only measurements; do not perform any analysis" )
   9920             | Opt( config.benchmarkWarmupTime, "benchmarkWarmupTime" )
   9921                 ["--benchmark-warmup-time"]
   9922                 ( "amount of time in milliseconds spent on warming up each test (default: 100)" )
   9923             | Arg( config.testsOrTags, "test name|pattern|tags" )
   9924                 ( "which test or tests to use" );
   9925 
   9926         return cli;
   9927     }
   9928 
   9929 } // end namespace Catch
   9930 // end catch_commandline.cpp
   9931 // start catch_common.cpp
   9932 
   9933 #include <cstring>
   9934 #include <ostream>
   9935 
   9936 namespace Catch {
   9937 
   9938     bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
   9939         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
   9940     }
   9941     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
   9942         // We can assume that the same file will usually have the same pointer.
   9943         // Thus, if the pointers are the same, there is no point in calling the strcmp
   9944         return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
   9945     }
   9946 
   9947     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
   9948 #ifndef __GNUG__
   9949         os << info.file << '(' << info.line << ')';
   9950 #else
   9951         os << info.file << ':' << info.line;
   9952 #endif
   9953         return os;
   9954     }
   9955 
   9956     std::string StreamEndStop::operator+() const {
   9957         return std::string();
   9958     }
   9959 
   9960     NonCopyable::NonCopyable() = default;
   9961     NonCopyable::~NonCopyable() = default;
   9962 
   9963 }
   9964 // end catch_common.cpp
   9965 // start catch_config.cpp
   9966 
   9967 namespace Catch {
   9968 
   9969     Config::Config( ConfigData const& data )
   9970     :   m_data( data ),
   9971         m_stream( openStream() )
   9972     {
   9973         // We need to trim filter specs to avoid trouble with superfluous
   9974         // whitespace (esp. important for bdd macros, as those are manually
   9975         // aligned with whitespace).
   9976 
   9977         for (auto& elem : m_data.testsOrTags) {
   9978             elem = trim(elem);
   9979         }
   9980         for (auto& elem : m_data.sectionsToRun) {
   9981             elem = trim(elem);
   9982         }
   9983 
   9984         TestSpecParser parser(ITagAliasRegistry::get());
   9985         if (!m_data.testsOrTags.empty()) {
   9986             m_hasTestFilters = true;
   9987             for (auto const& testOrTags : m_data.testsOrTags) {
   9988                 parser.parse(testOrTags);
   9989             }
   9990         }
   9991         m_testSpec = parser.testSpec();
   9992     }
   9993 
   9994     std::string const& Config::getFilename() const {
   9995         return m_data.outputFilename ;
   9996     }
   9997 
   9998     bool Config::listTests() const          { return m_data.listTests; }
   9999     bool Config::listTestNamesOnly() const  { return m_data.listTestNamesOnly; }
  10000     bool Config::listTags() const           { return m_data.listTags; }
  10001     bool Config::listReporters() const      { return m_data.listReporters; }
  10002 
  10003     std::string Config::getProcessName() const { return m_data.processName; }
  10004     std::string const& Config::getReporterName() const { return m_data.reporterName; }
  10005 
  10006     std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
  10007     std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
  10008 
  10009     TestSpec const& Config::testSpec() const { return m_testSpec; }
  10010     bool Config::hasTestFilters() const { return m_hasTestFilters; }
  10011 
  10012     bool Config::showHelp() const { return m_data.showHelp; }
  10013 
  10014     // IConfig interface
  10015     bool Config::allowThrows() const                   { return !m_data.noThrow; }
  10016     std::ostream& Config::stream() const               { return m_stream->stream(); }
  10017     std::string Config::name() const                   { return m_data.name.empty() ? m_data.processName : m_data.name; }
  10018     bool Config::includeSuccessfulResults() const      { return m_data.showSuccessfulTests; }
  10019     bool Config::warnAboutMissingAssertions() const    { return !!(m_data.warnings & WarnAbout::NoAssertions); }
  10020     bool Config::warnAboutNoTests() const              { return !!(m_data.warnings & WarnAbout::NoTests); }
  10021     ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
  10022     double Config::minDuration() const                 { return m_data.minDuration; }
  10023     RunTests::InWhatOrder Config::runOrder() const     { return m_data.runOrder; }
  10024     unsigned int Config::rngSeed() const               { return m_data.rngSeed; }
  10025     UseColour::YesOrNo Config::useColour() const       { return m_data.useColour; }
  10026     bool Config::shouldDebugBreak() const              { return m_data.shouldDebugBreak; }
  10027     int Config::abortAfter() const                     { return m_data.abortAfter; }
  10028     bool Config::showInvisibles() const                { return m_data.showInvisibles; }
  10029     Verbosity Config::verbosity() const                { return m_data.verbosity; }
  10030 
  10031     bool Config::benchmarkNoAnalysis() const                      { return m_data.benchmarkNoAnalysis; }
  10032     int Config::benchmarkSamples() const                          { return m_data.benchmarkSamples; }
  10033     double Config::benchmarkConfidenceInterval() const            { return m_data.benchmarkConfidenceInterval; }
  10034     unsigned int Config::benchmarkResamples() const               { return m_data.benchmarkResamples; }
  10035     std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }
  10036 
  10037     IStream const* Config::openStream() {
  10038         return Catch::makeStream(m_data.outputFilename);
  10039     }
  10040 
  10041 } // end namespace Catch
  10042 // end catch_config.cpp
  10043 // start catch_console_colour.cpp
  10044 
  10045 #if defined(__clang__)
  10046 #    pragma clang diagnostic push
  10047 #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  10048 #endif
  10049 
  10050 // start catch_errno_guard.h
  10051 
  10052 namespace Catch {
  10053 
  10054     class ErrnoGuard {
  10055     public:
  10056         ErrnoGuard();
  10057         ~ErrnoGuard();
  10058     private:
  10059         int m_oldErrno;
  10060     };
  10061 
  10062 }
  10063 
  10064 // end catch_errno_guard.h
  10065 #include <sstream>
  10066 
  10067 namespace Catch {
  10068     namespace {
  10069 
  10070         struct IColourImpl {
  10071             virtual ~IColourImpl() = default;
  10072             virtual void use( Colour::Code _colourCode ) = 0;
  10073         };
  10074 
  10075         struct NoColourImpl : IColourImpl {
  10076             void use( Colour::Code ) override {}
  10077 
  10078             static IColourImpl* instance() {
  10079                 static NoColourImpl s_instance;
  10080                 return &s_instance;
  10081             }
  10082         };
  10083 
  10084     } // anon namespace
  10085 } // namespace Catch
  10086 
  10087 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
  10088 #   ifdef CATCH_PLATFORM_WINDOWS
  10089 #       define CATCH_CONFIG_COLOUR_WINDOWS
  10090 #   else
  10091 #       define CATCH_CONFIG_COLOUR_ANSI
  10092 #   endif
  10093 #endif
  10094 
  10095 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
  10096 
  10097 namespace Catch {
  10098 namespace {
  10099 
  10100     class Win32ColourImpl : public IColourImpl {
  10101     public:
  10102         Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
  10103         {
  10104             CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
  10105             GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
  10106             originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
  10107             originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
  10108         }
  10109 
  10110         void use( Colour::Code _colourCode ) override {
  10111             switch( _colourCode ) {
  10112                 case Colour::None:      return setTextAttribute( originalForegroundAttributes );
  10113                 case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
  10114                 case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
  10115                 case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
  10116                 case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
  10117                 case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
  10118                 case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
  10119                 case Colour::Grey:      return setTextAttribute( 0 );
  10120 
  10121                 case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
  10122                 case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
  10123                 case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
  10124                 case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
  10125                 case Colour::BrightYellow:  return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
  10126 
  10127                 case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
  10128 
  10129                 default:
  10130                     CATCH_ERROR( "Unknown colour requested" );
  10131             }
  10132         }
  10133 
  10134     private:
  10135         void setTextAttribute( WORD _textAttribute ) {
  10136             SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
  10137         }
  10138         HANDLE stdoutHandle;
  10139         WORD originalForegroundAttributes;
  10140         WORD originalBackgroundAttributes;
  10141     };
  10142 
  10143     IColourImpl* platformColourInstance() {
  10144         static Win32ColourImpl s_instance;
  10145 
  10146         IConfigPtr config = getCurrentContext().getConfig();
  10147         UseColour::YesOrNo colourMode = config
  10148             ? config->useColour()
  10149             : UseColour::Auto;
  10150         if( colourMode == UseColour::Auto )
  10151             colourMode = UseColour::Yes;
  10152         return colourMode == UseColour::Yes
  10153             ? &s_instance
  10154             : NoColourImpl::instance();
  10155     }
  10156 
  10157 } // end anon namespace
  10158 } // end namespace Catch
  10159 
  10160 #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
  10161 
  10162 #include <unistd.h>
  10163 
  10164 namespace Catch {
  10165 namespace {
  10166 
  10167     // use POSIX/ ANSI console terminal codes
  10168     // Thanks to Adam Strzelecki for original contribution
  10169     // (http://github.com/nanoant)
  10170     // https://github.com/philsquared/Catch/pull/131
  10171     class PosixColourImpl : public IColourImpl {
  10172     public:
  10173         void use( Colour::Code _colourCode ) override {
  10174             switch( _colourCode ) {
  10175                 case Colour::None:
  10176                 case Colour::White:     return setColour( "[0m" );
  10177                 case Colour::Red:       return setColour( "[0;31m" );
  10178                 case Colour::Green:     return setColour( "[0;32m" );
  10179                 case Colour::Blue:      return setColour( "[0;34m" );
  10180                 case Colour::Cyan:      return setColour( "[0;36m" );
  10181                 case Colour::Yellow:    return setColour( "[0;33m" );
  10182                 case Colour::Grey:      return setColour( "[1;30m" );
  10183 
  10184                 case Colour::LightGrey:     return setColour( "[0;37m" );
  10185                 case Colour::BrightRed:     return setColour( "[1;31m" );
  10186                 case Colour::BrightGreen:   return setColour( "[1;32m" );
  10187                 case Colour::BrightWhite:   return setColour( "[1;37m" );
  10188                 case Colour::BrightYellow:  return setColour( "[1;33m" );
  10189 
  10190                 case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
  10191                 default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
  10192             }
  10193         }
  10194         static IColourImpl* instance() {
  10195             static PosixColourImpl s_instance;
  10196             return &s_instance;
  10197         }
  10198 
  10199     private:
  10200         void setColour( const char* _escapeCode ) {
  10201             getCurrentContext().getConfig()->stream()
  10202                 << '\033' << _escapeCode;
  10203         }
  10204     };
  10205 
  10206     bool useColourOnPlatform() {
  10207         return
  10208 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
  10209             !isDebuggerActive() &&
  10210 #endif
  10211 #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
  10212             isatty(STDOUT_FILENO)
  10213 #else
  10214             false
  10215 #endif
  10216             ;
  10217     }
  10218     IColourImpl* platformColourInstance() {
  10219         ErrnoGuard guard;
  10220         IConfigPtr config = getCurrentContext().getConfig();
  10221         UseColour::YesOrNo colourMode = config
  10222             ? config->useColour()
  10223             : UseColour::Auto;
  10224         if( colourMode == UseColour::Auto )
  10225             colourMode = useColourOnPlatform()
  10226                 ? UseColour::Yes
  10227                 : UseColour::No;
  10228         return colourMode == UseColour::Yes
  10229             ? PosixColourImpl::instance()
  10230             : NoColourImpl::instance();
  10231     }
  10232 
  10233 } // end anon namespace
  10234 } // end namespace Catch
  10235 
  10236 #else  // not Windows or ANSI ///////////////////////////////////////////////
  10237 
  10238 namespace Catch {
  10239 
  10240     static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
  10241 
  10242 } // end namespace Catch
  10243 
  10244 #endif // Windows/ ANSI/ None
  10245 
  10246 namespace Catch {
  10247 
  10248     Colour::Colour( Code _colourCode ) { use( _colourCode ); }
  10249     Colour::Colour( Colour&& other ) noexcept {
  10250         m_moved = other.m_moved;
  10251         other.m_moved = true;
  10252     }
  10253     Colour& Colour::operator=( Colour&& other ) noexcept {
  10254         m_moved = other.m_moved;
  10255         other.m_moved  = true;
  10256         return *this;
  10257     }
  10258 
  10259     Colour::~Colour(){ if( !m_moved ) use( None ); }
  10260 
  10261     void Colour::use( Code _colourCode ) {
  10262         static IColourImpl* impl = platformColourInstance();
  10263         // Strictly speaking, this cannot possibly happen.
  10264         // However, under some conditions it does happen (see #1626),
  10265         // and this change is small enough that we can let practicality
  10266         // triumph over purity in this case.
  10267         if (impl != nullptr) {
  10268             impl->use( _colourCode );
  10269         }
  10270     }
  10271 
  10272     std::ostream& operator << ( std::ostream& os, Colour const& ) {
  10273         return os;
  10274     }
  10275 
  10276 } // end namespace Catch
  10277 
  10278 #if defined(__clang__)
  10279 #    pragma clang diagnostic pop
  10280 #endif
  10281 
  10282 // end catch_console_colour.cpp
  10283 // start catch_context.cpp
  10284 
  10285 namespace Catch {
  10286 
  10287     class Context : public IMutableContext, NonCopyable {
  10288 
  10289     public: // IContext
  10290         IResultCapture* getResultCapture() override {
  10291             return m_resultCapture;
  10292         }
  10293         IRunner* getRunner() override {
  10294             return m_runner;
  10295         }
  10296 
  10297         IConfigPtr const& getConfig() const override {
  10298             return m_config;
  10299         }
  10300 
  10301         ~Context() override;
  10302 
  10303     public: // IMutableContext
  10304         void setResultCapture( IResultCapture* resultCapture ) override {
  10305             m_resultCapture = resultCapture;
  10306         }
  10307         void setRunner( IRunner* runner ) override {
  10308             m_runner = runner;
  10309         }
  10310         void setConfig( IConfigPtr const& config ) override {
  10311             m_config = config;
  10312         }
  10313 
  10314         friend IMutableContext& getCurrentMutableContext();
  10315 
  10316     private:
  10317         IConfigPtr m_config;
  10318         IRunner* m_runner = nullptr;
  10319         IResultCapture* m_resultCapture = nullptr;
  10320     };
  10321 
  10322     IMutableContext *IMutableContext::currentContext = nullptr;
  10323 
  10324     void IMutableContext::createContext()
  10325     {
  10326         currentContext = new Context();
  10327     }
  10328 
  10329     void cleanUpContext() {
  10330         delete IMutableContext::currentContext;
  10331         IMutableContext::currentContext = nullptr;
  10332     }
  10333     IContext::~IContext() = default;
  10334     IMutableContext::~IMutableContext() = default;
  10335     Context::~Context() = default;
  10336 
  10337     SimplePcg32& rng() {
  10338         static SimplePcg32 s_rng;
  10339         return s_rng;
  10340     }
  10341 
  10342 }
  10343 // end catch_context.cpp
  10344 // start catch_debug_console.cpp
  10345 
  10346 // start catch_debug_console.h
  10347 
  10348 #include <string>
  10349 
  10350 namespace Catch {
  10351     void writeToDebugConsole( std::string const& text );
  10352 }
  10353 
  10354 // end catch_debug_console.h
  10355 #if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
  10356 #include <android/log.h>
  10357 
  10358     namespace Catch {
  10359         void writeToDebugConsole( std::string const& text ) {
  10360             __android_log_write( ANDROID_LOG_DEBUG, "Catch", text.c_str() );
  10361         }
  10362     }
  10363 
  10364 #elif defined(CATCH_PLATFORM_WINDOWS)
  10365 
  10366     namespace Catch {
  10367         void writeToDebugConsole( std::string const& text ) {
  10368             ::OutputDebugStringA( text.c_str() );
  10369         }
  10370     }
  10371 
  10372 #else
  10373 
  10374     namespace Catch {
  10375         void writeToDebugConsole( std::string const& text ) {
  10376             // !TBD: Need a version for Mac/ XCode and other IDEs
  10377             Catch::cout() << text;
  10378         }
  10379     }
  10380 
  10381 #endif // Platform
  10382 // end catch_debug_console.cpp
  10383 // start catch_debugger.cpp
  10384 
  10385 #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
  10386 
  10387 #  include <cassert>
  10388 #  include <sys/types.h>
  10389 #  include <unistd.h>
  10390 #  include <cstddef>
  10391 #  include <ostream>
  10392 
  10393 #ifdef __apple_build_version__
  10394     // These headers will only compile with AppleClang (XCode)
  10395     // For other compilers (Clang, GCC, ... ) we need to exclude them
  10396 #  include <sys/sysctl.h>
  10397 #endif
  10398 
  10399     namespace Catch {
  10400         #ifdef __apple_build_version__
  10401         // The following function is taken directly from the following technical note:
  10402         // https://developer.apple.com/library/archive/qa/qa1361/_index.html
  10403 
  10404         // Returns true if the current process is being debugged (either
  10405         // running under the debugger or has a debugger attached post facto).
  10406         bool isDebuggerActive(){
  10407             int                 mib[4];
  10408             struct kinfo_proc   info;
  10409             std::size_t         size;
  10410 
  10411             // Initialize the flags so that, if sysctl fails for some bizarre
  10412             // reason, we get a predictable result.
  10413 
  10414             info.kp_proc.p_flag = 0;
  10415 
  10416             // Initialize mib, which tells sysctl the info we want, in this case
  10417             // we're looking for information about a specific process ID.
  10418 
  10419             mib[0] = CTL_KERN;
  10420             mib[1] = KERN_PROC;
  10421             mib[2] = KERN_PROC_PID;
  10422             mib[3] = getpid();
  10423 
  10424             // Call sysctl.
  10425 
  10426             size = sizeof(info);
  10427             if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
  10428                 Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
  10429                 return false;
  10430             }
  10431 
  10432             // We're being debugged if the P_TRACED flag is set.
  10433 
  10434             return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
  10435         }
  10436         #else
  10437         bool isDebuggerActive() {
  10438             // We need to find another way to determine this for non-appleclang compilers on macOS
  10439             return false;
  10440         }
  10441         #endif
  10442     } // namespace Catch
  10443 
  10444 #elif defined(CATCH_PLATFORM_LINUX)
  10445     #include <fstream>
  10446     #include <string>
  10447 
  10448     namespace Catch{
  10449         // The standard POSIX way of detecting a debugger is to attempt to
  10450         // ptrace() the process, but this needs to be done from a child and not
  10451         // this process itself to still allow attaching to this process later
  10452         // if wanted, so is rather heavy. Under Linux we have the PID of the
  10453         // "debugger" (which doesn't need to be gdb, of course, it could also
  10454         // be strace, for example) in /proc/$PID/status, so just get it from
  10455         // there instead.
  10456         bool isDebuggerActive(){
  10457             // Libstdc++ has a bug, where std::ifstream sets errno to 0
  10458             // This way our users can properly assert over errno values
  10459             ErrnoGuard guard;
  10460             std::ifstream in("/proc/self/status");
  10461             for( std::string line; std::getline(in, line); ) {
  10462                 static const int PREFIX_LEN = 11;
  10463                 if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
  10464                     // We're traced if the PID is not 0 and no other PID starts
  10465                     // with 0 digit, so it's enough to check for just a single
  10466                     // character.
  10467                     return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
  10468                 }
  10469             }
  10470 
  10471             return false;
  10472         }
  10473     } // namespace Catch
  10474 #elif defined(_MSC_VER)
  10475     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  10476     namespace Catch {
  10477         bool isDebuggerActive() {
  10478             return IsDebuggerPresent() != 0;
  10479         }
  10480     }
  10481 #elif defined(__MINGW32__)
  10482     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  10483     namespace Catch {
  10484         bool isDebuggerActive() {
  10485             return IsDebuggerPresent() != 0;
  10486         }
  10487     }
  10488 #else
  10489     namespace Catch {
  10490        bool isDebuggerActive() { return false; }
  10491     }
  10492 #endif // Platform
  10493 // end catch_debugger.cpp
  10494 // start catch_decomposer.cpp
  10495 
  10496 namespace Catch {
  10497 
  10498     ITransientExpression::~ITransientExpression() = default;
  10499 
  10500     void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
  10501         if( lhs.size() + rhs.size() < 40 &&
  10502                 lhs.find('\n') == std::string::npos &&
  10503                 rhs.find('\n') == std::string::npos )
  10504             os << lhs << " " << op << " " << rhs;
  10505         else
  10506             os << lhs << "\n" << op << "\n" << rhs;
  10507     }
  10508 }
  10509 // end catch_decomposer.cpp
  10510 // start catch_enforce.cpp
  10511 
  10512 #include <stdexcept>
  10513 
  10514 namespace Catch {
  10515 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
  10516     [[noreturn]]
  10517     void throw_exception(std::exception const& e) {
  10518         Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
  10519                       << "The message was: " << e.what() << '\n';
  10520         std::terminate();
  10521     }
  10522 #endif
  10523 
  10524     [[noreturn]]
  10525     void throw_logic_error(std::string const& msg) {
  10526         throw_exception(std::logic_error(msg));
  10527     }
  10528 
  10529     [[noreturn]]
  10530     void throw_domain_error(std::string const& msg) {
  10531         throw_exception(std::domain_error(msg));
  10532     }
  10533 
  10534     [[noreturn]]
  10535     void throw_runtime_error(std::string const& msg) {
  10536         throw_exception(std::runtime_error(msg));
  10537     }
  10538 
  10539 } // namespace Catch;
  10540 // end catch_enforce.cpp
  10541 // start catch_enum_values_registry.cpp
  10542 // start catch_enum_values_registry.h
  10543 
  10544 #include <vector>
  10545 #include <memory>
  10546 
  10547 namespace Catch {
  10548 
  10549     namespace Detail {
  10550 
  10551         std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
  10552 
  10553         class EnumValuesRegistry : public IMutableEnumValuesRegistry {
  10554 
  10555             std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
  10556 
  10557             EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
  10558         };
  10559 
  10560         std::vector<StringRef> parseEnums( StringRef enums );
  10561 
  10562     } // Detail
  10563 
  10564 } // Catch
  10565 
  10566 // end catch_enum_values_registry.h
  10567 
  10568 #include <map>
  10569 #include <cassert>
  10570 
  10571 namespace Catch {
  10572 
  10573     IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
  10574 
  10575     namespace Detail {
  10576 
  10577         namespace {
  10578             // Extracts the actual name part of an enum instance
  10579             // In other words, it returns the Blue part of Bikeshed::Colour::Blue
  10580             StringRef extractInstanceName(StringRef enumInstance) {
  10581                 // Find last occurence of ":"
  10582                 size_t name_start = enumInstance.size();
  10583                 while (name_start > 0 && enumInstance[name_start - 1] != ':') {
  10584                     --name_start;
  10585                 }
  10586                 return enumInstance.substr(name_start, enumInstance.size() - name_start);
  10587             }
  10588         }
  10589 
  10590         std::vector<StringRef> parseEnums( StringRef enums ) {
  10591             auto enumValues = splitStringRef( enums, ',' );
  10592             std::vector<StringRef> parsed;
  10593             parsed.reserve( enumValues.size() );
  10594             for( auto const& enumValue : enumValues ) {
  10595                 parsed.push_back(trim(extractInstanceName(enumValue)));
  10596             }
  10597             return parsed;
  10598         }
  10599 
  10600         EnumInfo::~EnumInfo() {}
  10601 
  10602         StringRef EnumInfo::lookup( int value ) const {
  10603             for( auto const& valueToName : m_values ) {
  10604                 if( valueToName.first == value )
  10605                     return valueToName.second;
  10606             }
  10607             return "{** unexpected enum value **}"_sr;
  10608         }
  10609 
  10610         std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
  10611             std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );
  10612             enumInfo->m_name = enumName;
  10613             enumInfo->m_values.reserve( values.size() );
  10614 
  10615             const auto valueNames = Catch::Detail::parseEnums( allValueNames );
  10616             assert( valueNames.size() == values.size() );
  10617             std::size_t i = 0;
  10618             for( auto value : values )
  10619                 enumInfo->m_values.emplace_back(value, valueNames[i++]);
  10620 
  10621             return enumInfo;
  10622         }
  10623 
  10624         EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
  10625             m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
  10626             return *m_enumInfos.back();
  10627         }
  10628 
  10629     } // Detail
  10630 } // Catch
  10631 
  10632 // end catch_enum_values_registry.cpp
  10633 // start catch_errno_guard.cpp
  10634 
  10635 #include <cerrno>
  10636 
  10637 namespace Catch {
  10638         ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
  10639         ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
  10640 }
  10641 // end catch_errno_guard.cpp
  10642 // start catch_exception_translator_registry.cpp
  10643 
  10644 // start catch_exception_translator_registry.h
  10645 
  10646 #include <vector>
  10647 #include <string>
  10648 #include <memory>
  10649 
  10650 namespace Catch {
  10651 
  10652     class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
  10653     public:
  10654         ~ExceptionTranslatorRegistry();
  10655         virtual void registerTranslator( const IExceptionTranslator* translator );
  10656         std::string translateActiveException() const override;
  10657         std::string tryTranslators() const;
  10658 
  10659     private:
  10660         std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
  10661     };
  10662 }
  10663 
  10664 // end catch_exception_translator_registry.h
  10665 #ifdef __OBJC__
  10666 #import "Foundation/Foundation.h"
  10667 #endif
  10668 
  10669 namespace Catch {
  10670 
  10671     ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
  10672     }
  10673 
  10674     void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
  10675         m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
  10676     }
  10677 
  10678 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  10679     std::string ExceptionTranslatorRegistry::translateActiveException() const {
  10680         try {
  10681 #ifdef __OBJC__
  10682             // In Objective-C try objective-c exceptions first
  10683             @try {
  10684                 return tryTranslators();
  10685             }
  10686             @catch (NSException *exception) {
  10687                 return Catch::Detail::stringify( [exception description] );
  10688             }
  10689 #else
  10690             // Compiling a mixed mode project with MSVC means that CLR
  10691             // exceptions will be caught in (...) as well. However, these
  10692             // do not fill-in std::current_exception and thus lead to crash
  10693             // when attempting rethrow.
  10694             // /EHa switch also causes structured exceptions to be caught
  10695             // here, but they fill-in current_exception properly, so
  10696             // at worst the output should be a little weird, instead of
  10697             // causing a crash.
  10698             if (std::current_exception() == nullptr) {
  10699                 return "Non C++ exception. Possibly a CLR exception.";
  10700             }
  10701             return tryTranslators();
  10702 #endif
  10703         }
  10704         catch( TestFailureException& ) {
  10705             std::rethrow_exception(std::current_exception());
  10706         }
  10707         catch( std::exception& ex ) {
  10708             return ex.what();
  10709         }
  10710         catch( std::string& msg ) {
  10711             return msg;
  10712         }
  10713         catch( const char* msg ) {
  10714             return msg;
  10715         }
  10716         catch(...) {
  10717             return "Unknown exception";
  10718         }
  10719     }
  10720 
  10721     std::string ExceptionTranslatorRegistry::tryTranslators() const {
  10722         if (m_translators.empty()) {
  10723             std::rethrow_exception(std::current_exception());
  10724         } else {
  10725             return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
  10726         }
  10727     }
  10728 
  10729 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
  10730     std::string ExceptionTranslatorRegistry::translateActiveException() const {
  10731         CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
  10732     }
  10733 
  10734     std::string ExceptionTranslatorRegistry::tryTranslators() const {
  10735         CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
  10736     }
  10737 #endif
  10738 
  10739 }
  10740 // end catch_exception_translator_registry.cpp
  10741 // start catch_fatal_condition.cpp
  10742 
  10743 #if defined(__GNUC__)
  10744 #    pragma GCC diagnostic push
  10745 #    pragma GCC diagnostic ignored "-Wmissing-field-initializers"
  10746 #endif
  10747 
  10748 #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
  10749 
  10750 namespace {
  10751     // Report the error condition
  10752     void reportFatal( char const * const message ) {
  10753         Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
  10754     }
  10755 }
  10756 
  10757 #endif // signals/SEH handling
  10758 
  10759 #if defined( CATCH_CONFIG_WINDOWS_SEH )
  10760 
  10761 namespace Catch {
  10762     struct SignalDefs { DWORD id; const char* name; };
  10763 
  10764     // There is no 1-1 mapping between signals and windows exceptions.
  10765     // Windows can easily distinguish between SO and SigSegV,
  10766     // but SigInt, SigTerm, etc are handled differently.
  10767     static SignalDefs signalDefs[] = {
  10768         { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),  "SIGILL - Illegal instruction signal" },
  10769         { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
  10770         { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
  10771         { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
  10772     };
  10773 
  10774     LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
  10775         for (auto const& def : signalDefs) {
  10776             if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
  10777                 reportFatal(def.name);
  10778             }
  10779         }
  10780         // If its not an exception we care about, pass it along.
  10781         // This stops us from eating debugger breaks etc.
  10782         return EXCEPTION_CONTINUE_SEARCH;
  10783     }
  10784 
  10785     FatalConditionHandler::FatalConditionHandler() {
  10786         isSet = true;
  10787         // 32k seems enough for Catch to handle stack overflow,
  10788         // but the value was found experimentally, so there is no strong guarantee
  10789         guaranteeSize = 32 * 1024;
  10790         exceptionHandlerHandle = nullptr;
  10791         // Register as first handler in current chain
  10792         exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
  10793         // Pass in guarantee size to be filled
  10794         SetThreadStackGuarantee(&guaranteeSize);
  10795     }
  10796 
  10797     void FatalConditionHandler::reset() {
  10798         if (isSet) {
  10799             RemoveVectoredExceptionHandler(exceptionHandlerHandle);
  10800             SetThreadStackGuarantee(&guaranteeSize);
  10801             exceptionHandlerHandle = nullptr;
  10802             isSet = false;
  10803         }
  10804     }
  10805 
  10806     FatalConditionHandler::~FatalConditionHandler() {
  10807         reset();
  10808     }
  10809 
  10810 bool FatalConditionHandler::isSet = false;
  10811 ULONG FatalConditionHandler::guaranteeSize = 0;
  10812 PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
  10813 
  10814 } // namespace Catch
  10815 
  10816 #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
  10817 
  10818 namespace Catch {
  10819 
  10820     struct SignalDefs {
  10821         int id;
  10822         const char* name;
  10823     };
  10824 
  10825     // 32kb for the alternate stack seems to be sufficient. However, this value
  10826     // is experimentally determined, so that's not guaranteed.
  10827     static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
  10828 
  10829     static SignalDefs signalDefs[] = {
  10830         { SIGINT,  "SIGINT - Terminal interrupt signal" },
  10831         { SIGILL,  "SIGILL - Illegal instruction signal" },
  10832         { SIGFPE,  "SIGFPE - Floating point error signal" },
  10833         { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
  10834         { SIGTERM, "SIGTERM - Termination request signal" },
  10835         { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
  10836     };
  10837 
  10838     void FatalConditionHandler::handleSignal( int sig ) {
  10839         char const * name = "<unknown signal>";
  10840         for (auto const& def : signalDefs) {
  10841             if (sig == def.id) {
  10842                 name = def.name;
  10843                 break;
  10844             }
  10845         }
  10846         reset();
  10847         reportFatal(name);
  10848         raise( sig );
  10849     }
  10850 
  10851     FatalConditionHandler::FatalConditionHandler() {
  10852         isSet = true;
  10853         stack_t sigStack;
  10854         sigStack.ss_sp = altStackMem;
  10855         sigStack.ss_size = sigStackSize;
  10856         sigStack.ss_flags = 0;
  10857         sigaltstack(&sigStack, &oldSigStack);
  10858         struct sigaction sa = { };
  10859 
  10860         sa.sa_handler = handleSignal;
  10861         sa.sa_flags = SA_ONSTACK;
  10862         for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
  10863             sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
  10864         }
  10865     }
  10866 
  10867     FatalConditionHandler::~FatalConditionHandler() {
  10868         reset();
  10869     }
  10870 
  10871     void FatalConditionHandler::reset() {
  10872         if( isSet ) {
  10873             // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
  10874             for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
  10875                 sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
  10876             }
  10877             // Return the old stack
  10878             sigaltstack(&oldSigStack, nullptr);
  10879             isSet = false;
  10880         }
  10881     }
  10882 
  10883     bool FatalConditionHandler::isSet = false;
  10884     struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
  10885     stack_t FatalConditionHandler::oldSigStack = {};
  10886     char FatalConditionHandler::altStackMem[sigStackSize] = {};
  10887 
  10888 } // namespace Catch
  10889 
  10890 #else
  10891 
  10892 namespace Catch {
  10893     void FatalConditionHandler::reset() {}
  10894 }
  10895 
  10896 #endif // signals/SEH handling
  10897 
  10898 #if defined(__GNUC__)
  10899 #    pragma GCC diagnostic pop
  10900 #endif
  10901 // end catch_fatal_condition.cpp
  10902 // start catch_generators.cpp
  10903 
  10904 #include <limits>
  10905 #include <set>
  10906 
  10907 namespace Catch {
  10908 
  10909 IGeneratorTracker::~IGeneratorTracker() {}
  10910 
  10911 const char* GeneratorException::what() const noexcept {
  10912     return m_msg;
  10913 }
  10914 
  10915 namespace Generators {
  10916 
  10917     GeneratorUntypedBase::~GeneratorUntypedBase() {}
  10918 
  10919     auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
  10920         return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );
  10921     }
  10922 
  10923 } // namespace Generators
  10924 } // namespace Catch
  10925 // end catch_generators.cpp
  10926 // start catch_interfaces_capture.cpp
  10927 
  10928 namespace Catch {
  10929     IResultCapture::~IResultCapture() = default;
  10930 }
  10931 // end catch_interfaces_capture.cpp
  10932 // start catch_interfaces_config.cpp
  10933 
  10934 namespace Catch {
  10935     IConfig::~IConfig() = default;
  10936 }
  10937 // end catch_interfaces_config.cpp
  10938 // start catch_interfaces_exception.cpp
  10939 
  10940 namespace Catch {
  10941     IExceptionTranslator::~IExceptionTranslator() = default;
  10942     IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
  10943 }
  10944 // end catch_interfaces_exception.cpp
  10945 // start catch_interfaces_registry_hub.cpp
  10946 
  10947 namespace Catch {
  10948     IRegistryHub::~IRegistryHub() = default;
  10949     IMutableRegistryHub::~IMutableRegistryHub() = default;
  10950 }
  10951 // end catch_interfaces_registry_hub.cpp
  10952 // start catch_interfaces_reporter.cpp
  10953 
  10954 // start catch_reporter_listening.h
  10955 
  10956 namespace Catch {
  10957 
  10958     class ListeningReporter : public IStreamingReporter {
  10959         using Reporters = std::vector<IStreamingReporterPtr>;
  10960         Reporters m_listeners;
  10961         IStreamingReporterPtr m_reporter = nullptr;
  10962         ReporterPreferences m_preferences;
  10963 
  10964     public:
  10965         ListeningReporter();
  10966 
  10967         void addListener( IStreamingReporterPtr&& listener );
  10968         void addReporter( IStreamingReporterPtr&& reporter );
  10969 
  10970     public: // IStreamingReporter
  10971 
  10972         ReporterPreferences getPreferences() const override;
  10973 
  10974         void noMatchingTestCases( std::string const& spec ) override;
  10975 
  10976         void reportInvalidArguments(std::string const&arg) override;
  10977 
  10978         static std::set<Verbosity> getSupportedVerbosities();
  10979 
  10980 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  10981         void benchmarkPreparing(std::string const& name) override;
  10982         void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
  10983         void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
  10984         void benchmarkFailed(std::string const&) override;
  10985 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  10986 
  10987         void testRunStarting( TestRunInfo const& testRunInfo ) override;
  10988         void testGroupStarting( GroupInfo const& groupInfo ) override;
  10989         void testCaseStarting( TestCaseInfo const& testInfo ) override;
  10990         void sectionStarting( SectionInfo const& sectionInfo ) override;
  10991         void assertionStarting( AssertionInfo const& assertionInfo ) override;
  10992 
  10993         // The return value indicates if the messages buffer should be cleared:
  10994         bool assertionEnded( AssertionStats const& assertionStats ) override;
  10995         void sectionEnded( SectionStats const& sectionStats ) override;
  10996         void testCaseEnded( TestCaseStats const& testCaseStats ) override;
  10997         void testGroupEnded( TestGroupStats const& testGroupStats ) override;
  10998         void testRunEnded( TestRunStats const& testRunStats ) override;
  10999 
  11000         void skipTest( TestCaseInfo const& testInfo ) override;
  11001         bool isMulti() const override;
  11002 
  11003     };
  11004 
  11005 } // end namespace Catch
  11006 
  11007 // end catch_reporter_listening.h
  11008 namespace Catch {
  11009 
  11010     ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
  11011     :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
  11012 
  11013     ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
  11014     :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
  11015 
  11016     std::ostream& ReporterConfig::stream() const { return *m_stream; }
  11017     IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
  11018 
  11019     TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
  11020 
  11021     GroupInfo::GroupInfo(  std::string const& _name,
  11022                            std::size_t _groupIndex,
  11023                            std::size_t _groupsCount )
  11024     :   name( _name ),
  11025         groupIndex( _groupIndex ),
  11026         groupsCounts( _groupsCount )
  11027     {}
  11028 
  11029      AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
  11030                                      std::vector<MessageInfo> const& _infoMessages,
  11031                                      Totals const& _totals )
  11032     :   assertionResult( _assertionResult ),
  11033         infoMessages( _infoMessages ),
  11034         totals( _totals )
  11035     {
  11036         assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
  11037 
  11038         if( assertionResult.hasMessage() ) {
  11039             // Copy message into messages list.
  11040             // !TBD This should have been done earlier, somewhere
  11041             MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
  11042             builder << assertionResult.getMessage();
  11043             builder.m_info.message = builder.m_stream.str();
  11044 
  11045             infoMessages.push_back( builder.m_info );
  11046         }
  11047     }
  11048 
  11049      AssertionStats::~AssertionStats() = default;
  11050 
  11051     SectionStats::SectionStats(  SectionInfo const& _sectionInfo,
  11052                                  Counts const& _assertions,
  11053                                  double _durationInSeconds,
  11054                                  bool _missingAssertions )
  11055     :   sectionInfo( _sectionInfo ),
  11056         assertions( _assertions ),
  11057         durationInSeconds( _durationInSeconds ),
  11058         missingAssertions( _missingAssertions )
  11059     {}
  11060 
  11061     SectionStats::~SectionStats() = default;
  11062 
  11063     TestCaseStats::TestCaseStats(  TestCaseInfo const& _testInfo,
  11064                                    Totals const& _totals,
  11065                                    std::string const& _stdOut,
  11066                                    std::string const& _stdErr,
  11067                                    bool _aborting )
  11068     : testInfo( _testInfo ),
  11069         totals( _totals ),
  11070         stdOut( _stdOut ),
  11071         stdErr( _stdErr ),
  11072         aborting( _aborting )
  11073     {}
  11074 
  11075     TestCaseStats::~TestCaseStats() = default;
  11076 
  11077     TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
  11078                                     Totals const& _totals,
  11079                                     bool _aborting )
  11080     :   groupInfo( _groupInfo ),
  11081         totals( _totals ),
  11082         aborting( _aborting )
  11083     {}
  11084 
  11085     TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
  11086     :   groupInfo( _groupInfo ),
  11087         aborting( false )
  11088     {}
  11089 
  11090     TestGroupStats::~TestGroupStats() = default;
  11091 
  11092     TestRunStats::TestRunStats(   TestRunInfo const& _runInfo,
  11093                     Totals const& _totals,
  11094                     bool _aborting )
  11095     :   runInfo( _runInfo ),
  11096         totals( _totals ),
  11097         aborting( _aborting )
  11098     {}
  11099 
  11100     TestRunStats::~TestRunStats() = default;
  11101 
  11102     void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
  11103     bool IStreamingReporter::isMulti() const { return false; }
  11104 
  11105     IReporterFactory::~IReporterFactory() = default;
  11106     IReporterRegistry::~IReporterRegistry() = default;
  11107 
  11108 } // end namespace Catch
  11109 // end catch_interfaces_reporter.cpp
  11110 // start catch_interfaces_runner.cpp
  11111 
  11112 namespace Catch {
  11113     IRunner::~IRunner() = default;
  11114 }
  11115 // end catch_interfaces_runner.cpp
  11116 // start catch_interfaces_testcase.cpp
  11117 
  11118 namespace Catch {
  11119     ITestInvoker::~ITestInvoker() = default;
  11120     ITestCaseRegistry::~ITestCaseRegistry() = default;
  11121 }
  11122 // end catch_interfaces_testcase.cpp
  11123 // start catch_leak_detector.cpp
  11124 
  11125 #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
  11126 #include <crtdbg.h>
  11127 
  11128 namespace Catch {
  11129 
  11130     LeakDetector::LeakDetector() {
  11131         int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  11132         flag |= _CRTDBG_LEAK_CHECK_DF;
  11133         flag |= _CRTDBG_ALLOC_MEM_DF;
  11134         _CrtSetDbgFlag(flag);
  11135         _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
  11136         _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  11137         // Change this to leaking allocation's number to break there
  11138         _CrtSetBreakAlloc(-1);
  11139     }
  11140 }
  11141 
  11142 #else
  11143 
  11144     Catch::LeakDetector::LeakDetector() {}
  11145 
  11146 #endif
  11147 
  11148 Catch::LeakDetector::~LeakDetector() {
  11149     Catch::cleanUp();
  11150 }
  11151 // end catch_leak_detector.cpp
  11152 // start catch_list.cpp
  11153 
  11154 // start catch_list.h
  11155 
  11156 #include <set>
  11157 
  11158 namespace Catch {
  11159 
  11160     std::size_t listTests( Config const& config );
  11161 
  11162     std::size_t listTestsNamesOnly( Config const& config );
  11163 
  11164     struct TagInfo {
  11165         void add( std::string const& spelling );
  11166         std::string all() const;
  11167 
  11168         std::set<std::string> spellings;
  11169         std::size_t count = 0;
  11170     };
  11171 
  11172     std::size_t listTags( Config const& config );
  11173 
  11174     std::size_t listReporters();
  11175 
  11176     Option<std::size_t> list( std::shared_ptr<Config> const& config );
  11177 
  11178 } // end namespace Catch
  11179 
  11180 // end catch_list.h
  11181 // start catch_text.h
  11182 
  11183 namespace Catch {
  11184     using namespace clara::TextFlow;
  11185 }
  11186 
  11187 // end catch_text.h
  11188 #include <limits>
  11189 #include <algorithm>
  11190 #include <iomanip>
  11191 
  11192 namespace Catch {
  11193 
  11194     std::size_t listTests( Config const& config ) {
  11195         TestSpec const& testSpec = config.testSpec();
  11196         if( config.hasTestFilters() )
  11197             Catch::cout() << "Matching test cases:\n";
  11198         else {
  11199             Catch::cout() << "All available test cases:\n";
  11200         }
  11201 
  11202         auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  11203         for( auto const& testCaseInfo : matchedTestCases ) {
  11204             Colour::Code colour = testCaseInfo.isHidden()
  11205                 ? Colour::SecondaryText
  11206                 : Colour::None;
  11207             Colour colourGuard( colour );
  11208 
  11209             Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
  11210             if( config.verbosity() >= Verbosity::High ) {
  11211                 Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
  11212                 std::string description = testCaseInfo.description;
  11213                 if( description.empty() )
  11214                     description = "(NO DESCRIPTION)";
  11215                 Catch::cout() << Column( description ).indent(4) << std::endl;
  11216             }
  11217             if( !testCaseInfo.tags.empty() )
  11218                 Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
  11219         }
  11220 
  11221         if( !config.hasTestFilters() )
  11222             Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
  11223         else
  11224             Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
  11225         return matchedTestCases.size();
  11226     }
  11227 
  11228     std::size_t listTestsNamesOnly( Config const& config ) {
  11229         TestSpec const& testSpec = config.testSpec();
  11230         std::size_t matchedTests = 0;
  11231         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  11232         for( auto const& testCaseInfo : matchedTestCases ) {
  11233             matchedTests++;
  11234             if( startsWith( testCaseInfo.name, '#' ) )
  11235                Catch::cout() << '"' << testCaseInfo.name << '"';
  11236             else
  11237                Catch::cout() << testCaseInfo.name;
  11238             if ( config.verbosity() >= Verbosity::High )
  11239                 Catch::cout() << "\t@" << testCaseInfo.lineInfo;
  11240             Catch::cout() << std::endl;
  11241         }
  11242         return matchedTests;
  11243     }
  11244 
  11245     void TagInfo::add( std::string const& spelling ) {
  11246         ++count;
  11247         spellings.insert( spelling );
  11248     }
  11249 
  11250     std::string TagInfo::all() const {
  11251         size_t size = 0;
  11252         for (auto const& spelling : spellings) {
  11253             // Add 2 for the brackes
  11254             size += spelling.size() + 2;
  11255         }
  11256 
  11257         std::string out; out.reserve(size);
  11258         for (auto const& spelling : spellings) {
  11259             out += '[';
  11260             out += spelling;
  11261             out += ']';
  11262         }
  11263         return out;
  11264     }
  11265 
  11266     std::size_t listTags( Config const& config ) {
  11267         TestSpec const& testSpec = config.testSpec();
  11268         if( config.hasTestFilters() )
  11269             Catch::cout() << "Tags for matching test cases:\n";
  11270         else {
  11271             Catch::cout() << "All available tags:\n";
  11272         }
  11273 
  11274         std::map<std::string, TagInfo> tagCounts;
  11275 
  11276         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  11277         for( auto const& testCase : matchedTestCases ) {
  11278             for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
  11279                 std::string lcaseTagName = toLower( tagName );
  11280                 auto countIt = tagCounts.find( lcaseTagName );
  11281                 if( countIt == tagCounts.end() )
  11282                     countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
  11283                 countIt->second.add( tagName );
  11284             }
  11285         }
  11286 
  11287         for( auto const& tagCount : tagCounts ) {
  11288             ReusableStringStream rss;
  11289             rss << "  " << std::setw(2) << tagCount.second.count << "  ";
  11290             auto str = rss.str();
  11291             auto wrapper = Column( tagCount.second.all() )
  11292                                                     .initialIndent( 0 )
  11293                                                     .indent( str.size() )
  11294                                                     .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
  11295             Catch::cout() << str << wrapper << '\n';
  11296         }
  11297         Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
  11298         return tagCounts.size();
  11299     }
  11300 
  11301     std::size_t listReporters() {
  11302         Catch::cout() << "Available reporters:\n";
  11303         IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
  11304         std::size_t maxNameLen = 0;
  11305         for( auto const& factoryKvp : factories )
  11306             maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
  11307 
  11308         for( auto const& factoryKvp : factories ) {
  11309             Catch::cout()
  11310                     << Column( factoryKvp.first + ":" )
  11311                             .indent(2)
  11312                             .width( 5+maxNameLen )
  11313                     +  Column( factoryKvp.second->getDescription() )
  11314                             .initialIndent(0)
  11315                             .indent(2)
  11316                             .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
  11317                     << "\n";
  11318         }
  11319         Catch::cout() << std::endl;
  11320         return factories.size();
  11321     }
  11322 
  11323     Option<std::size_t> list( std::shared_ptr<Config> const& config ) {
  11324         Option<std::size_t> listedCount;
  11325         getCurrentMutableContext().setConfig( config );
  11326         if( config->listTests() )
  11327             listedCount = listedCount.valueOr(0) + listTests( *config );
  11328         if( config->listTestNamesOnly() )
  11329             listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );
  11330         if( config->listTags() )
  11331             listedCount = listedCount.valueOr(0) + listTags( *config );
  11332         if( config->listReporters() )
  11333             listedCount = listedCount.valueOr(0) + listReporters();
  11334         return listedCount;
  11335     }
  11336 
  11337 } // end namespace Catch
  11338 // end catch_list.cpp
  11339 // start catch_matchers.cpp
  11340 
  11341 namespace Catch {
  11342 namespace Matchers {
  11343     namespace Impl {
  11344 
  11345         std::string MatcherUntypedBase::toString() const {
  11346             if( m_cachedToString.empty() )
  11347                 m_cachedToString = describe();
  11348             return m_cachedToString;
  11349         }
  11350 
  11351         MatcherUntypedBase::~MatcherUntypedBase() = default;
  11352 
  11353     } // namespace Impl
  11354 } // namespace Matchers
  11355 
  11356 using namespace Matchers;
  11357 using Matchers::Impl::MatcherBase;
  11358 
  11359 } // namespace Catch
  11360 // end catch_matchers.cpp
  11361 // start catch_matchers_exception.cpp
  11362 
  11363 namespace Catch {
  11364 namespace Matchers {
  11365 namespace Exception {
  11366 
  11367 bool ExceptionMessageMatcher::match(std::exception const& ex) const {
  11368     return ex.what() == m_message;
  11369 }
  11370 
  11371 std::string ExceptionMessageMatcher::describe() const {
  11372     return "exception message matches \"" + m_message + "\"";
  11373 }
  11374 
  11375 }
  11376 Exception::ExceptionMessageMatcher Message(std::string const& message) {
  11377     return Exception::ExceptionMessageMatcher(message);
  11378 }
  11379 
  11380 // namespace Exception
  11381 } // namespace Matchers
  11382 } // namespace Catch
  11383 // end catch_matchers_exception.cpp
  11384 // start catch_matchers_floating.cpp
  11385 
  11386 // start catch_polyfills.hpp
  11387 
  11388 namespace Catch {
  11389     bool isnan(float f);
  11390     bool isnan(double d);
  11391 }
  11392 
  11393 // end catch_polyfills.hpp
  11394 // start catch_to_string.hpp
  11395 
  11396 #include <string>
  11397 
  11398 namespace Catch {
  11399     template <typename T>
  11400     std::string to_string(T const& t) {
  11401 #if defined(CATCH_CONFIG_CPP11_TO_STRING)
  11402         return std::to_string(t);
  11403 #else
  11404         ReusableStringStream rss;
  11405         rss << t;
  11406         return rss.str();
  11407 #endif
  11408     }
  11409 } // end namespace Catch
  11410 
  11411 // end catch_to_string.hpp
  11412 #include <algorithm>
  11413 #include <cmath>
  11414 #include <cstdlib>
  11415 #include <cstdint>
  11416 #include <cstring>
  11417 #include <sstream>
  11418 #include <type_traits>
  11419 #include <iomanip>
  11420 #include <limits>
  11421 
  11422 namespace Catch {
  11423 namespace {
  11424 
  11425     int32_t convert(float f) {
  11426         static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
  11427         int32_t i;
  11428         std::memcpy(&i, &f, sizeof(f));
  11429         return i;
  11430     }
  11431 
  11432     int64_t convert(double d) {
  11433         static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
  11434         int64_t i;
  11435         std::memcpy(&i, &d, sizeof(d));
  11436         return i;
  11437     }
  11438 
  11439     template <typename FP>
  11440     bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
  11441         // Comparison with NaN should always be false.
  11442         // This way we can rule it out before getting into the ugly details
  11443         if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
  11444             return false;
  11445         }
  11446 
  11447         auto lc = convert(lhs);
  11448         auto rc = convert(rhs);
  11449 
  11450         if ((lc < 0) != (rc < 0)) {
  11451             // Potentially we can have +0 and -0
  11452             return lhs == rhs;
  11453         }
  11454 
  11455         auto ulpDiff = std::abs(lc - rc);
  11456         return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
  11457     }
  11458 
  11459 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
  11460 
  11461     float nextafter(float x, float y) {
  11462         return ::nextafterf(x, y);
  11463     }
  11464 
  11465     double nextafter(double x, double y) {
  11466         return ::nextafter(x, y);
  11467     }
  11468 
  11469 #endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
  11470 
  11471 template <typename FP>
  11472 FP step(FP start, FP direction, uint64_t steps) {
  11473     for (uint64_t i = 0; i < steps; ++i) {
  11474 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
  11475         start = Catch::nextafter(start, direction);
  11476 #else
  11477         start = std::nextafter(start, direction);
  11478 #endif
  11479     }
  11480     return start;
  11481 }
  11482 
  11483 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
  11484 // But without the subtraction to allow for INFINITY in comparison
  11485 bool marginComparison(double lhs, double rhs, double margin) {
  11486     return (lhs + margin >= rhs) && (rhs + margin >= lhs);
  11487 }
  11488 
  11489 template <typename FloatingPoint>
  11490 void write(std::ostream& out, FloatingPoint num) {
  11491     out << std::scientific
  11492         << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)
  11493         << num;
  11494 }
  11495 
  11496 } // end anonymous namespace
  11497 
  11498 namespace Matchers {
  11499 namespace Floating {
  11500 
  11501     enum class FloatingPointKind : uint8_t {
  11502         Float,
  11503         Double
  11504     };
  11505 
  11506     WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
  11507         :m_target{ target }, m_margin{ margin } {
  11508         CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
  11509             << " Margin has to be non-negative.");
  11510     }
  11511 
  11512     // Performs equivalent check of std::fabs(lhs - rhs) <= margin
  11513     // But without the subtraction to allow for INFINITY in comparison
  11514     bool WithinAbsMatcher::match(double const& matchee) const {
  11515         return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
  11516     }
  11517 
  11518     std::string WithinAbsMatcher::describe() const {
  11519         return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
  11520     }
  11521 
  11522     WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
  11523         :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
  11524         CATCH_ENFORCE(m_type == FloatingPointKind::Double
  11525                    || m_ulps < (std::numeric_limits<uint32_t>::max)(),
  11526             "Provided ULP is impossibly large for a float comparison.");
  11527     }
  11528 
  11529 #if defined(__clang__)
  11530 #pragma clang diagnostic push
  11531 // Clang <3.5 reports on the default branch in the switch below
  11532 #pragma clang diagnostic ignored "-Wunreachable-code"
  11533 #endif
  11534 
  11535     bool WithinUlpsMatcher::match(double const& matchee) const {
  11536         switch (m_type) {
  11537         case FloatingPointKind::Float:
  11538             return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
  11539         case FloatingPointKind::Double:
  11540             return almostEqualUlps<double>(matchee, m_target, m_ulps);
  11541         default:
  11542             CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
  11543         }
  11544     }
  11545 
  11546 #if defined(__clang__)
  11547 #pragma clang diagnostic pop
  11548 #endif
  11549 
  11550     std::string WithinUlpsMatcher::describe() const {
  11551         std::stringstream ret;
  11552 
  11553         ret << "is within " << m_ulps << " ULPs of ";
  11554 
  11555         if (m_type == FloatingPointKind::Float) {
  11556             write(ret, static_cast<float>(m_target));
  11557             ret << 'f';
  11558         } else {
  11559             write(ret, m_target);
  11560         }
  11561 
  11562         ret << " ([";
  11563         if (m_type == FloatingPointKind::Double) {
  11564             write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
  11565             ret << ", ";
  11566             write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
  11567         } else {
  11568             // We have to cast INFINITY to float because of MinGW, see #1782
  11569             write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
  11570             ret << ", ";
  11571             write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));
  11572         }
  11573         ret << "])";
  11574 
  11575         return ret.str();
  11576     }
  11577 
  11578     WithinRelMatcher::WithinRelMatcher(double target, double epsilon):
  11579         m_target(target),
  11580         m_epsilon(epsilon){
  11581         CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon <  0 does not make sense.");
  11582         CATCH_ENFORCE(m_epsilon  < 1., "Relative comparison with epsilon >= 1 does not make sense.");
  11583     }
  11584 
  11585     bool WithinRelMatcher::match(double const& matchee) const {
  11586         const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
  11587         return marginComparison(matchee, m_target,
  11588                                 std::isinf(relMargin)? 0 : relMargin);
  11589     }
  11590 
  11591     std::string WithinRelMatcher::describe() const {
  11592         Catch::ReusableStringStream sstr;
  11593         sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
  11594         return sstr.str();
  11595     }
  11596 
  11597 }// namespace Floating
  11598 
  11599 Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
  11600     return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
  11601 }
  11602 
  11603 Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
  11604     return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
  11605 }
  11606 
  11607 Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
  11608     return Floating::WithinAbsMatcher(target, margin);
  11609 }
  11610 
  11611 Floating::WithinRelMatcher WithinRel(double target, double eps) {
  11612     return Floating::WithinRelMatcher(target, eps);
  11613 }
  11614 
  11615 Floating::WithinRelMatcher WithinRel(double target) {
  11616     return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
  11617 }
  11618 
  11619 Floating::WithinRelMatcher WithinRel(float target, float eps) {
  11620     return Floating::WithinRelMatcher(target, eps);
  11621 }
  11622 
  11623 Floating::WithinRelMatcher WithinRel(float target) {
  11624     return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
  11625 }
  11626 
  11627 } // namespace Matchers
  11628 } // namespace Catch
  11629 
  11630 // end catch_matchers_floating.cpp
  11631 // start catch_matchers_generic.cpp
  11632 
  11633 std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
  11634     if (desc.empty()) {
  11635         return "matches undescribed predicate";
  11636     } else {
  11637         return "matches predicate: \"" + desc + '"';
  11638     }
  11639 }
  11640 // end catch_matchers_generic.cpp
  11641 // start catch_matchers_string.cpp
  11642 
  11643 #include <regex>
  11644 
  11645 namespace Catch {
  11646 namespace Matchers {
  11647 
  11648     namespace StdString {
  11649 
  11650         CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
  11651         :   m_caseSensitivity( caseSensitivity ),
  11652             m_str( adjustString( str ) )
  11653         {}
  11654         std::string CasedString::adjustString( std::string const& str ) const {
  11655             return m_caseSensitivity == CaseSensitive::No
  11656                    ? toLower( str )
  11657                    : str;
  11658         }
  11659         std::string CasedString::caseSensitivitySuffix() const {
  11660             return m_caseSensitivity == CaseSensitive::No
  11661                    ? " (case insensitive)"
  11662                    : std::string();
  11663         }
  11664 
  11665         StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
  11666         : m_comparator( comparator ),
  11667           m_operation( operation ) {
  11668         }
  11669 
  11670         std::string StringMatcherBase::describe() const {
  11671             std::string description;
  11672             description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
  11673                                         m_comparator.caseSensitivitySuffix().size());
  11674             description += m_operation;
  11675             description += ": \"";
  11676             description += m_comparator.m_str;
  11677             description += "\"";
  11678             description += m_comparator.caseSensitivitySuffix();
  11679             return description;
  11680         }
  11681 
  11682         EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
  11683 
  11684         bool EqualsMatcher::match( std::string const& source ) const {
  11685             return m_comparator.adjustString( source ) == m_comparator.m_str;
  11686         }
  11687 
  11688         ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
  11689 
  11690         bool ContainsMatcher::match( std::string const& source ) const {
  11691             return contains( m_comparator.adjustString( source ), m_comparator.m_str );
  11692         }
  11693 
  11694         StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
  11695 
  11696         bool StartsWithMatcher::match( std::string const& source ) const {
  11697             return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
  11698         }
  11699 
  11700         EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
  11701 
  11702         bool EndsWithMatcher::match( std::string const& source ) const {
  11703             return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
  11704         }
  11705 
  11706         RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
  11707 
  11708         bool RegexMatcher::match(std::string const& matchee) const {
  11709             auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
  11710             if (m_caseSensitivity == CaseSensitive::Choice::No) {
  11711                 flags |= std::regex::icase;
  11712             }
  11713             auto reg = std::regex(m_regex, flags);
  11714             return std::regex_match(matchee, reg);
  11715         }
  11716 
  11717         std::string RegexMatcher::describe() const {
  11718             return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
  11719         }
  11720 
  11721     } // namespace StdString
  11722 
  11723     StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  11724         return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
  11725     }
  11726     StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  11727         return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
  11728     }
  11729     StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  11730         return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
  11731     }
  11732     StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  11733         return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
  11734     }
  11735 
  11736     StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
  11737         return StdString::RegexMatcher(regex, caseSensitivity);
  11738     }
  11739 
  11740 } // namespace Matchers
  11741 } // namespace Catch
  11742 // end catch_matchers_string.cpp
  11743 // start catch_message.cpp
  11744 
  11745 // start catch_uncaught_exceptions.h
  11746 
  11747 namespace Catch {
  11748     bool uncaught_exceptions();
  11749 } // end namespace Catch
  11750 
  11751 // end catch_uncaught_exceptions.h
  11752 #include <cassert>
  11753 #include <stack>
  11754 
  11755 namespace Catch {
  11756 
  11757     MessageInfo::MessageInfo(   StringRef const& _macroName,
  11758                                 SourceLineInfo const& _lineInfo,
  11759                                 ResultWas::OfType _type )
  11760     :   macroName( _macroName ),
  11761         lineInfo( _lineInfo ),
  11762         type( _type ),
  11763         sequence( ++globalCount )
  11764     {}
  11765 
  11766     bool MessageInfo::operator==( MessageInfo const& other ) const {
  11767         return sequence == other.sequence;
  11768     }
  11769 
  11770     bool MessageInfo::operator<( MessageInfo const& other ) const {
  11771         return sequence < other.sequence;
  11772     }
  11773 
  11774     // This may need protecting if threading support is added
  11775     unsigned int MessageInfo::globalCount = 0;
  11776 
  11777     ////////////////////////////////////////////////////////////////////////////
  11778 
  11779     Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
  11780                                            SourceLineInfo const& lineInfo,
  11781                                            ResultWas::OfType type )
  11782         :m_info(macroName, lineInfo, type) {}
  11783 
  11784     ////////////////////////////////////////////////////////////////////////////
  11785 
  11786     ScopedMessage::ScopedMessage( MessageBuilder const& builder )
  11787     : m_info( builder.m_info ), m_moved()
  11788     {
  11789         m_info.message = builder.m_stream.str();
  11790         getResultCapture().pushScopedMessage( m_info );
  11791     }
  11792 
  11793     ScopedMessage::ScopedMessage( ScopedMessage&& old )
  11794     : m_info( old.m_info ), m_moved()
  11795     {
  11796         old.m_moved = true;
  11797     }
  11798 
  11799     ScopedMessage::~ScopedMessage() {
  11800         if ( !uncaught_exceptions() && !m_moved ){
  11801             getResultCapture().popScopedMessage(m_info);
  11802         }
  11803     }
  11804 
  11805     Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
  11806         auto trimmed = [&] (size_t start, size_t end) {
  11807             while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {
  11808                 ++start;
  11809             }
  11810             while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) {
  11811                 --end;
  11812             }
  11813             return names.substr(start, end - start + 1);
  11814         };
  11815         auto skipq = [&] (size_t start, char quote) {
  11816             for (auto i = start + 1; i < names.size() ; ++i) {
  11817                 if (names[i] == quote)
  11818                     return i;
  11819                 if (names[i] == '\\')
  11820                     ++i;
  11821             }
  11822             CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
  11823         };
  11824 
  11825         size_t start = 0;
  11826         std::stack<char> openings;
  11827         for (size_t pos = 0; pos < names.size(); ++pos) {
  11828             char c = names[pos];
  11829             switch (c) {
  11830             case '[':
  11831             case '{':
  11832             case '(':
  11833             // It is basically impossible to disambiguate between
  11834             // comparison and start of template args in this context
  11835 //            case '<':
  11836                 openings.push(c);
  11837                 break;
  11838             case ']':
  11839             case '}':
  11840             case ')':
  11841 //           case '>':
  11842                 openings.pop();
  11843                 break;
  11844             case '"':
  11845             case '\'':
  11846                 pos = skipq(pos, c);
  11847                 break;
  11848             case ',':
  11849                 if (start != pos && openings.empty()) {
  11850                     m_messages.emplace_back(macroName, lineInfo, resultType);
  11851                     m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
  11852                     m_messages.back().message += " := ";
  11853                     start = pos;
  11854                 }
  11855             }
  11856         }
  11857         assert(openings.empty() && "Mismatched openings");
  11858         m_messages.emplace_back(macroName, lineInfo, resultType);
  11859         m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
  11860         m_messages.back().message += " := ";
  11861     }
  11862     Capturer::~Capturer() {
  11863         if ( !uncaught_exceptions() ){
  11864             assert( m_captured == m_messages.size() );
  11865             for( size_t i = 0; i < m_captured; ++i  )
  11866                 m_resultCapture.popScopedMessage( m_messages[i] );
  11867         }
  11868     }
  11869 
  11870     void Capturer::captureValue( size_t index, std::string const& value ) {
  11871         assert( index < m_messages.size() );
  11872         m_messages[index].message += value;
  11873         m_resultCapture.pushScopedMessage( m_messages[index] );
  11874         m_captured++;
  11875     }
  11876 
  11877 } // end namespace Catch
  11878 // end catch_message.cpp
  11879 // start catch_output_redirect.cpp
  11880 
  11881 // start catch_output_redirect.h
  11882 #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
  11883 #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
  11884 
  11885 #include <cstdio>
  11886 #include <iosfwd>
  11887 #include <string>
  11888 
  11889 namespace Catch {
  11890 
  11891     class RedirectedStream {
  11892         std::ostream& m_originalStream;
  11893         std::ostream& m_redirectionStream;
  11894         std::streambuf* m_prevBuf;
  11895 
  11896     public:
  11897         RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
  11898         ~RedirectedStream();
  11899     };
  11900 
  11901     class RedirectedStdOut {
  11902         ReusableStringStream m_rss;
  11903         RedirectedStream m_cout;
  11904     public:
  11905         RedirectedStdOut();
  11906         auto str() const -> std::string;
  11907     };
  11908 
  11909     // StdErr has two constituent streams in C++, std::cerr and std::clog
  11910     // This means that we need to redirect 2 streams into 1 to keep proper
  11911     // order of writes
  11912     class RedirectedStdErr {
  11913         ReusableStringStream m_rss;
  11914         RedirectedStream m_cerr;
  11915         RedirectedStream m_clog;
  11916     public:
  11917         RedirectedStdErr();
  11918         auto str() const -> std::string;
  11919     };
  11920 
  11921     class RedirectedStreams {
  11922     public:
  11923         RedirectedStreams(RedirectedStreams const&) = delete;
  11924         RedirectedStreams& operator=(RedirectedStreams const&) = delete;
  11925         RedirectedStreams(RedirectedStreams&&) = delete;
  11926         RedirectedStreams& operator=(RedirectedStreams&&) = delete;
  11927 
  11928         RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
  11929         ~RedirectedStreams();
  11930     private:
  11931         std::string& m_redirectedCout;
  11932         std::string& m_redirectedCerr;
  11933         RedirectedStdOut m_redirectedStdOut;
  11934         RedirectedStdErr m_redirectedStdErr;
  11935     };
  11936 
  11937 #if defined(CATCH_CONFIG_NEW_CAPTURE)
  11938 
  11939     // Windows's implementation of std::tmpfile is terrible (it tries
  11940     // to create a file inside system folder, thus requiring elevated
  11941     // privileges for the binary), so we have to use tmpnam(_s) and
  11942     // create the file ourselves there.
  11943     class TempFile {
  11944     public:
  11945         TempFile(TempFile const&) = delete;
  11946         TempFile& operator=(TempFile const&) = delete;
  11947         TempFile(TempFile&&) = delete;
  11948         TempFile& operator=(TempFile&&) = delete;
  11949 
  11950         TempFile();
  11951         ~TempFile();
  11952 
  11953         std::FILE* getFile();
  11954         std::string getContents();
  11955 
  11956     private:
  11957         std::FILE* m_file = nullptr;
  11958     #if defined(_MSC_VER)
  11959         char m_buffer[L_tmpnam] = { 0 };
  11960     #endif
  11961     };
  11962 
  11963     class OutputRedirect {
  11964     public:
  11965         OutputRedirect(OutputRedirect const&) = delete;
  11966         OutputRedirect& operator=(OutputRedirect const&) = delete;
  11967         OutputRedirect(OutputRedirect&&) = delete;
  11968         OutputRedirect& operator=(OutputRedirect&&) = delete;
  11969 
  11970         OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
  11971         ~OutputRedirect();
  11972 
  11973     private:
  11974         int m_originalStdout = -1;
  11975         int m_originalStderr = -1;
  11976         TempFile m_stdoutFile;
  11977         TempFile m_stderrFile;
  11978         std::string& m_stdoutDest;
  11979         std::string& m_stderrDest;
  11980     };
  11981 
  11982 #endif
  11983 
  11984 } // end namespace Catch
  11985 
  11986 #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
  11987 // end catch_output_redirect.h
  11988 #include <cstdio>
  11989 #include <cstring>
  11990 #include <fstream>
  11991 #include <sstream>
  11992 #include <stdexcept>
  11993 
  11994 #if defined(CATCH_CONFIG_NEW_CAPTURE)
  11995     #if defined(_MSC_VER)
  11996     #include <io.h>      //_dup and _dup2
  11997     #define dup _dup
  11998     #define dup2 _dup2
  11999     #define fileno _fileno
  12000     #else
  12001     #include <unistd.h>  // dup and dup2
  12002     #endif
  12003 #endif
  12004 
  12005 namespace Catch {
  12006 
  12007     RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
  12008     :   m_originalStream( originalStream ),
  12009         m_redirectionStream( redirectionStream ),
  12010         m_prevBuf( m_originalStream.rdbuf() )
  12011     {
  12012         m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
  12013     }
  12014 
  12015     RedirectedStream::~RedirectedStream() {
  12016         m_originalStream.rdbuf( m_prevBuf );
  12017     }
  12018 
  12019     RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
  12020     auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
  12021 
  12022     RedirectedStdErr::RedirectedStdErr()
  12023     :   m_cerr( Catch::cerr(), m_rss.get() ),
  12024         m_clog( Catch::clog(), m_rss.get() )
  12025     {}
  12026     auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
  12027 
  12028     RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
  12029     :   m_redirectedCout(redirectedCout),
  12030         m_redirectedCerr(redirectedCerr)
  12031     {}
  12032 
  12033     RedirectedStreams::~RedirectedStreams() {
  12034         m_redirectedCout += m_redirectedStdOut.str();
  12035         m_redirectedCerr += m_redirectedStdErr.str();
  12036     }
  12037 
  12038 #if defined(CATCH_CONFIG_NEW_CAPTURE)
  12039 
  12040 #if defined(_MSC_VER)
  12041     TempFile::TempFile() {
  12042         if (tmpnam_s(m_buffer)) {
  12043             CATCH_RUNTIME_ERROR("Could not get a temp filename");
  12044         }
  12045         if (fopen_s(&m_file, m_buffer, "w")) {
  12046             char buffer[100];
  12047             if (strerror_s(buffer, errno)) {
  12048                 CATCH_RUNTIME_ERROR("Could not translate errno to a string");
  12049             }
  12050             CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
  12051         }
  12052     }
  12053 #else
  12054     TempFile::TempFile() {
  12055         m_file = std::tmpfile();
  12056         if (!m_file) {
  12057             CATCH_RUNTIME_ERROR("Could not create a temp file.");
  12058         }
  12059     }
  12060 
  12061 #endif
  12062 
  12063     TempFile::~TempFile() {
  12064          // TBD: What to do about errors here?
  12065          std::fclose(m_file);
  12066          // We manually create the file on Windows only, on Linux
  12067          // it will be autodeleted
  12068 #if defined(_MSC_VER)
  12069          std::remove(m_buffer);
  12070 #endif
  12071     }
  12072 
  12073     FILE* TempFile::getFile() {
  12074         return m_file;
  12075     }
  12076 
  12077     std::string TempFile::getContents() {
  12078         std::stringstream sstr;
  12079         char buffer[100] = {};
  12080         std::rewind(m_file);
  12081         while (std::fgets(buffer, sizeof(buffer), m_file)) {
  12082             sstr << buffer;
  12083         }
  12084         return sstr.str();
  12085     }
  12086 
  12087     OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
  12088         m_originalStdout(dup(1)),
  12089         m_originalStderr(dup(2)),
  12090         m_stdoutDest(stdout_dest),
  12091         m_stderrDest(stderr_dest) {
  12092         dup2(fileno(m_stdoutFile.getFile()), 1);
  12093         dup2(fileno(m_stderrFile.getFile()), 2);
  12094     }
  12095 
  12096     OutputRedirect::~OutputRedirect() {
  12097         Catch::cout() << std::flush;
  12098         fflush(stdout);
  12099         // Since we support overriding these streams, we flush cerr
  12100         // even though std::cerr is unbuffered
  12101         Catch::cerr() << std::flush;
  12102         Catch::clog() << std::flush;
  12103         fflush(stderr);
  12104 
  12105         dup2(m_originalStdout, 1);
  12106         dup2(m_originalStderr, 2);
  12107 
  12108         m_stdoutDest += m_stdoutFile.getContents();
  12109         m_stderrDest += m_stderrFile.getContents();
  12110     }
  12111 
  12112 #endif // CATCH_CONFIG_NEW_CAPTURE
  12113 
  12114 } // namespace Catch
  12115 
  12116 #if defined(CATCH_CONFIG_NEW_CAPTURE)
  12117     #if defined(_MSC_VER)
  12118     #undef dup
  12119     #undef dup2
  12120     #undef fileno
  12121     #endif
  12122 #endif
  12123 // end catch_output_redirect.cpp
  12124 // start catch_polyfills.cpp
  12125 
  12126 #include <cmath>
  12127 
  12128 namespace Catch {
  12129 
  12130 #if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
  12131     bool isnan(float f) {
  12132         return std::isnan(f);
  12133     }
  12134     bool isnan(double d) {
  12135         return std::isnan(d);
  12136     }
  12137 #else
  12138     // For now we only use this for embarcadero
  12139     bool isnan(float f) {
  12140         return std::_isnan(f);
  12141     }
  12142     bool isnan(double d) {
  12143         return std::_isnan(d);
  12144     }
  12145 #endif
  12146 
  12147 } // end namespace Catch
  12148 // end catch_polyfills.cpp
  12149 // start catch_random_number_generator.cpp
  12150 
  12151 namespace Catch {
  12152 
  12153 namespace {
  12154 
  12155 #if defined(_MSC_VER)
  12156 #pragma warning(push)
  12157 #pragma warning(disable:4146) // we negate uint32 during the rotate
  12158 #endif
  12159         // Safe rotr implementation thanks to John Regehr
  12160         uint32_t rotate_right(uint32_t val, uint32_t count) {
  12161             const uint32_t mask = 31;
  12162             count &= mask;
  12163             return (val >> count) | (val << (-count & mask));
  12164         }
  12165 
  12166 #if defined(_MSC_VER)
  12167 #pragma warning(pop)
  12168 #endif
  12169 
  12170 }
  12171 
  12172     SimplePcg32::SimplePcg32(result_type seed_) {
  12173         seed(seed_);
  12174     }
  12175 
  12176     void SimplePcg32::seed(result_type seed_) {
  12177         m_state = 0;
  12178         (*this)();
  12179         m_state += seed_;
  12180         (*this)();
  12181     }
  12182 
  12183     void SimplePcg32::discard(uint64_t skip) {
  12184         // We could implement this to run in O(log n) steps, but this
  12185         // should suffice for our use case.
  12186         for (uint64_t s = 0; s < skip; ++s) {
  12187             static_cast<void>((*this)());
  12188         }
  12189     }
  12190 
  12191     SimplePcg32::result_type SimplePcg32::operator()() {
  12192         // prepare the output value
  12193         const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
  12194         const auto output = rotate_right(xorshifted, m_state >> 59u);
  12195 
  12196         // advance state
  12197         m_state = m_state * 6364136223846793005ULL + s_inc;
  12198 
  12199         return output;
  12200     }
  12201 
  12202     bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
  12203         return lhs.m_state == rhs.m_state;
  12204     }
  12205 
  12206     bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
  12207         return lhs.m_state != rhs.m_state;
  12208     }
  12209 }
  12210 // end catch_random_number_generator.cpp
  12211 // start catch_registry_hub.cpp
  12212 
  12213 // start catch_test_case_registry_impl.h
  12214 
  12215 #include <vector>
  12216 #include <set>
  12217 #include <algorithm>
  12218 #include <ios>
  12219 
  12220 namespace Catch {
  12221 
  12222     class TestCase;
  12223     struct IConfig;
  12224 
  12225     std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
  12226 
  12227     bool isThrowSafe( TestCase const& testCase, IConfig const& config );
  12228     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
  12229 
  12230     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
  12231 
  12232     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
  12233     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
  12234 
  12235     class TestRegistry : public ITestCaseRegistry {
  12236     public:
  12237         virtual ~TestRegistry() = default;
  12238 
  12239         virtual void registerTest( TestCase const& testCase );
  12240 
  12241         std::vector<TestCase> const& getAllTests() const override;
  12242         std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
  12243 
  12244     private:
  12245         std::vector<TestCase> m_functions;
  12246         mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
  12247         mutable std::vector<TestCase> m_sortedFunctions;
  12248         std::size_t m_unnamedCount = 0;
  12249         std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
  12250     };
  12251 
  12252     ///////////////////////////////////////////////////////////////////////////
  12253 
  12254     class TestInvokerAsFunction : public ITestInvoker {
  12255         void(*m_testAsFunction)();
  12256     public:
  12257         TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
  12258 
  12259         void invoke() const override;
  12260     };
  12261 
  12262     std::string extractClassName( StringRef const& classOrQualifiedMethodName );
  12263 
  12264     ///////////////////////////////////////////////////////////////////////////
  12265 
  12266 } // end namespace Catch
  12267 
  12268 // end catch_test_case_registry_impl.h
  12269 // start catch_reporter_registry.h
  12270 
  12271 #include <map>
  12272 
  12273 namespace Catch {
  12274 
  12275     class ReporterRegistry : public IReporterRegistry {
  12276 
  12277     public:
  12278 
  12279         ~ReporterRegistry() override;
  12280 
  12281         IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
  12282 
  12283         void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
  12284         void registerListener( IReporterFactoryPtr const& factory );
  12285 
  12286         FactoryMap const& getFactories() const override;
  12287         Listeners const& getListeners() const override;
  12288 
  12289     private:
  12290         FactoryMap m_factories;
  12291         Listeners m_listeners;
  12292     };
  12293 }
  12294 
  12295 // end catch_reporter_registry.h
  12296 // start catch_tag_alias_registry.h
  12297 
  12298 // start catch_tag_alias.h
  12299 
  12300 #include <string>
  12301 
  12302 namespace Catch {
  12303 
  12304     struct TagAlias {
  12305         TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
  12306 
  12307         std::string tag;
  12308         SourceLineInfo lineInfo;
  12309     };
  12310 
  12311 } // end namespace Catch
  12312 
  12313 // end catch_tag_alias.h
  12314 #include <map>
  12315 
  12316 namespace Catch {
  12317 
  12318     class TagAliasRegistry : public ITagAliasRegistry {
  12319     public:
  12320         ~TagAliasRegistry() override;
  12321         TagAlias const* find( std::string const& alias ) const override;
  12322         std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
  12323         void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
  12324 
  12325     private:
  12326         std::map<std::string, TagAlias> m_registry;
  12327     };
  12328 
  12329 } // end namespace Catch
  12330 
  12331 // end catch_tag_alias_registry.h
  12332 // start catch_startup_exception_registry.h
  12333 
  12334 #include <vector>
  12335 #include <exception>
  12336 
  12337 namespace Catch {
  12338 
  12339     class StartupExceptionRegistry {
  12340 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  12341     public:
  12342         void add(std::exception_ptr const& exception) noexcept;
  12343         std::vector<std::exception_ptr> const& getExceptions() const noexcept;
  12344     private:
  12345         std::vector<std::exception_ptr> m_exceptions;
  12346 #endif
  12347     };
  12348 
  12349 } // end namespace Catch
  12350 
  12351 // end catch_startup_exception_registry.h
  12352 // start catch_singletons.hpp
  12353 
  12354 namespace Catch {
  12355 
  12356     struct ISingleton {
  12357         virtual ~ISingleton();
  12358     };
  12359 
  12360     void addSingleton( ISingleton* singleton );
  12361     void cleanupSingletons();
  12362 
  12363     template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
  12364     class Singleton : SingletonImplT, public ISingleton {
  12365 
  12366         static auto getInternal() -> Singleton* {
  12367             static Singleton* s_instance = nullptr;
  12368             if( !s_instance ) {
  12369                 s_instance = new Singleton;
  12370                 addSingleton( s_instance );
  12371             }
  12372             return s_instance;
  12373         }
  12374 
  12375     public:
  12376         static auto get() -> InterfaceT const& {
  12377             return *getInternal();
  12378         }
  12379         static auto getMutable() -> MutableInterfaceT& {
  12380             return *getInternal();
  12381         }
  12382     };
  12383 
  12384 } // namespace Catch
  12385 
  12386 // end catch_singletons.hpp
  12387 namespace Catch {
  12388 
  12389     namespace {
  12390 
  12391         class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
  12392                             private NonCopyable {
  12393 
  12394         public: // IRegistryHub
  12395             RegistryHub() = default;
  12396             IReporterRegistry const& getReporterRegistry() const override {
  12397                 return m_reporterRegistry;
  12398             }
  12399             ITestCaseRegistry const& getTestCaseRegistry() const override {
  12400                 return m_testCaseRegistry;
  12401             }
  12402             IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
  12403                 return m_exceptionTranslatorRegistry;
  12404             }
  12405             ITagAliasRegistry const& getTagAliasRegistry() const override {
  12406                 return m_tagAliasRegistry;
  12407             }
  12408             StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
  12409                 return m_exceptionRegistry;
  12410             }
  12411 
  12412         public: // IMutableRegistryHub
  12413             void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
  12414                 m_reporterRegistry.registerReporter( name, factory );
  12415             }
  12416             void registerListener( IReporterFactoryPtr const& factory ) override {
  12417                 m_reporterRegistry.registerListener( factory );
  12418             }
  12419             void registerTest( TestCase const& testInfo ) override {
  12420                 m_testCaseRegistry.registerTest( testInfo );
  12421             }
  12422             void registerTranslator( const IExceptionTranslator* translator ) override {
  12423                 m_exceptionTranslatorRegistry.registerTranslator( translator );
  12424             }
  12425             void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
  12426                 m_tagAliasRegistry.add( alias, tag, lineInfo );
  12427             }
  12428             void registerStartupException() noexcept override {
  12429 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  12430                 m_exceptionRegistry.add(std::current_exception());
  12431 #else
  12432                 CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
  12433 #endif
  12434             }
  12435             IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
  12436                 return m_enumValuesRegistry;
  12437             }
  12438 
  12439         private:
  12440             TestRegistry m_testCaseRegistry;
  12441             ReporterRegistry m_reporterRegistry;
  12442             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
  12443             TagAliasRegistry m_tagAliasRegistry;
  12444             StartupExceptionRegistry m_exceptionRegistry;
  12445             Detail::EnumValuesRegistry m_enumValuesRegistry;
  12446         };
  12447     }
  12448 
  12449     using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
  12450 
  12451     IRegistryHub const& getRegistryHub() {
  12452         return RegistryHubSingleton::get();
  12453     }
  12454     IMutableRegistryHub& getMutableRegistryHub() {
  12455         return RegistryHubSingleton::getMutable();
  12456     }
  12457     void cleanUp() {
  12458         cleanupSingletons();
  12459         cleanUpContext();
  12460     }
  12461     std::string translateActiveException() {
  12462         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
  12463     }
  12464 
  12465 } // end namespace Catch
  12466 // end catch_registry_hub.cpp
  12467 // start catch_reporter_registry.cpp
  12468 
  12469 namespace Catch {
  12470 
  12471     ReporterRegistry::~ReporterRegistry() = default;
  12472 
  12473     IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
  12474         auto it =  m_factories.find( name );
  12475         if( it == m_factories.end() )
  12476             return nullptr;
  12477         return it->second->create( ReporterConfig( config ) );
  12478     }
  12479 
  12480     void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
  12481         m_factories.emplace(name, factory);
  12482     }
  12483     void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
  12484         m_listeners.push_back( factory );
  12485     }
  12486 
  12487     IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
  12488         return m_factories;
  12489     }
  12490     IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
  12491         return m_listeners;
  12492     }
  12493 
  12494 }
  12495 // end catch_reporter_registry.cpp
  12496 // start catch_result_type.cpp
  12497 
  12498 namespace Catch {
  12499 
  12500     bool isOk( ResultWas::OfType resultType ) {
  12501         return ( resultType & ResultWas::FailureBit ) == 0;
  12502     }
  12503     bool isJustInfo( int flags ) {
  12504         return flags == ResultWas::Info;
  12505     }
  12506 
  12507     ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
  12508         return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
  12509     }
  12510 
  12511     bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
  12512     bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
  12513 
  12514 } // end namespace Catch
  12515 // end catch_result_type.cpp
  12516 // start catch_run_context.cpp
  12517 
  12518 #include <cassert>
  12519 #include <algorithm>
  12520 #include <sstream>
  12521 
  12522 namespace Catch {
  12523 
  12524     namespace Generators {
  12525         struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
  12526             GeneratorBasePtr m_generator;
  12527 
  12528             GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
  12529             :   TrackerBase( nameAndLocation, ctx, parent )
  12530             {}
  12531             ~GeneratorTracker();
  12532 
  12533             static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
  12534                 std::shared_ptr<GeneratorTracker> tracker;
  12535 
  12536                 ITracker& currentTracker = ctx.currentTracker();
  12537                 // Under specific circumstances, the generator we want
  12538                 // to acquire is also the current tracker. If this is
  12539                 // the case, we have to avoid looking through current
  12540                 // tracker's children, and instead return the current
  12541                 // tracker.
  12542                 // A case where this check is important is e.g.
  12543                 //     for (int i = 0; i < 5; ++i) {
  12544                 //         int n = GENERATE(1, 2);
  12545                 //     }
  12546                 //
  12547                 // without it, the code above creates 5 nested generators.
  12548                 if (currentTracker.nameAndLocation() == nameAndLocation) {
  12549                     auto thisTracker = currentTracker.parent().findChild(nameAndLocation);
  12550                     assert(thisTracker);
  12551                     assert(thisTracker->isGeneratorTracker());
  12552                     tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker);
  12553                 } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
  12554                     assert( childTracker );
  12555                     assert( childTracker->isGeneratorTracker() );
  12556                     tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
  12557                 } else {
  12558                     tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
  12559                     currentTracker.addChild( tracker );
  12560                 }
  12561 
  12562                 if( !tracker->isComplete() ) {
  12563                     tracker->open();
  12564                 }
  12565 
  12566                 return *tracker;
  12567             }
  12568 
  12569             // TrackerBase interface
  12570             bool isGeneratorTracker() const override { return true; }
  12571             auto hasGenerator() const -> bool override {
  12572                 return !!m_generator;
  12573             }
  12574             void close() override {
  12575                 TrackerBase::close();
  12576                 // If a generator has a child (it is followed by a section)
  12577                 // and none of its children have started, then we must wait
  12578                 // until later to start consuming its values.
  12579                 // This catches cases where `GENERATE` is placed between two
  12580                 // `SECTION`s.
  12581                 // **The check for m_children.empty cannot be removed**.
  12582                 // doing so would break `GENERATE` _not_ followed by `SECTION`s.
  12583                 const bool should_wait_for_child =
  12584                     !m_children.empty() &&
  12585                     std::find_if( m_children.begin(),
  12586                                   m_children.end(),
  12587                                   []( TestCaseTracking::ITrackerPtr tracker ) {
  12588                                       return tracker->hasStarted();
  12589                                   } ) == m_children.end();
  12590 
  12591                 // This check is a bit tricky, because m_generator->next()
  12592                 // has a side-effect, where it consumes generator's current
  12593                 // value, but we do not want to invoke the side-effect if
  12594                 // this generator is still waiting for any child to start.
  12595                 if ( should_wait_for_child ||
  12596                      ( m_runState == CompletedSuccessfully &&
  12597                        m_generator->next() ) ) {
  12598                     m_children.clear();
  12599                     m_runState = Executing;
  12600                 }
  12601             }
  12602 
  12603             // IGeneratorTracker interface
  12604             auto getGenerator() const -> GeneratorBasePtr const& override {
  12605                 return m_generator;
  12606             }
  12607             void setGenerator( GeneratorBasePtr&& generator ) override {
  12608                 m_generator = std::move( generator );
  12609             }
  12610         };
  12611         GeneratorTracker::~GeneratorTracker() {}
  12612     }
  12613 
  12614     RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
  12615     :   m_runInfo(_config->name()),
  12616         m_context(getCurrentMutableContext()),
  12617         m_config(_config),
  12618         m_reporter(std::move(reporter)),
  12619         m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
  12620         m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
  12621     {
  12622         m_context.setRunner(this);
  12623         m_context.setConfig(m_config);
  12624         m_context.setResultCapture(this);
  12625         m_reporter->testRunStarting(m_runInfo);
  12626     }
  12627 
  12628     RunContext::~RunContext() {
  12629         m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
  12630     }
  12631 
  12632     void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
  12633         m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
  12634     }
  12635 
  12636     void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
  12637         m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
  12638     }
  12639 
  12640     Totals RunContext::runTest(TestCase const& testCase) {
  12641         Totals prevTotals = m_totals;
  12642 
  12643         std::string redirectedCout;
  12644         std::string redirectedCerr;
  12645 
  12646         auto const& testInfo = testCase.getTestCaseInfo();
  12647 
  12648         m_reporter->testCaseStarting(testInfo);
  12649 
  12650         m_activeTestCase = &testCase;
  12651 
  12652         ITracker& rootTracker = m_trackerContext.startRun();
  12653         assert(rootTracker.isSectionTracker());
  12654         static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
  12655         do {
  12656             m_trackerContext.startCycle();
  12657             m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
  12658             runCurrentTest(redirectedCout, redirectedCerr);
  12659         } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
  12660 
  12661         Totals deltaTotals = m_totals.delta(prevTotals);
  12662         if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
  12663             deltaTotals.assertions.failed++;
  12664             deltaTotals.testCases.passed--;
  12665             deltaTotals.testCases.failed++;
  12666         }
  12667         m_totals.testCases += deltaTotals.testCases;
  12668         m_reporter->testCaseEnded(TestCaseStats(testInfo,
  12669                                   deltaTotals,
  12670                                   redirectedCout,
  12671                                   redirectedCerr,
  12672                                   aborting()));
  12673 
  12674         m_activeTestCase = nullptr;
  12675         m_testCaseTracker = nullptr;
  12676 
  12677         return deltaTotals;
  12678     }
  12679 
  12680     IConfigPtr RunContext::config() const {
  12681         return m_config;
  12682     }
  12683 
  12684     IStreamingReporter& RunContext::reporter() const {
  12685         return *m_reporter;
  12686     }
  12687 
  12688     void RunContext::assertionEnded(AssertionResult const & result) {
  12689         if (result.getResultType() == ResultWas::Ok) {
  12690             m_totals.assertions.passed++;
  12691             m_lastAssertionPassed = true;
  12692         } else if (!result.isOk()) {
  12693             m_lastAssertionPassed = false;
  12694             if( m_activeTestCase->getTestCaseInfo().okToFail() )
  12695                 m_totals.assertions.failedButOk++;
  12696             else
  12697                 m_totals.assertions.failed++;
  12698         }
  12699         else {
  12700             m_lastAssertionPassed = true;
  12701         }
  12702 
  12703         // We have no use for the return value (whether messages should be cleared), because messages were made scoped
  12704         // and should be let to clear themselves out.
  12705         static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
  12706 
  12707         if (result.getResultType() != ResultWas::Warning)
  12708             m_messageScopes.clear();
  12709 
  12710         // Reset working state
  12711         resetAssertionInfo();
  12712         m_lastResult = result;
  12713     }
  12714     void RunContext::resetAssertionInfo() {
  12715         m_lastAssertionInfo.macroName = StringRef();
  12716         m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
  12717     }
  12718 
  12719     bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
  12720         ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
  12721         if (!sectionTracker.isOpen())
  12722             return false;
  12723         m_activeSections.push_back(&sectionTracker);
  12724 
  12725         m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
  12726 
  12727         m_reporter->sectionStarting(sectionInfo);
  12728 
  12729         assertions = m_totals.assertions;
  12730 
  12731         return true;
  12732     }
  12733     auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
  12734         using namespace Generators;
  12735         GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,
  12736                                                               TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) );
  12737         m_lastAssertionInfo.lineInfo = lineInfo;
  12738         return tracker;
  12739     }
  12740 
  12741     bool RunContext::testForMissingAssertions(Counts& assertions) {
  12742         if (assertions.total() != 0)
  12743             return false;
  12744         if (!m_config->warnAboutMissingAssertions())
  12745             return false;
  12746         if (m_trackerContext.currentTracker().hasChildren())
  12747             return false;
  12748         m_totals.assertions.failed++;
  12749         assertions.failed++;
  12750         return true;
  12751     }
  12752 
  12753     void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
  12754         Counts assertions = m_totals.assertions - endInfo.prevAssertions;
  12755         bool missingAssertions = testForMissingAssertions(assertions);
  12756 
  12757         if (!m_activeSections.empty()) {
  12758             m_activeSections.back()->close();
  12759             m_activeSections.pop_back();
  12760         }
  12761 
  12762         m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
  12763         m_messages.clear();
  12764         m_messageScopes.clear();
  12765     }
  12766 
  12767     void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
  12768         if (m_unfinishedSections.empty())
  12769             m_activeSections.back()->fail();
  12770         else
  12771             m_activeSections.back()->close();
  12772         m_activeSections.pop_back();
  12773 
  12774         m_unfinishedSections.push_back(endInfo);
  12775     }
  12776 
  12777 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  12778     void RunContext::benchmarkPreparing(std::string const& name) {
  12779         m_reporter->benchmarkPreparing(name);
  12780     }
  12781     void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
  12782         m_reporter->benchmarkStarting( info );
  12783     }
  12784     void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
  12785         m_reporter->benchmarkEnded( stats );
  12786     }
  12787     void RunContext::benchmarkFailed(std::string const & error) {
  12788         m_reporter->benchmarkFailed(error);
  12789     }
  12790 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  12791 
  12792     void RunContext::pushScopedMessage(MessageInfo const & message) {
  12793         m_messages.push_back(message);
  12794     }
  12795 
  12796     void RunContext::popScopedMessage(MessageInfo const & message) {
  12797         m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
  12798     }
  12799 
  12800     void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
  12801         m_messageScopes.emplace_back( builder );
  12802     }
  12803 
  12804     std::string RunContext::getCurrentTestName() const {
  12805         return m_activeTestCase
  12806             ? m_activeTestCase->getTestCaseInfo().name
  12807             : std::string();
  12808     }
  12809 
  12810     const AssertionResult * RunContext::getLastResult() const {
  12811         return &(*m_lastResult);
  12812     }
  12813 
  12814     void RunContext::exceptionEarlyReported() {
  12815         m_shouldReportUnexpected = false;
  12816     }
  12817 
  12818     void RunContext::handleFatalErrorCondition( StringRef message ) {
  12819         // First notify reporter that bad things happened
  12820         m_reporter->fatalErrorEncountered(message);
  12821 
  12822         // Don't rebuild the result -- the stringification itself can cause more fatal errors
  12823         // Instead, fake a result data.
  12824         AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
  12825         tempResult.message = static_cast<std::string>(message);
  12826         AssertionResult result(m_lastAssertionInfo, tempResult);
  12827 
  12828         assertionEnded(result);
  12829 
  12830         handleUnfinishedSections();
  12831 
  12832         // Recreate section for test case (as we will lose the one that was in scope)
  12833         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  12834         SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
  12835 
  12836         Counts assertions;
  12837         assertions.failed = 1;
  12838         SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
  12839         m_reporter->sectionEnded(testCaseSectionStats);
  12840 
  12841         auto const& testInfo = m_activeTestCase->getTestCaseInfo();
  12842 
  12843         Totals deltaTotals;
  12844         deltaTotals.testCases.failed = 1;
  12845         deltaTotals.assertions.failed = 1;
  12846         m_reporter->testCaseEnded(TestCaseStats(testInfo,
  12847                                   deltaTotals,
  12848                                   std::string(),
  12849                                   std::string(),
  12850                                   false));
  12851         m_totals.testCases.failed++;
  12852         testGroupEnded(std::string(), m_totals, 1, 1);
  12853         m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
  12854     }
  12855 
  12856     bool RunContext::lastAssertionPassed() {
  12857          return m_lastAssertionPassed;
  12858     }
  12859 
  12860     void RunContext::assertionPassed() {
  12861         m_lastAssertionPassed = true;
  12862         ++m_totals.assertions.passed;
  12863         resetAssertionInfo();
  12864         m_messageScopes.clear();
  12865     }
  12866 
  12867     bool RunContext::aborting() const {
  12868         return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
  12869     }
  12870 
  12871     void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
  12872         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  12873         SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
  12874         m_reporter->sectionStarting(testCaseSection);
  12875         Counts prevAssertions = m_totals.assertions;
  12876         double duration = 0;
  12877         m_shouldReportUnexpected = true;
  12878         m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
  12879 
  12880         seedRng(*m_config);
  12881 
  12882         Timer timer;
  12883         CATCH_TRY {
  12884             if (m_reporter->getPreferences().shouldRedirectStdOut) {
  12885 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
  12886                 RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
  12887 
  12888                 timer.start();
  12889                 invokeActiveTestCase();
  12890 #else
  12891                 OutputRedirect r(redirectedCout, redirectedCerr);
  12892                 timer.start();
  12893                 invokeActiveTestCase();
  12894 #endif
  12895             } else {
  12896                 timer.start();
  12897                 invokeActiveTestCase();
  12898             }
  12899             duration = timer.getElapsedSeconds();
  12900         } CATCH_CATCH_ANON (TestFailureException&) {
  12901             // This just means the test was aborted due to failure
  12902         } CATCH_CATCH_ALL {
  12903             // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
  12904             // are reported without translation at the point of origin.
  12905             if( m_shouldReportUnexpected ) {
  12906                 AssertionReaction dummyReaction;
  12907                 handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
  12908             }
  12909         }
  12910         Counts assertions = m_totals.assertions - prevAssertions;
  12911         bool missingAssertions = testForMissingAssertions(assertions);
  12912 
  12913         m_testCaseTracker->close();
  12914         handleUnfinishedSections();
  12915         m_messages.clear();
  12916         m_messageScopes.clear();
  12917 
  12918         SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
  12919         m_reporter->sectionEnded(testCaseSectionStats);
  12920     }
  12921 
  12922     void RunContext::invokeActiveTestCase() {
  12923         FatalConditionHandler fatalConditionHandler; // Handle signals
  12924         m_activeTestCase->invoke();
  12925         fatalConditionHandler.reset();
  12926     }
  12927 
  12928     void RunContext::handleUnfinishedSections() {
  12929         // If sections ended prematurely due to an exception we stored their
  12930         // infos here so we can tear them down outside the unwind process.
  12931         for (auto it = m_unfinishedSections.rbegin(),
  12932              itEnd = m_unfinishedSections.rend();
  12933              it != itEnd;
  12934              ++it)
  12935             sectionEnded(*it);
  12936         m_unfinishedSections.clear();
  12937     }
  12938 
  12939     void RunContext::handleExpr(
  12940         AssertionInfo const& info,
  12941         ITransientExpression const& expr,
  12942         AssertionReaction& reaction
  12943     ) {
  12944         m_reporter->assertionStarting( info );
  12945 
  12946         bool negated = isFalseTest( info.resultDisposition );
  12947         bool result = expr.getResult() != negated;
  12948 
  12949         if( result ) {
  12950             if (!m_includeSuccessfulResults) {
  12951                 assertionPassed();
  12952             }
  12953             else {
  12954                 reportExpr(info, ResultWas::Ok, &expr, negated);
  12955             }
  12956         }
  12957         else {
  12958             reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
  12959             populateReaction( reaction );
  12960         }
  12961     }
  12962     void RunContext::reportExpr(
  12963             AssertionInfo const &info,
  12964             ResultWas::OfType resultType,
  12965             ITransientExpression const *expr,
  12966             bool negated ) {
  12967 
  12968         m_lastAssertionInfo = info;
  12969         AssertionResultData data( resultType, LazyExpression( negated ) );
  12970 
  12971         AssertionResult assertionResult{ info, data };
  12972         assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
  12973 
  12974         assertionEnded( assertionResult );
  12975     }
  12976 
  12977     void RunContext::handleMessage(
  12978             AssertionInfo const& info,
  12979             ResultWas::OfType resultType,
  12980             StringRef const& message,
  12981             AssertionReaction& reaction
  12982     ) {
  12983         m_reporter->assertionStarting( info );
  12984 
  12985         m_lastAssertionInfo = info;
  12986 
  12987         AssertionResultData data( resultType, LazyExpression( false ) );
  12988         data.message = static_cast<std::string>(message);
  12989         AssertionResult assertionResult{ m_lastAssertionInfo, data };
  12990         assertionEnded( assertionResult );
  12991         if( !assertionResult.isOk() )
  12992             populateReaction( reaction );
  12993     }
  12994     void RunContext::handleUnexpectedExceptionNotThrown(
  12995             AssertionInfo const& info,
  12996             AssertionReaction& reaction
  12997     ) {
  12998         handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
  12999     }
  13000 
  13001     void RunContext::handleUnexpectedInflightException(
  13002             AssertionInfo const& info,
  13003             std::string const& message,
  13004             AssertionReaction& reaction
  13005     ) {
  13006         m_lastAssertionInfo = info;
  13007 
  13008         AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
  13009         data.message = message;
  13010         AssertionResult assertionResult{ info, data };
  13011         assertionEnded( assertionResult );
  13012         populateReaction( reaction );
  13013     }
  13014 
  13015     void RunContext::populateReaction( AssertionReaction& reaction ) {
  13016         reaction.shouldDebugBreak = m_config->shouldDebugBreak();
  13017         reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
  13018     }
  13019 
  13020     void RunContext::handleIncomplete(
  13021             AssertionInfo const& info
  13022     ) {
  13023         m_lastAssertionInfo = info;
  13024 
  13025         AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
  13026         data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
  13027         AssertionResult assertionResult{ info, data };
  13028         assertionEnded( assertionResult );
  13029     }
  13030     void RunContext::handleNonExpr(
  13031             AssertionInfo const &info,
  13032             ResultWas::OfType resultType,
  13033             AssertionReaction &reaction
  13034     ) {
  13035         m_lastAssertionInfo = info;
  13036 
  13037         AssertionResultData data( resultType, LazyExpression( false ) );
  13038         AssertionResult assertionResult{ info, data };
  13039         assertionEnded( assertionResult );
  13040 
  13041         if( !assertionResult.isOk() )
  13042             populateReaction( reaction );
  13043     }
  13044 
  13045     IResultCapture& getResultCapture() {
  13046         if (auto* capture = getCurrentContext().getResultCapture())
  13047             return *capture;
  13048         else
  13049             CATCH_INTERNAL_ERROR("No result capture instance");
  13050     }
  13051 
  13052     void seedRng(IConfig const& config) {
  13053         if (config.rngSeed() != 0) {
  13054             std::srand(config.rngSeed());
  13055             rng().seed(config.rngSeed());
  13056         }
  13057     }
  13058 
  13059     unsigned int rngSeed() {
  13060         return getCurrentContext().getConfig()->rngSeed();
  13061     }
  13062 
  13063 }
  13064 // end catch_run_context.cpp
  13065 // start catch_section.cpp
  13066 
  13067 namespace Catch {
  13068 
  13069     Section::Section( SectionInfo const& info )
  13070     :   m_info( info ),
  13071         m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
  13072     {
  13073         m_timer.start();
  13074     }
  13075 
  13076     Section::~Section() {
  13077         if( m_sectionIncluded ) {
  13078             SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
  13079             if( uncaught_exceptions() )
  13080                 getResultCapture().sectionEndedEarly( endInfo );
  13081             else
  13082                 getResultCapture().sectionEnded( endInfo );
  13083         }
  13084     }
  13085 
  13086     // This indicates whether the section should be executed or not
  13087     Section::operator bool() const {
  13088         return m_sectionIncluded;
  13089     }
  13090 
  13091 } // end namespace Catch
  13092 // end catch_section.cpp
  13093 // start catch_section_info.cpp
  13094 
  13095 namespace Catch {
  13096 
  13097     SectionInfo::SectionInfo
  13098         (   SourceLineInfo const& _lineInfo,
  13099             std::string const& _name )
  13100     :   name( _name ),
  13101         lineInfo( _lineInfo )
  13102     {}
  13103 
  13104 } // end namespace Catch
  13105 // end catch_section_info.cpp
  13106 // start catch_session.cpp
  13107 
  13108 // start catch_session.h
  13109 
  13110 #include <memory>
  13111 
  13112 namespace Catch {
  13113 
  13114     class Session : NonCopyable {
  13115     public:
  13116 
  13117         Session();
  13118         ~Session() override;
  13119 
  13120         void showHelp() const;
  13121         void libIdentify();
  13122 
  13123         int applyCommandLine( int argc, char const * const * argv );
  13124     #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
  13125         int applyCommandLine( int argc, wchar_t const * const * argv );
  13126     #endif
  13127 
  13128         void useConfigData( ConfigData const& configData );
  13129 
  13130         template<typename CharT>
  13131         int run(int argc, CharT const * const argv[]) {
  13132             if (m_startupExceptions)
  13133                 return 1;
  13134             int returnCode = applyCommandLine(argc, argv);
  13135             if (returnCode == 0)
  13136                 returnCode = run();
  13137             return returnCode;
  13138         }
  13139 
  13140         int run();
  13141 
  13142         clara::Parser const& cli() const;
  13143         void cli( clara::Parser const& newParser );
  13144         ConfigData& configData();
  13145         Config& config();
  13146     private:
  13147         int runInternal();
  13148 
  13149         clara::Parser m_cli;
  13150         ConfigData m_configData;
  13151         std::shared_ptr<Config> m_config;
  13152         bool m_startupExceptions = false;
  13153     };
  13154 
  13155 } // end namespace Catch
  13156 
  13157 // end catch_session.h
  13158 // start catch_version.h
  13159 
  13160 #include <iosfwd>
  13161 
  13162 namespace Catch {
  13163 
  13164     // Versioning information
  13165     struct Version {
  13166         Version( Version const& ) = delete;
  13167         Version& operator=( Version const& ) = delete;
  13168         Version(    unsigned int _majorVersion,
  13169                     unsigned int _minorVersion,
  13170                     unsigned int _patchNumber,
  13171                     char const * const _branchName,
  13172                     unsigned int _buildNumber );
  13173 
  13174         unsigned int const majorVersion;
  13175         unsigned int const minorVersion;
  13176         unsigned int const patchNumber;
  13177 
  13178         // buildNumber is only used if branchName is not null
  13179         char const * const branchName;
  13180         unsigned int const buildNumber;
  13181 
  13182         friend std::ostream& operator << ( std::ostream& os, Version const& version );
  13183     };
  13184 
  13185     Version const& libraryVersion();
  13186 }
  13187 
  13188 // end catch_version.h
  13189 #include <cstdlib>
  13190 #include <iomanip>
  13191 #include <set>
  13192 #include <iterator>
  13193 
  13194 namespace Catch {
  13195 
  13196     namespace {
  13197         const int MaxExitCode = 255;
  13198 
  13199         IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
  13200             auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
  13201             CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
  13202 
  13203             return reporter;
  13204         }
  13205 
  13206         IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
  13207             if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
  13208                 return createReporter(config->getReporterName(), config);
  13209             }
  13210 
  13211             // On older platforms, returning std::unique_ptr<ListeningReporter>
  13212             // when the return type is std::unique_ptr<IStreamingReporter>
  13213             // doesn't compile without a std::move call. However, this causes
  13214             // a warning on newer platforms. Thus, we have to work around
  13215             // it a bit and downcast the pointer manually.
  13216             auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
  13217             auto& multi = static_cast<ListeningReporter&>(*ret);
  13218             auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
  13219             for (auto const& listener : listeners) {
  13220                 multi.addListener(listener->create(Catch::ReporterConfig(config)));
  13221             }
  13222             multi.addReporter(createReporter(config->getReporterName(), config));
  13223             return ret;
  13224         }
  13225 
  13226         class TestGroup {
  13227         public:
  13228             explicit TestGroup(std::shared_ptr<Config> const& config)
  13229             : m_config{config}
  13230             , m_context{config, makeReporter(config)}
  13231             {
  13232                 auto const& allTestCases = getAllTestCasesSorted(*m_config);
  13233                 m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
  13234                 auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
  13235 
  13236                 if (m_matches.empty() && invalidArgs.empty()) {
  13237                     for (auto const& test : allTestCases)
  13238                         if (!test.isHidden())
  13239                             m_tests.emplace(&test);
  13240                 } else {
  13241                     for (auto const& match : m_matches)
  13242                         m_tests.insert(match.tests.begin(), match.tests.end());
  13243                 }
  13244             }
  13245 
  13246             Totals execute() {
  13247                 auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
  13248                 Totals totals;
  13249                 m_context.testGroupStarting(m_config->name(), 1, 1);
  13250                 for (auto const& testCase : m_tests) {
  13251                     if (!m_context.aborting())
  13252                         totals += m_context.runTest(*testCase);
  13253                     else
  13254                         m_context.reporter().skipTest(*testCase);
  13255                 }
  13256 
  13257                 for (auto const& match : m_matches) {
  13258                     if (match.tests.empty()) {
  13259                         m_context.reporter().noMatchingTestCases(match.name);
  13260                         totals.error = -1;
  13261                     }
  13262                 }
  13263 
  13264                 if (!invalidArgs.empty()) {
  13265                     for (auto const& invalidArg: invalidArgs)
  13266                          m_context.reporter().reportInvalidArguments(invalidArg);
  13267                 }
  13268 
  13269                 m_context.testGroupEnded(m_config->name(), totals, 1, 1);
  13270                 return totals;
  13271             }
  13272 
  13273         private:
  13274             using Tests = std::set<TestCase const*>;
  13275 
  13276             std::shared_ptr<Config> m_config;
  13277             RunContext m_context;
  13278             Tests m_tests;
  13279             TestSpec::Matches m_matches;
  13280         };
  13281 
  13282         void applyFilenamesAsTags(Catch::IConfig const& config) {
  13283             auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
  13284             for (auto& testCase : tests) {
  13285                 auto tags = testCase.tags;
  13286 
  13287                 std::string filename = testCase.lineInfo.file;
  13288                 auto lastSlash = filename.find_last_of("\\/");
  13289                 if (lastSlash != std::string::npos) {
  13290                     filename.erase(0, lastSlash);
  13291                     filename[0] = '#';
  13292                 }
  13293 
  13294                 auto lastDot = filename.find_last_of('.');
  13295                 if (lastDot != std::string::npos) {
  13296                     filename.erase(lastDot);
  13297                 }
  13298 
  13299                 tags.push_back(std::move(filename));
  13300                 setTags(testCase, tags);
  13301             }
  13302         }
  13303 
  13304     } // anon namespace
  13305 
  13306     Session::Session() {
  13307         static bool alreadyInstantiated = false;
  13308         if( alreadyInstantiated ) {
  13309             CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
  13310             CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
  13311         }
  13312 
  13313         // There cannot be exceptions at startup in no-exception mode.
  13314 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  13315         const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
  13316         if ( !exceptions.empty() ) {
  13317             config();
  13318             getCurrentMutableContext().setConfig(m_config);
  13319 
  13320             m_startupExceptions = true;
  13321             Colour colourGuard( Colour::Red );
  13322             Catch::cerr() << "Errors occurred during startup!" << '\n';
  13323             // iterate over all exceptions and notify user
  13324             for ( const auto& ex_ptr : exceptions ) {
  13325                 try {
  13326                     std::rethrow_exception(ex_ptr);
  13327                 } catch ( std::exception const& ex ) {
  13328                     Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
  13329                 }
  13330             }
  13331         }
  13332 #endif
  13333 
  13334         alreadyInstantiated = true;
  13335         m_cli = makeCommandLineParser( m_configData );
  13336     }
  13337     Session::~Session() {
  13338         Catch::cleanUp();
  13339     }
  13340 
  13341     void Session::showHelp() const {
  13342         Catch::cout()
  13343                 << "\nCatch v" << libraryVersion() << "\n"
  13344                 << m_cli << std::endl
  13345                 << "For more detailed usage please see the project docs\n" << std::endl;
  13346     }
  13347     void Session::libIdentify() {
  13348         Catch::cout()
  13349                 << std::left << std::setw(16) << "description: " << "A Catch2 test executable\n"
  13350                 << std::left << std::setw(16) << "category: " << "testframework\n"
  13351                 << std::left << std::setw(16) << "framework: " << "Catch Test\n"
  13352                 << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
  13353     }
  13354 
  13355     int Session::applyCommandLine( int argc, char const * const * argv ) {
  13356         if( m_startupExceptions )
  13357             return 1;
  13358 
  13359         auto result = m_cli.parse( clara::Args( argc, argv ) );
  13360         if( !result ) {
  13361             config();
  13362             getCurrentMutableContext().setConfig(m_config);
  13363             Catch::cerr()
  13364                 << Colour( Colour::Red )
  13365                 << "\nError(s) in input:\n"
  13366                 << Column( result.errorMessage() ).indent( 2 )
  13367                 << "\n\n";
  13368             Catch::cerr() << "Run with -? for usage\n" << std::endl;
  13369             return MaxExitCode;
  13370         }
  13371 
  13372         if( m_configData.showHelp )
  13373             showHelp();
  13374         if( m_configData.libIdentify )
  13375             libIdentify();
  13376         m_config.reset();
  13377         return 0;
  13378     }
  13379 
  13380 #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
  13381     int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
  13382 
  13383         char **utf8Argv = new char *[ argc ];
  13384 
  13385         for ( int i = 0; i < argc; ++i ) {
  13386             int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr );
  13387 
  13388             utf8Argv[ i ] = new char[ bufSize ];
  13389 
  13390             WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr );
  13391         }
  13392 
  13393         int returnCode = applyCommandLine( argc, utf8Argv );
  13394 
  13395         for ( int i = 0; i < argc; ++i )
  13396             delete [] utf8Argv[ i ];
  13397 
  13398         delete [] utf8Argv;
  13399 
  13400         return returnCode;
  13401     }
  13402 #endif
  13403 
  13404     void Session::useConfigData( ConfigData const& configData ) {
  13405         m_configData = configData;
  13406         m_config.reset();
  13407     }
  13408 
  13409     int Session::run() {
  13410         if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
  13411             Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
  13412             static_cast<void>(std::getchar());
  13413         }
  13414         int exitCode = runInternal();
  13415         if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
  13416             Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
  13417             static_cast<void>(std::getchar());
  13418         }
  13419         return exitCode;
  13420     }
  13421 
  13422     clara::Parser const& Session::cli() const {
  13423         return m_cli;
  13424     }
  13425     void Session::cli( clara::Parser const& newParser ) {
  13426         m_cli = newParser;
  13427     }
  13428     ConfigData& Session::configData() {
  13429         return m_configData;
  13430     }
  13431     Config& Session::config() {
  13432         if( !m_config )
  13433             m_config = std::make_shared<Config>( m_configData );
  13434         return *m_config;
  13435     }
  13436 
  13437     int Session::runInternal() {
  13438         if( m_startupExceptions )
  13439             return 1;
  13440 
  13441         if (m_configData.showHelp || m_configData.libIdentify) {
  13442             return 0;
  13443         }
  13444 
  13445         CATCH_TRY {
  13446             config(); // Force config to be constructed
  13447 
  13448             seedRng( *m_config );
  13449 
  13450             if( m_configData.filenamesAsTags )
  13451                 applyFilenamesAsTags( *m_config );
  13452 
  13453             // Handle list request
  13454             if( Option<std::size_t> listed = list( m_config ) )
  13455                 return static_cast<int>( *listed );
  13456 
  13457             TestGroup tests { m_config };
  13458             auto const totals = tests.execute();
  13459 
  13460             if( m_config->warnAboutNoTests() && totals.error == -1 )
  13461                 return 2;
  13462 
  13463             // Note that on unices only the lower 8 bits are usually used, clamping
  13464             // the return value to 255 prevents false negative when some multiple
  13465             // of 256 tests has failed
  13466             return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
  13467         }
  13468 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  13469         catch( std::exception& ex ) {
  13470             Catch::cerr() << ex.what() << std::endl;
  13471             return MaxExitCode;
  13472         }
  13473 #endif
  13474     }
  13475 
  13476 } // end namespace Catch
  13477 // end catch_session.cpp
  13478 // start catch_singletons.cpp
  13479 
  13480 #include <vector>
  13481 
  13482 namespace Catch {
  13483 
  13484     namespace {
  13485         static auto getSingletons() -> std::vector<ISingleton*>*& {
  13486             static std::vector<ISingleton*>* g_singletons = nullptr;
  13487             if( !g_singletons )
  13488                 g_singletons = new std::vector<ISingleton*>();
  13489             return g_singletons;
  13490         }
  13491     }
  13492 
  13493     ISingleton::~ISingleton() {}
  13494 
  13495     void addSingleton(ISingleton* singleton ) {
  13496         getSingletons()->push_back( singleton );
  13497     }
  13498     void cleanupSingletons() {
  13499         auto& singletons = getSingletons();
  13500         for( auto singleton : *singletons )
  13501             delete singleton;
  13502         delete singletons;
  13503         singletons = nullptr;
  13504     }
  13505 
  13506 } // namespace Catch
  13507 // end catch_singletons.cpp
  13508 // start catch_startup_exception_registry.cpp
  13509 
  13510 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  13511 namespace Catch {
  13512 void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
  13513         CATCH_TRY {
  13514             m_exceptions.push_back(exception);
  13515         } CATCH_CATCH_ALL {
  13516             // If we run out of memory during start-up there's really not a lot more we can do about it
  13517             std::terminate();
  13518         }
  13519     }
  13520 
  13521     std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
  13522         return m_exceptions;
  13523     }
  13524 
  13525 } // end namespace Catch
  13526 #endif
  13527 // end catch_startup_exception_registry.cpp
  13528 // start catch_stream.cpp
  13529 
  13530 #include <cstdio>
  13531 #include <iostream>
  13532 #include <fstream>
  13533 #include <sstream>
  13534 #include <vector>
  13535 #include <memory>
  13536 
  13537 namespace Catch {
  13538 
  13539     Catch::IStream::~IStream() = default;
  13540 
  13541     namespace Detail { namespace {
  13542         template<typename WriterF, std::size_t bufferSize=256>
  13543         class StreamBufImpl : public std::streambuf {
  13544             char data[bufferSize];
  13545             WriterF m_writer;
  13546 
  13547         public:
  13548             StreamBufImpl() {
  13549                 setp( data, data + sizeof(data) );
  13550             }
  13551 
  13552             ~StreamBufImpl() noexcept {
  13553                 StreamBufImpl::sync();
  13554             }
  13555 
  13556         private:
  13557             int overflow( int c ) override {
  13558                 sync();
  13559 
  13560                 if( c != EOF ) {
  13561                     if( pbase() == epptr() )
  13562                         m_writer( std::string( 1, static_cast<char>( c ) ) );
  13563                     else
  13564                         sputc( static_cast<char>( c ) );
  13565                 }
  13566                 return 0;
  13567             }
  13568 
  13569             int sync() override {
  13570                 if( pbase() != pptr() ) {
  13571                     m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
  13572                     setp( pbase(), epptr() );
  13573                 }
  13574                 return 0;
  13575             }
  13576         };
  13577 
  13578         ///////////////////////////////////////////////////////////////////////////
  13579 
  13580         struct OutputDebugWriter {
  13581 
  13582             void operator()( std::string const&str ) {
  13583                 writeToDebugConsole( str );
  13584             }
  13585         };
  13586 
  13587         ///////////////////////////////////////////////////////////////////////////
  13588 
  13589         class FileStream : public IStream {
  13590             mutable std::ofstream m_ofs;
  13591         public:
  13592             FileStream( StringRef filename ) {
  13593                 m_ofs.open( filename.c_str() );
  13594                 CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
  13595             }
  13596             ~FileStream() override = default;
  13597         public: // IStream
  13598             std::ostream& stream() const override {
  13599                 return m_ofs;
  13600             }
  13601         };
  13602 
  13603         ///////////////////////////////////////////////////////////////////////////
  13604 
  13605         class CoutStream : public IStream {
  13606             mutable std::ostream m_os;
  13607         public:
  13608             // Store the streambuf from cout up-front because
  13609             // cout may get redirected when running tests
  13610             CoutStream() : m_os( Catch::cout().rdbuf() ) {}
  13611             ~CoutStream() override = default;
  13612 
  13613         public: // IStream
  13614             std::ostream& stream() const override { return m_os; }
  13615         };
  13616 
  13617         ///////////////////////////////////////////////////////////////////////////
  13618 
  13619         class DebugOutStream : public IStream {
  13620             std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
  13621             mutable std::ostream m_os;
  13622         public:
  13623             DebugOutStream()
  13624             :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
  13625                 m_os( m_streamBuf.get() )
  13626             {}
  13627 
  13628             ~DebugOutStream() override = default;
  13629 
  13630         public: // IStream
  13631             std::ostream& stream() const override { return m_os; }
  13632         };
  13633 
  13634     }} // namespace anon::detail
  13635 
  13636     ///////////////////////////////////////////////////////////////////////////
  13637 
  13638     auto makeStream( StringRef const &filename ) -> IStream const* {
  13639         if( filename.empty() )
  13640             return new Detail::CoutStream();
  13641         else if( filename[0] == '%' ) {
  13642             if( filename == "%debug" )
  13643                 return new Detail::DebugOutStream();
  13644             else
  13645                 CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
  13646         }
  13647         else
  13648             return new Detail::FileStream( filename );
  13649     }
  13650 
  13651     // This class encapsulates the idea of a pool of ostringstreams that can be reused.
  13652     struct StringStreams {
  13653         std::vector<std::unique_ptr<std::ostringstream>> m_streams;
  13654         std::vector<std::size_t> m_unused;
  13655         std::ostringstream m_referenceStream; // Used for copy state/ flags from
  13656 
  13657         auto add() -> std::size_t {
  13658             if( m_unused.empty() ) {
  13659                 m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
  13660                 return m_streams.size()-1;
  13661             }
  13662             else {
  13663                 auto index = m_unused.back();
  13664                 m_unused.pop_back();
  13665                 return index;
  13666             }
  13667         }
  13668 
  13669         void release( std::size_t index ) {
  13670             m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
  13671             m_unused.push_back(index);
  13672         }
  13673     };
  13674 
  13675     ReusableStringStream::ReusableStringStream()
  13676     :   m_index( Singleton<StringStreams>::getMutable().add() ),
  13677         m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
  13678     {}
  13679 
  13680     ReusableStringStream::~ReusableStringStream() {
  13681         static_cast<std::ostringstream*>( m_oss )->str("");
  13682         m_oss->clear();
  13683         Singleton<StringStreams>::getMutable().release( m_index );
  13684     }
  13685 
  13686     auto ReusableStringStream::str() const -> std::string {
  13687         return static_cast<std::ostringstream*>( m_oss )->str();
  13688     }
  13689 
  13690     ///////////////////////////////////////////////////////////////////////////
  13691 
  13692 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
  13693     std::ostream& cout() { return std::cout; }
  13694     std::ostream& cerr() { return std::cerr; }
  13695     std::ostream& clog() { return std::clog; }
  13696 #endif
  13697 }
  13698 // end catch_stream.cpp
  13699 // start catch_string_manip.cpp
  13700 
  13701 #include <algorithm>
  13702 #include <ostream>
  13703 #include <cstring>
  13704 #include <cctype>
  13705 #include <vector>
  13706 
  13707 namespace Catch {
  13708 
  13709     namespace {
  13710         char toLowerCh(char c) {
  13711             return static_cast<char>( std::tolower( static_cast<unsigned char>(c) ) );
  13712         }
  13713     }
  13714 
  13715     bool startsWith( std::string const& s, std::string const& prefix ) {
  13716         return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
  13717     }
  13718     bool startsWith( std::string const& s, char prefix ) {
  13719         return !s.empty() && s[0] == prefix;
  13720     }
  13721     bool endsWith( std::string const& s, std::string const& suffix ) {
  13722         return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
  13723     }
  13724     bool endsWith( std::string const& s, char suffix ) {
  13725         return !s.empty() && s[s.size()-1] == suffix;
  13726     }
  13727     bool contains( std::string const& s, std::string const& infix ) {
  13728         return s.find( infix ) != std::string::npos;
  13729     }
  13730     void toLowerInPlace( std::string& s ) {
  13731         std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
  13732     }
  13733     std::string toLower( std::string const& s ) {
  13734         std::string lc = s;
  13735         toLowerInPlace( lc );
  13736         return lc;
  13737     }
  13738     std::string trim( std::string const& str ) {
  13739         static char const* whitespaceChars = "\n\r\t ";
  13740         std::string::size_type start = str.find_first_not_of( whitespaceChars );
  13741         std::string::size_type end = str.find_last_not_of( whitespaceChars );
  13742 
  13743         return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
  13744     }
  13745 
  13746     StringRef trim(StringRef ref) {
  13747         const auto is_ws = [](char c) {
  13748             return c == ' ' || c == '\t' || c == '\n' || c == '\r';
  13749         };
  13750         size_t real_begin = 0;
  13751         while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }
  13752         size_t real_end = ref.size();
  13753         while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }
  13754 
  13755         return ref.substr(real_begin, real_end - real_begin);
  13756     }
  13757 
  13758     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
  13759         bool replaced = false;
  13760         std::size_t i = str.find( replaceThis );
  13761         while( i != std::string::npos ) {
  13762             replaced = true;
  13763             str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
  13764             if( i < str.size()-withThis.size() )
  13765                 i = str.find( replaceThis, i+withThis.size() );
  13766             else
  13767                 i = std::string::npos;
  13768         }
  13769         return replaced;
  13770     }
  13771 
  13772     std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
  13773         std::vector<StringRef> subStrings;
  13774         std::size_t start = 0;
  13775         for(std::size_t pos = 0; pos < str.size(); ++pos ) {
  13776             if( str[pos] == delimiter ) {
  13777                 if( pos - start > 1 )
  13778                     subStrings.push_back( str.substr( start, pos-start ) );
  13779                 start = pos+1;
  13780             }
  13781         }
  13782         if( start < str.size() )
  13783             subStrings.push_back( str.substr( start, str.size()-start ) );
  13784         return subStrings;
  13785     }
  13786 
  13787     pluralise::pluralise( std::size_t count, std::string const& label )
  13788     :   m_count( count ),
  13789         m_label( label )
  13790     {}
  13791 
  13792     std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
  13793         os << pluraliser.m_count << ' ' << pluraliser.m_label;
  13794         if( pluraliser.m_count != 1 )
  13795             os << 's';
  13796         return os;
  13797     }
  13798 
  13799 }
  13800 // end catch_string_manip.cpp
  13801 // start catch_stringref.cpp
  13802 
  13803 #include <algorithm>
  13804 #include <ostream>
  13805 #include <cstring>
  13806 #include <cstdint>
  13807 
  13808 namespace Catch {
  13809     StringRef::StringRef( char const* rawChars ) noexcept
  13810     : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
  13811     {}
  13812 
  13813     auto StringRef::c_str() const -> char const* {
  13814         CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
  13815         return m_start;
  13816     }
  13817     auto StringRef::data() const noexcept -> char const* {
  13818         return m_start;
  13819     }
  13820 
  13821     auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
  13822         if (start < m_size) {
  13823             return StringRef(m_start + start, (std::min)(m_size - start, size));
  13824         } else {
  13825             return StringRef();
  13826         }
  13827     }
  13828     auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
  13829         return m_size == other.m_size
  13830             && (std::memcmp( m_start, other.m_start, m_size ) == 0);
  13831     }
  13832 
  13833     auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
  13834         return os.write(str.data(), str.size());
  13835     }
  13836 
  13837     auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
  13838         lhs.append(rhs.data(), rhs.size());
  13839         return lhs;
  13840     }
  13841 
  13842 } // namespace Catch
  13843 // end catch_stringref.cpp
  13844 // start catch_tag_alias.cpp
  13845 
  13846 namespace Catch {
  13847     TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
  13848 }
  13849 // end catch_tag_alias.cpp
  13850 // start catch_tag_alias_autoregistrar.cpp
  13851 
  13852 namespace Catch {
  13853 
  13854     RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
  13855         CATCH_TRY {
  13856             getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
  13857         } CATCH_CATCH_ALL {
  13858             // Do not throw when constructing global objects, instead register the exception to be processed later
  13859             getMutableRegistryHub().registerStartupException();
  13860         }
  13861     }
  13862 
  13863 }
  13864 // end catch_tag_alias_autoregistrar.cpp
  13865 // start catch_tag_alias_registry.cpp
  13866 
  13867 #include <sstream>
  13868 
  13869 namespace Catch {
  13870 
  13871     TagAliasRegistry::~TagAliasRegistry() {}
  13872 
  13873     TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
  13874         auto it = m_registry.find( alias );
  13875         if( it != m_registry.end() )
  13876             return &(it->second);
  13877         else
  13878             return nullptr;
  13879     }
  13880 
  13881     std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
  13882         std::string expandedTestSpec = unexpandedTestSpec;
  13883         for( auto const& registryKvp : m_registry ) {
  13884             std::size_t pos = expandedTestSpec.find( registryKvp.first );
  13885             if( pos != std::string::npos ) {
  13886                 expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
  13887                                     registryKvp.second.tag +
  13888                                     expandedTestSpec.substr( pos + registryKvp.first.size() );
  13889             }
  13890         }
  13891         return expandedTestSpec;
  13892     }
  13893 
  13894     void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
  13895         CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
  13896                       "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
  13897 
  13898         CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
  13899                       "error: tag alias, '" << alias << "' already registered.\n"
  13900                       << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
  13901                       << "\tRedefined at: " << lineInfo );
  13902     }
  13903 
  13904     ITagAliasRegistry::~ITagAliasRegistry() {}
  13905 
  13906     ITagAliasRegistry const& ITagAliasRegistry::get() {
  13907         return getRegistryHub().getTagAliasRegistry();
  13908     }
  13909 
  13910 } // end namespace Catch
  13911 // end catch_tag_alias_registry.cpp
  13912 // start catch_test_case_info.cpp
  13913 
  13914 #include <cctype>
  13915 #include <exception>
  13916 #include <algorithm>
  13917 #include <sstream>
  13918 
  13919 namespace Catch {
  13920 
  13921     namespace {
  13922         TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
  13923             if( startsWith( tag, '.' ) ||
  13924                 tag == "!hide" )
  13925                 return TestCaseInfo::IsHidden;
  13926             else if( tag == "!throws" )
  13927                 return TestCaseInfo::Throws;
  13928             else if( tag == "!shouldfail" )
  13929                 return TestCaseInfo::ShouldFail;
  13930             else if( tag == "!mayfail" )
  13931                 return TestCaseInfo::MayFail;
  13932             else if( tag == "!nonportable" )
  13933                 return TestCaseInfo::NonPortable;
  13934             else if( tag == "!benchmark" )
  13935                 return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
  13936             else
  13937                 return TestCaseInfo::None;
  13938         }
  13939         bool isReservedTag( std::string const& tag ) {
  13940             return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
  13941         }
  13942         void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
  13943             CATCH_ENFORCE( !isReservedTag(tag),
  13944                           "Tag name: [" << tag << "] is not allowed.\n"
  13945                           << "Tag names starting with non alphanumeric characters are reserved\n"
  13946                           << _lineInfo );
  13947         }
  13948     }
  13949 
  13950     TestCase makeTestCase(  ITestInvoker* _testCase,
  13951                             std::string const& _className,
  13952                             NameAndTags const& nameAndTags,
  13953                             SourceLineInfo const& _lineInfo )
  13954     {
  13955         bool isHidden = false;
  13956 
  13957         // Parse out tags
  13958         std::vector<std::string> tags;
  13959         std::string desc, tag;
  13960         bool inTag = false;
  13961         for (char c : nameAndTags.tags) {
  13962             if( !inTag ) {
  13963                 if( c == '[' )
  13964                     inTag = true;
  13965                 else
  13966                     desc += c;
  13967             }
  13968             else {
  13969                 if( c == ']' ) {
  13970                     TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
  13971                     if( ( prop & TestCaseInfo::IsHidden ) != 0 )
  13972                         isHidden = true;
  13973                     else if( prop == TestCaseInfo::None )
  13974                         enforceNotReservedTag( tag, _lineInfo );
  13975 
  13976                     // Merged hide tags like `[.approvals]` should be added as
  13977                     // `[.][approvals]`. The `[.]` is added at later point, so
  13978                     // we only strip the prefix
  13979                     if (startsWith(tag, '.') && tag.size() > 1) {
  13980                         tag.erase(0, 1);
  13981                     }
  13982                     tags.push_back( tag );
  13983                     tag.clear();
  13984                     inTag = false;
  13985                 }
  13986                 else
  13987                     tag += c;
  13988             }
  13989         }
  13990         if( isHidden ) {
  13991             // Add all "hidden" tags to make them behave identically
  13992             tags.insert( tags.end(), { ".", "!hide" } );
  13993         }
  13994 
  13995         TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );
  13996         return TestCase( _testCase, std::move(info) );
  13997     }
  13998 
  13999     void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
  14000         std::sort(begin(tags), end(tags));
  14001         tags.erase(std::unique(begin(tags), end(tags)), end(tags));
  14002         testCaseInfo.lcaseTags.clear();
  14003 
  14004         for( auto const& tag : tags ) {
  14005             std::string lcaseTag = toLower( tag );
  14006             testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
  14007             testCaseInfo.lcaseTags.push_back( lcaseTag );
  14008         }
  14009         testCaseInfo.tags = std::move(tags);
  14010     }
  14011 
  14012     TestCaseInfo::TestCaseInfo( std::string const& _name,
  14013                                 std::string const& _className,
  14014                                 std::string const& _description,
  14015                                 std::vector<std::string> const& _tags,
  14016                                 SourceLineInfo const& _lineInfo )
  14017     :   name( _name ),
  14018         className( _className ),
  14019         description( _description ),
  14020         lineInfo( _lineInfo ),
  14021         properties( None )
  14022     {
  14023         setTags( *this, _tags );
  14024     }
  14025 
  14026     bool TestCaseInfo::isHidden() const {
  14027         return ( properties & IsHidden ) != 0;
  14028     }
  14029     bool TestCaseInfo::throws() const {
  14030         return ( properties & Throws ) != 0;
  14031     }
  14032     bool TestCaseInfo::okToFail() const {
  14033         return ( properties & (ShouldFail | MayFail ) ) != 0;
  14034     }
  14035     bool TestCaseInfo::expectedToFail() const {
  14036         return ( properties & (ShouldFail ) ) != 0;
  14037     }
  14038 
  14039     std::string TestCaseInfo::tagsAsString() const {
  14040         std::string ret;
  14041         // '[' and ']' per tag
  14042         std::size_t full_size = 2 * tags.size();
  14043         for (const auto& tag : tags) {
  14044             full_size += tag.size();
  14045         }
  14046         ret.reserve(full_size);
  14047         for (const auto& tag : tags) {
  14048             ret.push_back('[');
  14049             ret.append(tag);
  14050             ret.push_back(']');
  14051         }
  14052 
  14053         return ret;
  14054     }
  14055 
  14056     TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
  14057 
  14058     TestCase TestCase::withName( std::string const& _newName ) const {
  14059         TestCase other( *this );
  14060         other.name = _newName;
  14061         return other;
  14062     }
  14063 
  14064     void TestCase::invoke() const {
  14065         test->invoke();
  14066     }
  14067 
  14068     bool TestCase::operator == ( TestCase const& other ) const {
  14069         return  test.get() == other.test.get() &&
  14070                 name == other.name &&
  14071                 className == other.className;
  14072     }
  14073 
  14074     bool TestCase::operator < ( TestCase const& other ) const {
  14075         return name < other.name;
  14076     }
  14077 
  14078     TestCaseInfo const& TestCase::getTestCaseInfo() const
  14079     {
  14080         return *this;
  14081     }
  14082 
  14083 } // end namespace Catch
  14084 // end catch_test_case_info.cpp
  14085 // start catch_test_case_registry_impl.cpp
  14086 
  14087 #include <algorithm>
  14088 #include <sstream>
  14089 
  14090 namespace Catch {
  14091 
  14092     namespace {
  14093         struct TestHasher {
  14094             explicit TestHasher(Catch::SimplePcg32& rng) {
  14095                 basis = rng();
  14096                 basis <<= 32;
  14097                 basis |= rng();
  14098             }
  14099 
  14100             uint64_t basis;
  14101 
  14102             uint64_t operator()(TestCase const& t) const {
  14103                 // Modified FNV-1a hash
  14104                 static constexpr uint64_t prime = 1099511628211;
  14105                 uint64_t hash = basis;
  14106                 for (const char c : t.name) {
  14107                     hash ^= c;
  14108                     hash *= prime;
  14109                 }
  14110                 return hash;
  14111             }
  14112         };
  14113     } // end unnamed namespace
  14114 
  14115     std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
  14116         switch( config.runOrder() ) {
  14117             case RunTests::InDeclarationOrder:
  14118                 // already in declaration order
  14119                 break;
  14120 
  14121             case RunTests::InLexicographicalOrder: {
  14122                 std::vector<TestCase> sorted = unsortedTestCases;
  14123                 std::sort( sorted.begin(), sorted.end() );
  14124                 return sorted;
  14125             }
  14126 
  14127             case RunTests::InRandomOrder: {
  14128                 seedRng( config );
  14129                 TestHasher h( rng() );
  14130 
  14131                 using hashedTest = std::pair<uint64_t, TestCase const*>;
  14132                 std::vector<hashedTest> indexed_tests;
  14133                 indexed_tests.reserve( unsortedTestCases.size() );
  14134 
  14135                 for (auto const& testCase : unsortedTestCases) {
  14136                     indexed_tests.emplace_back(h(testCase), &testCase);
  14137                 }
  14138 
  14139                 std::sort(indexed_tests.begin(), indexed_tests.end(),
  14140                           [](hashedTest const& lhs, hashedTest const& rhs) {
  14141                           if (lhs.first == rhs.first) {
  14142                               return lhs.second->name < rhs.second->name;
  14143                           }
  14144                           return lhs.first < rhs.first;
  14145                 });
  14146 
  14147                 std::vector<TestCase> sorted;
  14148                 sorted.reserve( indexed_tests.size() );
  14149 
  14150                 for (auto const& hashed : indexed_tests) {
  14151                     sorted.emplace_back(*hashed.second);
  14152                 }
  14153 
  14154                 return sorted;
  14155             }
  14156         }
  14157         return unsortedTestCases;
  14158     }
  14159 
  14160     bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {
  14161         return !testCase.throws() || config.allowThrows();
  14162     }
  14163 
  14164     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
  14165         return testSpec.matches( testCase ) && isThrowSafe( testCase, config );
  14166     }
  14167 
  14168     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
  14169         std::set<TestCase> seenFunctions;
  14170         for( auto const& function : functions ) {
  14171             auto prev = seenFunctions.insert( function );
  14172             CATCH_ENFORCE( prev.second,
  14173                     "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
  14174                     << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
  14175                     << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
  14176         }
  14177     }
  14178 
  14179     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
  14180         std::vector<TestCase> filtered;
  14181         filtered.reserve( testCases.size() );
  14182         for (auto const& testCase : testCases) {
  14183             if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
  14184                 (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
  14185                 filtered.push_back(testCase);
  14186             }
  14187         }
  14188         return filtered;
  14189     }
  14190     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
  14191         return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
  14192     }
  14193 
  14194     void TestRegistry::registerTest( TestCase const& testCase ) {
  14195         std::string name = testCase.getTestCaseInfo().name;
  14196         if( name.empty() ) {
  14197             ReusableStringStream rss;
  14198             rss << "Anonymous test case " << ++m_unnamedCount;
  14199             return registerTest( testCase.withName( rss.str() ) );
  14200         }
  14201         m_functions.push_back( testCase );
  14202     }
  14203 
  14204     std::vector<TestCase> const& TestRegistry::getAllTests() const {
  14205         return m_functions;
  14206     }
  14207     std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
  14208         if( m_sortedFunctions.empty() )
  14209             enforceNoDuplicateTestCases( m_functions );
  14210 
  14211         if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
  14212             m_sortedFunctions = sortTests( config, m_functions );
  14213             m_currentSortOrder = config.runOrder();
  14214         }
  14215         return m_sortedFunctions;
  14216     }
  14217 
  14218     ///////////////////////////////////////////////////////////////////////////
  14219     TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
  14220 
  14221     void TestInvokerAsFunction::invoke() const {
  14222         m_testAsFunction();
  14223     }
  14224 
  14225     std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
  14226         std::string className(classOrQualifiedMethodName);
  14227         if( startsWith( className, '&' ) )
  14228         {
  14229             std::size_t lastColons = className.rfind( "::" );
  14230             std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
  14231             if( penultimateColons == std::string::npos )
  14232                 penultimateColons = 1;
  14233             className = className.substr( penultimateColons, lastColons-penultimateColons );
  14234         }
  14235         return className;
  14236     }
  14237 
  14238 } // end namespace Catch
  14239 // end catch_test_case_registry_impl.cpp
  14240 // start catch_test_case_tracker.cpp
  14241 
  14242 #include <algorithm>
  14243 #include <cassert>
  14244 #include <stdexcept>
  14245 #include <memory>
  14246 #include <sstream>
  14247 
  14248 #if defined(__clang__)
  14249 #    pragma clang diagnostic push
  14250 #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  14251 #endif
  14252 
  14253 namespace Catch {
  14254 namespace TestCaseTracking {
  14255 
  14256     NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
  14257     :   name( _name ),
  14258         location( _location )
  14259     {}
  14260 
  14261     ITracker::~ITracker() = default;
  14262 
  14263     ITracker& TrackerContext::startRun() {
  14264         m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
  14265         m_currentTracker = nullptr;
  14266         m_runState = Executing;
  14267         return *m_rootTracker;
  14268     }
  14269 
  14270     void TrackerContext::endRun() {
  14271         m_rootTracker.reset();
  14272         m_currentTracker = nullptr;
  14273         m_runState = NotStarted;
  14274     }
  14275 
  14276     void TrackerContext::startCycle() {
  14277         m_currentTracker = m_rootTracker.get();
  14278         m_runState = Executing;
  14279     }
  14280     void TrackerContext::completeCycle() {
  14281         m_runState = CompletedCycle;
  14282     }
  14283 
  14284     bool TrackerContext::completedCycle() const {
  14285         return m_runState == CompletedCycle;
  14286     }
  14287     ITracker& TrackerContext::currentTracker() {
  14288         return *m_currentTracker;
  14289     }
  14290     void TrackerContext::setCurrentTracker( ITracker* tracker ) {
  14291         m_currentTracker = tracker;
  14292     }
  14293 
  14294     TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ):
  14295         ITracker(nameAndLocation),
  14296         m_ctx( ctx ),
  14297         m_parent( parent )
  14298     {}
  14299 
  14300     bool TrackerBase::isComplete() const {
  14301         return m_runState == CompletedSuccessfully || m_runState == Failed;
  14302     }
  14303     bool TrackerBase::isSuccessfullyCompleted() const {
  14304         return m_runState == CompletedSuccessfully;
  14305     }
  14306     bool TrackerBase::isOpen() const {
  14307         return m_runState != NotStarted && !isComplete();
  14308     }
  14309     bool TrackerBase::hasChildren() const {
  14310         return !m_children.empty();
  14311     }
  14312 
  14313     void TrackerBase::addChild( ITrackerPtr const& child ) {
  14314         m_children.push_back( child );
  14315     }
  14316 
  14317     ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
  14318         auto it = std::find_if( m_children.begin(), m_children.end(),
  14319             [&nameAndLocation]( ITrackerPtr const& tracker ){
  14320                 return
  14321                     tracker->nameAndLocation().location == nameAndLocation.location &&
  14322                     tracker->nameAndLocation().name == nameAndLocation.name;
  14323             } );
  14324         return( it != m_children.end() )
  14325             ? *it
  14326             : nullptr;
  14327     }
  14328     ITracker& TrackerBase::parent() {
  14329         assert( m_parent ); // Should always be non-null except for root
  14330         return *m_parent;
  14331     }
  14332 
  14333     void TrackerBase::openChild() {
  14334         if( m_runState != ExecutingChildren ) {
  14335             m_runState = ExecutingChildren;
  14336             if( m_parent )
  14337                 m_parent->openChild();
  14338         }
  14339     }
  14340 
  14341     bool TrackerBase::isSectionTracker() const { return false; }
  14342     bool TrackerBase::isGeneratorTracker() const { return false; }
  14343 
  14344     void TrackerBase::open() {
  14345         m_runState = Executing;
  14346         moveToThis();
  14347         if( m_parent )
  14348             m_parent->openChild();
  14349     }
  14350 
  14351     void TrackerBase::close() {
  14352 
  14353         // Close any still open children (e.g. generators)
  14354         while( &m_ctx.currentTracker() != this )
  14355             m_ctx.currentTracker().close();
  14356 
  14357         switch( m_runState ) {
  14358             case NeedsAnotherRun:
  14359                 break;
  14360 
  14361             case Executing:
  14362                 m_runState = CompletedSuccessfully;
  14363                 break;
  14364             case ExecutingChildren:
  14365                 if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )
  14366                     m_runState = CompletedSuccessfully;
  14367                 break;
  14368 
  14369             case NotStarted:
  14370             case CompletedSuccessfully:
  14371             case Failed:
  14372                 CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
  14373 
  14374             default:
  14375                 CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
  14376         }
  14377         moveToParent();
  14378         m_ctx.completeCycle();
  14379     }
  14380     void TrackerBase::fail() {
  14381         m_runState = Failed;
  14382         if( m_parent )
  14383             m_parent->markAsNeedingAnotherRun();
  14384         moveToParent();
  14385         m_ctx.completeCycle();
  14386     }
  14387     void TrackerBase::markAsNeedingAnotherRun() {
  14388         m_runState = NeedsAnotherRun;
  14389     }
  14390 
  14391     void TrackerBase::moveToParent() {
  14392         assert( m_parent );
  14393         m_ctx.setCurrentTracker( m_parent );
  14394     }
  14395     void TrackerBase::moveToThis() {
  14396         m_ctx.setCurrentTracker( this );
  14397     }
  14398 
  14399     SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
  14400     :   TrackerBase( nameAndLocation, ctx, parent ),
  14401         m_trimmed_name(trim(nameAndLocation.name))
  14402     {
  14403         if( parent ) {
  14404             while( !parent->isSectionTracker() )
  14405                 parent = &parent->parent();
  14406 
  14407             SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
  14408             addNextFilters( parentSection.m_filters );
  14409         }
  14410     }
  14411 
  14412     bool SectionTracker::isComplete() const {
  14413         bool complete = true;
  14414 
  14415         if (m_filters.empty()
  14416             || m_filters[0] == ""
  14417             || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
  14418             complete = TrackerBase::isComplete();
  14419         }
  14420         return complete;
  14421     }
  14422 
  14423     bool SectionTracker::isSectionTracker() const { return true; }
  14424 
  14425     SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
  14426         std::shared_ptr<SectionTracker> section;
  14427 
  14428         ITracker& currentTracker = ctx.currentTracker();
  14429         if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
  14430             assert( childTracker );
  14431             assert( childTracker->isSectionTracker() );
  14432             section = std::static_pointer_cast<SectionTracker>( childTracker );
  14433         }
  14434         else {
  14435             section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
  14436             currentTracker.addChild( section );
  14437         }
  14438         if( !ctx.completedCycle() )
  14439             section->tryOpen();
  14440         return *section;
  14441     }
  14442 
  14443     void SectionTracker::tryOpen() {
  14444         if( !isComplete() )
  14445             open();
  14446     }
  14447 
  14448     void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
  14449         if( !filters.empty() ) {
  14450             m_filters.reserve( m_filters.size() + filters.size() + 2 );
  14451             m_filters.emplace_back(""); // Root - should never be consulted
  14452             m_filters.emplace_back(""); // Test Case - not a section filter
  14453             m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
  14454         }
  14455     }
  14456     void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
  14457         if( filters.size() > 1 )
  14458             m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
  14459     }
  14460 
  14461 } // namespace TestCaseTracking
  14462 
  14463 using TestCaseTracking::ITracker;
  14464 using TestCaseTracking::TrackerContext;
  14465 using TestCaseTracking::SectionTracker;
  14466 
  14467 } // namespace Catch
  14468 
  14469 #if defined(__clang__)
  14470 #    pragma clang diagnostic pop
  14471 #endif
  14472 // end catch_test_case_tracker.cpp
  14473 // start catch_test_registry.cpp
  14474 
  14475 namespace Catch {
  14476 
  14477     auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
  14478         return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
  14479     }
  14480 
  14481     NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
  14482 
  14483     AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
  14484         CATCH_TRY {
  14485             getMutableRegistryHub()
  14486                     .registerTest(
  14487                         makeTestCase(
  14488                             invoker,
  14489                             extractClassName( classOrMethod ),
  14490                             nameAndTags,
  14491                             lineInfo));
  14492         } CATCH_CATCH_ALL {
  14493             // Do not throw when constructing global objects, instead register the exception to be processed later
  14494             getMutableRegistryHub().registerStartupException();
  14495         }
  14496     }
  14497 
  14498     AutoReg::~AutoReg() = default;
  14499 }
  14500 // end catch_test_registry.cpp
  14501 // start catch_test_spec.cpp
  14502 
  14503 #include <algorithm>
  14504 #include <string>
  14505 #include <vector>
  14506 #include <memory>
  14507 
  14508 namespace Catch {
  14509 
  14510     TestSpec::Pattern::Pattern( std::string const& name )
  14511     : m_name( name )
  14512     {}
  14513 
  14514     TestSpec::Pattern::~Pattern() = default;
  14515 
  14516     std::string const& TestSpec::Pattern::name() const {
  14517         return m_name;
  14518     }
  14519 
  14520     TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )
  14521     : Pattern( filterString )
  14522     , m_wildcardPattern( toLower( name ), CaseSensitive::No )
  14523     {}
  14524 
  14525     bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
  14526         return m_wildcardPattern.matches( testCase.name );
  14527     }
  14528 
  14529     TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
  14530     : Pattern( filterString )
  14531     , m_tag( toLower( tag ) )
  14532     {}
  14533 
  14534     bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
  14535         return std::find(begin(testCase.lcaseTags),
  14536                          end(testCase.lcaseTags),
  14537                          m_tag) != end(testCase.lcaseTags);
  14538     }
  14539 
  14540     TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )
  14541     : Pattern( underlyingPattern->name() )
  14542     , m_underlyingPattern( underlyingPattern )
  14543     {}
  14544 
  14545     bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {
  14546         return !m_underlyingPattern->matches( testCase );
  14547     }
  14548 
  14549     bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
  14550         return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );
  14551     }
  14552 
  14553     std::string TestSpec::Filter::name() const {
  14554         std::string name;
  14555         for( auto const& p : m_patterns )
  14556             name += p->name();
  14557         return name;
  14558     }
  14559 
  14560     bool TestSpec::hasFilters() const {
  14561         return !m_filters.empty();
  14562     }
  14563 
  14564     bool TestSpec::matches( TestCaseInfo const& testCase ) const {
  14565         return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
  14566     }
  14567 
  14568     TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const
  14569     {
  14570         Matches matches( m_filters.size() );
  14571         std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
  14572             std::vector<TestCase const*> currentMatches;
  14573             for( auto const& test : testCases )
  14574                 if( isThrowSafe( test, config ) && filter.matches( test ) )
  14575                     currentMatches.emplace_back( &test );
  14576             return FilterMatch{ filter.name(), currentMatches };
  14577         } );
  14578         return matches;
  14579     }
  14580 
  14581     const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{
  14582         return  (m_invalidArgs);
  14583     }
  14584 
  14585 }
  14586 // end catch_test_spec.cpp
  14587 // start catch_test_spec_parser.cpp
  14588 
  14589 namespace Catch {
  14590 
  14591     TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
  14592 
  14593     TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
  14594         m_mode = None;
  14595         m_exclusion = false;
  14596         m_arg = m_tagAliases->expandAliases( arg );
  14597         m_escapeChars.clear();
  14598         m_substring.reserve(m_arg.size());
  14599         m_patternName.reserve(m_arg.size());
  14600         m_realPatternPos = 0;
  14601 
  14602         for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
  14603           //if visitChar fails
  14604            if( !visitChar( m_arg[m_pos] ) ){
  14605                m_testSpec.m_invalidArgs.push_back(arg);
  14606                break;
  14607            }
  14608         endMode();
  14609         return *this;
  14610     }
  14611     TestSpec TestSpecParser::testSpec() {
  14612         addFilter();
  14613         return m_testSpec;
  14614     }
  14615     bool TestSpecParser::visitChar( char c ) {
  14616         if( (m_mode != EscapedName) && (c == '\\') ) {
  14617             escape();
  14618             addCharToPattern(c);
  14619             return true;
  14620         }else if((m_mode != EscapedName) && (c == ',') )  {
  14621             return separate();
  14622         }
  14623 
  14624         switch( m_mode ) {
  14625         case None:
  14626             if( processNoneChar( c ) )
  14627                 return true;
  14628             break;
  14629         case Name:
  14630             processNameChar( c );
  14631             break;
  14632         case EscapedName:
  14633             endMode();
  14634             addCharToPattern(c);
  14635             return true;
  14636         default:
  14637         case Tag:
  14638         case QuotedName:
  14639             if( processOtherChar( c ) )
  14640                 return true;
  14641             break;
  14642         }
  14643 
  14644         m_substring += c;
  14645         if( !isControlChar( c ) ) {
  14646             m_patternName += c;
  14647             m_realPatternPos++;
  14648         }
  14649         return true;
  14650     }
  14651     // Two of the processing methods return true to signal the caller to return
  14652     // without adding the given character to the current pattern strings
  14653     bool TestSpecParser::processNoneChar( char c ) {
  14654         switch( c ) {
  14655         case ' ':
  14656             return true;
  14657         case '~':
  14658             m_exclusion = true;
  14659             return false;
  14660         case '[':
  14661             startNewMode( Tag );
  14662             return false;
  14663         case '"':
  14664             startNewMode( QuotedName );
  14665             return false;
  14666         default:
  14667             startNewMode( Name );
  14668             return false;
  14669         }
  14670     }
  14671     void TestSpecParser::processNameChar( char c ) {
  14672         if( c == '[' ) {
  14673             if( m_substring == "exclude:" )
  14674                 m_exclusion = true;
  14675             else
  14676                 endMode();
  14677             startNewMode( Tag );
  14678         }
  14679     }
  14680     bool TestSpecParser::processOtherChar( char c ) {
  14681         if( !isControlChar( c ) )
  14682             return false;
  14683         m_substring += c;
  14684         endMode();
  14685         return true;
  14686     }
  14687     void TestSpecParser::startNewMode( Mode mode ) {
  14688         m_mode = mode;
  14689     }
  14690     void TestSpecParser::endMode() {
  14691         switch( m_mode ) {
  14692         case Name:
  14693         case QuotedName:
  14694             return addNamePattern();
  14695         case Tag:
  14696             return addTagPattern();
  14697         case EscapedName:
  14698             revertBackToLastMode();
  14699             return;
  14700         case None:
  14701         default:
  14702             return startNewMode( None );
  14703         }
  14704     }
  14705     void TestSpecParser::escape() {
  14706         saveLastMode();
  14707         m_mode = EscapedName;
  14708         m_escapeChars.push_back(m_realPatternPos);
  14709     }
  14710     bool TestSpecParser::isControlChar( char c ) const {
  14711         switch( m_mode ) {
  14712             default:
  14713                 return false;
  14714             case None:
  14715                 return c == '~';
  14716             case Name:
  14717                 return c == '[';
  14718             case EscapedName:
  14719                 return true;
  14720             case QuotedName:
  14721                 return c == '"';
  14722             case Tag:
  14723                 return c == '[' || c == ']';
  14724         }
  14725     }
  14726 
  14727     void TestSpecParser::addFilter() {
  14728         if( !m_currentFilter.m_patterns.empty() ) {
  14729             m_testSpec.m_filters.push_back( m_currentFilter );
  14730             m_currentFilter = TestSpec::Filter();
  14731         }
  14732     }
  14733 
  14734     void TestSpecParser::saveLastMode() {
  14735       lastMode = m_mode;
  14736     }
  14737 
  14738     void TestSpecParser::revertBackToLastMode() {
  14739       m_mode = lastMode;
  14740     }
  14741 
  14742     bool TestSpecParser::separate() {
  14743       if( (m_mode==QuotedName) || (m_mode==Tag) ){
  14744          //invalid argument, signal failure to previous scope.
  14745          m_mode = None;
  14746          m_pos = m_arg.size();
  14747          m_substring.clear();
  14748          m_patternName.clear();
  14749          m_realPatternPos = 0;
  14750          return false;
  14751       }
  14752       endMode();
  14753       addFilter();
  14754       return true; //success
  14755     }
  14756 
  14757     std::string TestSpecParser::preprocessPattern() {
  14758         std::string token = m_patternName;
  14759         for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
  14760             token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);
  14761         m_escapeChars.clear();
  14762         if (startsWith(token, "exclude:")) {
  14763             m_exclusion = true;
  14764             token = token.substr(8);
  14765         }
  14766 
  14767         m_patternName.clear();
  14768         m_realPatternPos = 0;
  14769 
  14770         return token;
  14771     }
  14772 
  14773     void TestSpecParser::addNamePattern() {
  14774         auto token = preprocessPattern();
  14775 
  14776         if (!token.empty()) {
  14777             TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);
  14778             if (m_exclusion)
  14779                 pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
  14780             m_currentFilter.m_patterns.push_back(pattern);
  14781         }
  14782         m_substring.clear();
  14783         m_exclusion = false;
  14784         m_mode = None;
  14785     }
  14786 
  14787     void TestSpecParser::addTagPattern() {
  14788         auto token = preprocessPattern();
  14789 
  14790         if (!token.empty()) {
  14791             // If the tag pattern is the "hide and tag" shorthand (e.g. [.foo])
  14792             // we have to create a separate hide tag and shorten the real one
  14793             if (token.size() > 1 && token[0] == '.') {
  14794                 token.erase(token.begin());
  14795                 TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring);
  14796                 if (m_exclusion) {
  14797                     pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
  14798                 }
  14799                 m_currentFilter.m_patterns.push_back(pattern);
  14800             }
  14801 
  14802             TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);
  14803 
  14804             if (m_exclusion) {
  14805                 pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
  14806             }
  14807             m_currentFilter.m_patterns.push_back(pattern);
  14808         }
  14809         m_substring.clear();
  14810         m_exclusion = false;
  14811         m_mode = None;
  14812     }
  14813 
  14814     TestSpec parseTestSpec( std::string const& arg ) {
  14815         return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
  14816     }
  14817 
  14818 } // namespace Catch
  14819 // end catch_test_spec_parser.cpp
  14820 // start catch_timer.cpp
  14821 
  14822 #include <chrono>
  14823 
  14824 static const uint64_t nanosecondsInSecond = 1000000000;
  14825 
  14826 namespace Catch {
  14827 
  14828     auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
  14829         return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
  14830     }
  14831 
  14832     namespace {
  14833         auto estimateClockResolution() -> uint64_t {
  14834             uint64_t sum = 0;
  14835             static const uint64_t iterations = 1000000;
  14836 
  14837             auto startTime = getCurrentNanosecondsSinceEpoch();
  14838 
  14839             for( std::size_t i = 0; i < iterations; ++i ) {
  14840 
  14841                 uint64_t ticks;
  14842                 uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
  14843                 do {
  14844                     ticks = getCurrentNanosecondsSinceEpoch();
  14845                 } while( ticks == baseTicks );
  14846 
  14847                 auto delta = ticks - baseTicks;
  14848                 sum += delta;
  14849 
  14850                 // If we have been calibrating for over 3 seconds -- the clock
  14851                 // is terrible and we should move on.
  14852                 // TBD: How to signal that the measured resolution is probably wrong?
  14853                 if (ticks > startTime + 3 * nanosecondsInSecond) {
  14854                     return sum / ( i + 1u );
  14855                 }
  14856             }
  14857 
  14858             // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
  14859             // - and potentially do more iterations if there's a high variance.
  14860             return sum/iterations;
  14861         }
  14862     }
  14863     auto getEstimatedClockResolution() -> uint64_t {
  14864         static auto s_resolution = estimateClockResolution();
  14865         return s_resolution;
  14866     }
  14867 
  14868     void Timer::start() {
  14869        m_nanoseconds = getCurrentNanosecondsSinceEpoch();
  14870     }
  14871     auto Timer::getElapsedNanoseconds() const -> uint64_t {
  14872         return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
  14873     }
  14874     auto Timer::getElapsedMicroseconds() const -> uint64_t {
  14875         return getElapsedNanoseconds()/1000;
  14876     }
  14877     auto Timer::getElapsedMilliseconds() const -> unsigned int {
  14878         return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
  14879     }
  14880     auto Timer::getElapsedSeconds() const -> double {
  14881         return getElapsedMicroseconds()/1000000.0;
  14882     }
  14883 
  14884 } // namespace Catch
  14885 // end catch_timer.cpp
  14886 // start catch_tostring.cpp
  14887 
  14888 #if defined(__clang__)
  14889 #    pragma clang diagnostic push
  14890 #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  14891 #    pragma clang diagnostic ignored "-Wglobal-constructors"
  14892 #endif
  14893 
  14894 // Enable specific decls locally
  14895 #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  14896 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  14897 #endif
  14898 
  14899 #include <cmath>
  14900 #include <iomanip>
  14901 
  14902 namespace Catch {
  14903 
  14904 namespace Detail {
  14905 
  14906     const std::string unprintableString = "{?}";
  14907 
  14908     namespace {
  14909         const int hexThreshold = 255;
  14910 
  14911         struct Endianness {
  14912             enum Arch { Big, Little };
  14913 
  14914             static Arch which() {
  14915                 int one = 1;
  14916                 // If the lowest byte we read is non-zero, we can assume
  14917                 // that little endian format is used.
  14918                 auto value = *reinterpret_cast<char*>(&one);
  14919                 return value ? Little : Big;
  14920             }
  14921         };
  14922     }
  14923 
  14924     std::string rawMemoryToString( const void *object, std::size_t size ) {
  14925         // Reverse order for little endian architectures
  14926         int i = 0, end = static_cast<int>( size ), inc = 1;
  14927         if( Endianness::which() == Endianness::Little ) {
  14928             i = end-1;
  14929             end = inc = -1;
  14930         }
  14931 
  14932         unsigned char const *bytes = static_cast<unsigned char const *>(object);
  14933         ReusableStringStream rss;
  14934         rss << "0x" << std::setfill('0') << std::hex;
  14935         for( ; i != end; i += inc )
  14936              rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
  14937        return rss.str();
  14938     }
  14939 }
  14940 
  14941 template<typename T>
  14942 std::string fpToString( T value, int precision ) {
  14943     if (Catch::isnan(value)) {
  14944         return "nan";
  14945     }
  14946 
  14947     ReusableStringStream rss;
  14948     rss << std::setprecision( precision )
  14949         << std::fixed
  14950         << value;
  14951     std::string d = rss.str();
  14952     std::size_t i = d.find_last_not_of( '0' );
  14953     if( i != std::string::npos && i != d.size()-1 ) {
  14954         if( d[i] == '.' )
  14955             i++;
  14956         d = d.substr( 0, i+1 );
  14957     }
  14958     return d;
  14959 }
  14960 
  14961 //// ======================================================= ////
  14962 //
  14963 //   Out-of-line defs for full specialization of StringMaker
  14964 //
  14965 //// ======================================================= ////
  14966 
  14967 std::string StringMaker<std::string>::convert(const std::string& str) {
  14968     if (!getCurrentContext().getConfig()->showInvisibles()) {
  14969         return '"' + str + '"';
  14970     }
  14971 
  14972     std::string s("\"");
  14973     for (char c : str) {
  14974         switch (c) {
  14975         case '\n':
  14976             s.append("\\n");
  14977             break;
  14978         case '\t':
  14979             s.append("\\t");
  14980             break;
  14981         default:
  14982             s.push_back(c);
  14983             break;
  14984         }
  14985     }
  14986     s.append("\"");
  14987     return s;
  14988 }
  14989 
  14990 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  14991 std::string StringMaker<std::string_view>::convert(std::string_view str) {
  14992     return ::Catch::Detail::stringify(std::string{ str });
  14993 }
  14994 #endif
  14995 
  14996 std::string StringMaker<char const*>::convert(char const* str) {
  14997     if (str) {
  14998         return ::Catch::Detail::stringify(std::string{ str });
  14999     } else {
  15000         return{ "{null string}" };
  15001     }
  15002 }
  15003 std::string StringMaker<char*>::convert(char* str) {
  15004     if (str) {
  15005         return ::Catch::Detail::stringify(std::string{ str });
  15006     } else {
  15007         return{ "{null string}" };
  15008     }
  15009 }
  15010 
  15011 #ifdef CATCH_CONFIG_WCHAR
  15012 std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
  15013     std::string s;
  15014     s.reserve(wstr.size());
  15015     for (auto c : wstr) {
  15016         s += (c <= 0xff) ? static_cast<char>(c) : '?';
  15017     }
  15018     return ::Catch::Detail::stringify(s);
  15019 }
  15020 
  15021 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  15022 std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
  15023     return StringMaker<std::wstring>::convert(std::wstring(str));
  15024 }
  15025 # endif
  15026 
  15027 std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
  15028     if (str) {
  15029         return ::Catch::Detail::stringify(std::wstring{ str });
  15030     } else {
  15031         return{ "{null string}" };
  15032     }
  15033 }
  15034 std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
  15035     if (str) {
  15036         return ::Catch::Detail::stringify(std::wstring{ str });
  15037     } else {
  15038         return{ "{null string}" };
  15039     }
  15040 }
  15041 #endif
  15042 
  15043 #if defined(CATCH_CONFIG_CPP17_BYTE)
  15044 #include <cstddef>
  15045 std::string StringMaker<std::byte>::convert(std::byte value) {
  15046     return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
  15047 }
  15048 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
  15049 
  15050 std::string StringMaker<int>::convert(int value) {
  15051     return ::Catch::Detail::stringify(static_cast<long long>(value));
  15052 }
  15053 std::string StringMaker<long>::convert(long value) {
  15054     return ::Catch::Detail::stringify(static_cast<long long>(value));
  15055 }
  15056 std::string StringMaker<long long>::convert(long long value) {
  15057     ReusableStringStream rss;
  15058     rss << value;
  15059     if (value > Detail::hexThreshold) {
  15060         rss << " (0x" << std::hex << value << ')';
  15061     }
  15062     return rss.str();
  15063 }
  15064 
  15065 std::string StringMaker<unsigned int>::convert(unsigned int value) {
  15066     return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  15067 }
  15068 std::string StringMaker<unsigned long>::convert(unsigned long value) {
  15069     return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  15070 }
  15071 std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
  15072     ReusableStringStream rss;
  15073     rss << value;
  15074     if (value > Detail::hexThreshold) {
  15075         rss << " (0x" << std::hex << value << ')';
  15076     }
  15077     return rss.str();
  15078 }
  15079 
  15080 std::string StringMaker<bool>::convert(bool b) {
  15081     return b ? "true" : "false";
  15082 }
  15083 
  15084 std::string StringMaker<signed char>::convert(signed char value) {
  15085     if (value == '\r') {
  15086         return "'\\r'";
  15087     } else if (value == '\f') {
  15088         return "'\\f'";
  15089     } else if (value == '\n') {
  15090         return "'\\n'";
  15091     } else if (value == '\t') {
  15092         return "'\\t'";
  15093     } else if ('\0' <= value && value < ' ') {
  15094         return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
  15095     } else {
  15096         char chstr[] = "' '";
  15097         chstr[1] = value;
  15098         return chstr;
  15099     }
  15100 }
  15101 std::string StringMaker<char>::convert(char c) {
  15102     return ::Catch::Detail::stringify(static_cast<signed char>(c));
  15103 }
  15104 std::string StringMaker<unsigned char>::convert(unsigned char c) {
  15105     return ::Catch::Detail::stringify(static_cast<char>(c));
  15106 }
  15107 
  15108 std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
  15109     return "nullptr";
  15110 }
  15111 
  15112 int StringMaker<float>::precision = 5;
  15113 
  15114 std::string StringMaker<float>::convert(float value) {
  15115     return fpToString(value, precision) + 'f';
  15116 }
  15117 
  15118 int StringMaker<double>::precision = 10;
  15119 
  15120 std::string StringMaker<double>::convert(double value) {
  15121     return fpToString(value, precision);
  15122 }
  15123 
  15124 std::string ratio_string<std::atto>::symbol() { return "a"; }
  15125 std::string ratio_string<std::femto>::symbol() { return "f"; }
  15126 std::string ratio_string<std::pico>::symbol() { return "p"; }
  15127 std::string ratio_string<std::nano>::symbol() { return "n"; }
  15128 std::string ratio_string<std::micro>::symbol() { return "u"; }
  15129 std::string ratio_string<std::milli>::symbol() { return "m"; }
  15130 
  15131 } // end namespace Catch
  15132 
  15133 #if defined(__clang__)
  15134 #    pragma clang diagnostic pop
  15135 #endif
  15136 
  15137 // end catch_tostring.cpp
  15138 // start catch_totals.cpp
  15139 
  15140 namespace Catch {
  15141 
  15142     Counts Counts::operator - ( Counts const& other ) const {
  15143         Counts diff;
  15144         diff.passed = passed - other.passed;
  15145         diff.failed = failed - other.failed;
  15146         diff.failedButOk = failedButOk - other.failedButOk;
  15147         return diff;
  15148     }
  15149 
  15150     Counts& Counts::operator += ( Counts const& other ) {
  15151         passed += other.passed;
  15152         failed += other.failed;
  15153         failedButOk += other.failedButOk;
  15154         return *this;
  15155     }
  15156 
  15157     std::size_t Counts::total() const {
  15158         return passed + failed + failedButOk;
  15159     }
  15160     bool Counts::allPassed() const {
  15161         return failed == 0 && failedButOk == 0;
  15162     }
  15163     bool Counts::allOk() const {
  15164         return failed == 0;
  15165     }
  15166 
  15167     Totals Totals::operator - ( Totals const& other ) const {
  15168         Totals diff;
  15169         diff.assertions = assertions - other.assertions;
  15170         diff.testCases = testCases - other.testCases;
  15171         return diff;
  15172     }
  15173 
  15174     Totals& Totals::operator += ( Totals const& other ) {
  15175         assertions += other.assertions;
  15176         testCases += other.testCases;
  15177         return *this;
  15178     }
  15179 
  15180     Totals Totals::delta( Totals const& prevTotals ) const {
  15181         Totals diff = *this - prevTotals;
  15182         if( diff.assertions.failed > 0 )
  15183             ++diff.testCases.failed;
  15184         else if( diff.assertions.failedButOk > 0 )
  15185             ++diff.testCases.failedButOk;
  15186         else
  15187             ++diff.testCases.passed;
  15188         return diff;
  15189     }
  15190 
  15191 }
  15192 // end catch_totals.cpp
  15193 // start catch_uncaught_exceptions.cpp
  15194 
  15195 #include <exception>
  15196 
  15197 namespace Catch {
  15198     bool uncaught_exceptions() {
  15199 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  15200         return false;
  15201 #elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
  15202         return std::uncaught_exceptions() > 0;
  15203 #else
  15204         return std::uncaught_exception();
  15205 #endif
  15206   }
  15207 } // end namespace Catch
  15208 // end catch_uncaught_exceptions.cpp
  15209 // start catch_version.cpp
  15210 
  15211 #include <ostream>
  15212 
  15213 namespace Catch {
  15214 
  15215     Version::Version
  15216         (   unsigned int _majorVersion,
  15217             unsigned int _minorVersion,
  15218             unsigned int _patchNumber,
  15219             char const * const _branchName,
  15220             unsigned int _buildNumber )
  15221     :   majorVersion( _majorVersion ),
  15222         minorVersion( _minorVersion ),
  15223         patchNumber( _patchNumber ),
  15224         branchName( _branchName ),
  15225         buildNumber( _buildNumber )
  15226     {}
  15227 
  15228     std::ostream& operator << ( std::ostream& os, Version const& version ) {
  15229         os  << version.majorVersion << '.'
  15230             << version.minorVersion << '.'
  15231             << version.patchNumber;
  15232         // branchName is never null -> 0th char is \0 if it is empty
  15233         if (version.branchName[0]) {
  15234             os << '-' << version.branchName
  15235                << '.' << version.buildNumber;
  15236         }
  15237         return os;
  15238     }
  15239 
  15240     Version const& libraryVersion() {
  15241         static Version version( 2, 13, 0, "", 0 );
  15242         return version;
  15243     }
  15244 
  15245 }
  15246 // end catch_version.cpp
  15247 // start catch_wildcard_pattern.cpp
  15248 
  15249 namespace Catch {
  15250 
  15251     WildcardPattern::WildcardPattern( std::string const& pattern,
  15252                                       CaseSensitive::Choice caseSensitivity )
  15253     :   m_caseSensitivity( caseSensitivity ),
  15254         m_pattern( normaliseString( pattern ) )
  15255     {
  15256         if( startsWith( m_pattern, '*' ) ) {
  15257             m_pattern = m_pattern.substr( 1 );
  15258             m_wildcard = WildcardAtStart;
  15259         }
  15260         if( endsWith( m_pattern, '*' ) ) {
  15261             m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
  15262             m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
  15263         }
  15264     }
  15265 
  15266     bool WildcardPattern::matches( std::string const& str ) const {
  15267         switch( m_wildcard ) {
  15268             case NoWildcard:
  15269                 return m_pattern == normaliseString( str );
  15270             case WildcardAtStart:
  15271                 return endsWith( normaliseString( str ), m_pattern );
  15272             case WildcardAtEnd:
  15273                 return startsWith( normaliseString( str ), m_pattern );
  15274             case WildcardAtBothEnds:
  15275                 return contains( normaliseString( str ), m_pattern );
  15276             default:
  15277                 CATCH_INTERNAL_ERROR( "Unknown enum" );
  15278         }
  15279     }
  15280 
  15281     std::string WildcardPattern::normaliseString( std::string const& str ) const {
  15282         return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );
  15283     }
  15284 }
  15285 // end catch_wildcard_pattern.cpp
  15286 // start catch_xmlwriter.cpp
  15287 
  15288 #include <iomanip>
  15289 #include <type_traits>
  15290 
  15291 namespace Catch {
  15292 
  15293 namespace {
  15294 
  15295     size_t trailingBytes(unsigned char c) {
  15296         if ((c & 0xE0) == 0xC0) {
  15297             return 2;
  15298         }
  15299         if ((c & 0xF0) == 0xE0) {
  15300             return 3;
  15301         }
  15302         if ((c & 0xF8) == 0xF0) {
  15303             return 4;
  15304         }
  15305         CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  15306     }
  15307 
  15308     uint32_t headerValue(unsigned char c) {
  15309         if ((c & 0xE0) == 0xC0) {
  15310             return c & 0x1F;
  15311         }
  15312         if ((c & 0xF0) == 0xE0) {
  15313             return c & 0x0F;
  15314         }
  15315         if ((c & 0xF8) == 0xF0) {
  15316             return c & 0x07;
  15317         }
  15318         CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  15319     }
  15320 
  15321     void hexEscapeChar(std::ostream& os, unsigned char c) {
  15322         std::ios_base::fmtflags f(os.flags());
  15323         os << "\\x"
  15324             << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
  15325             << static_cast<int>(c);
  15326         os.flags(f);
  15327     }
  15328 
  15329     bool shouldNewline(XmlFormatting fmt) {
  15330         return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));
  15331     }
  15332 
  15333     bool shouldIndent(XmlFormatting fmt) {
  15334         return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));
  15335     }
  15336 
  15337 } // anonymous namespace
  15338 
  15339     XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) {
  15340         return static_cast<XmlFormatting>(
  15341             static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |
  15342             static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
  15343         );
  15344     }
  15345 
  15346     XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) {
  15347         return static_cast<XmlFormatting>(
  15348             static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &
  15349             static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
  15350         );
  15351     }
  15352 
  15353     XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
  15354     :   m_str( str ),
  15355         m_forWhat( forWhat )
  15356     {}
  15357 
  15358     void XmlEncode::encodeTo( std::ostream& os ) const {
  15359         // Apostrophe escaping not necessary if we always use " to write attributes
  15360         // (see: http://www.w3.org/TR/xml/#syntax)
  15361 
  15362         for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
  15363             unsigned char c = m_str[idx];
  15364             switch (c) {
  15365             case '<':   os << "&lt;"; break;
  15366             case '&':   os << "&amp;"; break;
  15367 
  15368             case '>':
  15369                 // See: http://www.w3.org/TR/xml/#syntax
  15370                 if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
  15371                     os << "&gt;";
  15372                 else
  15373                     os << c;
  15374                 break;
  15375 
  15376             case '\"':
  15377                 if (m_forWhat == ForAttributes)
  15378                     os << "&quot;";
  15379                 else
  15380                     os << c;
  15381                 break;
  15382 
  15383             default:
  15384                 // Check for control characters and invalid utf-8
  15385 
  15386                 // Escape control characters in standard ascii
  15387                 // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
  15388                 if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
  15389                     hexEscapeChar(os, c);
  15390                     break;
  15391                 }
  15392 
  15393                 // Plain ASCII: Write it to stream
  15394                 if (c < 0x7F) {
  15395                     os << c;
  15396                     break;
  15397                 }
  15398 
  15399                 // UTF-8 territory
  15400                 // Check if the encoding is valid and if it is not, hex escape bytes.
  15401                 // Important: We do not check the exact decoded values for validity, only the encoding format
  15402                 // First check that this bytes is a valid lead byte:
  15403                 // This means that it is not encoded as 1111 1XXX
  15404                 // Or as 10XX XXXX
  15405                 if (c <  0xC0 ||
  15406                     c >= 0xF8) {
  15407                     hexEscapeChar(os, c);
  15408                     break;
  15409                 }
  15410 
  15411                 auto encBytes = trailingBytes(c);
  15412                 // Are there enough bytes left to avoid accessing out-of-bounds memory?
  15413                 if (idx + encBytes - 1 >= m_str.size()) {
  15414                     hexEscapeChar(os, c);
  15415                     break;
  15416                 }
  15417                 // The header is valid, check data
  15418                 // The next encBytes bytes must together be a valid utf-8
  15419                 // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
  15420                 bool valid = true;
  15421                 uint32_t value = headerValue(c);
  15422                 for (std::size_t n = 1; n < encBytes; ++n) {
  15423                     unsigned char nc = m_str[idx + n];
  15424                     valid &= ((nc & 0xC0) == 0x80);
  15425                     value = (value << 6) | (nc & 0x3F);
  15426                 }
  15427 
  15428                 if (
  15429                     // Wrong bit pattern of following bytes
  15430                     (!valid) ||
  15431                     // Overlong encodings
  15432                     (value < 0x80) ||
  15433                     (0x80 <= value && value < 0x800   && encBytes > 2) ||
  15434                     (0x800 < value && value < 0x10000 && encBytes > 3) ||
  15435                     // Encoded value out of range
  15436                     (value >= 0x110000)
  15437                     ) {
  15438                     hexEscapeChar(os, c);
  15439                     break;
  15440                 }
  15441 
  15442                 // If we got here, this is in fact a valid(ish) utf-8 sequence
  15443                 for (std::size_t n = 0; n < encBytes; ++n) {
  15444                     os << m_str[idx + n];
  15445                 }
  15446                 idx += encBytes - 1;
  15447                 break;
  15448             }
  15449         }
  15450     }
  15451 
  15452     std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
  15453         xmlEncode.encodeTo( os );
  15454         return os;
  15455     }
  15456 
  15457     XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt )
  15458     :   m_writer( writer ),
  15459         m_fmt(fmt)
  15460     {}
  15461 
  15462     XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
  15463     :   m_writer( other.m_writer ),
  15464         m_fmt(other.m_fmt)
  15465     {
  15466         other.m_writer = nullptr;
  15467         other.m_fmt = XmlFormatting::None;
  15468     }
  15469     XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
  15470         if ( m_writer ) {
  15471             m_writer->endElement();
  15472         }
  15473         m_writer = other.m_writer;
  15474         other.m_writer = nullptr;
  15475         m_fmt = other.m_fmt;
  15476         other.m_fmt = XmlFormatting::None;
  15477         return *this;
  15478     }
  15479 
  15480     XmlWriter::ScopedElement::~ScopedElement() {
  15481         if (m_writer) {
  15482             m_writer->endElement(m_fmt);
  15483         }
  15484     }
  15485 
  15486     XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) {
  15487         m_writer->writeText( text, fmt );
  15488         return *this;
  15489     }
  15490 
  15491     XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
  15492     {
  15493         writeDeclaration();
  15494     }
  15495 
  15496     XmlWriter::~XmlWriter() {
  15497         while (!m_tags.empty()) {
  15498             endElement();
  15499         }
  15500         newlineIfNecessary();
  15501     }
  15502 
  15503     XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) {
  15504         ensureTagClosed();
  15505         newlineIfNecessary();
  15506         if (shouldIndent(fmt)) {
  15507             m_os << m_indent;
  15508             m_indent += "  ";
  15509         }
  15510         m_os << '<' << name;
  15511         m_tags.push_back( name );
  15512         m_tagIsOpen = true;
  15513         applyFormatting(fmt);
  15514         return *this;
  15515     }
  15516 
  15517     XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) {
  15518         ScopedElement scoped( this, fmt );
  15519         startElement( name, fmt );
  15520         return scoped;
  15521     }
  15522 
  15523     XmlWriter& XmlWriter::endElement(XmlFormatting fmt) {
  15524         m_indent = m_indent.substr(0, m_indent.size() - 2);
  15525 
  15526         if( m_tagIsOpen ) {
  15527             m_os << "/>";
  15528             m_tagIsOpen = false;
  15529         } else {
  15530             newlineIfNecessary();
  15531             if (shouldIndent(fmt)) {
  15532                 m_os << m_indent;
  15533             }
  15534             m_os << "</" << m_tags.back() << ">";
  15535         }
  15536         m_os << std::flush;
  15537         applyFormatting(fmt);
  15538         m_tags.pop_back();
  15539         return *this;
  15540     }
  15541 
  15542     XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
  15543         if( !name.empty() && !attribute.empty() )
  15544             m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
  15545         return *this;
  15546     }
  15547 
  15548     XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
  15549         m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
  15550         return *this;
  15551     }
  15552 
  15553     XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) {
  15554         if( !text.empty() ){
  15555             bool tagWasOpen = m_tagIsOpen;
  15556             ensureTagClosed();
  15557             if (tagWasOpen && shouldIndent(fmt)) {
  15558                 m_os << m_indent;
  15559             }
  15560             m_os << XmlEncode( text );
  15561             applyFormatting(fmt);
  15562         }
  15563         return *this;
  15564     }
  15565 
  15566     XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) {
  15567         ensureTagClosed();
  15568         if (shouldIndent(fmt)) {
  15569             m_os << m_indent;
  15570         }
  15571         m_os << "<!--" << text << "-->";
  15572         applyFormatting(fmt);
  15573         return *this;
  15574     }
  15575 
  15576     void XmlWriter::writeStylesheetRef( std::string const& url ) {
  15577         m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
  15578     }
  15579 
  15580     XmlWriter& XmlWriter::writeBlankLine() {
  15581         ensureTagClosed();
  15582         m_os << '\n';
  15583         return *this;
  15584     }
  15585 
  15586     void XmlWriter::ensureTagClosed() {
  15587         if( m_tagIsOpen ) {
  15588             m_os << '>' << std::flush;
  15589             newlineIfNecessary();
  15590             m_tagIsOpen = false;
  15591         }
  15592     }
  15593 
  15594     void XmlWriter::applyFormatting(XmlFormatting fmt) {
  15595         m_needsNewline = shouldNewline(fmt);
  15596     }
  15597 
  15598     void XmlWriter::writeDeclaration() {
  15599         m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  15600     }
  15601 
  15602     void XmlWriter::newlineIfNecessary() {
  15603         if( m_needsNewline ) {
  15604             m_os << std::endl;
  15605             m_needsNewline = false;
  15606         }
  15607     }
  15608 }
  15609 // end catch_xmlwriter.cpp
  15610 // start catch_reporter_bases.cpp
  15611 
  15612 #include <cstring>
  15613 #include <cfloat>
  15614 #include <cstdio>
  15615 #include <cassert>
  15616 #include <memory>
  15617 
  15618 namespace Catch {
  15619     void prepareExpandedExpression(AssertionResult& result) {
  15620         result.getExpandedExpression();
  15621     }
  15622 
  15623     // Because formatting using c++ streams is stateful, drop down to C is required
  15624     // Alternatively we could use stringstream, but its performance is... not good.
  15625     std::string getFormattedDuration( double duration ) {
  15626         // Max exponent + 1 is required to represent the whole part
  15627         // + 1 for decimal point
  15628         // + 3 for the 3 decimal places
  15629         // + 1 for null terminator
  15630         const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
  15631         char buffer[maxDoubleSize];
  15632 
  15633         // Save previous errno, to prevent sprintf from overwriting it
  15634         ErrnoGuard guard;
  15635 #ifdef _MSC_VER
  15636         sprintf_s(buffer, "%.3f", duration);
  15637 #else
  15638         std::sprintf(buffer, "%.3f", duration);
  15639 #endif
  15640         return std::string(buffer);
  15641     }
  15642 
  15643     bool shouldShowDuration( IConfig const& config, double duration ) {
  15644         if ( config.showDurations() == ShowDurations::Always ) {
  15645             return true;
  15646         }
  15647         if ( config.showDurations() == ShowDurations::Never ) {
  15648             return false;
  15649         }
  15650         const double min = config.minDuration();
  15651         return min >= 0 && duration >= min;
  15652     }
  15653 
  15654     std::string serializeFilters( std::vector<std::string> const& container ) {
  15655         ReusableStringStream oss;
  15656         bool first = true;
  15657         for (auto&& filter : container)
  15658         {
  15659             if (!first)
  15660                 oss << ' ';
  15661             else
  15662                 first = false;
  15663 
  15664             oss << filter;
  15665         }
  15666         return oss.str();
  15667     }
  15668 
  15669     TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
  15670         :StreamingReporterBase(_config) {}
  15671 
  15672     std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
  15673         return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };
  15674     }
  15675 
  15676     void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
  15677 
  15678     bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
  15679         return false;
  15680     }
  15681 
  15682 } // end namespace Catch
  15683 // end catch_reporter_bases.cpp
  15684 // start catch_reporter_compact.cpp
  15685 
  15686 namespace {
  15687 
  15688 #ifdef CATCH_PLATFORM_MAC
  15689     const char* failedString() { return "FAILED"; }
  15690     const char* passedString() { return "PASSED"; }
  15691 #else
  15692     const char* failedString() { return "failed"; }
  15693     const char* passedString() { return "passed"; }
  15694 #endif
  15695 
  15696     // Colour::LightGrey
  15697     Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
  15698 
  15699     std::string bothOrAll( std::size_t count ) {
  15700         return count == 1 ? std::string() :
  15701                count == 2 ? "both " : "all " ;
  15702     }
  15703 
  15704 } // anon namespace
  15705 
  15706 namespace Catch {
  15707 namespace {
  15708 // Colour, message variants:
  15709 // - white: No tests ran.
  15710 // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
  15711 // - white: Passed [both/all] N test cases (no assertions).
  15712 // -   red: Failed N tests cases, failed M assertions.
  15713 // - green: Passed [both/all] N tests cases with M assertions.
  15714 void printTotals(std::ostream& out, const Totals& totals) {
  15715     if (totals.testCases.total() == 0) {
  15716         out << "No tests ran.";
  15717     } else if (totals.testCases.failed == totals.testCases.total()) {
  15718         Colour colour(Colour::ResultError);
  15719         const std::string qualify_assertions_failed =
  15720             totals.assertions.failed == totals.assertions.total() ?
  15721             bothOrAll(totals.assertions.failed) : std::string();
  15722         out <<
  15723             "Failed " << bothOrAll(totals.testCases.failed)
  15724             << pluralise(totals.testCases.failed, "test case") << ", "
  15725             "failed " << qualify_assertions_failed <<
  15726             pluralise(totals.assertions.failed, "assertion") << '.';
  15727     } else if (totals.assertions.total() == 0) {
  15728         out <<
  15729             "Passed " << bothOrAll(totals.testCases.total())
  15730             << pluralise(totals.testCases.total(), "test case")
  15731             << " (no assertions).";
  15732     } else if (totals.assertions.failed) {
  15733         Colour colour(Colour::ResultError);
  15734         out <<
  15735             "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
  15736             "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
  15737     } else {
  15738         Colour colour(Colour::ResultSuccess);
  15739         out <<
  15740             "Passed " << bothOrAll(totals.testCases.passed)
  15741             << pluralise(totals.testCases.passed, "test case") <<
  15742             " with " << pluralise(totals.assertions.passed, "assertion") << '.';
  15743     }
  15744 }
  15745 
  15746 // Implementation of CompactReporter formatting
  15747 class AssertionPrinter {
  15748 public:
  15749     AssertionPrinter& operator= (AssertionPrinter const&) = delete;
  15750     AssertionPrinter(AssertionPrinter const&) = delete;
  15751     AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
  15752         : stream(_stream)
  15753         , result(_stats.assertionResult)
  15754         , messages(_stats.infoMessages)
  15755         , itMessage(_stats.infoMessages.begin())
  15756         , printInfoMessages(_printInfoMessages) {}
  15757 
  15758     void print() {
  15759         printSourceInfo();
  15760 
  15761         itMessage = messages.begin();
  15762 
  15763         switch (result.getResultType()) {
  15764         case ResultWas::Ok:
  15765             printResultType(Colour::ResultSuccess, passedString());
  15766             printOriginalExpression();
  15767             printReconstructedExpression();
  15768             if (!result.hasExpression())
  15769                 printRemainingMessages(Colour::None);
  15770             else
  15771                 printRemainingMessages();
  15772             break;
  15773         case ResultWas::ExpressionFailed:
  15774             if (result.isOk())
  15775                 printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
  15776             else
  15777                 printResultType(Colour::Error, failedString());
  15778             printOriginalExpression();
  15779             printReconstructedExpression();
  15780             printRemainingMessages();
  15781             break;
  15782         case ResultWas::ThrewException:
  15783             printResultType(Colour::Error, failedString());
  15784             printIssue("unexpected exception with message:");
  15785             printMessage();
  15786             printExpressionWas();
  15787             printRemainingMessages();
  15788             break;
  15789         case ResultWas::FatalErrorCondition:
  15790             printResultType(Colour::Error, failedString());
  15791             printIssue("fatal error condition with message:");
  15792             printMessage();
  15793             printExpressionWas();
  15794             printRemainingMessages();
  15795             break;
  15796         case ResultWas::DidntThrowException:
  15797             printResultType(Colour::Error, failedString());
  15798             printIssue("expected exception, got none");
  15799             printExpressionWas();
  15800             printRemainingMessages();
  15801             break;
  15802         case ResultWas::Info:
  15803             printResultType(Colour::None, "info");
  15804             printMessage();
  15805             printRemainingMessages();
  15806             break;
  15807         case ResultWas::Warning:
  15808             printResultType(Colour::None, "warning");
  15809             printMessage();
  15810             printRemainingMessages();
  15811             break;
  15812         case ResultWas::ExplicitFailure:
  15813             printResultType(Colour::Error, failedString());
  15814             printIssue("explicitly");
  15815             printRemainingMessages(Colour::None);
  15816             break;
  15817             // These cases are here to prevent compiler warnings
  15818         case ResultWas::Unknown:
  15819         case ResultWas::FailureBit:
  15820         case ResultWas::Exception:
  15821             printResultType(Colour::Error, "** internal error **");
  15822             break;
  15823         }
  15824     }
  15825 
  15826 private:
  15827     void printSourceInfo() const {
  15828         Colour colourGuard(Colour::FileName);
  15829         stream << result.getSourceInfo() << ':';
  15830     }
  15831 
  15832     void printResultType(Colour::Code colour, std::string const& passOrFail) const {
  15833         if (!passOrFail.empty()) {
  15834             {
  15835                 Colour colourGuard(colour);
  15836                 stream << ' ' << passOrFail;
  15837             }
  15838             stream << ':';
  15839         }
  15840     }
  15841 
  15842     void printIssue(std::string const& issue) const {
  15843         stream << ' ' << issue;
  15844     }
  15845 
  15846     void printExpressionWas() {
  15847         if (result.hasExpression()) {
  15848             stream << ';';
  15849             {
  15850                 Colour colour(dimColour());
  15851                 stream << " expression was:";
  15852             }
  15853             printOriginalExpression();
  15854         }
  15855     }
  15856 
  15857     void printOriginalExpression() const {
  15858         if (result.hasExpression()) {
  15859             stream << ' ' << result.getExpression();
  15860         }
  15861     }
  15862 
  15863     void printReconstructedExpression() const {
  15864         if (result.hasExpandedExpression()) {
  15865             {
  15866                 Colour colour(dimColour());
  15867                 stream << " for: ";
  15868             }
  15869             stream << result.getExpandedExpression();
  15870         }
  15871     }
  15872 
  15873     void printMessage() {
  15874         if (itMessage != messages.end()) {
  15875             stream << " '" << itMessage->message << '\'';
  15876             ++itMessage;
  15877         }
  15878     }
  15879 
  15880     void printRemainingMessages(Colour::Code colour = dimColour()) {
  15881         if (itMessage == messages.end())
  15882             return;
  15883 
  15884         const auto itEnd = messages.cend();
  15885         const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
  15886 
  15887         {
  15888             Colour colourGuard(colour);
  15889             stream << " with " << pluralise(N, "message") << ':';
  15890         }
  15891 
  15892         while (itMessage != itEnd) {
  15893             // If this assertion is a warning ignore any INFO messages
  15894             if (printInfoMessages || itMessage->type != ResultWas::Info) {
  15895                 printMessage();
  15896                 if (itMessage != itEnd) {
  15897                     Colour colourGuard(dimColour());
  15898                     stream << " and";
  15899                 }
  15900                 continue;
  15901             }
  15902             ++itMessage;
  15903         }
  15904     }
  15905 
  15906 private:
  15907     std::ostream& stream;
  15908     AssertionResult const& result;
  15909     std::vector<MessageInfo> messages;
  15910     std::vector<MessageInfo>::const_iterator itMessage;
  15911     bool printInfoMessages;
  15912 };
  15913 
  15914 } // anon namespace
  15915 
  15916         std::string CompactReporter::getDescription() {
  15917             return "Reports test results on a single line, suitable for IDEs";
  15918         }
  15919 
  15920         void CompactReporter::noMatchingTestCases( std::string const& spec ) {
  15921             stream << "No test cases matched '" << spec << '\'' << std::endl;
  15922         }
  15923 
  15924         void CompactReporter::assertionStarting( AssertionInfo const& ) {}
  15925 
  15926         bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
  15927             AssertionResult const& result = _assertionStats.assertionResult;
  15928 
  15929             bool printInfoMessages = true;
  15930 
  15931             // Drop out if result was successful and we're not printing those
  15932             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
  15933                 if( result.getResultType() != ResultWas::Warning )
  15934                     return false;
  15935                 printInfoMessages = false;
  15936             }
  15937 
  15938             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
  15939             printer.print();
  15940 
  15941             stream << std::endl;
  15942             return true;
  15943         }
  15944 
  15945         void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
  15946             double dur = _sectionStats.durationInSeconds;
  15947             if ( shouldShowDuration( *m_config, dur ) ) {
  15948                 stream << getFormattedDuration( dur ) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  15949             }
  15950         }
  15951 
  15952         void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
  15953             printTotals( stream, _testRunStats.totals );
  15954             stream << '\n' << std::endl;
  15955             StreamingReporterBase::testRunEnded( _testRunStats );
  15956         }
  15957 
  15958         CompactReporter::~CompactReporter() {}
  15959 
  15960     CATCH_REGISTER_REPORTER( "compact", CompactReporter )
  15961 
  15962 } // end namespace Catch
  15963 // end catch_reporter_compact.cpp
  15964 // start catch_reporter_console.cpp
  15965 
  15966 #include <cfloat>
  15967 #include <cstdio>
  15968 
  15969 #if defined(_MSC_VER)
  15970 #pragma warning(push)
  15971 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  15972  // Note that 4062 (not all labels are handled and default is missing) is enabled
  15973 #endif
  15974 
  15975 #if defined(__clang__)
  15976 #  pragma clang diagnostic push
  15977 // For simplicity, benchmarking-only helpers are always enabled
  15978 #  pragma clang diagnostic ignored "-Wunused-function"
  15979 #endif
  15980 
  15981 namespace Catch {
  15982 
  15983 namespace {
  15984 
  15985 // Formatter impl for ConsoleReporter
  15986 class ConsoleAssertionPrinter {
  15987 public:
  15988     ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
  15989     ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
  15990     ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
  15991         : stream(_stream),
  15992         stats(_stats),
  15993         result(_stats.assertionResult),
  15994         colour(Colour::None),
  15995         message(result.getMessage()),
  15996         messages(_stats.infoMessages),
  15997         printInfoMessages(_printInfoMessages) {
  15998         switch (result.getResultType()) {
  15999         case ResultWas::Ok:
  16000             colour = Colour::Success;
  16001             passOrFail = "PASSED";
  16002             //if( result.hasMessage() )
  16003             if (_stats.infoMessages.size() == 1)
  16004                 messageLabel = "with message";
  16005             if (_stats.infoMessages.size() > 1)
  16006                 messageLabel = "with messages";
  16007             break;
  16008         case ResultWas::ExpressionFailed:
  16009             if (result.isOk()) {
  16010                 colour = Colour::Success;
  16011                 passOrFail = "FAILED - but was ok";
  16012             } else {
  16013                 colour = Colour::Error;
  16014                 passOrFail = "FAILED";
  16015             }
  16016             if (_stats.infoMessages.size() == 1)
  16017                 messageLabel = "with message";
  16018             if (_stats.infoMessages.size() > 1)
  16019                 messageLabel = "with messages";
  16020             break;
  16021         case ResultWas::ThrewException:
  16022             colour = Colour::Error;
  16023             passOrFail = "FAILED";
  16024             messageLabel = "due to unexpected exception with ";
  16025             if (_stats.infoMessages.size() == 1)
  16026                 messageLabel += "message";
  16027             if (_stats.infoMessages.size() > 1)
  16028                 messageLabel += "messages";
  16029             break;
  16030         case ResultWas::FatalErrorCondition:
  16031             colour = Colour::Error;
  16032             passOrFail = "FAILED";
  16033             messageLabel = "due to a fatal error condition";
  16034             break;
  16035         case ResultWas::DidntThrowException:
  16036             colour = Colour::Error;
  16037             passOrFail = "FAILED";
  16038             messageLabel = "because no exception was thrown where one was expected";
  16039             break;
  16040         case ResultWas::Info:
  16041             messageLabel = "info";
  16042             break;
  16043         case ResultWas::Warning:
  16044             messageLabel = "warning";
  16045             break;
  16046         case ResultWas::ExplicitFailure:
  16047             passOrFail = "FAILED";
  16048             colour = Colour::Error;
  16049             if (_stats.infoMessages.size() == 1)
  16050                 messageLabel = "explicitly with message";
  16051             if (_stats.infoMessages.size() > 1)
  16052                 messageLabel = "explicitly with messages";
  16053             break;
  16054             // These cases are here to prevent compiler warnings
  16055         case ResultWas::Unknown:
  16056         case ResultWas::FailureBit:
  16057         case ResultWas::Exception:
  16058             passOrFail = "** internal error **";
  16059             colour = Colour::Error;
  16060             break;
  16061         }
  16062     }
  16063 
  16064     void print() const {
  16065         printSourceInfo();
  16066         if (stats.totals.assertions.total() > 0) {
  16067             printResultType();
  16068             printOriginalExpression();
  16069             printReconstructedExpression();
  16070         } else {
  16071             stream << '\n';
  16072         }
  16073         printMessage();
  16074     }
  16075 
  16076 private:
  16077     void printResultType() const {
  16078         if (!passOrFail.empty()) {
  16079             Colour colourGuard(colour);
  16080             stream << passOrFail << ":\n";
  16081         }
  16082     }
  16083     void printOriginalExpression() const {
  16084         if (result.hasExpression()) {
  16085             Colour colourGuard(Colour::OriginalExpression);
  16086             stream << "  ";
  16087             stream << result.getExpressionInMacro();
  16088             stream << '\n';
  16089         }
  16090     }
  16091     void printReconstructedExpression() const {
  16092         if (result.hasExpandedExpression()) {
  16093             stream << "with expansion:\n";
  16094             Colour colourGuard(Colour::ReconstructedExpression);
  16095             stream << Column(result.getExpandedExpression()).indent(2) << '\n';
  16096         }
  16097     }
  16098     void printMessage() const {
  16099         if (!messageLabel.empty())
  16100             stream << messageLabel << ':' << '\n';
  16101         for (auto const& msg : messages) {
  16102             // If this assertion is a warning ignore any INFO messages
  16103             if (printInfoMessages || msg.type != ResultWas::Info)
  16104                 stream << Column(msg.message).indent(2) << '\n';
  16105         }
  16106     }
  16107     void printSourceInfo() const {
  16108         Colour colourGuard(Colour::FileName);
  16109         stream << result.getSourceInfo() << ": ";
  16110     }
  16111 
  16112     std::ostream& stream;
  16113     AssertionStats const& stats;
  16114     AssertionResult const& result;
  16115     Colour::Code colour;
  16116     std::string passOrFail;
  16117     std::string messageLabel;
  16118     std::string message;
  16119     std::vector<MessageInfo> messages;
  16120     bool printInfoMessages;
  16121 };
  16122 
  16123 std::size_t makeRatio(std::size_t number, std::size_t total) {
  16124     std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
  16125     return (ratio == 0 && number > 0) ? 1 : ratio;
  16126 }
  16127 
  16128 std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
  16129     if (i > j && i > k)
  16130         return i;
  16131     else if (j > k)
  16132         return j;
  16133     else
  16134         return k;
  16135 }
  16136 
  16137 struct ColumnInfo {
  16138     enum Justification { Left, Right };
  16139     std::string name;
  16140     int width;
  16141     Justification justification;
  16142 };
  16143 struct ColumnBreak {};
  16144 struct RowBreak {};
  16145 
  16146 class Duration {
  16147     enum class Unit {
  16148         Auto,
  16149         Nanoseconds,
  16150         Microseconds,
  16151         Milliseconds,
  16152         Seconds,
  16153         Minutes
  16154     };
  16155     static const uint64_t s_nanosecondsInAMicrosecond = 1000;
  16156     static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
  16157     static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
  16158     static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
  16159 
  16160     double m_inNanoseconds;
  16161     Unit m_units;
  16162 
  16163 public:
  16164     explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
  16165         : m_inNanoseconds(inNanoseconds),
  16166         m_units(units) {
  16167         if (m_units == Unit::Auto) {
  16168             if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
  16169                 m_units = Unit::Nanoseconds;
  16170             else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
  16171                 m_units = Unit::Microseconds;
  16172             else if (m_inNanoseconds < s_nanosecondsInASecond)
  16173                 m_units = Unit::Milliseconds;
  16174             else if (m_inNanoseconds < s_nanosecondsInAMinute)
  16175                 m_units = Unit::Seconds;
  16176             else
  16177                 m_units = Unit::Minutes;
  16178         }
  16179 
  16180     }
  16181 
  16182     auto value() const -> double {
  16183         switch (m_units) {
  16184         case Unit::Microseconds:
  16185             return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
  16186         case Unit::Milliseconds:
  16187             return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
  16188         case Unit::Seconds:
  16189             return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
  16190         case Unit::Minutes:
  16191             return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
  16192         default:
  16193             return m_inNanoseconds;
  16194         }
  16195     }
  16196     auto unitsAsString() const -> std::string {
  16197         switch (m_units) {
  16198         case Unit::Nanoseconds:
  16199             return "ns";
  16200         case Unit::Microseconds:
  16201             return "us";
  16202         case Unit::Milliseconds:
  16203             return "ms";
  16204         case Unit::Seconds:
  16205             return "s";
  16206         case Unit::Minutes:
  16207             return "m";
  16208         default:
  16209             return "** internal error **";
  16210         }
  16211 
  16212     }
  16213     friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
  16214         return os << duration.value() << ' ' << duration.unitsAsString();
  16215     }
  16216 };
  16217 } // end anon namespace
  16218 
  16219 class TablePrinter {
  16220     std::ostream& m_os;
  16221     std::vector<ColumnInfo> m_columnInfos;
  16222     std::ostringstream m_oss;
  16223     int m_currentColumn = -1;
  16224     bool m_isOpen = false;
  16225 
  16226 public:
  16227     TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
  16228     :   m_os( os ),
  16229         m_columnInfos( std::move( columnInfos ) ) {}
  16230 
  16231     auto columnInfos() const -> std::vector<ColumnInfo> const& {
  16232         return m_columnInfos;
  16233     }
  16234 
  16235     void open() {
  16236         if (!m_isOpen) {
  16237             m_isOpen = true;
  16238             *this << RowBreak();
  16239 
  16240 			Columns headerCols;
  16241 			Spacer spacer(2);
  16242 			for (auto const& info : m_columnInfos) {
  16243 				headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
  16244 				headerCols += spacer;
  16245 			}
  16246 			m_os << headerCols << '\n';
  16247 
  16248             m_os << Catch::getLineOfChars<'-'>() << '\n';
  16249         }
  16250     }
  16251     void close() {
  16252         if (m_isOpen) {
  16253             *this << RowBreak();
  16254             m_os << std::endl;
  16255             m_isOpen = false;
  16256         }
  16257     }
  16258 
  16259     template<typename T>
  16260     friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
  16261         tp.m_oss << value;
  16262         return tp;
  16263     }
  16264 
  16265     friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
  16266         auto colStr = tp.m_oss.str();
  16267         const auto strSize = colStr.size();
  16268         tp.m_oss.str("");
  16269         tp.open();
  16270         if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
  16271             tp.m_currentColumn = -1;
  16272             tp.m_os << '\n';
  16273         }
  16274         tp.m_currentColumn++;
  16275 
  16276         auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
  16277         auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))
  16278             ? std::string(colInfo.width - (strSize + 1), ' ')
  16279             : std::string();
  16280         if (colInfo.justification == ColumnInfo::Left)
  16281             tp.m_os << colStr << padding << ' ';
  16282         else
  16283             tp.m_os << padding << colStr << ' ';
  16284         return tp;
  16285     }
  16286 
  16287     friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
  16288         if (tp.m_currentColumn > 0) {
  16289             tp.m_os << '\n';
  16290             tp.m_currentColumn = -1;
  16291         }
  16292         return tp;
  16293     }
  16294 };
  16295 
  16296 ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
  16297     : StreamingReporterBase(config),
  16298     m_tablePrinter(new TablePrinter(config.stream(),
  16299         [&config]() -> std::vector<ColumnInfo> {
  16300         if (config.fullConfig()->benchmarkNoAnalysis())
  16301         {
  16302             return{
  16303                 { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
  16304                 { "     samples", 14, ColumnInfo::Right },
  16305                 { "  iterations", 14, ColumnInfo::Right },
  16306                 { "        mean", 14, ColumnInfo::Right }
  16307             };
  16308         }
  16309         else
  16310         {
  16311             return{
  16312                 { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
  16313                 { "samples      mean       std dev", 14, ColumnInfo::Right },
  16314                 { "iterations   low mean   low std dev", 14, ColumnInfo::Right },
  16315                 { "estimated    high mean  high std dev", 14, ColumnInfo::Right }
  16316             };
  16317         }
  16318     }())) {}
  16319 ConsoleReporter::~ConsoleReporter() = default;
  16320 
  16321 std::string ConsoleReporter::getDescription() {
  16322     return "Reports test results as plain lines of text";
  16323 }
  16324 
  16325 void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
  16326     stream << "No test cases matched '" << spec << '\'' << std::endl;
  16327 }
  16328 
  16329 void ConsoleReporter::reportInvalidArguments(std::string const&arg){
  16330     stream << "Invalid Filter: " << arg << std::endl;
  16331 }
  16332 
  16333 void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
  16334 
  16335 bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
  16336     AssertionResult const& result = _assertionStats.assertionResult;
  16337 
  16338     bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  16339 
  16340     // Drop out if result was successful but we're not printing them.
  16341     if (!includeResults && result.getResultType() != ResultWas::Warning)
  16342         return false;
  16343 
  16344     lazyPrint();
  16345 
  16346     ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
  16347     printer.print();
  16348     stream << std::endl;
  16349     return true;
  16350 }
  16351 
  16352 void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
  16353     m_tablePrinter->close();
  16354     m_headerPrinted = false;
  16355     StreamingReporterBase::sectionStarting(_sectionInfo);
  16356 }
  16357 void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
  16358     m_tablePrinter->close();
  16359     if (_sectionStats.missingAssertions) {
  16360         lazyPrint();
  16361         Colour colour(Colour::ResultError);
  16362         if (m_sectionStack.size() > 1)
  16363             stream << "\nNo assertions in section";
  16364         else
  16365             stream << "\nNo assertions in test case";
  16366         stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
  16367     }
  16368     double dur = _sectionStats.durationInSeconds;
  16369     if (shouldShowDuration(*m_config, dur)) {
  16370         stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  16371     }
  16372     if (m_headerPrinted) {
  16373         m_headerPrinted = false;
  16374     }
  16375     StreamingReporterBase::sectionEnded(_sectionStats);
  16376 }
  16377 
  16378 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  16379 void ConsoleReporter::benchmarkPreparing(std::string const& name) {
  16380 	lazyPrintWithoutClosingBenchmarkTable();
  16381 
  16382 	auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
  16383 
  16384 	bool firstLine = true;
  16385 	for (auto line : nameCol) {
  16386 		if (!firstLine)
  16387 			(*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
  16388 		else
  16389 			firstLine = false;
  16390 
  16391 		(*m_tablePrinter) << line << ColumnBreak();
  16392 	}
  16393 }
  16394 
  16395 void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
  16396     (*m_tablePrinter) << info.samples << ColumnBreak()
  16397         << info.iterations << ColumnBreak();
  16398     if (!m_config->benchmarkNoAnalysis())
  16399         (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
  16400 }
  16401 void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
  16402     if (m_config->benchmarkNoAnalysis())
  16403     {
  16404         (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
  16405     }
  16406     else
  16407     {
  16408         (*m_tablePrinter) << ColumnBreak()
  16409             << Duration(stats.mean.point.count()) << ColumnBreak()
  16410             << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
  16411             << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
  16412             << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
  16413             << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
  16414             << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
  16415     }
  16416 }
  16417 
  16418 void ConsoleReporter::benchmarkFailed(std::string const& error) {
  16419 	Colour colour(Colour::Red);
  16420     (*m_tablePrinter)
  16421         << "Benchmark failed (" << error << ')'
  16422         << ColumnBreak() << RowBreak();
  16423 }
  16424 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  16425 
  16426 void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
  16427     m_tablePrinter->close();
  16428     StreamingReporterBase::testCaseEnded(_testCaseStats);
  16429     m_headerPrinted = false;
  16430 }
  16431 void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
  16432     if (currentGroupInfo.used) {
  16433         printSummaryDivider();
  16434         stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
  16435         printTotals(_testGroupStats.totals);
  16436         stream << '\n' << std::endl;
  16437     }
  16438     StreamingReporterBase::testGroupEnded(_testGroupStats);
  16439 }
  16440 void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
  16441     printTotalsDivider(_testRunStats.totals);
  16442     printTotals(_testRunStats.totals);
  16443     stream << std::endl;
  16444     StreamingReporterBase::testRunEnded(_testRunStats);
  16445 }
  16446 void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
  16447     StreamingReporterBase::testRunStarting(_testInfo);
  16448     printTestFilters();
  16449 }
  16450 
  16451 void ConsoleReporter::lazyPrint() {
  16452 
  16453     m_tablePrinter->close();
  16454     lazyPrintWithoutClosingBenchmarkTable();
  16455 }
  16456 
  16457 void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
  16458 
  16459     if (!currentTestRunInfo.used)
  16460         lazyPrintRunInfo();
  16461     if (!currentGroupInfo.used)
  16462         lazyPrintGroupInfo();
  16463 
  16464     if (!m_headerPrinted) {
  16465         printTestCaseAndSectionHeader();
  16466         m_headerPrinted = true;
  16467     }
  16468 }
  16469 void ConsoleReporter::lazyPrintRunInfo() {
  16470     stream << '\n' << getLineOfChars<'~'>() << '\n';
  16471     Colour colour(Colour::SecondaryText);
  16472     stream << currentTestRunInfo->name
  16473         << " is a Catch v" << libraryVersion() << " host application.\n"
  16474         << "Run with -? for options\n\n";
  16475 
  16476     if (m_config->rngSeed() != 0)
  16477         stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
  16478 
  16479     currentTestRunInfo.used = true;
  16480 }
  16481 void ConsoleReporter::lazyPrintGroupInfo() {
  16482     if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
  16483         printClosedHeader("Group: " + currentGroupInfo->name);
  16484         currentGroupInfo.used = true;
  16485     }
  16486 }
  16487 void ConsoleReporter::printTestCaseAndSectionHeader() {
  16488     assert(!m_sectionStack.empty());
  16489     printOpenHeader(currentTestCaseInfo->name);
  16490 
  16491     if (m_sectionStack.size() > 1) {
  16492         Colour colourGuard(Colour::Headers);
  16493 
  16494         auto
  16495             it = m_sectionStack.begin() + 1, // Skip first section (test case)
  16496             itEnd = m_sectionStack.end();
  16497         for (; it != itEnd; ++it)
  16498             printHeaderString(it->name, 2);
  16499     }
  16500 
  16501     SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
  16502 
  16503     stream << getLineOfChars<'-'>() << '\n';
  16504     Colour colourGuard(Colour::FileName);
  16505     stream << lineInfo << '\n';
  16506     stream << getLineOfChars<'.'>() << '\n' << std::endl;
  16507 }
  16508 
  16509 void ConsoleReporter::printClosedHeader(std::string const& _name) {
  16510     printOpenHeader(_name);
  16511     stream << getLineOfChars<'.'>() << '\n';
  16512 }
  16513 void ConsoleReporter::printOpenHeader(std::string const& _name) {
  16514     stream << getLineOfChars<'-'>() << '\n';
  16515     {
  16516         Colour colourGuard(Colour::Headers);
  16517         printHeaderString(_name);
  16518     }
  16519 }
  16520 
  16521 // if string has a : in first line will set indent to follow it on
  16522 // subsequent lines
  16523 void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
  16524     std::size_t i = _string.find(": ");
  16525     if (i != std::string::npos)
  16526         i += 2;
  16527     else
  16528         i = 0;
  16529     stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
  16530 }
  16531 
  16532 struct SummaryColumn {
  16533 
  16534     SummaryColumn( std::string _label, Colour::Code _colour )
  16535     :   label( std::move( _label ) ),
  16536         colour( _colour ) {}
  16537     SummaryColumn addRow( std::size_t count ) {
  16538         ReusableStringStream rss;
  16539         rss << count;
  16540         std::string row = rss.str();
  16541         for (auto& oldRow : rows) {
  16542             while (oldRow.size() < row.size())
  16543                 oldRow = ' ' + oldRow;
  16544             while (oldRow.size() > row.size())
  16545                 row = ' ' + row;
  16546         }
  16547         rows.push_back(row);
  16548         return *this;
  16549     }
  16550 
  16551     std::string label;
  16552     Colour::Code colour;
  16553     std::vector<std::string> rows;
  16554 
  16555 };
  16556 
  16557 void ConsoleReporter::printTotals( Totals const& totals ) {
  16558     if (totals.testCases.total() == 0) {
  16559         stream << Colour(Colour::Warning) << "No tests ran\n";
  16560     } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
  16561         stream << Colour(Colour::ResultSuccess) << "All tests passed";
  16562         stream << " ("
  16563             << pluralise(totals.assertions.passed, "assertion") << " in "
  16564             << pluralise(totals.testCases.passed, "test case") << ')'
  16565             << '\n';
  16566     } else {
  16567 
  16568         std::vector<SummaryColumn> columns;
  16569         columns.push_back(SummaryColumn("", Colour::None)
  16570                           .addRow(totals.testCases.total())
  16571                           .addRow(totals.assertions.total()));
  16572         columns.push_back(SummaryColumn("passed", Colour::Success)
  16573                           .addRow(totals.testCases.passed)
  16574                           .addRow(totals.assertions.passed));
  16575         columns.push_back(SummaryColumn("failed", Colour::ResultError)
  16576                           .addRow(totals.testCases.failed)
  16577                           .addRow(totals.assertions.failed));
  16578         columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
  16579                           .addRow(totals.testCases.failedButOk)
  16580                           .addRow(totals.assertions.failedButOk));
  16581 
  16582         printSummaryRow("test cases", columns, 0);
  16583         printSummaryRow("assertions", columns, 1);
  16584     }
  16585 }
  16586 void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
  16587     for (auto col : cols) {
  16588         std::string value = col.rows[row];
  16589         if (col.label.empty()) {
  16590             stream << label << ": ";
  16591             if (value != "0")
  16592                 stream << value;
  16593             else
  16594                 stream << Colour(Colour::Warning) << "- none -";
  16595         } else if (value != "0") {
  16596             stream << Colour(Colour::LightGrey) << " | ";
  16597             stream << Colour(col.colour)
  16598                 << value << ' ' << col.label;
  16599         }
  16600     }
  16601     stream << '\n';
  16602 }
  16603 
  16604 void ConsoleReporter::printTotalsDivider(Totals const& totals) {
  16605     if (totals.testCases.total() > 0) {
  16606         std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
  16607         std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
  16608         std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
  16609         while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
  16610             findMax(failedRatio, failedButOkRatio, passedRatio)++;
  16611         while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
  16612             findMax(failedRatio, failedButOkRatio, passedRatio)--;
  16613 
  16614         stream << Colour(Colour::Error) << std::string(failedRatio, '=');
  16615         stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
  16616         if (totals.testCases.allPassed())
  16617             stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
  16618         else
  16619             stream << Colour(Colour::Success) << std::string(passedRatio, '=');
  16620     } else {
  16621         stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
  16622     }
  16623     stream << '\n';
  16624 }
  16625 void ConsoleReporter::printSummaryDivider() {
  16626     stream << getLineOfChars<'-'>() << '\n';
  16627 }
  16628 
  16629 void ConsoleReporter::printTestFilters() {
  16630     if (m_config->testSpec().hasFilters()) {
  16631         Colour guard(Colour::BrightYellow);
  16632         stream << "Filters: " << serializeFilters(m_config->getTestsOrTags()) << '\n';
  16633     }
  16634 }
  16635 
  16636 CATCH_REGISTER_REPORTER("console", ConsoleReporter)
  16637 
  16638 } // end namespace Catch
  16639 
  16640 #if defined(_MSC_VER)
  16641 #pragma warning(pop)
  16642 #endif
  16643 
  16644 #if defined(__clang__)
  16645 #  pragma clang diagnostic pop
  16646 #endif
  16647 // end catch_reporter_console.cpp
  16648 // start catch_reporter_junit.cpp
  16649 
  16650 #include <cassert>
  16651 #include <sstream>
  16652 #include <ctime>
  16653 #include <algorithm>
  16654 
  16655 namespace Catch {
  16656 
  16657     namespace {
  16658         std::string getCurrentTimestamp() {
  16659             // Beware, this is not reentrant because of backward compatibility issues
  16660             // Also, UTC only, again because of backward compatibility (%z is C++11)
  16661             time_t rawtime;
  16662             std::time(&rawtime);
  16663             auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  16664 
  16665 #ifdef _MSC_VER
  16666             std::tm timeInfo = {};
  16667             gmtime_s(&timeInfo, &rawtime);
  16668 #else
  16669             std::tm* timeInfo;
  16670             timeInfo = std::gmtime(&rawtime);
  16671 #endif
  16672 
  16673             char timeStamp[timeStampSize];
  16674             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
  16675 
  16676 #ifdef _MSC_VER
  16677             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  16678 #else
  16679             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
  16680 #endif
  16681             return std::string(timeStamp);
  16682         }
  16683 
  16684         std::string fileNameTag(const std::vector<std::string> &tags) {
  16685             auto it = std::find_if(begin(tags),
  16686                                    end(tags),
  16687                                    [] (std::string const& tag) {return tag.front() == '#'; });
  16688             if (it != tags.end())
  16689                 return it->substr(1);
  16690             return std::string();
  16691         }
  16692     } // anonymous namespace
  16693 
  16694     JunitReporter::JunitReporter( ReporterConfig const& _config )
  16695         :   CumulativeReporterBase( _config ),
  16696             xml( _config.stream() )
  16697         {
  16698             m_reporterPrefs.shouldRedirectStdOut = true;
  16699             m_reporterPrefs.shouldReportAllAssertions = true;
  16700         }
  16701 
  16702     JunitReporter::~JunitReporter() {}
  16703 
  16704     std::string JunitReporter::getDescription() {
  16705         return "Reports test results in an XML format that looks like Ant's junitreport target";
  16706     }
  16707 
  16708     void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
  16709 
  16710     void JunitReporter::testRunStarting( TestRunInfo const& runInfo )  {
  16711         CumulativeReporterBase::testRunStarting( runInfo );
  16712         xml.startElement( "testsuites" );
  16713     }
  16714 
  16715     void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
  16716         suiteTimer.start();
  16717         stdOutForSuite.clear();
  16718         stdErrForSuite.clear();
  16719         unexpectedExceptions = 0;
  16720         CumulativeReporterBase::testGroupStarting( groupInfo );
  16721     }
  16722 
  16723     void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
  16724         m_okToFail = testCaseInfo.okToFail();
  16725     }
  16726 
  16727     bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
  16728         if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
  16729             unexpectedExceptions++;
  16730         return CumulativeReporterBase::assertionEnded( assertionStats );
  16731     }
  16732 
  16733     void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
  16734         stdOutForSuite += testCaseStats.stdOut;
  16735         stdErrForSuite += testCaseStats.stdErr;
  16736         CumulativeReporterBase::testCaseEnded( testCaseStats );
  16737     }
  16738 
  16739     void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
  16740         double suiteTime = suiteTimer.getElapsedSeconds();
  16741         CumulativeReporterBase::testGroupEnded( testGroupStats );
  16742         writeGroup( *m_testGroups.back(), suiteTime );
  16743     }
  16744 
  16745     void JunitReporter::testRunEndedCumulative() {
  16746         xml.endElement();
  16747     }
  16748 
  16749     void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
  16750         XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
  16751 
  16752         TestGroupStats const& stats = groupNode.value;
  16753         xml.writeAttribute( "name", stats.groupInfo.name );
  16754         xml.writeAttribute( "errors", unexpectedExceptions );
  16755         xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
  16756         xml.writeAttribute( "tests", stats.totals.assertions.total() );
  16757         xml.writeAttribute( "hostname", "tbd" ); // !TBD
  16758         if( m_config->showDurations() == ShowDurations::Never )
  16759             xml.writeAttribute( "time", "" );
  16760         else
  16761             xml.writeAttribute( "time", suiteTime );
  16762         xml.writeAttribute( "timestamp", getCurrentTimestamp() );
  16763 
  16764         // Write properties if there are any
  16765         if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
  16766             auto properties = xml.scopedElement("properties");
  16767             if (m_config->hasTestFilters()) {
  16768                 xml.scopedElement("property")
  16769                     .writeAttribute("name", "filters")
  16770                     .writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
  16771             }
  16772             if (m_config->rngSeed() != 0) {
  16773                 xml.scopedElement("property")
  16774                     .writeAttribute("name", "random-seed")
  16775                     .writeAttribute("value", m_config->rngSeed());
  16776             }
  16777         }
  16778 
  16779         // Write test cases
  16780         for( auto const& child : groupNode.children )
  16781             writeTestCase( *child );
  16782 
  16783         xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );
  16784         xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline );
  16785     }
  16786 
  16787     void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
  16788         TestCaseStats const& stats = testCaseNode.value;
  16789 
  16790         // All test cases have exactly one section - which represents the
  16791         // test case itself. That section may have 0-n nested sections
  16792         assert( testCaseNode.children.size() == 1 );
  16793         SectionNode const& rootSection = *testCaseNode.children.front();
  16794 
  16795         std::string className = stats.testInfo.className;
  16796 
  16797         if( className.empty() ) {
  16798             className = fileNameTag(stats.testInfo.tags);
  16799             if ( className.empty() )
  16800                 className = "global";
  16801         }
  16802 
  16803         if ( !m_config->name().empty() )
  16804             className = m_config->name() + "." + className;
  16805 
  16806         writeSection( className, "", rootSection );
  16807     }
  16808 
  16809     void JunitReporter::writeSection(  std::string const& className,
  16810                         std::string const& rootName,
  16811                         SectionNode const& sectionNode ) {
  16812         std::string name = trim( sectionNode.stats.sectionInfo.name );
  16813         if( !rootName.empty() )
  16814             name = rootName + '/' + name;
  16815 
  16816         if( !sectionNode.assertions.empty() ||
  16817             !sectionNode.stdOut.empty() ||
  16818             !sectionNode.stdErr.empty() ) {
  16819             XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
  16820             if( className.empty() ) {
  16821                 xml.writeAttribute( "classname", name );
  16822                 xml.writeAttribute( "name", "root" );
  16823             }
  16824             else {
  16825                 xml.writeAttribute( "classname", className );
  16826                 xml.writeAttribute( "name", name );
  16827             }
  16828             xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
  16829             // This is not ideal, but it should be enough to mimic gtest's
  16830             // junit output.
  16831             // Ideally the JUnit reporter would also handle `skipTest`
  16832             // events and write those out appropriately.
  16833             xml.writeAttribute( "status", "run" );
  16834 
  16835             writeAssertions( sectionNode );
  16836 
  16837             if( !sectionNode.stdOut.empty() )
  16838                 xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );
  16839             if( !sectionNode.stdErr.empty() )
  16840                 xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline );
  16841         }
  16842         for( auto const& childNode : sectionNode.childSections )
  16843             if( className.empty() )
  16844                 writeSection( name, "", *childNode );
  16845             else
  16846                 writeSection( className, name, *childNode );
  16847     }
  16848 
  16849     void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
  16850         for( auto const& assertion : sectionNode.assertions )
  16851             writeAssertion( assertion );
  16852     }
  16853 
  16854     void JunitReporter::writeAssertion( AssertionStats const& stats ) {
  16855         AssertionResult const& result = stats.assertionResult;
  16856         if( !result.isOk() ) {
  16857             std::string elementName;
  16858             switch( result.getResultType() ) {
  16859                 case ResultWas::ThrewException:
  16860                 case ResultWas::FatalErrorCondition:
  16861                     elementName = "error";
  16862                     break;
  16863                 case ResultWas::ExplicitFailure:
  16864                 case ResultWas::ExpressionFailed:
  16865                 case ResultWas::DidntThrowException:
  16866                     elementName = "failure";
  16867                     break;
  16868 
  16869                 // We should never see these here:
  16870                 case ResultWas::Info:
  16871                 case ResultWas::Warning:
  16872                 case ResultWas::Ok:
  16873                 case ResultWas::Unknown:
  16874                 case ResultWas::FailureBit:
  16875                 case ResultWas::Exception:
  16876                     elementName = "internalError";
  16877                     break;
  16878             }
  16879 
  16880             XmlWriter::ScopedElement e = xml.scopedElement( elementName );
  16881 
  16882             xml.writeAttribute( "message", result.getExpression() );
  16883             xml.writeAttribute( "type", result.getTestMacroName() );
  16884 
  16885             ReusableStringStream rss;
  16886             if (stats.totals.assertions.total() > 0) {
  16887                 rss << "FAILED" << ":\n";
  16888                 if (result.hasExpression()) {
  16889                     rss << "  ";
  16890                     rss << result.getExpressionInMacro();
  16891                     rss << '\n';
  16892                 }
  16893                 if (result.hasExpandedExpression()) {
  16894                     rss << "with expansion:\n";
  16895                     rss << Column(result.getExpandedExpression()).indent(2) << '\n';
  16896                 }
  16897             } else {
  16898                 rss << '\n';
  16899             }
  16900 
  16901             if( !result.getMessage().empty() )
  16902                 rss << result.getMessage() << '\n';
  16903             for( auto const& msg : stats.infoMessages )
  16904                 if( msg.type == ResultWas::Info )
  16905                     rss << msg.message << '\n';
  16906 
  16907             rss << "at " << result.getSourceInfo();
  16908             xml.writeText( rss.str(), XmlFormatting::Newline );
  16909         }
  16910     }
  16911 
  16912     CATCH_REGISTER_REPORTER( "junit", JunitReporter )
  16913 
  16914 } // end namespace Catch
  16915 // end catch_reporter_junit.cpp
  16916 // start catch_reporter_listening.cpp
  16917 
  16918 #include <cassert>
  16919 
  16920 namespace Catch {
  16921 
  16922     ListeningReporter::ListeningReporter() {
  16923         // We will assume that listeners will always want all assertions
  16924         m_preferences.shouldReportAllAssertions = true;
  16925     }
  16926 
  16927     void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
  16928         m_listeners.push_back( std::move( listener ) );
  16929     }
  16930 
  16931     void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
  16932         assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
  16933         m_reporter = std::move( reporter );
  16934         m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
  16935     }
  16936 
  16937     ReporterPreferences ListeningReporter::getPreferences() const {
  16938         return m_preferences;
  16939     }
  16940 
  16941     std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
  16942         return std::set<Verbosity>{ };
  16943     }
  16944 
  16945     void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
  16946         for ( auto const& listener : m_listeners ) {
  16947             listener->noMatchingTestCases( spec );
  16948         }
  16949         m_reporter->noMatchingTestCases( spec );
  16950     }
  16951 
  16952     void ListeningReporter::reportInvalidArguments(std::string const&arg){
  16953         for ( auto const& listener : m_listeners ) {
  16954             listener->reportInvalidArguments( arg );
  16955         }
  16956         m_reporter->reportInvalidArguments( arg );
  16957     }
  16958 
  16959 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  16960     void ListeningReporter::benchmarkPreparing( std::string const& name ) {
  16961 		for (auto const& listener : m_listeners) {
  16962 			listener->benchmarkPreparing(name);
  16963 		}
  16964 		m_reporter->benchmarkPreparing(name);
  16965 	}
  16966     void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
  16967         for ( auto const& listener : m_listeners ) {
  16968             listener->benchmarkStarting( benchmarkInfo );
  16969         }
  16970         m_reporter->benchmarkStarting( benchmarkInfo );
  16971     }
  16972     void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {
  16973         for ( auto const& listener : m_listeners ) {
  16974             listener->benchmarkEnded( benchmarkStats );
  16975         }
  16976         m_reporter->benchmarkEnded( benchmarkStats );
  16977     }
  16978 
  16979 	void ListeningReporter::benchmarkFailed( std::string const& error ) {
  16980 		for (auto const& listener : m_listeners) {
  16981 			listener->benchmarkFailed(error);
  16982 		}
  16983 		m_reporter->benchmarkFailed(error);
  16984 	}
  16985 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  16986 
  16987     void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
  16988         for ( auto const& listener : m_listeners ) {
  16989             listener->testRunStarting( testRunInfo );
  16990         }
  16991         m_reporter->testRunStarting( testRunInfo );
  16992     }
  16993 
  16994     void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
  16995         for ( auto const& listener : m_listeners ) {
  16996             listener->testGroupStarting( groupInfo );
  16997         }
  16998         m_reporter->testGroupStarting( groupInfo );
  16999     }
  17000 
  17001     void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
  17002         for ( auto const& listener : m_listeners ) {
  17003             listener->testCaseStarting( testInfo );
  17004         }
  17005         m_reporter->testCaseStarting( testInfo );
  17006     }
  17007 
  17008     void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
  17009         for ( auto const& listener : m_listeners ) {
  17010             listener->sectionStarting( sectionInfo );
  17011         }
  17012         m_reporter->sectionStarting( sectionInfo );
  17013     }
  17014 
  17015     void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
  17016         for ( auto const& listener : m_listeners ) {
  17017             listener->assertionStarting( assertionInfo );
  17018         }
  17019         m_reporter->assertionStarting( assertionInfo );
  17020     }
  17021 
  17022     // The return value indicates if the messages buffer should be cleared:
  17023     bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
  17024         for( auto const& listener : m_listeners ) {
  17025             static_cast<void>( listener->assertionEnded( assertionStats ) );
  17026         }
  17027         return m_reporter->assertionEnded( assertionStats );
  17028     }
  17029 
  17030     void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
  17031         for ( auto const& listener : m_listeners ) {
  17032             listener->sectionEnded( sectionStats );
  17033         }
  17034         m_reporter->sectionEnded( sectionStats );
  17035     }
  17036 
  17037     void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
  17038         for ( auto const& listener : m_listeners ) {
  17039             listener->testCaseEnded( testCaseStats );
  17040         }
  17041         m_reporter->testCaseEnded( testCaseStats );
  17042     }
  17043 
  17044     void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
  17045         for ( auto const& listener : m_listeners ) {
  17046             listener->testGroupEnded( testGroupStats );
  17047         }
  17048         m_reporter->testGroupEnded( testGroupStats );
  17049     }
  17050 
  17051     void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
  17052         for ( auto const& listener : m_listeners ) {
  17053             listener->testRunEnded( testRunStats );
  17054         }
  17055         m_reporter->testRunEnded( testRunStats );
  17056     }
  17057 
  17058     void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
  17059         for ( auto const& listener : m_listeners ) {
  17060             listener->skipTest( testInfo );
  17061         }
  17062         m_reporter->skipTest( testInfo );
  17063     }
  17064 
  17065     bool ListeningReporter::isMulti() const {
  17066         return true;
  17067     }
  17068 
  17069 } // end namespace Catch
  17070 // end catch_reporter_listening.cpp
  17071 // start catch_reporter_xml.cpp
  17072 
  17073 #if defined(_MSC_VER)
  17074 #pragma warning(push)
  17075 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  17076                               // Note that 4062 (not all labels are handled
  17077                               // and default is missing) is enabled
  17078 #endif
  17079 
  17080 namespace Catch {
  17081     XmlReporter::XmlReporter( ReporterConfig const& _config )
  17082     :   StreamingReporterBase( _config ),
  17083         m_xml(_config.stream())
  17084     {
  17085         m_reporterPrefs.shouldRedirectStdOut = true;
  17086         m_reporterPrefs.shouldReportAllAssertions = true;
  17087     }
  17088 
  17089     XmlReporter::~XmlReporter() = default;
  17090 
  17091     std::string XmlReporter::getDescription() {
  17092         return "Reports test results as an XML document";
  17093     }
  17094 
  17095     std::string XmlReporter::getStylesheetRef() const {
  17096         return std::string();
  17097     }
  17098 
  17099     void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
  17100         m_xml
  17101             .writeAttribute( "filename", sourceInfo.file )
  17102             .writeAttribute( "line", sourceInfo.line );
  17103     }
  17104 
  17105     void XmlReporter::noMatchingTestCases( std::string const& s ) {
  17106         StreamingReporterBase::noMatchingTestCases( s );
  17107     }
  17108 
  17109     void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
  17110         StreamingReporterBase::testRunStarting( testInfo );
  17111         std::string stylesheetRef = getStylesheetRef();
  17112         if( !stylesheetRef.empty() )
  17113             m_xml.writeStylesheetRef( stylesheetRef );
  17114         m_xml.startElement( "Catch" );
  17115         if( !m_config->name().empty() )
  17116             m_xml.writeAttribute( "name", m_config->name() );
  17117         if (m_config->testSpec().hasFilters())
  17118             m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) );
  17119         if( m_config->rngSeed() != 0 )
  17120             m_xml.scopedElement( "Randomness" )
  17121                 .writeAttribute( "seed", m_config->rngSeed() );
  17122     }
  17123 
  17124     void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
  17125         StreamingReporterBase::testGroupStarting( groupInfo );
  17126         m_xml.startElement( "Group" )
  17127             .writeAttribute( "name", groupInfo.name );
  17128     }
  17129 
  17130     void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
  17131         StreamingReporterBase::testCaseStarting(testInfo);
  17132         m_xml.startElement( "TestCase" )
  17133             .writeAttribute( "name", trim( testInfo.name ) )
  17134             .writeAttribute( "description", testInfo.description )
  17135             .writeAttribute( "tags", testInfo.tagsAsString() );
  17136 
  17137         writeSourceInfo( testInfo.lineInfo );
  17138 
  17139         if ( m_config->showDurations() == ShowDurations::Always )
  17140             m_testCaseTimer.start();
  17141         m_xml.ensureTagClosed();
  17142     }
  17143 
  17144     void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
  17145         StreamingReporterBase::sectionStarting( sectionInfo );
  17146         if( m_sectionDepth++ > 0 ) {
  17147             m_xml.startElement( "Section" )
  17148                 .writeAttribute( "name", trim( sectionInfo.name ) );
  17149             writeSourceInfo( sectionInfo.lineInfo );
  17150             m_xml.ensureTagClosed();
  17151         }
  17152     }
  17153 
  17154     void XmlReporter::assertionStarting( AssertionInfo const& ) { }
  17155 
  17156     bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
  17157 
  17158         AssertionResult const& result = assertionStats.assertionResult;
  17159 
  17160         bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  17161 
  17162         if( includeResults || result.getResultType() == ResultWas::Warning ) {
  17163             // Print any info messages in <Info> tags.
  17164             for( auto const& msg : assertionStats.infoMessages ) {
  17165                 if( msg.type == ResultWas::Info && includeResults ) {
  17166                     m_xml.scopedElement( "Info" )
  17167                             .writeText( msg.message );
  17168                 } else if ( msg.type == ResultWas::Warning ) {
  17169                     m_xml.scopedElement( "Warning" )
  17170                             .writeText( msg.message );
  17171                 }
  17172             }
  17173         }
  17174 
  17175         // Drop out if result was successful but we're not printing them.
  17176         if( !includeResults && result.getResultType() != ResultWas::Warning )
  17177             return true;
  17178 
  17179         // Print the expression if there is one.
  17180         if( result.hasExpression() ) {
  17181             m_xml.startElement( "Expression" )
  17182                 .writeAttribute( "success", result.succeeded() )
  17183                 .writeAttribute( "type", result.getTestMacroName() );
  17184 
  17185             writeSourceInfo( result.getSourceInfo() );
  17186 
  17187             m_xml.scopedElement( "Original" )
  17188                 .writeText( result.getExpression() );
  17189             m_xml.scopedElement( "Expanded" )
  17190                 .writeText( result.getExpandedExpression() );
  17191         }
  17192 
  17193         // And... Print a result applicable to each result type.
  17194         switch( result.getResultType() ) {
  17195             case ResultWas::ThrewException:
  17196                 m_xml.startElement( "Exception" );
  17197                 writeSourceInfo( result.getSourceInfo() );
  17198                 m_xml.writeText( result.getMessage() );
  17199                 m_xml.endElement();
  17200                 break;
  17201             case ResultWas::FatalErrorCondition:
  17202                 m_xml.startElement( "FatalErrorCondition" );
  17203                 writeSourceInfo( result.getSourceInfo() );
  17204                 m_xml.writeText( result.getMessage() );
  17205                 m_xml.endElement();
  17206                 break;
  17207             case ResultWas::Info:
  17208                 m_xml.scopedElement( "Info" )
  17209                     .writeText( result.getMessage() );
  17210                 break;
  17211             case ResultWas::Warning:
  17212                 // Warning will already have been written
  17213                 break;
  17214             case ResultWas::ExplicitFailure:
  17215                 m_xml.startElement( "Failure" );
  17216                 writeSourceInfo( result.getSourceInfo() );
  17217                 m_xml.writeText( result.getMessage() );
  17218                 m_xml.endElement();
  17219                 break;
  17220             default:
  17221                 break;
  17222         }
  17223 
  17224         if( result.hasExpression() )
  17225             m_xml.endElement();
  17226 
  17227         return true;
  17228     }
  17229 
  17230     void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
  17231         StreamingReporterBase::sectionEnded( sectionStats );
  17232         if( --m_sectionDepth > 0 ) {
  17233             XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
  17234             e.writeAttribute( "successes", sectionStats.assertions.passed );
  17235             e.writeAttribute( "failures", sectionStats.assertions.failed );
  17236             e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
  17237 
  17238             if ( m_config->showDurations() == ShowDurations::Always )
  17239                 e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
  17240 
  17241             m_xml.endElement();
  17242         }
  17243     }
  17244 
  17245     void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
  17246         StreamingReporterBase::testCaseEnded( testCaseStats );
  17247         XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
  17248         e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
  17249 
  17250         if ( m_config->showDurations() == ShowDurations::Always )
  17251             e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
  17252 
  17253         if( !testCaseStats.stdOut.empty() )
  17254             m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );
  17255         if( !testCaseStats.stdErr.empty() )
  17256             m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );
  17257 
  17258         m_xml.endElement();
  17259     }
  17260 
  17261     void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
  17262         StreamingReporterBase::testGroupEnded( testGroupStats );
  17263         // TODO: Check testGroupStats.aborting and act accordingly.
  17264         m_xml.scopedElement( "OverallResults" )
  17265             .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
  17266             .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
  17267             .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
  17268         m_xml.scopedElement( "OverallResultsCases")
  17269             .writeAttribute( "successes", testGroupStats.totals.testCases.passed )
  17270             .writeAttribute( "failures", testGroupStats.totals.testCases.failed )
  17271             .writeAttribute( "expectedFailures", testGroupStats.totals.testCases.failedButOk );
  17272         m_xml.endElement();
  17273     }
  17274 
  17275     void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
  17276         StreamingReporterBase::testRunEnded( testRunStats );
  17277         m_xml.scopedElement( "OverallResults" )
  17278             .writeAttribute( "successes", testRunStats.totals.assertions.passed )
  17279             .writeAttribute( "failures", testRunStats.totals.assertions.failed )
  17280             .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
  17281         m_xml.scopedElement( "OverallResultsCases")
  17282             .writeAttribute( "successes", testRunStats.totals.testCases.passed )
  17283             .writeAttribute( "failures", testRunStats.totals.testCases.failed )
  17284             .writeAttribute( "expectedFailures", testRunStats.totals.testCases.failedButOk );
  17285         m_xml.endElement();
  17286     }
  17287 
  17288 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  17289     void XmlReporter::benchmarkPreparing(std::string const& name) {
  17290         m_xml.startElement("BenchmarkResults")
  17291             .writeAttribute("name", name);
  17292     }
  17293 
  17294     void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
  17295         m_xml.writeAttribute("samples", info.samples)
  17296             .writeAttribute("resamples", info.resamples)
  17297             .writeAttribute("iterations", info.iterations)
  17298             .writeAttribute("clockResolution", info.clockResolution)
  17299             .writeAttribute("estimatedDuration", info.estimatedDuration)
  17300             .writeComment("All values in nano seconds");
  17301     }
  17302 
  17303     void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
  17304         m_xml.startElement("mean")
  17305             .writeAttribute("value", benchmarkStats.mean.point.count())
  17306             .writeAttribute("lowerBound", benchmarkStats.mean.lower_bound.count())
  17307             .writeAttribute("upperBound", benchmarkStats.mean.upper_bound.count())
  17308             .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
  17309         m_xml.endElement();
  17310         m_xml.startElement("standardDeviation")
  17311             .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
  17312             .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
  17313             .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
  17314             .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
  17315         m_xml.endElement();
  17316         m_xml.startElement("outliers")
  17317             .writeAttribute("variance", benchmarkStats.outlierVariance)
  17318             .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
  17319             .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
  17320             .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
  17321             .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
  17322         m_xml.endElement();
  17323         m_xml.endElement();
  17324     }
  17325 
  17326     void XmlReporter::benchmarkFailed(std::string const &error) {
  17327         m_xml.scopedElement("failed").
  17328             writeAttribute("message", error);
  17329         m_xml.endElement();
  17330     }
  17331 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  17332 
  17333     CATCH_REGISTER_REPORTER( "xml", XmlReporter )
  17334 
  17335 } // end namespace Catch
  17336 
  17337 #if defined(_MSC_VER)
  17338 #pragma warning(pop)
  17339 #endif
  17340 // end catch_reporter_xml.cpp
  17341 
  17342 namespace Catch {
  17343     LeakDetector leakDetector;
  17344 }
  17345 
  17346 #ifdef __clang__
  17347 #pragma clang diagnostic pop
  17348 #endif
  17349 
  17350 // end catch_impl.hpp
  17351 #endif
  17352 
  17353 #ifdef CATCH_CONFIG_MAIN
  17354 // start catch_default_main.hpp
  17355 
  17356 #ifndef __OBJC__
  17357 
  17358 #if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
  17359 // Standard C/C++ Win32 Unicode wmain entry point
  17360 extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
  17361 #else
  17362 // Standard C/C++ main entry point
  17363 int main (int argc, char * argv[]) {
  17364 #endif
  17365 
  17366     return Catch::Session().run( argc, argv );
  17367 }
  17368 
  17369 #else // __OBJC__
  17370 
  17371 // Objective-C entry point
  17372 int main (int argc, char * const argv[]) {
  17373 #if !CATCH_ARC_ENABLED
  17374     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  17375 #endif
  17376 
  17377     Catch::registerTestMethods();
  17378     int result = Catch::Session().run( argc, (char**)argv );
  17379 
  17380 #if !CATCH_ARC_ENABLED
  17381     [pool drain];
  17382 #endif
  17383 
  17384     return result;
  17385 }
  17386 
  17387 #endif // __OBJC__
  17388 
  17389 // end catch_default_main.hpp
  17390 #endif
  17391 
  17392 #if !defined(CATCH_CONFIG_IMPL_ONLY)
  17393 
  17394 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
  17395 #  undef CLARA_CONFIG_MAIN
  17396 #endif
  17397 
  17398 #if !defined(CATCH_CONFIG_DISABLE)
  17399 //////
  17400 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  17401 #ifdef CATCH_CONFIG_PREFIX_ALL
  17402 
  17403 #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17404 #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  17405 
  17406 #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17407 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  17408 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  17409 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17410 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  17411 #endif// CATCH_CONFIG_DISABLE_MATCHERS
  17412 #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17413 
  17414 #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17415 #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  17416 #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17417 #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17418 #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  17419 
  17420 #define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17421 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  17422 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  17423 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17424 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  17425 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17426 #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17427 
  17428 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17429 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  17430 
  17431 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  17432 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17433 
  17434 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
  17435 #define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
  17436 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  17437 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
  17438 
  17439 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  17440 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17441 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  17442 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  17443 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  17444 #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
  17445 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17446 #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17447 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17448 
  17449 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  17450 
  17451 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  17452 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17453 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
  17454 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17455 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  17456 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
  17457 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
  17458 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17459 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  17460 #else
  17461 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
  17462 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
  17463 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  17464 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  17465 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
  17466 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
  17467 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  17468 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  17469 #endif
  17470 
  17471 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
  17472 #define CATCH_STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__ ,      #__VA_ARGS__ );     CATCH_SUCCEED( #__VA_ARGS__ )
  17473 #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
  17474 #else
  17475 #define CATCH_STATIC_REQUIRE( ... )       CATCH_REQUIRE( __VA_ARGS__ )
  17476 #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
  17477 #endif
  17478 
  17479 // "BDD-style" convenience wrappers
  17480 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
  17481 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  17482 #define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
  17483 #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
  17484 #define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
  17485 #define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
  17486 #define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
  17487 #define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
  17488 
  17489 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  17490 #define CATCH_BENCHMARK(...) \
  17491     INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
  17492 #define CATCH_BENCHMARK_ADVANCED(name) \
  17493     INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
  17494 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  17495 
  17496 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  17497 #else
  17498 
  17499 #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__  )
  17500 #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  17501 
  17502 #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17503 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  17504 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  17505 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17506 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  17507 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17508 #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17509 
  17510 #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17511 #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  17512 #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17513 #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17514 #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  17515 
  17516 #define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17517 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  17518 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  17519 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17520 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  17521 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17522 #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17523 
  17524 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17525 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  17526 
  17527 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  17528 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17529 
  17530 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
  17531 #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
  17532 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  17533 #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
  17534 
  17535 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  17536 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17537 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  17538 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  17539 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  17540 #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
  17541 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17542 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17543 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17544 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  17545 
  17546 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  17547 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17548 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
  17549 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17550 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  17551 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
  17552 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
  17553 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17554 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  17555 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
  17556 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17557 #else
  17558 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
  17559 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
  17560 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  17561 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  17562 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
  17563 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
  17564 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  17565 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  17566 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
  17567 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  17568 #endif
  17569 
  17570 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
  17571 #define STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__,  #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
  17572 #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
  17573 #else
  17574 #define STATIC_REQUIRE( ... )       REQUIRE( __VA_ARGS__ )
  17575 #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
  17576 #endif
  17577 
  17578 #endif
  17579 
  17580 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
  17581 
  17582 // "BDD-style" convenience wrappers
  17583 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
  17584 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  17585 
  17586 #define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
  17587 #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
  17588 #define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
  17589 #define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
  17590 #define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
  17591 #define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
  17592 
  17593 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  17594 #define BENCHMARK(...) \
  17595     INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
  17596 #define BENCHMARK_ADVANCED(name) \
  17597     INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
  17598 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  17599 
  17600 using Catch::Detail::Approx;
  17601 
  17602 #else // CATCH_CONFIG_DISABLE
  17603 
  17604 //////
  17605 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  17606 #ifdef CATCH_CONFIG_PREFIX_ALL
  17607 
  17608 #define CATCH_REQUIRE( ... )        (void)(0)
  17609 #define CATCH_REQUIRE_FALSE( ... )  (void)(0)
  17610 
  17611 #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
  17612 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  17613 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0)
  17614 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17615 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  17616 #endif// CATCH_CONFIG_DISABLE_MATCHERS
  17617 #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
  17618 
  17619 #define CATCH_CHECK( ... )         (void)(0)
  17620 #define CATCH_CHECK_FALSE( ... )   (void)(0)
  17621 #define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__)
  17622 #define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__))
  17623 #define CATCH_CHECK_NOFAIL( ... )  (void)(0)
  17624 
  17625 #define CATCH_CHECK_THROWS( ... )  (void)(0)
  17626 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  17627 #define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0)
  17628 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17629 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  17630 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17631 #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
  17632 
  17633 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17634 #define CATCH_CHECK_THAT( arg, matcher )   (void)(0)
  17635 
  17636 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
  17637 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17638 
  17639 #define CATCH_INFO( msg )          (void)(0)
  17640 #define CATCH_UNSCOPED_INFO( msg ) (void)(0)
  17641 #define CATCH_WARN( msg )          (void)(0)
  17642 #define CATCH_CAPTURE( msg )       (void)(0)
  17643 
  17644 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17645 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17646 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
  17647 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
  17648 #define CATCH_SECTION( ... )
  17649 #define CATCH_DYNAMIC_SECTION( ... )
  17650 #define CATCH_FAIL( ... ) (void)(0)
  17651 #define CATCH_FAIL_CHECK( ... ) (void)(0)
  17652 #define CATCH_SUCCEED( ... ) (void)(0)
  17653 
  17654 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17655 
  17656 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  17657 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
  17658 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
  17659 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
  17660 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
  17661 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17662 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17663 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17664 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17665 #else
  17666 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
  17667 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
  17668 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
  17669 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
  17670 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17671 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17672 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17673 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17674 #endif
  17675 
  17676 // "BDD-style" convenience wrappers
  17677 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17678 #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 )
  17679 #define CATCH_GIVEN( desc )
  17680 #define CATCH_AND_GIVEN( desc )
  17681 #define CATCH_WHEN( desc )
  17682 #define CATCH_AND_WHEN( desc )
  17683 #define CATCH_THEN( desc )
  17684 #define CATCH_AND_THEN( desc )
  17685 
  17686 #define CATCH_STATIC_REQUIRE( ... )       (void)(0)
  17687 #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
  17688 
  17689 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  17690 #else
  17691 
  17692 #define REQUIRE( ... )       (void)(0)
  17693 #define REQUIRE_FALSE( ... ) (void)(0)
  17694 
  17695 #define REQUIRE_THROWS( ... ) (void)(0)
  17696 #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  17697 #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
  17698 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17699 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  17700 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17701 #define REQUIRE_NOTHROW( ... ) (void)(0)
  17702 
  17703 #define CHECK( ... ) (void)(0)
  17704 #define CHECK_FALSE( ... ) (void)(0)
  17705 #define CHECKED_IF( ... ) if (__VA_ARGS__)
  17706 #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
  17707 #define CHECK_NOFAIL( ... ) (void)(0)
  17708 
  17709 #define CHECK_THROWS( ... )  (void)(0)
  17710 #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  17711 #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
  17712 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17713 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  17714 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17715 #define CHECK_NOTHROW( ... ) (void)(0)
  17716 
  17717 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17718 #define CHECK_THAT( arg, matcher ) (void)(0)
  17719 
  17720 #define REQUIRE_THAT( arg, matcher ) (void)(0)
  17721 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17722 
  17723 #define INFO( msg ) (void)(0)
  17724 #define UNSCOPED_INFO( msg ) (void)(0)
  17725 #define WARN( msg ) (void)(0)
  17726 #define CAPTURE( msg ) (void)(0)
  17727 
  17728 #define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17729 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17730 #define METHOD_AS_TEST_CASE( method, ... )
  17731 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
  17732 #define SECTION( ... )
  17733 #define DYNAMIC_SECTION( ... )
  17734 #define FAIL( ... ) (void)(0)
  17735 #define FAIL_CHECK( ... ) (void)(0)
  17736 #define SUCCEED( ... ) (void)(0)
  17737 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17738 
  17739 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  17740 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
  17741 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
  17742 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
  17743 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
  17744 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17745 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17746 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17747 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17748 #else
  17749 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
  17750 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
  17751 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
  17752 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
  17753 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17754 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17755 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17756 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17757 #endif
  17758 
  17759 #define STATIC_REQUIRE( ... )       (void)(0)
  17760 #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
  17761 
  17762 #endif
  17763 
  17764 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
  17765 
  17766 // "BDD-style" convenience wrappers
  17767 #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
  17768 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
  17769 
  17770 #define GIVEN( desc )
  17771 #define AND_GIVEN( desc )
  17772 #define WHEN( desc )
  17773 #define AND_WHEN( desc )
  17774 #define THEN( desc )
  17775 #define AND_THEN( desc )
  17776 
  17777 using Catch::Detail::Approx;
  17778 
  17779 #endif
  17780 
  17781 #endif // ! CATCH_CONFIG_IMPL_ONLY
  17782 
  17783 // start catch_reenable_warnings.h
  17784 
  17785 
  17786 #ifdef __clang__
  17787 #    ifdef __ICC // icpc defines the __clang__ macro
  17788 #        pragma warning(pop)
  17789 #    else
  17790 #        pragma clang diagnostic pop
  17791 #    endif
  17792 #elif defined __GNUC__
  17793 #    pragma GCC diagnostic pop
  17794 #endif
  17795 
  17796 // end catch_reenable_warnings.h
  17797 // end catch.hpp
  17798 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
  17799