tfrun

An easy-to-use C++ wrapper over the stable C API of TensorFlow
git clone https://0xff.ir/g/tfrun.git
Log | Files | Refs | README | LICENSE

catch.hpp (639329B)


      1 /*
      2  *  Catch v2.11.0
      3  *  Generated: 2019-11-15 15:01:56.628356
      4  *  ----------------------------------------------------------
      5  *  This file has been merged from multiple headers. Please don't edit it directly
      6  *  Copyright (c) 2019 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 11
     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(CATCH_CPP17_OR_GREATER)
    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 #endif
    145 
    146 #if defined(__clang__)
    147 
    148 #    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
    149 #    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "clang diagnostic pop" )
    150 
    151 #    define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
    152          _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
    153          _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
    154 
    155 #    define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
    156          _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
    157 
    158 #    define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
    159          _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
    160 
    161 #    define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
    162          _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
    163 
    164 #    define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
    165          _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
    166 
    167 #endif // __clang__
    168 
    169 ////////////////////////////////////////////////////////////////////////////////
    170 // Assume that non-Windows platforms support posix signals by default
    171 #if !defined(CATCH_PLATFORM_WINDOWS)
    172     #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
    173 #endif
    174 
    175 ////////////////////////////////////////////////////////////////////////////////
    176 // We know some environments not to support full POSIX signals
    177 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
    178     #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
    179 #endif
    180 
    181 #ifdef __OS400__
    182 #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
    183 #       define CATCH_CONFIG_COLOUR_NONE
    184 #endif
    185 
    186 ////////////////////////////////////////////////////////////////////////////////
    187 // Android somehow still does not support std::to_string
    188 #if defined(__ANDROID__)
    189 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
    190 #    define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
    191 #endif
    192 
    193 ////////////////////////////////////////////////////////////////////////////////
    194 // Not all Windows environments support SEH properly
    195 #if defined(__MINGW32__)
    196 #    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
    197 #endif
    198 
    199 ////////////////////////////////////////////////////////////////////////////////
    200 // PS4
    201 #if defined(__ORBIS__)
    202 #    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
    203 #endif
    204 
    205 ////////////////////////////////////////////////////////////////////////////////
    206 // Cygwin
    207 #ifdef __CYGWIN__
    208 
    209 // Required for some versions of Cygwin to declare gettimeofday
    210 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
    211 #   define _BSD_SOURCE
    212 // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
    213 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
    214 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
    215            && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
    216 
    217 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
    218 
    219 # endif
    220 #endif // __CYGWIN__
    221 
    222 ////////////////////////////////////////////////////////////////////////////////
    223 // Visual C++
    224 #if defined(_MSC_VER)
    225 
    226 #  define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
    227 #  define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  __pragma( warning(pop) )
    228 
    229 #  if _MSC_VER >= 1900 // Visual Studio 2015 or newer
    230 #    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
    231 #  endif
    232 
    233 // Universal Windows platform does not support SEH
    234 // Or console colours (or console at all...)
    235 #  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
    236 #    define CATCH_CONFIG_COLOUR_NONE
    237 #  else
    238 #    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
    239 #  endif
    240 
    241 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
    242 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
    243 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
    244 #  if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
    245 #    define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    246 #  endif
    247 #endif // _MSC_VER
    248 
    249 #if defined(_REENTRANT) || defined(_MSC_VER)
    250 // Enable async processing, as -pthread is specified or no additional linking is required
    251 # define CATCH_INTERNAL_CONFIG_USE_ASYNC
    252 #endif // _MSC_VER
    253 
    254 ////////////////////////////////////////////////////////////////////////////////
    255 // Check if we are compiled with -fno-exceptions or equivalent
    256 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
    257 #  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
    258 #endif
    259 
    260 ////////////////////////////////////////////////////////////////////////////////
    261 // DJGPP
    262 #ifdef __DJGPP__
    263 #  define CATCH_INTERNAL_CONFIG_NO_WCHAR
    264 #endif // __DJGPP__
    265 
    266 ////////////////////////////////////////////////////////////////////////////////
    267 // Embarcadero C++Build
    268 #if defined(__BORLANDC__)
    269     #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
    270 #endif
    271 
    272 ////////////////////////////////////////////////////////////////////////////////
    273 
    274 // Use of __COUNTER__ is suppressed during code analysis in
    275 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
    276 // handled by it.
    277 // Otherwise all supported compilers support COUNTER macro,
    278 // but user still might want to turn it off
    279 #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
    280     #define CATCH_INTERNAL_CONFIG_COUNTER
    281 #endif
    282 
    283 ////////////////////////////////////////////////////////////////////////////////
    284 
    285 // RTX is a special version of Windows that is real time.
    286 // This means that it is detected as Windows, but does not provide
    287 // the same set of capabilities as real Windows does.
    288 #if defined(UNDER_RTSS) || defined(RTX64_BUILD)
    289     #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
    290     #define CATCH_INTERNAL_CONFIG_NO_ASYNC
    291     #define CATCH_CONFIG_COLOUR_NONE
    292 #endif
    293 
    294 #if defined(__UCLIBC__)
    295 #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
    296 #endif
    297 
    298 // Various stdlib support checks that require __has_include
    299 #if defined(__has_include)
    300   // Check if string_view is available and usable
    301   #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
    302   #    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
    303   #endif
    304 
    305   // Check if optional is available and usable
    306   #  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
    307   #    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
    308   #  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
    309 
    310   // Check if byte is available and usable
    311   #  if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
    312   #    define CATCH_INTERNAL_CONFIG_CPP17_BYTE
    313   #  endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
    314 
    315   // Check if variant is available and usable
    316   #  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
    317   #    if defined(__clang__) && (__clang_major__ < 8)
    318          // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
    319          // fix should be in clang 8, workaround in libstdc++ 8.2
    320   #      include <ciso646>
    321   #      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
    322   #        define CATCH_CONFIG_NO_CPP17_VARIANT
    323   #      else
    324   #        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
    325   #      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
    326   #    else
    327   #      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
    328   #    endif // defined(__clang__) && (__clang_major__ < 8)
    329   #  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
    330 #endif // defined(__has_include)
    331 
    332 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
    333 #   define CATCH_CONFIG_COUNTER
    334 #endif
    335 #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)
    336 #   define CATCH_CONFIG_WINDOWS_SEH
    337 #endif
    338 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
    339 #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)
    340 #   define CATCH_CONFIG_POSIX_SIGNALS
    341 #endif
    342 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
    343 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
    344 #   define CATCH_CONFIG_WCHAR
    345 #endif
    346 
    347 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
    348 #    define CATCH_CONFIG_CPP11_TO_STRING
    349 #endif
    350 
    351 #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
    352 #  define CATCH_CONFIG_CPP17_OPTIONAL
    353 #endif
    354 
    355 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
    356 #  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
    357 #endif
    358 
    359 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
    360 #  define CATCH_CONFIG_CPP17_STRING_VIEW
    361 #endif
    362 
    363 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
    364 #  define CATCH_CONFIG_CPP17_VARIANT
    365 #endif
    366 
    367 #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
    368 #  define CATCH_CONFIG_CPP17_BYTE
    369 #endif
    370 
    371 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
    372 #  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
    373 #endif
    374 
    375 #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)
    376 #  define CATCH_CONFIG_NEW_CAPTURE
    377 #endif
    378 
    379 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
    380 #  define CATCH_CONFIG_DISABLE_EXCEPTIONS
    381 #endif
    382 
    383 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
    384 #  define CATCH_CONFIG_POLYFILL_ISNAN
    385 #endif
    386 
    387 #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC)  && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
    388 #  define CATCH_CONFIG_USE_ASYNC
    389 #endif
    390 
    391 #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
    392 #  define CATCH_CONFIG_ANDROID_LOGWRITE
    393 #endif
    394 
    395 #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
    396 #  define CATCH_CONFIG_GLOBAL_NEXTAFTER
    397 #endif
    398 
    399 // Even if we do not think the compiler has that warning, we still have
    400 // to provide a macro that can be used by the code.
    401 #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
    402 #   define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
    403 #endif
    404 #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
    405 #   define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
    406 #endif
    407 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
    408 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
    409 #endif
    410 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
    411 #   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
    412 #endif
    413 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
    414 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
    415 #endif
    416 #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
    417 #   define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
    418 #endif
    419 
    420 #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
    421 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
    422 #elif defined(__clang__) && (__clang_major__ < 5)
    423 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
    424 #endif
    425 
    426 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
    427 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
    428 #endif
    429 
    430 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
    431 #define CATCH_TRY if ((true))
    432 #define CATCH_CATCH_ALL if ((false))
    433 #define CATCH_CATCH_ANON(type) if ((false))
    434 #else
    435 #define CATCH_TRY try
    436 #define CATCH_CATCH_ALL catch (...)
    437 #define CATCH_CATCH_ANON(type) catch (type)
    438 #endif
    439 
    440 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
    441 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    442 #endif
    443 
    444 // end catch_compiler_capabilities.h
    445 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
    446 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
    447 #ifdef CATCH_CONFIG_COUNTER
    448 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
    449 #else
    450 #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
    451 #endif
    452 
    453 #include <iosfwd>
    454 #include <string>
    455 #include <cstdint>
    456 
    457 // We need a dummy global operator<< so we can bring it into Catch namespace later
    458 struct Catch_global_namespace_dummy {};
    459 std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
    460 
    461 namespace Catch {
    462 
    463     struct CaseSensitive { enum Choice {
    464         Yes,
    465         No
    466     }; };
    467 
    468     class NonCopyable {
    469         NonCopyable( NonCopyable const& )              = delete;
    470         NonCopyable( NonCopyable && )                  = delete;
    471         NonCopyable& operator = ( NonCopyable const& ) = delete;
    472         NonCopyable& operator = ( NonCopyable && )     = delete;
    473 
    474     protected:
    475         NonCopyable();
    476         virtual ~NonCopyable();
    477     };
    478 
    479     struct SourceLineInfo {
    480 
    481         SourceLineInfo() = delete;
    482         SourceLineInfo( char const* _file, std::size_t _line ) noexcept
    483         :   file( _file ),
    484             line( _line )
    485         {}
    486 
    487         SourceLineInfo( SourceLineInfo const& other )            = default;
    488         SourceLineInfo& operator = ( SourceLineInfo const& )     = default;
    489         SourceLineInfo( SourceLineInfo&& )              noexcept = default;
    490         SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
    491 
    492         bool empty() const noexcept { return file[0] == '\0'; }
    493         bool operator == ( SourceLineInfo const& other ) const noexcept;
    494         bool operator < ( SourceLineInfo const& other ) const noexcept;
    495 
    496         char const* file;
    497         std::size_t line;
    498     };
    499 
    500     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
    501 
    502     // Bring in operator<< from global namespace into Catch namespace
    503     // This is necessary because the overload of operator<< above makes
    504     // lookup stop at namespace Catch
    505     using ::operator<<;
    506 
    507     // Use this in variadic streaming macros to allow
    508     //    >> +StreamEndStop
    509     // as well as
    510     //    >> stuff +StreamEndStop
    511     struct StreamEndStop {
    512         std::string operator+() const;
    513     };
    514     template<typename T>
    515     T const& operator + ( T const& value, StreamEndStop ) {
    516         return value;
    517     }
    518 }
    519 
    520 #define CATCH_INTERNAL_LINEINFO \
    521     ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
    522 
    523 // end catch_common.h
    524 namespace Catch {
    525 
    526     struct RegistrarForTagAliases {
    527         RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
    528     };
    529 
    530 } // end namespace Catch
    531 
    532 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
    533     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
    534     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
    535     namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
    536     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
    537 
    538 // end catch_tag_alias_autoregistrar.h
    539 // start catch_test_registry.h
    540 
    541 // start catch_interfaces_testcase.h
    542 
    543 #include <vector>
    544 
    545 namespace Catch {
    546 
    547     class TestSpec;
    548 
    549     struct ITestInvoker {
    550         virtual void invoke () const = 0;
    551         virtual ~ITestInvoker();
    552     };
    553 
    554     class TestCase;
    555     struct IConfig;
    556 
    557     struct ITestCaseRegistry {
    558         virtual ~ITestCaseRegistry();
    559         virtual std::vector<TestCase> const& getAllTests() const = 0;
    560         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
    561     };
    562 
    563     bool isThrowSafe( TestCase const& testCase, IConfig const& config );
    564     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
    565     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
    566     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
    567 
    568 }
    569 
    570 // end catch_interfaces_testcase.h
    571 // start catch_stringref.h
    572 
    573 #include <cstddef>
    574 #include <string>
    575 #include <iosfwd>
    576 #include <cassert>
    577 
    578 namespace Catch {
    579 
    580     /// A non-owning string class (similar to the forthcoming std::string_view)
    581     /// Note that, because a StringRef may be a substring of another string,
    582     /// it may not be null terminated.
    583     class StringRef {
    584     public:
    585         using size_type = std::size_t;
    586         using const_iterator = const char*;
    587 
    588     private:
    589         static constexpr char const* const s_empty = "";
    590 
    591         char const* m_start = s_empty;
    592         size_type m_size = 0;
    593 
    594     public: // construction
    595         constexpr StringRef() noexcept = default;
    596 
    597         StringRef( char const* rawChars ) noexcept;
    598 
    599         constexpr StringRef( char const* rawChars, size_type size ) noexcept
    600         :   m_start( rawChars ),
    601             m_size( size )
    602         {}
    603 
    604         StringRef( std::string const& stdString ) noexcept
    605         :   m_start( stdString.c_str() ),
    606             m_size( stdString.size() )
    607         {}
    608 
    609         explicit operator std::string() const {
    610             return std::string(m_start, m_size);
    611         }
    612 
    613     public: // operators
    614         auto operator == ( StringRef const& other ) const noexcept -> bool;
    615         auto operator != (StringRef const& other) const noexcept -> bool {
    616             return !(*this == other);
    617         }
    618 
    619         auto operator[] ( size_type index ) const noexcept -> char {
    620             assert(index < m_size);
    621             return m_start[index];
    622         }
    623 
    624     public: // named queries
    625         constexpr auto empty() const noexcept -> bool {
    626             return m_size == 0;
    627         }
    628         constexpr auto size() const noexcept -> size_type {
    629             return m_size;
    630         }
    631 
    632         // Returns the current start pointer. If the StringRef is not
    633         // null-terminated, throws std::domain_exception
    634         auto c_str() const -> char const*;
    635 
    636     public: // substrings and searches
    637         // Returns a substring of [start, start + length).
    638         // If start + length > size(), then the substring is [start, size()).
    639         // If start > size(), then the substring is empty.
    640         auto substr( size_type start, size_type length ) const noexcept -> StringRef;
    641 
    642         // Returns the current start pointer. May not be null-terminated.
    643         auto data() const noexcept -> char const*;
    644 
    645         constexpr auto isNullTerminated() const noexcept -> bool {
    646             return m_start[m_size] == '\0';
    647         }
    648 
    649     public: // iterators
    650         constexpr const_iterator begin() const { return m_start; }
    651         constexpr const_iterator end() const { return m_start + m_size; }
    652     };
    653 
    654     auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
    655     auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
    656 
    657     constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
    658         return StringRef( rawChars, size );
    659     }
    660 } // namespace Catch
    661 
    662 constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
    663     return Catch::StringRef( rawChars, size );
    664 }
    665 
    666 // end catch_stringref.h
    667 // start catch_preprocessor.hpp
    668 
    669 
    670 #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
    671 #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
    672 #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
    673 #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
    674 #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
    675 #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
    676 
    677 #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    678 #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
    679 // MSVC needs more evaluations
    680 #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
    681 #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
    682 #else
    683 #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL5(__VA_ARGS__)
    684 #endif
    685 
    686 #define CATCH_REC_END(...)
    687 #define CATCH_REC_OUT
    688 
    689 #define CATCH_EMPTY()
    690 #define CATCH_DEFER(id) id CATCH_EMPTY()
    691 
    692 #define CATCH_REC_GET_END2() 0, CATCH_REC_END
    693 #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
    694 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
    695 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
    696 #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
    697 #define CATCH_REC_NEXT(test, next)  CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
    698 
    699 #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
    700 #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
    701 #define CATCH_REC_LIST2(f, x, peek, ...)   f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
    702 
    703 #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__ )
    704 #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__ )
    705 #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__ )
    706 
    707 // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
    708 // and passes userdata as the first parameter to each invocation,
    709 // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
    710 #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
    711 
    712 #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
    713 
    714 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
    715 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
    716 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
    717 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
    718 #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
    719 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    720 #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
    721 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
    722 #else
    723 // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
    724 #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
    725 #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
    726 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
    727 #endif
    728 
    729 #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
    730 #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
    731 
    732 #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
    733 
    734 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    735 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
    736 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
    737 #else
    738 #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
    739 #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
    740 #endif
    741 
    742 #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
    743     CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
    744 
    745 #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
    746 #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
    747 #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
    748 #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)
    749 #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)
    750 #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)
    751 #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, _4, _5, _6)
    752 #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)
    753 #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)
    754 #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)
    755 #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)
    756 
    757 #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
    758 
    759 #define INTERNAL_CATCH_TYPE_GEN\
    760     template<typename...> struct TypeList {};\
    761     template<typename...Ts>\
    762     constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
    763     template<template<typename...> class...> struct TemplateTypeList{};\
    764     template<template<typename...> class...Cs>\
    765     constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
    766     template<typename...>\
    767     struct append;\
    768     template<typename...>\
    769     struct rewrap;\
    770     template<template<typename...> class, typename...>\
    771     struct create;\
    772     template<template<typename...> class, typename>\
    773     struct convert;\
    774     \
    775     template<typename T> \
    776     struct append<T> { using type = T; };\
    777     template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
    778     struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
    779     template< template<typename...> class L1, typename...E1, typename...Rest>\
    780     struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
    781     \
    782     template< template<typename...> class Container, template<typename...> class List, typename...elems>\
    783     struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
    784     template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
    785     struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
    786     \
    787     template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
    788     struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
    789     template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
    790     struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
    791 
    792 #define INTERNAL_CATCH_NTTP_1(signature, ...)\
    793     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
    794     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    795     constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
    796     template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
    797     template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
    798     constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
    799     \
    800     template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    801     struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
    802     template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
    803     struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
    804     template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
    805     struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
    806 
    807 #define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
    808 #define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
    809     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    810     static void TestName()
    811 #define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
    812     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    813     static void TestName()
    814 
    815 #define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
    816 #define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
    817     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    818     static void TestName()
    819 #define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
    820     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    821     static void TestName()
    822 
    823 #define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
    824     template<typename Type>\
    825     void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
    826     {\
    827         Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
    828     }
    829 
    830 #define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
    831     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    832     void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
    833     {\
    834         Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
    835     }
    836 
    837 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
    838     template<typename Type>\
    839     void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
    840     {\
    841         Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
    842     }
    843 
    844 #define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
    845     template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
    846     void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
    847     {\
    848         Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
    849     }
    850 
    851 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
    852 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
    853     template<typename TestType> \
    854     struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
    855         void test();\
    856     }
    857 
    858 #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
    859     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
    860     struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
    861         void test();\
    862     }
    863 
    864 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
    865 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
    866     template<typename TestType> \
    867     void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
    868 #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
    869     template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
    870     void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
    871 
    872 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    873 #define INTERNAL_CATCH_NTTP_0
    874 #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)
    875 #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__)
    876 #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__)
    877 #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__)
    878 #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__)
    879 #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__)
    880 #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__)
    881 #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__)
    882 #else
    883 #define INTERNAL_CATCH_NTTP_0(signature)
    884 #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__))
    885 #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__))
    886 #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__))
    887 #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__))
    888 #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__))
    889 #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__))
    890 #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__))
    891 #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__))
    892 #endif
    893 
    894 // end catch_preprocessor.hpp
    895 // start catch_meta.hpp
    896 
    897 
    898 #include <type_traits>
    899 
    900 namespace Catch {
    901     template<typename T>
    902     struct always_false : std::false_type {};
    903 
    904     template <typename> struct true_given : std::true_type {};
    905     struct is_callable_tester {
    906         template <typename Fun, typename... Args>
    907         true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
    908         template <typename...>
    909         std::false_type static test(...);
    910     };
    911 
    912     template <typename T>
    913     struct is_callable;
    914 
    915     template <typename Fun, typename... Args>
    916     struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
    917 
    918 #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
    919     // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
    920     // replaced with std::invoke_result here. Also *_t format is preferred over
    921     // typename *::type format.
    922     template <typename Func, typename U>
    923     using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>;
    924 #else
    925     template <typename Func, typename U>
    926     using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type;
    927 #endif
    928 
    929 } // namespace Catch
    930 
    931 namespace mpl_{
    932     struct na;
    933 }
    934 
    935 // end catch_meta.hpp
    936 namespace Catch {
    937 
    938 template<typename C>
    939 class TestInvokerAsMethod : public ITestInvoker {
    940     void (C::*m_testAsMethod)();
    941 public:
    942     TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
    943 
    944     void invoke() const override {
    945         C obj;
    946         (obj.*m_testAsMethod)();
    947     }
    948 };
    949 
    950 auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
    951 
    952 template<typename C>
    953 auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
    954     return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
    955 }
    956 
    957 struct NameAndTags {
    958     NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
    959     StringRef name;
    960     StringRef tags;
    961 };
    962 
    963 struct AutoReg : NonCopyable {
    964     AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
    965     ~AutoReg();
    966 };
    967 
    968 } // end namespace Catch
    969 
    970 #if defined(CATCH_CONFIG_DISABLE)
    971     #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
    972         static void TestName()
    973     #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
    974         namespace{                        \
    975             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
    976                 void test();              \
    977             };                            \
    978         }                                 \
    979         void TestName::test()
    980     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... )  \
    981         INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
    982     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... )    \
    983         namespace{                                                                                  \
    984             namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                      \
    985             INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
    986         }                                                                                           \
    987         }                                                                                           \
    988         INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
    989 
    990     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    991         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
    992             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__ )
    993     #else
    994         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
    995             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__ ) )
    996     #endif
    997 
    998     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
    999         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
   1000             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__ )
   1001     #else
   1002         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
   1003             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__ ) )
   1004     #endif
   1005 
   1006     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1007         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
   1008             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__ )
   1009     #else
   1010         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
   1011             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__ ) )
   1012     #endif
   1013 
   1014     #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1015         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
   1016             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__ )
   1017     #else
   1018         #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
   1019             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__ ) )
   1020     #endif
   1021 #endif
   1022 
   1023     ///////////////////////////////////////////////////////////////////////////////
   1024     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
   1025         static void TestName(); \
   1026         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1027         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1028         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
   1029         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   1030         static void TestName()
   1031     #define INTERNAL_CATCH_TESTCASE( ... ) \
   1032         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
   1033 
   1034     ///////////////////////////////////////////////////////////////////////////////
   1035     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
   1036         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1037         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1038         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
   1039         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   1040 
   1041     ///////////////////////////////////////////////////////////////////////////////
   1042     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
   1043         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1044         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1045         namespace{ \
   1046             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
   1047                 void test(); \
   1048             }; \
   1049             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
   1050         } \
   1051         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   1052         void TestName::test()
   1053     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
   1054         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
   1055 
   1056     ///////////////////////////////////////////////////////////////////////////////
   1057     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
   1058         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1059         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1060         Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
   1061         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   1062 
   1063     ///////////////////////////////////////////////////////////////////////////////
   1064     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
   1065         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1066         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1067         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
   1068         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
   1069         INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
   1070         namespace {\
   1071         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
   1072             INTERNAL_CATCH_TYPE_GEN\
   1073             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
   1074             INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
   1075             template<typename...Types> \
   1076             struct TestName{\
   1077                 TestName(){\
   1078                     int index = 0;                                    \
   1079                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
   1080                     using expander = int[];\
   1081                     (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
   1082                 }\
   1083             };\
   1084             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
   1085             TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
   1086             return 0;\
   1087         }();\
   1088         }\
   1089         }\
   1090         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   1091         INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
   1092 
   1093 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1094     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
   1095         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__ )
   1096 #else
   1097     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
   1098         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__ ) )
   1099 #endif
   1100 
   1101 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1102     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
   1103         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__ )
   1104 #else
   1105     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
   1106         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__ ) )
   1107 #endif
   1108 
   1109     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
   1110         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                      \
   1111         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \
   1112         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                \
   1113         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS              \
   1114         template<typename TestType> static void TestFuncName();       \
   1115         namespace {\
   1116         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                     \
   1117             INTERNAL_CATCH_TYPE_GEN                                                  \
   1118             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))         \
   1119             template<typename... Types>                               \
   1120             struct TestName {                                         \
   1121                 void reg_tests() {                                          \
   1122                     int index = 0;                                    \
   1123                     using expander = int[];                           \
   1124                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
   1125                     constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
   1126                     constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
   1127                     (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 */\
   1128                 }                                                     \
   1129             };                                                        \
   1130             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
   1131                 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; \
   1132                 TestInit t;                                           \
   1133                 t.reg_tests();                                        \
   1134                 return 0;                                             \
   1135             }();                                                      \
   1136         }                                                             \
   1137         }                                                             \
   1138         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
   1139         template<typename TestType>                                   \
   1140         static void TestFuncName()
   1141 
   1142 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1143     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
   1144         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__)
   1145 #else
   1146     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
   1147         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__ ) )
   1148 #endif
   1149 
   1150 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1151     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
   1152         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__)
   1153 #else
   1154     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
   1155         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__ ) )
   1156 #endif
   1157 
   1158     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
   1159         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1160         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1161         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
   1162         template<typename TestType> static void TestFunc();       \
   1163         namespace {\
   1164         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
   1165         INTERNAL_CATCH_TYPE_GEN\
   1166         template<typename... Types>                               \
   1167         struct TestName {                                         \
   1168             void reg_tests() {                                          \
   1169                 int index = 0;                                    \
   1170                 using expander = int[];                           \
   1171                 (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 */\
   1172             }                                                     \
   1173         };\
   1174         static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
   1175                 using TestInit = typename convert<TestName, TmplList>::type; \
   1176                 TestInit t;                                           \
   1177                 t.reg_tests();                                        \
   1178                 return 0;                                             \
   1179             }();                                                      \
   1180         }}\
   1181         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
   1182         template<typename TestType>                                   \
   1183         static void TestFunc()
   1184 
   1185     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
   1186         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 )
   1187 
   1188     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
   1189         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1190         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1191         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
   1192         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
   1193         namespace {\
   1194         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
   1195             INTERNAL_CATCH_TYPE_GEN\
   1196             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
   1197             INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
   1198             INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
   1199             template<typename...Types> \
   1200             struct TestNameClass{\
   1201                 TestNameClass(){\
   1202                     int index = 0;                                    \
   1203                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
   1204                     using expander = int[];\
   1205                     (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
   1206                 }\
   1207             };\
   1208             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
   1209                 TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
   1210                 return 0;\
   1211         }();\
   1212         }\
   1213         }\
   1214         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   1215         INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
   1216 
   1217 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1218     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
   1219         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__ )
   1220 #else
   1221     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
   1222         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__ ) )
   1223 #endif
   1224 
   1225 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1226     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
   1227         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__ )
   1228 #else
   1229     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
   1230         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__ ) )
   1231 #endif
   1232 
   1233     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
   1234         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1235         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1236         CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
   1237         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
   1238         template<typename TestType> \
   1239             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
   1240                 void test();\
   1241             };\
   1242         namespace {\
   1243         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
   1244             INTERNAL_CATCH_TYPE_GEN                  \
   1245             INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
   1246             template<typename...Types>\
   1247             struct TestNameClass{\
   1248                 void reg_tests(){\
   1249                     int index = 0;\
   1250                     using expander = int[];\
   1251                     constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
   1252                     constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
   1253                     constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
   1254                     (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 */ \
   1255                 }\
   1256             };\
   1257             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
   1258                 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;\
   1259                 TestInit t;\
   1260                 t.reg_tests();\
   1261                 return 0;\
   1262             }(); \
   1263         }\
   1264         }\
   1265         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   1266         template<typename TestType> \
   1267         void TestName<TestType>::test()
   1268 
   1269 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1270     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
   1271         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__ )
   1272 #else
   1273     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
   1274         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__ ) )
   1275 #endif
   1276 
   1277 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
   1278     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
   1279         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__ )
   1280 #else
   1281     #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
   1282         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__ ) )
   1283 #endif
   1284 
   1285     #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
   1286         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   1287         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   1288         CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
   1289         template<typename TestType> \
   1290         struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
   1291             void test();\
   1292         };\
   1293         namespace {\
   1294         namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
   1295             INTERNAL_CATCH_TYPE_GEN\
   1296             template<typename...Types>\
   1297             struct TestNameClass{\
   1298                 void reg_tests(){\
   1299                     int index = 0;\
   1300                     using expander = int[];\
   1301                     (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 */ \
   1302                 }\
   1303             };\
   1304             static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
   1305                 using TestInit = typename convert<TestNameClass, TmplList>::type;\
   1306                 TestInit t;\
   1307                 t.reg_tests();\
   1308                 return 0;\
   1309             }(); \
   1310         }}\
   1311         CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   1312         template<typename TestType> \
   1313         void TestName<TestType>::test()
   1314 
   1315 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
   1316         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 )
   1317 
   1318 // end catch_test_registry.h
   1319 // start catch_capture.hpp
   1320 
   1321 // start catch_assertionhandler.h
   1322 
   1323 // start catch_assertioninfo.h
   1324 
   1325 // start catch_result_type.h
   1326 
   1327 namespace Catch {
   1328 
   1329     // ResultWas::OfType enum
   1330     struct ResultWas { enum OfType {
   1331         Unknown = -1,
   1332         Ok = 0,
   1333         Info = 1,
   1334         Warning = 2,
   1335 
   1336         FailureBit = 0x10,
   1337 
   1338         ExpressionFailed = FailureBit | 1,
   1339         ExplicitFailure = FailureBit | 2,
   1340 
   1341         Exception = 0x100 | FailureBit,
   1342 
   1343         ThrewException = Exception | 1,
   1344         DidntThrowException = Exception | 2,
   1345 
   1346         FatalErrorCondition = 0x200 | FailureBit
   1347 
   1348     }; };
   1349 
   1350     bool isOk( ResultWas::OfType resultType );
   1351     bool isJustInfo( int flags );
   1352 
   1353     // ResultDisposition::Flags enum
   1354     struct ResultDisposition { enum Flags {
   1355         Normal = 0x01,
   1356 
   1357         ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
   1358         FalseTest = 0x04,           // Prefix expression with !
   1359         SuppressFail = 0x08         // Failures are reported but do not fail the test
   1360     }; };
   1361 
   1362     ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
   1363 
   1364     bool shouldContinueOnFailure( int flags );
   1365     inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
   1366     bool shouldSuppressFailure( int flags );
   1367 
   1368 } // end namespace Catch
   1369 
   1370 // end catch_result_type.h
   1371 namespace Catch {
   1372 
   1373     struct AssertionInfo
   1374     {
   1375         StringRef macroName;
   1376         SourceLineInfo lineInfo;
   1377         StringRef capturedExpression;
   1378         ResultDisposition::Flags resultDisposition;
   1379 
   1380         // We want to delete this constructor but a compiler bug in 4.8 means
   1381         // the struct is then treated as non-aggregate
   1382         //AssertionInfo() = delete;
   1383     };
   1384 
   1385 } // end namespace Catch
   1386 
   1387 // end catch_assertioninfo.h
   1388 // start catch_decomposer.h
   1389 
   1390 // start catch_tostring.h
   1391 
   1392 #include <vector>
   1393 #include <cstddef>
   1394 #include <type_traits>
   1395 #include <string>
   1396 // start catch_stream.h
   1397 
   1398 #include <iosfwd>
   1399 #include <cstddef>
   1400 #include <ostream>
   1401 
   1402 namespace Catch {
   1403 
   1404     std::ostream& cout();
   1405     std::ostream& cerr();
   1406     std::ostream& clog();
   1407 
   1408     class StringRef;
   1409 
   1410     struct IStream {
   1411         virtual ~IStream();
   1412         virtual std::ostream& stream() const = 0;
   1413     };
   1414 
   1415     auto makeStream( StringRef const &filename ) -> IStream const*;
   1416 
   1417     class ReusableStringStream : NonCopyable {
   1418         std::size_t m_index;
   1419         std::ostream* m_oss;
   1420     public:
   1421         ReusableStringStream();
   1422         ~ReusableStringStream();
   1423 
   1424         auto str() const -> std::string;
   1425 
   1426         template<typename T>
   1427         auto operator << ( T const& value ) -> ReusableStringStream& {
   1428             *m_oss << value;
   1429             return *this;
   1430         }
   1431         auto get() -> std::ostream& { return *m_oss; }
   1432     };
   1433 }
   1434 
   1435 // end catch_stream.h
   1436 // start catch_interfaces_enum_values_registry.h
   1437 
   1438 #include <vector>
   1439 
   1440 namespace Catch {
   1441 
   1442     namespace Detail {
   1443         struct EnumInfo {
   1444             StringRef m_name;
   1445             std::vector<std::pair<int, StringRef>> m_values;
   1446 
   1447             ~EnumInfo();
   1448 
   1449             StringRef lookup( int value ) const;
   1450         };
   1451     } // namespace Detail
   1452 
   1453     struct IMutableEnumValuesRegistry {
   1454         virtual ~IMutableEnumValuesRegistry();
   1455 
   1456         virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
   1457 
   1458         template<typename E>
   1459         Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
   1460             static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
   1461             std::vector<int> intValues;
   1462             intValues.reserve( values.size() );
   1463             for( auto enumValue : values )
   1464                 intValues.push_back( static_cast<int>( enumValue ) );
   1465             return registerEnum( enumName, allEnums, intValues );
   1466         }
   1467     };
   1468 
   1469 } // Catch
   1470 
   1471 // end catch_interfaces_enum_values_registry.h
   1472 
   1473 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
   1474 #include <string_view>
   1475 #endif
   1476 
   1477 #ifdef __OBJC__
   1478 // start catch_objc_arc.hpp
   1479 
   1480 #import <Foundation/Foundation.h>
   1481 
   1482 #ifdef __has_feature
   1483 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
   1484 #else
   1485 #define CATCH_ARC_ENABLED 0
   1486 #endif
   1487 
   1488 void arcSafeRelease( NSObject* obj );
   1489 id performOptionalSelector( id obj, SEL sel );
   1490 
   1491 #if !CATCH_ARC_ENABLED
   1492 inline void arcSafeRelease( NSObject* obj ) {
   1493     [obj release];
   1494 }
   1495 inline id performOptionalSelector( id obj, SEL sel ) {
   1496     if( [obj respondsToSelector: sel] )
   1497         return [obj performSelector: sel];
   1498     return nil;
   1499 }
   1500 #define CATCH_UNSAFE_UNRETAINED
   1501 #define CATCH_ARC_STRONG
   1502 #else
   1503 inline void arcSafeRelease( NSObject* ){}
   1504 inline id performOptionalSelector( id obj, SEL sel ) {
   1505 #ifdef __clang__
   1506 #pragma clang diagnostic push
   1507 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
   1508 #endif
   1509     if( [obj respondsToSelector: sel] )
   1510         return [obj performSelector: sel];
   1511 #ifdef __clang__
   1512 #pragma clang diagnostic pop
   1513 #endif
   1514     return nil;
   1515 }
   1516 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
   1517 #define CATCH_ARC_STRONG __strong
   1518 #endif
   1519 
   1520 // end catch_objc_arc.hpp
   1521 #endif
   1522 
   1523 #ifdef _MSC_VER
   1524 #pragma warning(push)
   1525 #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
   1526 #endif
   1527 
   1528 namespace Catch {
   1529     namespace Detail {
   1530 
   1531         extern const std::string unprintableString;
   1532 
   1533         std::string rawMemoryToString( const void *object, std::size_t size );
   1534 
   1535         template<typename T>
   1536         std::string rawMemoryToString( const T& object ) {
   1537           return rawMemoryToString( &object, sizeof(object) );
   1538         }
   1539 
   1540         template<typename T>
   1541         class IsStreamInsertable {
   1542             template<typename Stream, typename U>
   1543             static auto test(int)
   1544                 -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
   1545 
   1546             template<typename, typename>
   1547             static auto test(...)->std::false_type;
   1548 
   1549         public:
   1550             static const bool value = decltype(test<std::ostream, const T&>(0))::value;
   1551         };
   1552 
   1553         template<typename E>
   1554         std::string convertUnknownEnumToString( E e );
   1555 
   1556         template<typename T>
   1557         typename std::enable_if<
   1558             !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
   1559         std::string>::type convertUnstreamable( T const& ) {
   1560             return Detail::unprintableString;
   1561         }
   1562         template<typename T>
   1563         typename std::enable_if<
   1564             !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
   1565          std::string>::type convertUnstreamable(T const& ex) {
   1566             return ex.what();
   1567         }
   1568 
   1569         template<typename T>
   1570         typename std::enable_if<
   1571             std::is_enum<T>::value
   1572         , std::string>::type convertUnstreamable( T const& value ) {
   1573             return convertUnknownEnumToString( value );
   1574         }
   1575 
   1576 #if defined(_MANAGED)
   1577         //! Convert a CLR string to a utf8 std::string
   1578         template<typename T>
   1579         std::string clrReferenceToString( T^ ref ) {
   1580             if (ref == nullptr)
   1581                 return std::string("null");
   1582             auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
   1583             cli::pin_ptr<System::Byte> p = &bytes[0];
   1584             return std::string(reinterpret_cast<char const *>(p), bytes->Length);
   1585         }
   1586 #endif
   1587 
   1588     } // namespace Detail
   1589 
   1590     // If we decide for C++14, change these to enable_if_ts
   1591     template <typename T, typename = void>
   1592     struct StringMaker {
   1593         template <typename Fake = T>
   1594         static
   1595         typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
   1596             convert(const Fake& value) {
   1597                 ReusableStringStream rss;
   1598                 // NB: call using the function-like syntax to avoid ambiguity with
   1599                 // user-defined templated operator<< under clang.
   1600                 rss.operator<<(value);
   1601                 return rss.str();
   1602         }
   1603 
   1604         template <typename Fake = T>
   1605         static
   1606         typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
   1607             convert( const Fake& value ) {
   1608 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
   1609             return Detail::convertUnstreamable(value);
   1610 #else
   1611             return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
   1612 #endif
   1613         }
   1614     };
   1615 
   1616     namespace Detail {
   1617 
   1618         // This function dispatches all stringification requests inside of Catch.
   1619         // Should be preferably called fully qualified, like ::Catch::Detail::stringify
   1620         template <typename T>
   1621         std::string stringify(const T& e) {
   1622             return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
   1623         }
   1624 
   1625         template<typename E>
   1626         std::string convertUnknownEnumToString( E e ) {
   1627             return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
   1628         }
   1629 
   1630 #if defined(_MANAGED)
   1631         template <typename T>
   1632         std::string stringify( T^ e ) {
   1633             return ::Catch::StringMaker<T^>::convert(e);
   1634         }
   1635 #endif
   1636 
   1637     } // namespace Detail
   1638 
   1639     // Some predefined specializations
   1640 
   1641     template<>
   1642     struct StringMaker<std::string> {
   1643         static std::string convert(const std::string& str);
   1644     };
   1645 
   1646 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
   1647     template<>
   1648     struct StringMaker<std::string_view> {
   1649         static std::string convert(std::string_view str);
   1650     };
   1651 #endif
   1652 
   1653     template<>
   1654     struct StringMaker<char const *> {
   1655         static std::string convert(char const * str);
   1656     };
   1657     template<>
   1658     struct StringMaker<char *> {
   1659         static std::string convert(char * str);
   1660     };
   1661 
   1662 #ifdef CATCH_CONFIG_WCHAR
   1663     template<>
   1664     struct StringMaker<std::wstring> {
   1665         static std::string convert(const std::wstring& wstr);
   1666     };
   1667 
   1668 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
   1669     template<>
   1670     struct StringMaker<std::wstring_view> {
   1671         static std::string convert(std::wstring_view str);
   1672     };
   1673 # endif
   1674 
   1675     template<>
   1676     struct StringMaker<wchar_t const *> {
   1677         static std::string convert(wchar_t const * str);
   1678     };
   1679     template<>
   1680     struct StringMaker<wchar_t *> {
   1681         static std::string convert(wchar_t * str);
   1682     };
   1683 #endif
   1684 
   1685     // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
   1686     //      while keeping string semantics?
   1687     template<int SZ>
   1688     struct StringMaker<char[SZ]> {
   1689         static std::string convert(char const* str) {
   1690             return ::Catch::Detail::stringify(std::string{ str });
   1691         }
   1692     };
   1693     template<int SZ>
   1694     struct StringMaker<signed char[SZ]> {
   1695         static std::string convert(signed char const* str) {
   1696             return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
   1697         }
   1698     };
   1699     template<int SZ>
   1700     struct StringMaker<unsigned char[SZ]> {
   1701         static std::string convert(unsigned char const* str) {
   1702             return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
   1703         }
   1704     };
   1705 
   1706 #if defined(CATCH_CONFIG_CPP17_BYTE)
   1707     template<>
   1708     struct StringMaker<std::byte> {
   1709         static std::string convert(std::byte value);
   1710     };
   1711 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
   1712     template<>
   1713     struct StringMaker<int> {
   1714         static std::string convert(int value);
   1715     };
   1716     template<>
   1717     struct StringMaker<long> {
   1718         static std::string convert(long value);
   1719     };
   1720     template<>
   1721     struct StringMaker<long long> {
   1722         static std::string convert(long long value);
   1723     };
   1724     template<>
   1725     struct StringMaker<unsigned int> {
   1726         static std::string convert(unsigned int value);
   1727     };
   1728     template<>
   1729     struct StringMaker<unsigned long> {
   1730         static std::string convert(unsigned long value);
   1731     };
   1732     template<>
   1733     struct StringMaker<unsigned long long> {
   1734         static std::string convert(unsigned long long value);
   1735     };
   1736 
   1737     template<>
   1738     struct StringMaker<bool> {
   1739         static std::string convert(bool b);
   1740     };
   1741 
   1742     template<>
   1743     struct StringMaker<char> {
   1744         static std::string convert(char c);
   1745     };
   1746     template<>
   1747     struct StringMaker<signed char> {
   1748         static std::string convert(signed char c);
   1749     };
   1750     template<>
   1751     struct StringMaker<unsigned char> {
   1752         static std::string convert(unsigned char c);
   1753     };
   1754 
   1755     template<>
   1756     struct StringMaker<std::nullptr_t> {
   1757         static std::string convert(std::nullptr_t);
   1758     };
   1759 
   1760     template<>
   1761     struct StringMaker<float> {
   1762         static std::string convert(float value);
   1763         static int precision;
   1764     };
   1765 
   1766     template<>
   1767     struct StringMaker<double> {
   1768         static std::string convert(double value);
   1769         static int precision;
   1770     };
   1771 
   1772     template <typename T>
   1773     struct StringMaker<T*> {
   1774         template <typename U>
   1775         static std::string convert(U* p) {
   1776             if (p) {
   1777                 return ::Catch::Detail::rawMemoryToString(p);
   1778             } else {
   1779                 return "nullptr";
   1780             }
   1781         }
   1782     };
   1783 
   1784     template <typename R, typename C>
   1785     struct StringMaker<R C::*> {
   1786         static std::string convert(R C::* p) {
   1787             if (p) {
   1788                 return ::Catch::Detail::rawMemoryToString(p);
   1789             } else {
   1790                 return "nullptr";
   1791             }
   1792         }
   1793     };
   1794 
   1795 #if defined(_MANAGED)
   1796     template <typename T>
   1797     struct StringMaker<T^> {
   1798         static std::string convert( T^ ref ) {
   1799             return ::Catch::Detail::clrReferenceToString(ref);
   1800         }
   1801     };
   1802 #endif
   1803 
   1804     namespace Detail {
   1805         template<typename InputIterator>
   1806         std::string rangeToString(InputIterator first, InputIterator last) {
   1807             ReusableStringStream rss;
   1808             rss << "{ ";
   1809             if (first != last) {
   1810                 rss << ::Catch::Detail::stringify(*first);
   1811                 for (++first; first != last; ++first)
   1812                     rss << ", " << ::Catch::Detail::stringify(*first);
   1813             }
   1814             rss << " }";
   1815             return rss.str();
   1816         }
   1817     }
   1818 
   1819 #ifdef __OBJC__
   1820     template<>
   1821     struct StringMaker<NSString*> {
   1822         static std::string convert(NSString * nsstring) {
   1823             if (!nsstring)
   1824                 return "nil";
   1825             return std::string("@") + [nsstring UTF8String];
   1826         }
   1827     };
   1828     template<>
   1829     struct StringMaker<NSObject*> {
   1830         static std::string convert(NSObject* nsObject) {
   1831             return ::Catch::Detail::stringify([nsObject description]);
   1832         }
   1833 
   1834     };
   1835     namespace Detail {
   1836         inline std::string stringify( NSString* nsstring ) {
   1837             return StringMaker<NSString*>::convert( nsstring );
   1838         }
   1839 
   1840     } // namespace Detail
   1841 #endif // __OBJC__
   1842 
   1843 } // namespace Catch
   1844 
   1845 //////////////////////////////////////////////////////
   1846 // Separate std-lib types stringification, so it can be selectively enabled
   1847 // This means that we do not bring in
   1848 
   1849 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
   1850 #  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
   1851 #  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
   1852 #  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
   1853 #  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
   1854 #  define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
   1855 #endif
   1856 
   1857 // Separate std::pair specialization
   1858 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
   1859 #include <utility>
   1860 namespace Catch {
   1861     template<typename T1, typename T2>
   1862     struct StringMaker<std::pair<T1, T2> > {
   1863         static std::string convert(const std::pair<T1, T2>& pair) {
   1864             ReusableStringStream rss;
   1865             rss << "{ "
   1866                 << ::Catch::Detail::stringify(pair.first)
   1867                 << ", "
   1868                 << ::Catch::Detail::stringify(pair.second)
   1869                 << " }";
   1870             return rss.str();
   1871         }
   1872     };
   1873 }
   1874 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
   1875 
   1876 #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
   1877 #include <optional>
   1878 namespace Catch {
   1879     template<typename T>
   1880     struct StringMaker<std::optional<T> > {
   1881         static std::string convert(const std::optional<T>& optional) {
   1882             ReusableStringStream rss;
   1883             if (optional.has_value()) {
   1884                 rss << ::Catch::Detail::stringify(*optional);
   1885             } else {
   1886                 rss << "{ }";
   1887             }
   1888             return rss.str();
   1889         }
   1890     };
   1891 }
   1892 #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
   1893 
   1894 // Separate std::tuple specialization
   1895 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
   1896 #include <tuple>
   1897 namespace Catch {
   1898     namespace Detail {
   1899         template<
   1900             typename Tuple,
   1901             std::size_t N = 0,
   1902             bool = (N < std::tuple_size<Tuple>::value)
   1903             >
   1904             struct TupleElementPrinter {
   1905             static void print(const Tuple& tuple, std::ostream& os) {
   1906                 os << (N ? ", " : " ")
   1907                     << ::Catch::Detail::stringify(std::get<N>(tuple));
   1908                 TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
   1909             }
   1910         };
   1911 
   1912         template<
   1913             typename Tuple,
   1914             std::size_t N
   1915         >
   1916             struct TupleElementPrinter<Tuple, N, false> {
   1917             static void print(const Tuple&, std::ostream&) {}
   1918         };
   1919 
   1920     }
   1921 
   1922     template<typename ...Types>
   1923     struct StringMaker<std::tuple<Types...>> {
   1924         static std::string convert(const std::tuple<Types...>& tuple) {
   1925             ReusableStringStream rss;
   1926             rss << '{';
   1927             Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
   1928             rss << " }";
   1929             return rss.str();
   1930         }
   1931     };
   1932 }
   1933 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
   1934 
   1935 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
   1936 #include <variant>
   1937 namespace Catch {
   1938     template<>
   1939     struct StringMaker<std::monostate> {
   1940         static std::string convert(const std::monostate&) {
   1941             return "{ }";
   1942         }
   1943     };
   1944 
   1945     template<typename... Elements>
   1946     struct StringMaker<std::variant<Elements...>> {
   1947         static std::string convert(const std::variant<Elements...>& variant) {
   1948             if (variant.valueless_by_exception()) {
   1949                 return "{valueless variant}";
   1950             } else {
   1951                 return std::visit(
   1952                     [](const auto& value) {
   1953                         return ::Catch::Detail::stringify(value);
   1954                     },
   1955                     variant
   1956                 );
   1957             }
   1958         }
   1959     };
   1960 }
   1961 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
   1962 
   1963 namespace Catch {
   1964     struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
   1965 
   1966     // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
   1967     using std::begin;
   1968     using std::end;
   1969 
   1970     not_this_one begin( ... );
   1971     not_this_one end( ... );
   1972 
   1973     template <typename T>
   1974     struct is_range {
   1975         static const bool value =
   1976             !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
   1977             !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
   1978     };
   1979 
   1980 #if defined(_MANAGED) // Managed types are never ranges
   1981     template <typename T>
   1982     struct is_range<T^> {
   1983         static const bool value = false;
   1984     };
   1985 #endif
   1986 
   1987     template<typename Range>
   1988     std::string rangeToString( Range const& range ) {
   1989         return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
   1990     }
   1991 
   1992     // Handle vector<bool> specially
   1993     template<typename Allocator>
   1994     std::string rangeToString( std::vector<bool, Allocator> const& v ) {
   1995         ReusableStringStream rss;
   1996         rss << "{ ";
   1997         bool first = true;
   1998         for( bool b : v ) {
   1999             if( first )
   2000                 first = false;
   2001             else
   2002                 rss << ", ";
   2003             rss << ::Catch::Detail::stringify( b );
   2004         }
   2005         rss << " }";
   2006         return rss.str();
   2007     }
   2008 
   2009     template<typename R>
   2010     struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
   2011         static std::string convert( R const& range ) {
   2012             return rangeToString( range );
   2013         }
   2014     };
   2015 
   2016     template <typename T, int SZ>
   2017     struct StringMaker<T[SZ]> {
   2018         static std::string convert(T const(&arr)[SZ]) {
   2019             return rangeToString(arr);
   2020         }
   2021     };
   2022 
   2023 } // namespace Catch
   2024 
   2025 // Separate std::chrono::duration specialization
   2026 #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
   2027 #include <ctime>
   2028 #include <ratio>
   2029 #include <chrono>
   2030 
   2031 namespace Catch {
   2032 
   2033 template <class Ratio>
   2034 struct ratio_string {
   2035     static std::string symbol();
   2036 };
   2037 
   2038 template <class Ratio>
   2039 std::string ratio_string<Ratio>::symbol() {
   2040     Catch::ReusableStringStream rss;
   2041     rss << '[' << Ratio::num << '/'
   2042         << Ratio::den << ']';
   2043     return rss.str();
   2044 }
   2045 template <>
   2046 struct ratio_string<std::atto> {
   2047     static std::string symbol();
   2048 };
   2049 template <>
   2050 struct ratio_string<std::femto> {
   2051     static std::string symbol();
   2052 };
   2053 template <>
   2054 struct ratio_string<std::pico> {
   2055     static std::string symbol();
   2056 };
   2057 template <>
   2058 struct ratio_string<std::nano> {
   2059     static std::string symbol();
   2060 };
   2061 template <>
   2062 struct ratio_string<std::micro> {
   2063     static std::string symbol();
   2064 };
   2065 template <>
   2066 struct ratio_string<std::milli> {
   2067     static std::string symbol();
   2068 };
   2069 
   2070     ////////////
   2071     // std::chrono::duration specializations
   2072     template<typename Value, typename Ratio>
   2073     struct StringMaker<std::chrono::duration<Value, Ratio>> {
   2074         static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
   2075             ReusableStringStream rss;
   2076             rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
   2077             return rss.str();
   2078         }
   2079     };
   2080     template<typename Value>
   2081     struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
   2082         static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
   2083             ReusableStringStream rss;
   2084             rss << duration.count() << " s";
   2085             return rss.str();
   2086         }
   2087     };
   2088     template<typename Value>
   2089     struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
   2090         static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
   2091             ReusableStringStream rss;
   2092             rss << duration.count() << " m";
   2093             return rss.str();
   2094         }
   2095     };
   2096     template<typename Value>
   2097     struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
   2098         static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
   2099             ReusableStringStream rss;
   2100             rss << duration.count() << " h";
   2101             return rss.str();
   2102         }
   2103     };
   2104 
   2105     ////////////
   2106     // std::chrono::time_point specialization
   2107     // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
   2108     template<typename Clock, typename Duration>
   2109     struct StringMaker<std::chrono::time_point<Clock, Duration>> {
   2110         static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
   2111             return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
   2112         }
   2113     };
   2114     // std::chrono::time_point<system_clock> specialization
   2115     template<typename Duration>
   2116     struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
   2117         static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
   2118             auto converted = std::chrono::system_clock::to_time_t(time_point);
   2119 
   2120 #ifdef _MSC_VER
   2121             std::tm timeInfo = {};
   2122             gmtime_s(&timeInfo, &converted);
   2123 #else
   2124             std::tm* timeInfo = std::gmtime(&converted);
   2125 #endif
   2126 
   2127             auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
   2128             char timeStamp[timeStampSize];
   2129             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
   2130 
   2131 #ifdef _MSC_VER
   2132             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
   2133 #else
   2134             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
   2135 #endif
   2136             return std::string(timeStamp);
   2137         }
   2138     };
   2139 }
   2140 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
   2141 
   2142 #define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
   2143 namespace Catch { \
   2144     template<> struct StringMaker<enumName> { \
   2145         static std::string convert( enumName value ) { \
   2146             static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
   2147             return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
   2148         } \
   2149     }; \
   2150 }
   2151 
   2152 #define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
   2153 
   2154 #ifdef _MSC_VER
   2155 #pragma warning(pop)
   2156 #endif
   2157 
   2158 // end catch_tostring.h
   2159 #include <iosfwd>
   2160 
   2161 #ifdef _MSC_VER
   2162 #pragma warning(push)
   2163 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
   2164 #pragma warning(disable:4018) // more "signed/unsigned mismatch"
   2165 #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
   2166 #pragma warning(disable:4180) // qualifier applied to function type has no meaning
   2167 #pragma warning(disable:4800) // Forcing result to true or false
   2168 #endif
   2169 
   2170 namespace Catch {
   2171 
   2172     struct ITransientExpression {
   2173         auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
   2174         auto getResult() const -> bool { return m_result; }
   2175         virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
   2176 
   2177         ITransientExpression( bool isBinaryExpression, bool result )
   2178         :   m_isBinaryExpression( isBinaryExpression ),
   2179             m_result( result )
   2180         {}
   2181 
   2182         // We don't actually need a virtual destructor, but many static analysers
   2183         // complain if it's not here :-(
   2184         virtual ~ITransientExpression();
   2185 
   2186         bool m_isBinaryExpression;
   2187         bool m_result;
   2188 
   2189     };
   2190 
   2191     void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
   2192 
   2193     template<typename LhsT, typename RhsT>
   2194     class BinaryExpr  : public ITransientExpression {
   2195         LhsT m_lhs;
   2196         StringRef m_op;
   2197         RhsT m_rhs;
   2198 
   2199         void streamReconstructedExpression( std::ostream &os ) const override {
   2200             formatReconstructedExpression
   2201                     ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
   2202         }
   2203 
   2204     public:
   2205         BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
   2206         :   ITransientExpression{ true, comparisonResult },
   2207             m_lhs( lhs ),
   2208             m_op( op ),
   2209             m_rhs( rhs )
   2210         {}
   2211 
   2212         template<typename T>
   2213         auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2214             static_assert(always_false<T>::value,
   2215             "chained comparisons are not supported inside assertions, "
   2216             "wrap the expression inside parentheses, or decompose it");
   2217         }
   2218 
   2219         template<typename T>
   2220         auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2221             static_assert(always_false<T>::value,
   2222             "chained comparisons are not supported inside assertions, "
   2223             "wrap the expression inside parentheses, or decompose it");
   2224         }
   2225 
   2226         template<typename T>
   2227         auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2228             static_assert(always_false<T>::value,
   2229             "chained comparisons are not supported inside assertions, "
   2230             "wrap the expression inside parentheses, or decompose it");
   2231         }
   2232 
   2233         template<typename T>
   2234         auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2235             static_assert(always_false<T>::value,
   2236             "chained comparisons are not supported inside assertions, "
   2237             "wrap the expression inside parentheses, or decompose it");
   2238         }
   2239 
   2240         template<typename T>
   2241         auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2242             static_assert(always_false<T>::value,
   2243             "chained comparisons are not supported inside assertions, "
   2244             "wrap the expression inside parentheses, or decompose it");
   2245         }
   2246 
   2247         template<typename T>
   2248         auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2249             static_assert(always_false<T>::value,
   2250             "chained comparisons are not supported inside assertions, "
   2251             "wrap the expression inside parentheses, or decompose it");
   2252         }
   2253 
   2254         template<typename T>
   2255         auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2256             static_assert(always_false<T>::value,
   2257             "chained comparisons are not supported inside assertions, "
   2258             "wrap the expression inside parentheses, or decompose it");
   2259         }
   2260 
   2261         template<typename T>
   2262         auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
   2263             static_assert(always_false<T>::value,
   2264             "chained comparisons are not supported inside assertions, "
   2265             "wrap the expression inside parentheses, or decompose it");
   2266         }
   2267     };
   2268 
   2269     template<typename LhsT>
   2270     class UnaryExpr : public ITransientExpression {
   2271         LhsT m_lhs;
   2272 
   2273         void streamReconstructedExpression( std::ostream &os ) const override {
   2274             os << Catch::Detail::stringify( m_lhs );
   2275         }
   2276 
   2277     public:
   2278         explicit UnaryExpr( LhsT lhs )
   2279         :   ITransientExpression{ false, static_cast<bool>(lhs) },
   2280             m_lhs( lhs )
   2281         {}
   2282     };
   2283 
   2284     // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
   2285     template<typename LhsT, typename RhsT>
   2286     auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
   2287     template<typename T>
   2288     auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
   2289     template<typename T>
   2290     auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
   2291     template<typename T>
   2292     auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
   2293     template<typename T>
   2294     auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
   2295 
   2296     template<typename LhsT, typename RhsT>
   2297     auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
   2298     template<typename T>
   2299     auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
   2300     template<typename T>
   2301     auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
   2302     template<typename T>
   2303     auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
   2304     template<typename T>
   2305     auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
   2306 
   2307     template<typename LhsT>
   2308     class ExprLhs {
   2309         LhsT m_lhs;
   2310     public:
   2311         explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
   2312 
   2313         template<typename RhsT>
   2314         auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
   2315             return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
   2316         }
   2317         auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
   2318             return { m_lhs == rhs, m_lhs, "==", rhs };
   2319         }
   2320 
   2321         template<typename RhsT>
   2322         auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
   2323             return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
   2324         }
   2325         auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
   2326             return { m_lhs != rhs, m_lhs, "!=", rhs };
   2327         }
   2328 
   2329         template<typename RhsT>
   2330         auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
   2331             return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
   2332         }
   2333         template<typename RhsT>
   2334         auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
   2335             return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
   2336         }
   2337         template<typename RhsT>
   2338         auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
   2339             return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
   2340         }
   2341         template<typename RhsT>
   2342         auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
   2343             return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
   2344         }
   2345 
   2346         template<typename RhsT>
   2347         auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
   2348             static_assert(always_false<RhsT>::value,
   2349             "operator&& is not supported inside assertions, "
   2350             "wrap the expression inside parentheses, or decompose it");
   2351         }
   2352 
   2353         template<typename RhsT>
   2354         auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
   2355             static_assert(always_false<RhsT>::value,
   2356             "operator|| is not supported inside assertions, "
   2357             "wrap the expression inside parentheses, or decompose it");
   2358         }
   2359 
   2360         auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
   2361             return UnaryExpr<LhsT>{ m_lhs };
   2362         }
   2363     };
   2364 
   2365     void handleExpression( ITransientExpression const& expr );
   2366 
   2367     template<typename T>
   2368     void handleExpression( ExprLhs<T> const& expr ) {
   2369         handleExpression( expr.makeUnaryExpr() );
   2370     }
   2371 
   2372     struct Decomposer {
   2373         template<typename T>
   2374         auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
   2375             return ExprLhs<T const&>{ lhs };
   2376         }
   2377 
   2378         auto operator <=( bool value ) -> ExprLhs<bool> {
   2379             return ExprLhs<bool>{ value };
   2380         }
   2381     };
   2382 
   2383 } // end namespace Catch
   2384 
   2385 #ifdef _MSC_VER
   2386 #pragma warning(pop)
   2387 #endif
   2388 
   2389 // end catch_decomposer.h
   2390 // start catch_interfaces_capture.h
   2391 
   2392 #include <string>
   2393 #include <chrono>
   2394 
   2395 namespace Catch {
   2396 
   2397     class AssertionResult;
   2398     struct AssertionInfo;
   2399     struct SectionInfo;
   2400     struct SectionEndInfo;
   2401     struct MessageInfo;
   2402     struct MessageBuilder;
   2403     struct Counts;
   2404     struct AssertionReaction;
   2405     struct SourceLineInfo;
   2406 
   2407     struct ITransientExpression;
   2408     struct IGeneratorTracker;
   2409 
   2410 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   2411     struct BenchmarkInfo;
   2412     template <typename Duration = std::chrono::duration<double, std::nano>>
   2413     struct BenchmarkStats;
   2414 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   2415 
   2416     struct IResultCapture {
   2417 
   2418         virtual ~IResultCapture();
   2419 
   2420         virtual bool sectionStarted(    SectionInfo const& sectionInfo,
   2421                                         Counts& assertions ) = 0;
   2422         virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
   2423         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
   2424 
   2425         virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
   2426 
   2427 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   2428         virtual void benchmarkPreparing( std::string const& name ) = 0;
   2429         virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
   2430         virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
   2431         virtual void benchmarkFailed( std::string const& error ) = 0;
   2432 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   2433 
   2434         virtual void pushScopedMessage( MessageInfo const& message ) = 0;
   2435         virtual void popScopedMessage( MessageInfo const& message ) = 0;
   2436 
   2437         virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
   2438 
   2439         virtual void handleFatalErrorCondition( StringRef message ) = 0;
   2440 
   2441         virtual void handleExpr
   2442                 (   AssertionInfo const& info,
   2443                     ITransientExpression const& expr,
   2444                     AssertionReaction& reaction ) = 0;
   2445         virtual void handleMessage
   2446                 (   AssertionInfo const& info,
   2447                     ResultWas::OfType resultType,
   2448                     StringRef const& message,
   2449                     AssertionReaction& reaction ) = 0;
   2450         virtual void handleUnexpectedExceptionNotThrown
   2451                 (   AssertionInfo const& info,
   2452                     AssertionReaction& reaction ) = 0;
   2453         virtual void handleUnexpectedInflightException
   2454                 (   AssertionInfo const& info,
   2455                     std::string const& message,
   2456                     AssertionReaction& reaction ) = 0;
   2457         virtual void handleIncomplete
   2458                 (   AssertionInfo const& info ) = 0;
   2459         virtual void handleNonExpr
   2460                 (   AssertionInfo const &info,
   2461                     ResultWas::OfType resultType,
   2462                     AssertionReaction &reaction ) = 0;
   2463 
   2464         virtual bool lastAssertionPassed() = 0;
   2465         virtual void assertionPassed() = 0;
   2466 
   2467         // Deprecated, do not use:
   2468         virtual std::string getCurrentTestName() const = 0;
   2469         virtual const AssertionResult* getLastResult() const = 0;
   2470         virtual void exceptionEarlyReported() = 0;
   2471     };
   2472 
   2473     IResultCapture& getResultCapture();
   2474 }
   2475 
   2476 // end catch_interfaces_capture.h
   2477 namespace Catch {
   2478 
   2479     struct TestFailureException{};
   2480     struct AssertionResultData;
   2481     struct IResultCapture;
   2482     class RunContext;
   2483 
   2484     class LazyExpression {
   2485         friend class AssertionHandler;
   2486         friend struct AssertionStats;
   2487         friend class RunContext;
   2488 
   2489         ITransientExpression const* m_transientExpression = nullptr;
   2490         bool m_isNegated;
   2491     public:
   2492         LazyExpression( bool isNegated );
   2493         LazyExpression( LazyExpression const& other );
   2494         LazyExpression& operator = ( LazyExpression const& ) = delete;
   2495 
   2496         explicit operator bool() const;
   2497 
   2498         friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
   2499     };
   2500 
   2501     struct AssertionReaction {
   2502         bool shouldDebugBreak = false;
   2503         bool shouldThrow = false;
   2504     };
   2505 
   2506     class AssertionHandler {
   2507         AssertionInfo m_assertionInfo;
   2508         AssertionReaction m_reaction;
   2509         bool m_completed = false;
   2510         IResultCapture& m_resultCapture;
   2511 
   2512     public:
   2513         AssertionHandler
   2514             (   StringRef const& macroName,
   2515                 SourceLineInfo const& lineInfo,
   2516                 StringRef capturedExpression,
   2517                 ResultDisposition::Flags resultDisposition );
   2518         ~AssertionHandler() {
   2519             if ( !m_completed ) {
   2520                 m_resultCapture.handleIncomplete( m_assertionInfo );
   2521             }
   2522         }
   2523 
   2524         template<typename T>
   2525         void handleExpr( ExprLhs<T> const& expr ) {
   2526             handleExpr( expr.makeUnaryExpr() );
   2527         }
   2528         void handleExpr( ITransientExpression const& expr );
   2529 
   2530         void handleMessage(ResultWas::OfType resultType, StringRef const& message);
   2531 
   2532         void handleExceptionThrownAsExpected();
   2533         void handleUnexpectedExceptionNotThrown();
   2534         void handleExceptionNotThrownAsExpected();
   2535         void handleThrowingCallSkipped();
   2536         void handleUnexpectedInflightException();
   2537 
   2538         void complete();
   2539         void setCompleted();
   2540 
   2541         // query
   2542         auto allowThrows() const -> bool;
   2543     };
   2544 
   2545     void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
   2546 
   2547 } // namespace Catch
   2548 
   2549 // end catch_assertionhandler.h
   2550 // start catch_message.h
   2551 
   2552 #include <string>
   2553 #include <vector>
   2554 
   2555 namespace Catch {
   2556 
   2557     struct MessageInfo {
   2558         MessageInfo(    StringRef const& _macroName,
   2559                         SourceLineInfo const& _lineInfo,
   2560                         ResultWas::OfType _type );
   2561 
   2562         StringRef macroName;
   2563         std::string message;
   2564         SourceLineInfo lineInfo;
   2565         ResultWas::OfType type;
   2566         unsigned int sequence;
   2567 
   2568         bool operator == ( MessageInfo const& other ) const;
   2569         bool operator < ( MessageInfo const& other ) const;
   2570     private:
   2571         static unsigned int globalCount;
   2572     };
   2573 
   2574     struct MessageStream {
   2575 
   2576         template<typename T>
   2577         MessageStream& operator << ( T const& value ) {
   2578             m_stream << value;
   2579             return *this;
   2580         }
   2581 
   2582         ReusableStringStream m_stream;
   2583     };
   2584 
   2585     struct MessageBuilder : MessageStream {
   2586         MessageBuilder( StringRef const& macroName,
   2587                         SourceLineInfo const& lineInfo,
   2588                         ResultWas::OfType type );
   2589 
   2590         template<typename T>
   2591         MessageBuilder& operator << ( T const& value ) {
   2592             m_stream << value;
   2593             return *this;
   2594         }
   2595 
   2596         MessageInfo m_info;
   2597     };
   2598 
   2599     class ScopedMessage {
   2600     public:
   2601         explicit ScopedMessage( MessageBuilder const& builder );
   2602         ScopedMessage( ScopedMessage& duplicate ) = delete;
   2603         ScopedMessage( ScopedMessage&& old );
   2604         ~ScopedMessage();
   2605 
   2606         MessageInfo m_info;
   2607         bool m_moved;
   2608     };
   2609 
   2610     class Capturer {
   2611         std::vector<MessageInfo> m_messages;
   2612         IResultCapture& m_resultCapture = getResultCapture();
   2613         size_t m_captured = 0;
   2614     public:
   2615         Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
   2616         ~Capturer();
   2617 
   2618         void captureValue( size_t index, std::string const& value );
   2619 
   2620         template<typename T>
   2621         void captureValues( size_t index, T const& value ) {
   2622             captureValue( index, Catch::Detail::stringify( value ) );
   2623         }
   2624 
   2625         template<typename T, typename... Ts>
   2626         void captureValues( size_t index, T const& value, Ts const&... values ) {
   2627             captureValue( index, Catch::Detail::stringify(value) );
   2628             captureValues( index+1, values... );
   2629         }
   2630     };
   2631 
   2632 } // end namespace Catch
   2633 
   2634 // end catch_message.h
   2635 #if !defined(CATCH_CONFIG_DISABLE)
   2636 
   2637 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
   2638   #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
   2639 #else
   2640   #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
   2641 #endif
   2642 
   2643 #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
   2644 
   2645 ///////////////////////////////////////////////////////////////////////////////
   2646 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
   2647 // macros.
   2648 #define INTERNAL_CATCH_TRY
   2649 #define INTERNAL_CATCH_CATCH( capturer )
   2650 
   2651 #else // CATCH_CONFIG_FAST_COMPILE
   2652 
   2653 #define INTERNAL_CATCH_TRY try
   2654 #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
   2655 
   2656 #endif
   2657 
   2658 #define INTERNAL_CATCH_REACT( handler ) handler.complete();
   2659 
   2660 ///////////////////////////////////////////////////////////////////////////////
   2661 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
   2662     do { \
   2663         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
   2664         INTERNAL_CATCH_TRY { \
   2665             CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   2666             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
   2667             catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
   2668             CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   2669         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
   2670         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   2671     } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
   2672     // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
   2673 
   2674 ///////////////////////////////////////////////////////////////////////////////
   2675 #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
   2676     INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
   2677     if( Catch::getResultCapture().lastAssertionPassed() )
   2678 
   2679 ///////////////////////////////////////////////////////////////////////////////
   2680 #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
   2681     INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
   2682     if( !Catch::getResultCapture().lastAssertionPassed() )
   2683 
   2684 ///////////////////////////////////////////////////////////////////////////////
   2685 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
   2686     do { \
   2687         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
   2688         try { \
   2689             static_cast<void>(__VA_ARGS__); \
   2690             catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
   2691         } \
   2692         catch( ... ) { \
   2693             catchAssertionHandler.handleUnexpectedInflightException(); \
   2694         } \
   2695         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   2696     } while( false )
   2697 
   2698 ///////////////////////////////////////////////////////////////////////////////
   2699 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
   2700     do { \
   2701         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
   2702         if( catchAssertionHandler.allowThrows() ) \
   2703             try { \
   2704                 static_cast<void>(__VA_ARGS__); \
   2705                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
   2706             } \
   2707             catch( ... ) { \
   2708                 catchAssertionHandler.handleExceptionThrownAsExpected(); \
   2709             } \
   2710         else \
   2711             catchAssertionHandler.handleThrowingCallSkipped(); \
   2712         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   2713     } while( false )
   2714 
   2715 ///////////////////////////////////////////////////////////////////////////////
   2716 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
   2717     do { \
   2718         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
   2719         if( catchAssertionHandler.allowThrows() ) \
   2720             try { \
   2721                 static_cast<void>(expr); \
   2722                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
   2723             } \
   2724             catch( exceptionType const& ) { \
   2725                 catchAssertionHandler.handleExceptionThrownAsExpected(); \
   2726             } \
   2727             catch( ... ) { \
   2728                 catchAssertionHandler.handleUnexpectedInflightException(); \
   2729             } \
   2730         else \
   2731             catchAssertionHandler.handleThrowingCallSkipped(); \
   2732         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   2733     } while( false )
   2734 
   2735 ///////////////////////////////////////////////////////////////////////////////
   2736 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
   2737     do { \
   2738         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
   2739         catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
   2740         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   2741     } while( false )
   2742 
   2743 ///////////////////////////////////////////////////////////////////////////////
   2744 #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
   2745     auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
   2746     varName.captureValues( 0, __VA_ARGS__ )
   2747 
   2748 ///////////////////////////////////////////////////////////////////////////////
   2749 #define INTERNAL_CATCH_INFO( macroName, log ) \
   2750     Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
   2751 
   2752 ///////////////////////////////////////////////////////////////////////////////
   2753 #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
   2754     Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
   2755 
   2756 ///////////////////////////////////////////////////////////////////////////////
   2757 // Although this is matcher-based, it can be used with just a string
   2758 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
   2759     do { \
   2760         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
   2761         if( catchAssertionHandler.allowThrows() ) \
   2762             try { \
   2763                 static_cast<void>(__VA_ARGS__); \
   2764                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
   2765             } \
   2766             catch( ... ) { \
   2767                 Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
   2768             } \
   2769         else \
   2770             catchAssertionHandler.handleThrowingCallSkipped(); \
   2771         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   2772     } while( false )
   2773 
   2774 #endif // CATCH_CONFIG_DISABLE
   2775 
   2776 // end catch_capture.hpp
   2777 // start catch_section.h
   2778 
   2779 // start catch_section_info.h
   2780 
   2781 // start catch_totals.h
   2782 
   2783 #include <cstddef>
   2784 
   2785 namespace Catch {
   2786 
   2787     struct Counts {
   2788         Counts operator - ( Counts const& other ) const;
   2789         Counts& operator += ( Counts const& other );
   2790 
   2791         std::size_t total() const;
   2792         bool allPassed() const;
   2793         bool allOk() const;
   2794 
   2795         std::size_t passed = 0;
   2796         std::size_t failed = 0;
   2797         std::size_t failedButOk = 0;
   2798     };
   2799 
   2800     struct Totals {
   2801 
   2802         Totals operator - ( Totals const& other ) const;
   2803         Totals& operator += ( Totals const& other );
   2804 
   2805         Totals delta( Totals const& prevTotals ) const;
   2806 
   2807         int error = 0;
   2808         Counts assertions;
   2809         Counts testCases;
   2810     };
   2811 }
   2812 
   2813 // end catch_totals.h
   2814 #include <string>
   2815 
   2816 namespace Catch {
   2817 
   2818     struct SectionInfo {
   2819         SectionInfo
   2820             (   SourceLineInfo const& _lineInfo,
   2821                 std::string const& _name );
   2822 
   2823         // Deprecated
   2824         SectionInfo
   2825             (   SourceLineInfo const& _lineInfo,
   2826                 std::string const& _name,
   2827                 std::string const& ) : SectionInfo( _lineInfo, _name ) {}
   2828 
   2829         std::string name;
   2830         std::string description; // !Deprecated: this will always be empty
   2831         SourceLineInfo lineInfo;
   2832     };
   2833 
   2834     struct SectionEndInfo {
   2835         SectionInfo sectionInfo;
   2836         Counts prevAssertions;
   2837         double durationInSeconds;
   2838     };
   2839 
   2840 } // end namespace Catch
   2841 
   2842 // end catch_section_info.h
   2843 // start catch_timer.h
   2844 
   2845 #include <cstdint>
   2846 
   2847 namespace Catch {
   2848 
   2849     auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
   2850     auto getEstimatedClockResolution() -> uint64_t;
   2851 
   2852     class Timer {
   2853         uint64_t m_nanoseconds = 0;
   2854     public:
   2855         void start();
   2856         auto getElapsedNanoseconds() const -> uint64_t;
   2857         auto getElapsedMicroseconds() const -> uint64_t;
   2858         auto getElapsedMilliseconds() const -> unsigned int;
   2859         auto getElapsedSeconds() const -> double;
   2860     };
   2861 
   2862 } // namespace Catch
   2863 
   2864 // end catch_timer.h
   2865 #include <string>
   2866 
   2867 namespace Catch {
   2868 
   2869     class Section : NonCopyable {
   2870     public:
   2871         Section( SectionInfo const& info );
   2872         ~Section();
   2873 
   2874         // This indicates whether the section should be executed or not
   2875         explicit operator bool() const;
   2876 
   2877     private:
   2878         SectionInfo m_info;
   2879 
   2880         std::string m_name;
   2881         Counts m_assertions;
   2882         bool m_sectionIncluded;
   2883         Timer m_timer;
   2884     };
   2885 
   2886 } // end namespace Catch
   2887 
   2888 #define INTERNAL_CATCH_SECTION( ... ) \
   2889     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   2890     CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
   2891     if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
   2892     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   2893 
   2894 #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
   2895     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   2896     CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
   2897     if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
   2898     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   2899 
   2900 // end catch_section.h
   2901 // start catch_interfaces_exception.h
   2902 
   2903 // start catch_interfaces_registry_hub.h
   2904 
   2905 #include <string>
   2906 #include <memory>
   2907 
   2908 namespace Catch {
   2909 
   2910     class TestCase;
   2911     struct ITestCaseRegistry;
   2912     struct IExceptionTranslatorRegistry;
   2913     struct IExceptionTranslator;
   2914     struct IReporterRegistry;
   2915     struct IReporterFactory;
   2916     struct ITagAliasRegistry;
   2917     struct IMutableEnumValuesRegistry;
   2918 
   2919     class StartupExceptionRegistry;
   2920 
   2921     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
   2922 
   2923     struct IRegistryHub {
   2924         virtual ~IRegistryHub();
   2925 
   2926         virtual IReporterRegistry const& getReporterRegistry() const = 0;
   2927         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
   2928         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
   2929         virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
   2930 
   2931         virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
   2932     };
   2933 
   2934     struct IMutableRegistryHub {
   2935         virtual ~IMutableRegistryHub();
   2936         virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
   2937         virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
   2938         virtual void registerTest( TestCase const& testInfo ) = 0;
   2939         virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
   2940         virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
   2941         virtual void registerStartupException() noexcept = 0;
   2942         virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
   2943     };
   2944 
   2945     IRegistryHub const& getRegistryHub();
   2946     IMutableRegistryHub& getMutableRegistryHub();
   2947     void cleanUp();
   2948     std::string translateActiveException();
   2949 
   2950 }
   2951 
   2952 // end catch_interfaces_registry_hub.h
   2953 #if defined(CATCH_CONFIG_DISABLE)
   2954     #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
   2955         static std::string translatorName( signature )
   2956 #endif
   2957 
   2958 #include <exception>
   2959 #include <string>
   2960 #include <vector>
   2961 
   2962 namespace Catch {
   2963     using exceptionTranslateFunction = std::string(*)();
   2964 
   2965     struct IExceptionTranslator;
   2966     using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
   2967 
   2968     struct IExceptionTranslator {
   2969         virtual ~IExceptionTranslator();
   2970         virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
   2971     };
   2972 
   2973     struct IExceptionTranslatorRegistry {
   2974         virtual ~IExceptionTranslatorRegistry();
   2975 
   2976         virtual std::string translateActiveException() const = 0;
   2977     };
   2978 
   2979     class ExceptionTranslatorRegistrar {
   2980         template<typename T>
   2981         class ExceptionTranslator : public IExceptionTranslator {
   2982         public:
   2983 
   2984             ExceptionTranslator( std::string(*translateFunction)( T& ) )
   2985             : m_translateFunction( translateFunction )
   2986             {}
   2987 
   2988             std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
   2989                 try {
   2990                     if( it == itEnd )
   2991                         std::rethrow_exception(std::current_exception());
   2992                     else
   2993                         return (*it)->translate( it+1, itEnd );
   2994                 }
   2995                 catch( T& ex ) {
   2996                     return m_translateFunction( ex );
   2997                 }
   2998             }
   2999 
   3000         protected:
   3001             std::string(*m_translateFunction)( T& );
   3002         };
   3003 
   3004     public:
   3005         template<typename T>
   3006         ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
   3007             getMutableRegistryHub().registerTranslator
   3008                 ( new ExceptionTranslator<T>( translateFunction ) );
   3009         }
   3010     };
   3011 }
   3012 
   3013 ///////////////////////////////////////////////////////////////////////////////
   3014 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
   3015     static std::string translatorName( signature ); \
   3016     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
   3017     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
   3018     namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
   3019     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
   3020     static std::string translatorName( signature )
   3021 
   3022 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
   3023 
   3024 // end catch_interfaces_exception.h
   3025 // start catch_approx.h
   3026 
   3027 #include <type_traits>
   3028 
   3029 namespace Catch {
   3030 namespace Detail {
   3031 
   3032     class Approx {
   3033     private:
   3034         bool equalityComparisonImpl(double other) const;
   3035         // Validates the new margin (margin >= 0)
   3036         // out-of-line to avoid including stdexcept in the header
   3037         void setMargin(double margin);
   3038         // Validates the new epsilon (0 < epsilon < 1)
   3039         // out-of-line to avoid including stdexcept in the header
   3040         void setEpsilon(double epsilon);
   3041 
   3042     public:
   3043         explicit Approx ( double value );
   3044 
   3045         static Approx custom();
   3046 
   3047         Approx operator-() const;
   3048 
   3049         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3050         Approx operator()( T const& value ) {
   3051             Approx approx( static_cast<double>(value) );
   3052             approx.m_epsilon = m_epsilon;
   3053             approx.m_margin = m_margin;
   3054             approx.m_scale = m_scale;
   3055             return approx;
   3056         }
   3057 
   3058         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3059         explicit Approx( T const& value ): Approx(static_cast<double>(value))
   3060         {}
   3061 
   3062         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3063         friend bool operator == ( const T& lhs, Approx const& rhs ) {
   3064             auto lhs_v = static_cast<double>(lhs);
   3065             return rhs.equalityComparisonImpl(lhs_v);
   3066         }
   3067 
   3068         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3069         friend bool operator == ( Approx const& lhs, const T& rhs ) {
   3070             return operator==( rhs, lhs );
   3071         }
   3072 
   3073         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3074         friend bool operator != ( T const& lhs, Approx const& rhs ) {
   3075             return !operator==( lhs, rhs );
   3076         }
   3077 
   3078         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3079         friend bool operator != ( Approx const& lhs, T const& rhs ) {
   3080             return !operator==( rhs, lhs );
   3081         }
   3082 
   3083         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3084         friend bool operator <= ( T const& lhs, Approx const& rhs ) {
   3085             return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
   3086         }
   3087 
   3088         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3089         friend bool operator <= ( Approx const& lhs, T const& rhs ) {
   3090             return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
   3091         }
   3092 
   3093         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3094         friend bool operator >= ( T const& lhs, Approx const& rhs ) {
   3095             return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
   3096         }
   3097 
   3098         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3099         friend bool operator >= ( Approx const& lhs, T const& rhs ) {
   3100             return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
   3101         }
   3102 
   3103         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3104         Approx& epsilon( T const& newEpsilon ) {
   3105             double epsilonAsDouble = static_cast<double>(newEpsilon);
   3106             setEpsilon(epsilonAsDouble);
   3107             return *this;
   3108         }
   3109 
   3110         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3111         Approx& margin( T const& newMargin ) {
   3112             double marginAsDouble = static_cast<double>(newMargin);
   3113             setMargin(marginAsDouble);
   3114             return *this;
   3115         }
   3116 
   3117         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3118         Approx& scale( T const& newScale ) {
   3119             m_scale = static_cast<double>(newScale);
   3120             return *this;
   3121         }
   3122 
   3123         std::string toString() const;
   3124 
   3125     private:
   3126         double m_epsilon;
   3127         double m_margin;
   3128         double m_scale;
   3129         double m_value;
   3130     };
   3131 } // end namespace Detail
   3132 
   3133 namespace literals {
   3134     Detail::Approx operator "" _a(long double val);
   3135     Detail::Approx operator "" _a(unsigned long long val);
   3136 } // end namespace literals
   3137 
   3138 template<>
   3139 struct StringMaker<Catch::Detail::Approx> {
   3140     static std::string convert(Catch::Detail::Approx const& value);
   3141 };
   3142 
   3143 } // end namespace Catch
   3144 
   3145 // end catch_approx.h
   3146 // start catch_string_manip.h
   3147 
   3148 #include <string>
   3149 #include <iosfwd>
   3150 #include <vector>
   3151 
   3152 namespace Catch {
   3153 
   3154     bool startsWith( std::string const& s, std::string const& prefix );
   3155     bool startsWith( std::string const& s, char prefix );
   3156     bool endsWith( std::string const& s, std::string const& suffix );
   3157     bool endsWith( std::string const& s, char suffix );
   3158     bool contains( std::string const& s, std::string const& infix );
   3159     void toLowerInPlace( std::string& s );
   3160     std::string toLower( std::string const& s );
   3161     //! Returns a new string without whitespace at the start/end
   3162     std::string trim( std::string const& str );
   3163     //! Returns a substring of the original ref without whitespace. Beware lifetimes!
   3164     StringRef trim(StringRef ref);
   3165 
   3166     // !!! Be aware, returns refs into original string - make sure original string outlives them
   3167     std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
   3168     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
   3169 
   3170     struct pluralise {
   3171         pluralise( std::size_t count, std::string const& label );
   3172 
   3173         friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
   3174 
   3175         std::size_t m_count;
   3176         std::string m_label;
   3177     };
   3178 }
   3179 
   3180 // end catch_string_manip.h
   3181 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
   3182 // start catch_capture_matchers.h
   3183 
   3184 // start catch_matchers.h
   3185 
   3186 #include <string>
   3187 #include <vector>
   3188 
   3189 namespace Catch {
   3190 namespace Matchers {
   3191     namespace Impl {
   3192 
   3193         template<typename ArgT> struct MatchAllOf;
   3194         template<typename ArgT> struct MatchAnyOf;
   3195         template<typename ArgT> struct MatchNotOf;
   3196 
   3197         class MatcherUntypedBase {
   3198         public:
   3199             MatcherUntypedBase() = default;
   3200             MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
   3201             MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
   3202             std::string toString() const;
   3203 
   3204         protected:
   3205             virtual ~MatcherUntypedBase();
   3206             virtual std::string describe() const = 0;
   3207             mutable std::string m_cachedToString;
   3208         };
   3209 
   3210 #ifdef __clang__
   3211 #    pragma clang diagnostic push
   3212 #    pragma clang diagnostic ignored "-Wnon-virtual-dtor"
   3213 #endif
   3214 
   3215         template<typename ObjectT>
   3216         struct MatcherMethod {
   3217             virtual bool match( ObjectT const& arg ) const = 0;
   3218         };
   3219 
   3220 #if defined(__OBJC__)
   3221         // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
   3222         // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
   3223         template<>
   3224         struct MatcherMethod<NSString*> {
   3225             virtual bool match( NSString* arg ) const = 0;
   3226         };
   3227 #endif
   3228 
   3229 #ifdef __clang__
   3230 #    pragma clang diagnostic pop
   3231 #endif
   3232 
   3233         template<typename T>
   3234         struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
   3235 
   3236             MatchAllOf<T> operator && ( MatcherBase const& other ) const;
   3237             MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
   3238             MatchNotOf<T> operator ! () const;
   3239         };
   3240 
   3241         template<typename ArgT>
   3242         struct MatchAllOf : MatcherBase<ArgT> {
   3243             bool match( ArgT const& arg ) const override {
   3244                 for( auto matcher : m_matchers ) {
   3245                     if (!matcher->match(arg))
   3246                         return false;
   3247                 }
   3248                 return true;
   3249             }
   3250             std::string describe() const override {
   3251                 std::string description;
   3252                 description.reserve( 4 + m_matchers.size()*32 );
   3253                 description += "( ";
   3254                 bool first = true;
   3255                 for( auto matcher : m_matchers ) {
   3256                     if( first )
   3257                         first = false;
   3258                     else
   3259                         description += " and ";
   3260                     description += matcher->toString();
   3261                 }
   3262                 description += " )";
   3263                 return description;
   3264             }
   3265 
   3266             MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
   3267                 m_matchers.push_back( &other );
   3268                 return *this;
   3269             }
   3270 
   3271             std::vector<MatcherBase<ArgT> const*> m_matchers;
   3272         };
   3273         template<typename ArgT>
   3274         struct MatchAnyOf : MatcherBase<ArgT> {
   3275 
   3276             bool match( ArgT const& arg ) const override {
   3277                 for( auto matcher : m_matchers ) {
   3278                     if (matcher->match(arg))
   3279                         return true;
   3280                 }
   3281                 return false;
   3282             }
   3283             std::string describe() const override {
   3284                 std::string description;
   3285                 description.reserve( 4 + m_matchers.size()*32 );
   3286                 description += "( ";
   3287                 bool first = true;
   3288                 for( auto matcher : m_matchers ) {
   3289                     if( first )
   3290                         first = false;
   3291                     else
   3292                         description += " or ";
   3293                     description += matcher->toString();
   3294                 }
   3295                 description += " )";
   3296                 return description;
   3297             }
   3298 
   3299             MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
   3300                 m_matchers.push_back( &other );
   3301                 return *this;
   3302             }
   3303 
   3304             std::vector<MatcherBase<ArgT> const*> m_matchers;
   3305         };
   3306 
   3307         template<typename ArgT>
   3308         struct MatchNotOf : MatcherBase<ArgT> {
   3309 
   3310             MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
   3311 
   3312             bool match( ArgT const& arg ) const override {
   3313                 return !m_underlyingMatcher.match( arg );
   3314             }
   3315 
   3316             std::string describe() const override {
   3317                 return "not " + m_underlyingMatcher.toString();
   3318             }
   3319             MatcherBase<ArgT> const& m_underlyingMatcher;
   3320         };
   3321 
   3322         template<typename T>
   3323         MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {
   3324             return MatchAllOf<T>() && *this && other;
   3325         }
   3326         template<typename T>
   3327         MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
   3328             return MatchAnyOf<T>() || *this || other;
   3329         }
   3330         template<typename T>
   3331         MatchNotOf<T> MatcherBase<T>::operator ! () const {
   3332             return MatchNotOf<T>( *this );
   3333         }
   3334 
   3335     } // namespace Impl
   3336 
   3337 } // namespace Matchers
   3338 
   3339 using namespace Matchers;
   3340 using Matchers::Impl::MatcherBase;
   3341 
   3342 } // namespace Catch
   3343 
   3344 // end catch_matchers.h
   3345 // start catch_matchers_exception.hpp
   3346 
   3347 namespace Catch {
   3348 namespace Matchers {
   3349 namespace Exception {
   3350 
   3351 class ExceptionMessageMatcher : public MatcherBase<std::exception> {
   3352     std::string m_message;
   3353 public:
   3354 
   3355     ExceptionMessageMatcher(std::string const& message):
   3356         m_message(message)
   3357     {}
   3358 
   3359     bool match(std::exception const& ex) const override;
   3360 
   3361     std::string describe() const override;
   3362 };
   3363 
   3364 } // namespace Exception
   3365 
   3366 Exception::ExceptionMessageMatcher Message(std::string const& message);
   3367 
   3368 } // namespace Matchers
   3369 } // namespace Catch
   3370 
   3371 // end catch_matchers_exception.hpp
   3372 // start catch_matchers_floating.h
   3373 
   3374 namespace Catch {
   3375 namespace Matchers {
   3376 
   3377     namespace Floating {
   3378 
   3379         enum class FloatingPointKind : uint8_t;
   3380 
   3381         struct WithinAbsMatcher : MatcherBase<double> {
   3382             WithinAbsMatcher(double target, double margin);
   3383             bool match(double const& matchee) const override;
   3384             std::string describe() const override;
   3385         private:
   3386             double m_target;
   3387             double m_margin;
   3388         };
   3389 
   3390         struct WithinUlpsMatcher : MatcherBase<double> {
   3391             WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
   3392             bool match(double const& matchee) const override;
   3393             std::string describe() const override;
   3394         private:
   3395             double m_target;
   3396             uint64_t m_ulps;
   3397             FloatingPointKind m_type;
   3398         };
   3399 
   3400         // Given IEEE-754 format for floats and doubles, we can assume
   3401         // that float -> double promotion is lossless. Given this, we can
   3402         // assume that if we do the standard relative comparison of
   3403         // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
   3404         // the same result if we do this for floats, as if we do this for
   3405         // doubles that were promoted from floats.
   3406         struct WithinRelMatcher : MatcherBase<double> {
   3407             WithinRelMatcher(double target, double epsilon);
   3408             bool match(double const& matchee) const override;
   3409             std::string describe() const override;
   3410         private:
   3411             double m_target;
   3412             double m_epsilon;
   3413         };
   3414 
   3415     } // namespace Floating
   3416 
   3417     // The following functions create the actual matcher objects.
   3418     // This allows the types to be inferred
   3419     Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
   3420     Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
   3421     Floating::WithinAbsMatcher WithinAbs(double target, double margin);
   3422     Floating::WithinRelMatcher WithinRel(double target, double eps);
   3423     // defaults epsilon to 100*numeric_limits<double>::epsilon()
   3424     Floating::WithinRelMatcher WithinRel(double target);
   3425     Floating::WithinRelMatcher WithinRel(float target, float eps);
   3426     // defaults epsilon to 100*numeric_limits<float>::epsilon()
   3427     Floating::WithinRelMatcher WithinRel(float target);
   3428 
   3429 } // namespace Matchers
   3430 } // namespace Catch
   3431 
   3432 // end catch_matchers_floating.h
   3433 // start catch_matchers_generic.hpp
   3434 
   3435 #include <functional>
   3436 #include <string>
   3437 
   3438 namespace Catch {
   3439 namespace Matchers {
   3440 namespace Generic {
   3441 
   3442 namespace Detail {
   3443     std::string finalizeDescription(const std::string& desc);
   3444 }
   3445 
   3446 template <typename T>
   3447 class PredicateMatcher : public MatcherBase<T> {
   3448     std::function<bool(T const&)> m_predicate;
   3449     std::string m_description;
   3450 public:
   3451 
   3452     PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
   3453         :m_predicate(std::move(elem)),
   3454         m_description(Detail::finalizeDescription(descr))
   3455     {}
   3456 
   3457     bool match( T const& item ) const override {
   3458         return m_predicate(item);
   3459     }
   3460 
   3461     std::string describe() const override {
   3462         return m_description;
   3463     }
   3464 };
   3465 
   3466 } // namespace Generic
   3467 
   3468     // The following functions create the actual matcher objects.
   3469     // The user has to explicitly specify type to the function, because
   3470     // inferring std::function<bool(T const&)> is hard (but possible) and
   3471     // requires a lot of TMP.
   3472     template<typename T>
   3473     Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
   3474         return Generic::PredicateMatcher<T>(predicate, description);
   3475     }
   3476 
   3477 } // namespace Matchers
   3478 } // namespace Catch
   3479 
   3480 // end catch_matchers_generic.hpp
   3481 // start catch_matchers_string.h
   3482 
   3483 #include <string>
   3484 
   3485 namespace Catch {
   3486 namespace Matchers {
   3487 
   3488     namespace StdString {
   3489 
   3490         struct CasedString
   3491         {
   3492             CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
   3493             std::string adjustString( std::string const& str ) const;
   3494             std::string caseSensitivitySuffix() const;
   3495 
   3496             CaseSensitive::Choice m_caseSensitivity;
   3497             std::string m_str;
   3498         };
   3499 
   3500         struct StringMatcherBase : MatcherBase<std::string> {
   3501             StringMatcherBase( std::string const& operation, CasedString const& comparator );
   3502             std::string describe() const override;
   3503 
   3504             CasedString m_comparator;
   3505             std::string m_operation;
   3506         };
   3507 
   3508         struct EqualsMatcher : StringMatcherBase {
   3509             EqualsMatcher( CasedString const& comparator );
   3510             bool match( std::string const& source ) const override;
   3511         };
   3512         struct ContainsMatcher : StringMatcherBase {
   3513             ContainsMatcher( CasedString const& comparator );
   3514             bool match( std::string const& source ) const override;
   3515         };
   3516         struct StartsWithMatcher : StringMatcherBase {
   3517             StartsWithMatcher( CasedString const& comparator );
   3518             bool match( std::string const& source ) const override;
   3519         };
   3520         struct EndsWithMatcher : StringMatcherBase {
   3521             EndsWithMatcher( CasedString const& comparator );
   3522             bool match( std::string const& source ) const override;
   3523         };
   3524 
   3525         struct RegexMatcher : MatcherBase<std::string> {
   3526             RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
   3527             bool match( std::string const& matchee ) const override;
   3528             std::string describe() const override;
   3529 
   3530         private:
   3531             std::string m_regex;
   3532             CaseSensitive::Choice m_caseSensitivity;
   3533         };
   3534 
   3535     } // namespace StdString
   3536 
   3537     // The following functions create the actual matcher objects.
   3538     // This allows the types to be inferred
   3539 
   3540     StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
   3541     StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
   3542     StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
   3543     StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
   3544     StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
   3545 
   3546 } // namespace Matchers
   3547 } // namespace Catch
   3548 
   3549 // end catch_matchers_string.h
   3550 // start catch_matchers_vector.h
   3551 
   3552 #include <algorithm>
   3553 
   3554 namespace Catch {
   3555 namespace Matchers {
   3556 
   3557     namespace Vector {
   3558         template<typename T>
   3559         struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
   3560 
   3561             ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
   3562 
   3563             bool match(std::vector<T> const &v) const override {
   3564                 for (auto const& el : v) {
   3565                     if (el == m_comparator) {
   3566                         return true;
   3567                     }
   3568                 }
   3569                 return false;
   3570             }
   3571 
   3572             std::string describe() const override {
   3573                 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
   3574             }
   3575 
   3576             T const& m_comparator;
   3577         };
   3578 
   3579         template<typename T>
   3580         struct ContainsMatcher : MatcherBase<std::vector<T>> {
   3581 
   3582             ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
   3583 
   3584             bool match(std::vector<T> const &v) const override {
   3585                 // !TBD: see note in EqualsMatcher
   3586                 if (m_comparator.size() > v.size())
   3587                     return false;
   3588                 for (auto const& comparator : m_comparator) {
   3589                     auto present = false;
   3590                     for (const auto& el : v) {
   3591                         if (el == comparator) {
   3592                             present = true;
   3593                             break;
   3594                         }
   3595                     }
   3596                     if (!present) {
   3597                         return false;
   3598                     }
   3599                 }
   3600                 return true;
   3601             }
   3602             std::string describe() const override {
   3603                 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
   3604             }
   3605 
   3606             std::vector<T> const& m_comparator;
   3607         };
   3608 
   3609         template<typename T>
   3610         struct EqualsMatcher : MatcherBase<std::vector<T>> {
   3611 
   3612             EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
   3613 
   3614             bool match(std::vector<T> const &v) const override {
   3615                 // !TBD: This currently works if all elements can be compared using !=
   3616                 // - a more general approach would be via a compare template that defaults
   3617                 // to using !=. but could be specialised for, e.g. std::vector<T> etc
   3618                 // - then just call that directly
   3619                 if (m_comparator.size() != v.size())
   3620                     return false;
   3621                 for (std::size_t i = 0; i < v.size(); ++i)
   3622                     if (m_comparator[i] != v[i])
   3623                         return false;
   3624                 return true;
   3625             }
   3626             std::string describe() const override {
   3627                 return "Equals: " + ::Catch::Detail::stringify( m_comparator );
   3628             }
   3629             std::vector<T> const& m_comparator;
   3630         };
   3631 
   3632         template<typename T>
   3633         struct ApproxMatcher : MatcherBase<std::vector<T>> {
   3634 
   3635             ApproxMatcher(std::vector<T> const& comparator) : m_comparator( comparator ) {}
   3636 
   3637             bool match(std::vector<T> const &v) const override {
   3638                 if (m_comparator.size() != v.size())
   3639                     return false;
   3640                 for (std::size_t i = 0; i < v.size(); ++i)
   3641                     if (m_comparator[i] != approx(v[i]))
   3642                         return false;
   3643                 return true;
   3644             }
   3645             std::string describe() const override {
   3646                 return "is approx: " + ::Catch::Detail::stringify( m_comparator );
   3647             }
   3648             template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3649             ApproxMatcher& epsilon( T const& newEpsilon ) {
   3650                 approx.epsilon(newEpsilon);
   3651                 return *this;
   3652             }
   3653             template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3654             ApproxMatcher& margin( T const& newMargin ) {
   3655                 approx.margin(newMargin);
   3656                 return *this;
   3657             }
   3658             template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
   3659             ApproxMatcher& scale( T const& newScale ) {
   3660                 approx.scale(newScale);
   3661                 return *this;
   3662             }
   3663 
   3664             std::vector<T> const& m_comparator;
   3665             mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
   3666         };
   3667 
   3668         template<typename T>
   3669         struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
   3670             UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
   3671             bool match(std::vector<T> const& vec) const override {
   3672                 // Note: This is a reimplementation of std::is_permutation,
   3673                 //       because I don't want to include <algorithm> inside the common path
   3674                 if (m_target.size() != vec.size()) {
   3675                     return false;
   3676                 }
   3677                 return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
   3678             }
   3679 
   3680             std::string describe() const override {
   3681                 return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
   3682             }
   3683         private:
   3684             std::vector<T> const& m_target;
   3685         };
   3686 
   3687     } // namespace Vector
   3688 
   3689     // The following functions create the actual matcher objects.
   3690     // This allows the types to be inferred
   3691 
   3692     template<typename T>
   3693     Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
   3694         return Vector::ContainsMatcher<T>( comparator );
   3695     }
   3696 
   3697     template<typename T>
   3698     Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
   3699         return Vector::ContainsElementMatcher<T>( comparator );
   3700     }
   3701 
   3702     template<typename T>
   3703     Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
   3704         return Vector::EqualsMatcher<T>( comparator );
   3705     }
   3706 
   3707     template<typename T>
   3708     Vector::ApproxMatcher<T> Approx( std::vector<T> const& comparator ) {
   3709         return Vector::ApproxMatcher<T>( comparator );
   3710     }
   3711 
   3712     template<typename T>
   3713     Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
   3714         return Vector::UnorderedEqualsMatcher<T>(target);
   3715     }
   3716 
   3717 } // namespace Matchers
   3718 } // namespace Catch
   3719 
   3720 // end catch_matchers_vector.h
   3721 namespace Catch {
   3722 
   3723     template<typename ArgT, typename MatcherT>
   3724     class MatchExpr : public ITransientExpression {
   3725         ArgT const& m_arg;
   3726         MatcherT m_matcher;
   3727         StringRef m_matcherString;
   3728     public:
   3729         MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
   3730         :   ITransientExpression{ true, matcher.match( arg ) },
   3731             m_arg( arg ),
   3732             m_matcher( matcher ),
   3733             m_matcherString( matcherString )
   3734         {}
   3735 
   3736         void streamReconstructedExpression( std::ostream &os ) const override {
   3737             auto matcherAsString = m_matcher.toString();
   3738             os << Catch::Detail::stringify( m_arg ) << ' ';
   3739             if( matcherAsString == Detail::unprintableString )
   3740                 os << m_matcherString;
   3741             else
   3742                 os << matcherAsString;
   3743         }
   3744     };
   3745 
   3746     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
   3747 
   3748     void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );
   3749 
   3750     template<typename ArgT, typename MatcherT>
   3751     auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {
   3752         return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
   3753     }
   3754 
   3755 } // namespace Catch
   3756 
   3757 ///////////////////////////////////////////////////////////////////////////////
   3758 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
   3759     do { \
   3760         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
   3761         INTERNAL_CATCH_TRY { \
   3762             catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
   3763         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
   3764         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   3765     } while( false )
   3766 
   3767 ///////////////////////////////////////////////////////////////////////////////
   3768 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
   3769     do { \
   3770         Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
   3771         if( catchAssertionHandler.allowThrows() ) \
   3772             try { \
   3773                 static_cast<void>(__VA_ARGS__ ); \
   3774                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
   3775             } \
   3776             catch( exceptionType const& ex ) { \
   3777                 catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
   3778             } \
   3779             catch( ... ) { \
   3780                 catchAssertionHandler.handleUnexpectedInflightException(); \
   3781             } \
   3782         else \
   3783             catchAssertionHandler.handleThrowingCallSkipped(); \
   3784         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
   3785     } while( false )
   3786 
   3787 // end catch_capture_matchers.h
   3788 #endif
   3789 // start catch_generators.hpp
   3790 
   3791 // start catch_interfaces_generatortracker.h
   3792 
   3793 
   3794 #include <memory>
   3795 
   3796 namespace Catch {
   3797 
   3798     namespace Generators {
   3799         class GeneratorUntypedBase {
   3800         public:
   3801             GeneratorUntypedBase() = default;
   3802             virtual ~GeneratorUntypedBase();
   3803             // Attempts to move the generator to the next element
   3804              //
   3805              // Returns true iff the move succeeded (and a valid element
   3806              // can be retrieved).
   3807             virtual bool next() = 0;
   3808         };
   3809         using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
   3810 
   3811     } // namespace Generators
   3812 
   3813     struct IGeneratorTracker {
   3814         virtual ~IGeneratorTracker();
   3815         virtual auto hasGenerator() const -> bool = 0;
   3816         virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
   3817         virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
   3818     };
   3819 
   3820 } // namespace Catch
   3821 
   3822 // end catch_interfaces_generatortracker.h
   3823 // start catch_enforce.h
   3824 
   3825 #include <exception>
   3826 
   3827 namespace Catch {
   3828 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
   3829     template <typename Ex>
   3830     [[noreturn]]
   3831     void throw_exception(Ex const& e) {
   3832         throw e;
   3833     }
   3834 #else // ^^ Exceptions are enabled //  Exceptions are disabled vv
   3835     [[noreturn]]
   3836     void throw_exception(std::exception const& e);
   3837 #endif
   3838 
   3839     [[noreturn]]
   3840     void throw_logic_error(std::string const& msg);
   3841     [[noreturn]]
   3842     void throw_domain_error(std::string const& msg);
   3843     [[noreturn]]
   3844     void throw_runtime_error(std::string const& msg);
   3845 
   3846 } // namespace Catch;
   3847 
   3848 #define CATCH_MAKE_MSG(...) \
   3849     (Catch::ReusableStringStream() << __VA_ARGS__).str()
   3850 
   3851 #define CATCH_INTERNAL_ERROR(...) \
   3852     Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
   3853 
   3854 #define CATCH_ERROR(...) \
   3855     Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
   3856 
   3857 #define CATCH_RUNTIME_ERROR(...) \
   3858     Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
   3859 
   3860 #define CATCH_ENFORCE( condition, ... ) \
   3861     do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
   3862 
   3863 // end catch_enforce.h
   3864 #include <memory>
   3865 #include <vector>
   3866 #include <cassert>
   3867 
   3868 #include <utility>
   3869 #include <exception>
   3870 
   3871 namespace Catch {
   3872 
   3873 class GeneratorException : public std::exception {
   3874     const char* const m_msg = "";
   3875 
   3876 public:
   3877     GeneratorException(const char* msg):
   3878         m_msg(msg)
   3879     {}
   3880 
   3881     const char* what() const noexcept override final;
   3882 };
   3883 
   3884 namespace Generators {
   3885 
   3886     // !TBD move this into its own location?
   3887     namespace pf{
   3888         template<typename T, typename... Args>
   3889         std::unique_ptr<T> make_unique( Args&&... args ) {
   3890             return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
   3891         }
   3892     }
   3893 
   3894     template<typename T>
   3895     struct IGenerator : GeneratorUntypedBase {
   3896         virtual ~IGenerator() = default;
   3897 
   3898         // Returns the current element of the generator
   3899         //
   3900         // \Precondition The generator is either freshly constructed,
   3901         // or the last call to `next()` returned true
   3902         virtual T const& get() const = 0;
   3903         using type = T;
   3904     };
   3905 
   3906     template<typename T>
   3907     class SingleValueGenerator final : public IGenerator<T> {
   3908         T m_value;
   3909     public:
   3910         SingleValueGenerator(T const& value) : m_value( value ) {}
   3911         SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
   3912 
   3913         T const& get() const override {
   3914             return m_value;
   3915         }
   3916         bool next() override {
   3917             return false;
   3918         }
   3919     };
   3920 
   3921     template<typename T>
   3922     class FixedValuesGenerator final : public IGenerator<T> {
   3923         static_assert(!std::is_same<T, bool>::value,
   3924             "FixedValuesGenerator does not support bools because of std::vector<bool>"
   3925             "specialization, use SingleValue Generator instead.");
   3926         std::vector<T> m_values;
   3927         size_t m_idx = 0;
   3928     public:
   3929         FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
   3930 
   3931         T const& get() const override {
   3932             return m_values[m_idx];
   3933         }
   3934         bool next() override {
   3935             ++m_idx;
   3936             return m_idx < m_values.size();
   3937         }
   3938     };
   3939 
   3940     template <typename T>
   3941     class GeneratorWrapper final {
   3942         std::unique_ptr<IGenerator<T>> m_generator;
   3943     public:
   3944         GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
   3945             m_generator(std::move(generator))
   3946         {}
   3947         T const& get() const {
   3948             return m_generator->get();
   3949         }
   3950         bool next() {
   3951             return m_generator->next();
   3952         }
   3953     };
   3954 
   3955     template <typename T>
   3956     GeneratorWrapper<T> value(T&& value) {
   3957         return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
   3958     }
   3959     template <typename T>
   3960     GeneratorWrapper<T> values(std::initializer_list<T> values) {
   3961         return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
   3962     }
   3963 
   3964     template<typename T>
   3965     class Generators : public IGenerator<T> {
   3966         std::vector<GeneratorWrapper<T>> m_generators;
   3967         size_t m_current = 0;
   3968 
   3969         void populate(GeneratorWrapper<T>&& generator) {
   3970             m_generators.emplace_back(std::move(generator));
   3971         }
   3972         void populate(T&& val) {
   3973             m_generators.emplace_back(value(std::move(val)));
   3974         }
   3975         template<typename U>
   3976         void populate(U&& val) {
   3977             populate(T(std::move(val)));
   3978         }
   3979         template<typename U, typename... Gs>
   3980         void populate(U&& valueOrGenerator, Gs... moreGenerators) {
   3981             populate(std::forward<U>(valueOrGenerator));
   3982             populate(std::forward<Gs>(moreGenerators)...);
   3983         }
   3984 
   3985     public:
   3986         template <typename... Gs>
   3987         Generators(Gs... moreGenerators) {
   3988             m_generators.reserve(sizeof...(Gs));
   3989             populate(std::forward<Gs>(moreGenerators)...);
   3990         }
   3991 
   3992         T const& get() const override {
   3993             return m_generators[m_current].get();
   3994         }
   3995 
   3996         bool next() override {
   3997             if (m_current >= m_generators.size()) {
   3998                 return false;
   3999             }
   4000             const bool current_status = m_generators[m_current].next();
   4001             if (!current_status) {
   4002                 ++m_current;
   4003             }
   4004             return m_current < m_generators.size();
   4005         }
   4006     };
   4007 
   4008     template<typename... Ts>
   4009     GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {
   4010         return values<std::tuple<Ts...>>( tuples );
   4011     }
   4012 
   4013     // Tag type to signal that a generator sequence should convert arguments to a specific type
   4014     template <typename T>
   4015     struct as {};
   4016 
   4017     template<typename T, typename... Gs>
   4018     auto makeGenerators( GeneratorWrapper<T>&& generator, Gs... moreGenerators ) -> Generators<T> {
   4019         return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
   4020     }
   4021     template<typename T>
   4022     auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {
   4023         return Generators<T>(std::move(generator));
   4024     }
   4025     template<typename T, typename... Gs>
   4026     auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> {
   4027         return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
   4028     }
   4029     template<typename T, typename U, typename... Gs>
   4030     auto makeGenerators( as<T>, U&& val, Gs... moreGenerators ) -> Generators<T> {
   4031         return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
   4032     }
   4033 
   4034     auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
   4035 
   4036     template<typename L>
   4037     // Note: The type after -> is weird, because VS2015 cannot parse
   4038     //       the expression used in the typedef inside, when it is in
   4039     //       return type. Yeah.
   4040     auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
   4041         using UnderlyingType = typename decltype(generatorExpression())::type;
   4042 
   4043         IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
   4044         if (!tracker.hasGenerator()) {
   4045             tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
   4046         }
   4047 
   4048         auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
   4049         return generator.get();
   4050     }
   4051 
   4052 } // namespace Generators
   4053 } // namespace Catch
   4054 
   4055 #define GENERATE( ... ) \
   4056     Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
   4057 #define GENERATE_COPY( ... ) \
   4058     Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
   4059 #define GENERATE_REF( ... ) \
   4060     Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
   4061 
   4062 // end catch_generators.hpp
   4063 // start catch_generators_generic.hpp
   4064 
   4065 namespace Catch {
   4066 namespace Generators {
   4067 
   4068     template <typename T>
   4069     class TakeGenerator : public IGenerator<T> {
   4070         GeneratorWrapper<T> m_generator;
   4071         size_t m_returned = 0;
   4072         size_t m_target;
   4073     public:
   4074         TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
   4075             m_generator(std::move(generator)),
   4076             m_target(target)
   4077         {
   4078             assert(target != 0 && "Empty generators are not allowed");
   4079         }
   4080         T const& get() const override {
   4081             return m_generator.get();
   4082         }
   4083         bool next() override {
   4084             ++m_returned;
   4085             if (m_returned >= m_target) {
   4086                 return false;
   4087             }
   4088 
   4089             const auto success = m_generator.next();
   4090             // If the underlying generator does not contain enough values
   4091             // then we cut short as well
   4092             if (!success) {
   4093                 m_returned = m_target;
   4094             }
   4095             return success;
   4096         }
   4097     };
   4098 
   4099     template <typename T>
   4100     GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
   4101         return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
   4102     }
   4103 
   4104     template <typename T, typename Predicate>
   4105     class FilterGenerator : public IGenerator<T> {
   4106         GeneratorWrapper<T> m_generator;
   4107         Predicate m_predicate;
   4108     public:
   4109         template <typename P = Predicate>
   4110         FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
   4111             m_generator(std::move(generator)),
   4112             m_predicate(std::forward<P>(pred))
   4113         {
   4114             if (!m_predicate(m_generator.get())) {
   4115                 // It might happen that there are no values that pass the
   4116                 // filter. In that case we throw an exception.
   4117                 auto has_initial_value = next();
   4118                 if (!has_initial_value) {
   4119                     Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
   4120                 }
   4121             }
   4122         }
   4123 
   4124         T const& get() const override {
   4125             return m_generator.get();
   4126         }
   4127 
   4128         bool next() override {
   4129             bool success = m_generator.next();
   4130             if (!success) {
   4131                 return false;
   4132             }
   4133             while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
   4134             return success;
   4135         }
   4136     };
   4137 
   4138     template <typename T, typename Predicate>
   4139     GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
   4140         return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
   4141     }
   4142 
   4143     template <typename T>
   4144     class RepeatGenerator : public IGenerator<T> {
   4145         static_assert(!std::is_same<T, bool>::value,
   4146             "RepeatGenerator currently does not support bools"
   4147             "because of std::vector<bool> specialization");
   4148         GeneratorWrapper<T> m_generator;
   4149         mutable std::vector<T> m_returned;
   4150         size_t m_target_repeats;
   4151         size_t m_current_repeat = 0;
   4152         size_t m_repeat_index = 0;
   4153     public:
   4154         RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
   4155             m_generator(std::move(generator)),
   4156             m_target_repeats(repeats)
   4157         {
   4158             assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
   4159         }
   4160 
   4161         T const& get() const override {
   4162             if (m_current_repeat == 0) {
   4163                 m_returned.push_back(m_generator.get());
   4164                 return m_returned.back();
   4165             }
   4166             return m_returned[m_repeat_index];
   4167         }
   4168 
   4169         bool next() override {
   4170             // There are 2 basic cases:
   4171             // 1) We are still reading the generator
   4172             // 2) We are reading our own cache
   4173 
   4174             // In the first case, we need to poke the underlying generator.
   4175             // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
   4176             if (m_current_repeat == 0) {
   4177                 const auto success = m_generator.next();
   4178                 if (!success) {
   4179                     ++m_current_repeat;
   4180                 }
   4181                 return m_current_repeat < m_target_repeats;
   4182             }
   4183 
   4184             // In the second case, we need to move indices forward and check that we haven't run up against the end
   4185             ++m_repeat_index;
   4186             if (m_repeat_index == m_returned.size()) {
   4187                 m_repeat_index = 0;
   4188                 ++m_current_repeat;
   4189             }
   4190             return m_current_repeat < m_target_repeats;
   4191         }
   4192     };
   4193 
   4194     template <typename T>
   4195     GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
   4196         return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
   4197     }
   4198 
   4199     template <typename T, typename U, typename Func>
   4200     class MapGenerator : public IGenerator<T> {
   4201         // TBD: provide static assert for mapping function, for friendly error message
   4202         GeneratorWrapper<U> m_generator;
   4203         Func m_function;
   4204         // To avoid returning dangling reference, we have to save the values
   4205         T m_cache;
   4206     public:
   4207         template <typename F2 = Func>
   4208         MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
   4209             m_generator(std::move(generator)),
   4210             m_function(std::forward<F2>(function)),
   4211             m_cache(m_function(m_generator.get()))
   4212         {}
   4213 
   4214         T const& get() const override {
   4215             return m_cache;
   4216         }
   4217         bool next() override {
   4218             const auto success = m_generator.next();
   4219             if (success) {
   4220                 m_cache = m_function(m_generator.get());
   4221             }
   4222             return success;
   4223         }
   4224     };
   4225 
   4226     template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
   4227     GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
   4228         return GeneratorWrapper<T>(
   4229             pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
   4230         );
   4231     }
   4232 
   4233     template <typename T, typename U, typename Func>
   4234     GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
   4235         return GeneratorWrapper<T>(
   4236             pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
   4237         );
   4238     }
   4239 
   4240     template <typename T>
   4241     class ChunkGenerator final : public IGenerator<std::vector<T>> {
   4242         std::vector<T> m_chunk;
   4243         size_t m_chunk_size;
   4244         GeneratorWrapper<T> m_generator;
   4245         bool m_used_up = false;
   4246     public:
   4247         ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
   4248             m_chunk_size(size), m_generator(std::move(generator))
   4249         {
   4250             m_chunk.reserve(m_chunk_size);
   4251             if (m_chunk_size != 0) {
   4252                 m_chunk.push_back(m_generator.get());
   4253                 for (size_t i = 1; i < m_chunk_size; ++i) {
   4254                     if (!m_generator.next()) {
   4255                         Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
   4256                     }
   4257                     m_chunk.push_back(m_generator.get());
   4258                 }
   4259             }
   4260         }
   4261         std::vector<T> const& get() const override {
   4262             return m_chunk;
   4263         }
   4264         bool next() override {
   4265             m_chunk.clear();
   4266             for (size_t idx = 0; idx < m_chunk_size; ++idx) {
   4267                 if (!m_generator.next()) {
   4268                     return false;
   4269                 }
   4270                 m_chunk.push_back(m_generator.get());
   4271             }
   4272             return true;
   4273         }
   4274     };
   4275 
   4276     template <typename T>
   4277     GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {
   4278         return GeneratorWrapper<std::vector<T>>(
   4279             pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
   4280         );
   4281     }
   4282 
   4283 } // namespace Generators
   4284 } // namespace Catch
   4285 
   4286 // end catch_generators_generic.hpp
   4287 // start catch_generators_specific.hpp
   4288 
   4289 // start catch_context.h
   4290 
   4291 #include <memory>
   4292 
   4293 namespace Catch {
   4294 
   4295     struct IResultCapture;
   4296     struct IRunner;
   4297     struct IConfig;
   4298     struct IMutableContext;
   4299 
   4300     using IConfigPtr = std::shared_ptr<IConfig const>;
   4301 
   4302     struct IContext
   4303     {
   4304         virtual ~IContext();
   4305 
   4306         virtual IResultCapture* getResultCapture() = 0;
   4307         virtual IRunner* getRunner() = 0;
   4308         virtual IConfigPtr const& getConfig() const = 0;
   4309     };
   4310 
   4311     struct IMutableContext : IContext
   4312     {
   4313         virtual ~IMutableContext();
   4314         virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
   4315         virtual void setRunner( IRunner* runner ) = 0;
   4316         virtual void setConfig( IConfigPtr const& config ) = 0;
   4317 
   4318     private:
   4319         static IMutableContext *currentContext;
   4320         friend IMutableContext& getCurrentMutableContext();
   4321         friend void cleanUpContext();
   4322         static void createContext();
   4323     };
   4324 
   4325     inline IMutableContext& getCurrentMutableContext()
   4326     {
   4327         if( !IMutableContext::currentContext )
   4328             IMutableContext::createContext();
   4329         // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
   4330         return *IMutableContext::currentContext;
   4331     }
   4332 
   4333     inline IContext& getCurrentContext()
   4334     {
   4335         return getCurrentMutableContext();
   4336     }
   4337 
   4338     void cleanUpContext();
   4339 
   4340     class SimplePcg32;
   4341     SimplePcg32& rng();
   4342 }
   4343 
   4344 // end catch_context.h
   4345 // start catch_interfaces_config.h
   4346 
   4347 // start catch_option.hpp
   4348 
   4349 namespace Catch {
   4350 
   4351     // An optional type
   4352     template<typename T>
   4353     class Option {
   4354     public:
   4355         Option() : nullableValue( nullptr ) {}
   4356         Option( T const& _value )
   4357         : nullableValue( new( storage ) T( _value ) )
   4358         {}
   4359         Option( Option const& _other )
   4360         : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
   4361         {}
   4362 
   4363         ~Option() {
   4364             reset();
   4365         }
   4366 
   4367         Option& operator= ( Option const& _other ) {
   4368             if( &_other != this ) {
   4369                 reset();
   4370                 if( _other )
   4371                     nullableValue = new( storage ) T( *_other );
   4372             }
   4373             return *this;
   4374         }
   4375         Option& operator = ( T const& _value ) {
   4376             reset();
   4377             nullableValue = new( storage ) T( _value );
   4378             return *this;
   4379         }
   4380 
   4381         void reset() {
   4382             if( nullableValue )
   4383                 nullableValue->~T();
   4384             nullableValue = nullptr;
   4385         }
   4386 
   4387         T& operator*() { return *nullableValue; }
   4388         T const& operator*() const { return *nullableValue; }
   4389         T* operator->() { return nullableValue; }
   4390         const T* operator->() const { return nullableValue; }
   4391 
   4392         T valueOr( T const& defaultValue ) const {
   4393             return nullableValue ? *nullableValue : defaultValue;
   4394         }
   4395 
   4396         bool some() const { return nullableValue != nullptr; }
   4397         bool none() const { return nullableValue == nullptr; }
   4398 
   4399         bool operator !() const { return nullableValue == nullptr; }
   4400         explicit operator bool() const {
   4401             return some();
   4402         }
   4403 
   4404     private:
   4405         T *nullableValue;
   4406         alignas(alignof(T)) char storage[sizeof(T)];
   4407     };
   4408 
   4409 } // end namespace Catch
   4410 
   4411 // end catch_option.hpp
   4412 #include <iosfwd>
   4413 #include <string>
   4414 #include <vector>
   4415 #include <memory>
   4416 
   4417 namespace Catch {
   4418 
   4419     enum class Verbosity {
   4420         Quiet = 0,
   4421         Normal,
   4422         High
   4423     };
   4424 
   4425     struct WarnAbout { enum What {
   4426         Nothing = 0x00,
   4427         NoAssertions = 0x01,
   4428         NoTests = 0x02
   4429     }; };
   4430 
   4431     struct ShowDurations { enum OrNot {
   4432         DefaultForReporter,
   4433         Always,
   4434         Never
   4435     }; };
   4436     struct RunTests { enum InWhatOrder {
   4437         InDeclarationOrder,
   4438         InLexicographicalOrder,
   4439         InRandomOrder
   4440     }; };
   4441     struct UseColour { enum YesOrNo {
   4442         Auto,
   4443         Yes,
   4444         No
   4445     }; };
   4446     struct WaitForKeypress { enum When {
   4447         Never,
   4448         BeforeStart = 1,
   4449         BeforeExit = 2,
   4450         BeforeStartAndExit = BeforeStart | BeforeExit
   4451     }; };
   4452 
   4453     class TestSpec;
   4454 
   4455     struct IConfig : NonCopyable {
   4456 
   4457         virtual ~IConfig();
   4458 
   4459         virtual bool allowThrows() const = 0;
   4460         virtual std::ostream& stream() const = 0;
   4461         virtual std::string name() const = 0;
   4462         virtual bool includeSuccessfulResults() const = 0;
   4463         virtual bool shouldDebugBreak() const = 0;
   4464         virtual bool warnAboutMissingAssertions() const = 0;
   4465         virtual bool warnAboutNoTests() const = 0;
   4466         virtual int abortAfter() const = 0;
   4467         virtual bool showInvisibles() const = 0;
   4468         virtual ShowDurations::OrNot showDurations() const = 0;
   4469         virtual TestSpec const& testSpec() const = 0;
   4470         virtual bool hasTestFilters() const = 0;
   4471         virtual std::vector<std::string> const& getTestsOrTags() const = 0;
   4472         virtual RunTests::InWhatOrder runOrder() const = 0;
   4473         virtual unsigned int rngSeed() const = 0;
   4474         virtual UseColour::YesOrNo useColour() const = 0;
   4475         virtual std::vector<std::string> const& getSectionsToRun() const = 0;
   4476         virtual Verbosity verbosity() const = 0;
   4477 
   4478         virtual bool benchmarkNoAnalysis() const = 0;
   4479         virtual int benchmarkSamples() const = 0;
   4480         virtual double benchmarkConfidenceInterval() const = 0;
   4481         virtual unsigned int benchmarkResamples() const = 0;
   4482     };
   4483 
   4484     using IConfigPtr = std::shared_ptr<IConfig const>;
   4485 }
   4486 
   4487 // end catch_interfaces_config.h
   4488 // start catch_random_number_generator.h
   4489 
   4490 #include <cstdint>
   4491 
   4492 namespace Catch {
   4493 
   4494     // This is a simple implementation of C++11 Uniform Random Number
   4495     // Generator. It does not provide all operators, because Catch2
   4496     // does not use it, but it should behave as expected inside stdlib's
   4497     // distributions.
   4498     // The implementation is based on the PCG family (http://pcg-random.org)
   4499     class SimplePcg32 {
   4500         using state_type = std::uint64_t;
   4501     public:
   4502         using result_type = std::uint32_t;
   4503         static constexpr result_type (min)() {
   4504             return 0;
   4505         }
   4506         static constexpr result_type (max)() {
   4507             return static_cast<result_type>(-1);
   4508         }
   4509 
   4510         // Provide some default initial state for the default constructor
   4511         SimplePcg32():SimplePcg32(0xed743cc4U) {}
   4512 
   4513         explicit SimplePcg32(result_type seed_);
   4514 
   4515         void seed(result_type seed_);
   4516         void discard(uint64_t skip);
   4517 
   4518         result_type operator()();
   4519 
   4520     private:
   4521         friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
   4522         friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
   4523 
   4524         // In theory we also need operator<< and operator>>
   4525         // In practice we do not use them, so we will skip them for now
   4526 
   4527         std::uint64_t m_state;
   4528         // This part of the state determines which "stream" of the numbers
   4529         // is chosen -- we take it as a constant for Catch2, so we only
   4530         // need to deal with seeding the main state.
   4531         // Picked by reading 8 bytes from `/dev/random` :-)
   4532         static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
   4533     };
   4534 
   4535 } // end namespace Catch
   4536 
   4537 // end catch_random_number_generator.h
   4538 #include <random>
   4539 
   4540 namespace Catch {
   4541 namespace Generators {
   4542 
   4543 template <typename Float>
   4544 class RandomFloatingGenerator final : public IGenerator<Float> {
   4545     Catch::SimplePcg32& m_rng;
   4546     std::uniform_real_distribution<Float> m_dist;
   4547     Float m_current_number;
   4548 public:
   4549 
   4550     RandomFloatingGenerator(Float a, Float b):
   4551         m_rng(rng()),
   4552         m_dist(a, b) {
   4553         static_cast<void>(next());
   4554     }
   4555 
   4556     Float const& get() const override {
   4557         return m_current_number;
   4558     }
   4559     bool next() override {
   4560         m_current_number = m_dist(m_rng);
   4561         return true;
   4562     }
   4563 };
   4564 
   4565 template <typename Integer>
   4566 class RandomIntegerGenerator final : public IGenerator<Integer> {
   4567     Catch::SimplePcg32& m_rng;
   4568     std::uniform_int_distribution<Integer> m_dist;
   4569     Integer m_current_number;
   4570 public:
   4571 
   4572     RandomIntegerGenerator(Integer a, Integer b):
   4573         m_rng(rng()),
   4574         m_dist(a, b) {
   4575         static_cast<void>(next());
   4576     }
   4577 
   4578     Integer const& get() const override {
   4579         return m_current_number;
   4580     }
   4581     bool next() override {
   4582         m_current_number = m_dist(m_rng);
   4583         return true;
   4584     }
   4585 };
   4586 
   4587 // TODO: Ideally this would be also constrained against the various char types,
   4588 //       but I don't expect users to run into that in practice.
   4589 template <typename T>
   4590 typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
   4591 GeneratorWrapper<T>>::type
   4592 random(T a, T b) {
   4593     return GeneratorWrapper<T>(
   4594         pf::make_unique<RandomIntegerGenerator<T>>(a, b)
   4595     );
   4596 }
   4597 
   4598 template <typename T>
   4599 typename std::enable_if<std::is_floating_point<T>::value,
   4600 GeneratorWrapper<T>>::type
   4601 random(T a, T b) {
   4602     return GeneratorWrapper<T>(
   4603         pf::make_unique<RandomFloatingGenerator<T>>(a, b)
   4604     );
   4605 }
   4606 
   4607 template <typename T>
   4608 class RangeGenerator final : public IGenerator<T> {
   4609     T m_current;
   4610     T m_end;
   4611     T m_step;
   4612     bool m_positive;
   4613 
   4614 public:
   4615     RangeGenerator(T const& start, T const& end, T const& step):
   4616         m_current(start),
   4617         m_end(end),
   4618         m_step(step),
   4619         m_positive(m_step > T(0))
   4620     {
   4621         assert(m_current != m_end && "Range start and end cannot be equal");
   4622         assert(m_step != T(0) && "Step size cannot be zero");
   4623         assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
   4624     }
   4625 
   4626     RangeGenerator(T const& start, T const& end):
   4627         RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
   4628     {}
   4629 
   4630     T const& get() const override {
   4631         return m_current;
   4632     }
   4633 
   4634     bool next() override {
   4635         m_current += m_step;
   4636         return (m_positive) ? (m_current < m_end) : (m_current > m_end);
   4637     }
   4638 };
   4639 
   4640 template <typename T>
   4641 GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
   4642     static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
   4643     return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
   4644 }
   4645 
   4646 template <typename T>
   4647 GeneratorWrapper<T> range(T const& start, T const& end) {
   4648     static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
   4649     return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
   4650 }
   4651 
   4652 template <typename T>
   4653 class IteratorGenerator final : public IGenerator<T> {
   4654     static_assert(!std::is_same<T, bool>::value,
   4655         "IteratorGenerator currently does not support bools"
   4656         "because of std::vector<bool> specialization");
   4657 
   4658     std::vector<T> m_elems;
   4659     size_t m_current = 0;
   4660 public:
   4661     template <typename InputIterator, typename InputSentinel>
   4662     IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
   4663         if (m_elems.empty()) {
   4664             Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
   4665         }
   4666     }
   4667 
   4668     T const& get() const override {
   4669         return m_elems[m_current];
   4670     }
   4671 
   4672     bool next() override {
   4673         ++m_current;
   4674         return m_current != m_elems.size();
   4675     }
   4676 };
   4677 
   4678 template <typename InputIterator,
   4679           typename InputSentinel,
   4680           typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
   4681 GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
   4682     return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
   4683 }
   4684 
   4685 template <typename Container,
   4686           typename ResultType = typename Container::value_type>
   4687 GeneratorWrapper<ResultType> from_range(Container const& cnt) {
   4688     return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
   4689 }
   4690 
   4691 } // namespace Generators
   4692 } // namespace Catch
   4693 
   4694 // end catch_generators_specific.hpp
   4695 
   4696 // These files are included here so the single_include script doesn't put them
   4697 // in the conditionally compiled sections
   4698 // start catch_test_case_info.h
   4699 
   4700 #include <string>
   4701 #include <vector>
   4702 #include <memory>
   4703 
   4704 #ifdef __clang__
   4705 #pragma clang diagnostic push
   4706 #pragma clang diagnostic ignored "-Wpadded"
   4707 #endif
   4708 
   4709 namespace Catch {
   4710 
   4711     struct ITestInvoker;
   4712 
   4713     struct TestCaseInfo {
   4714         enum SpecialProperties{
   4715             None = 0,
   4716             IsHidden = 1 << 1,
   4717             ShouldFail = 1 << 2,
   4718             MayFail = 1 << 3,
   4719             Throws = 1 << 4,
   4720             NonPortable = 1 << 5,
   4721             Benchmark = 1 << 6
   4722         };
   4723 
   4724         TestCaseInfo(   std::string const& _name,
   4725                         std::string const& _className,
   4726                         std::string const& _description,
   4727                         std::vector<std::string> const& _tags,
   4728                         SourceLineInfo const& _lineInfo );
   4729 
   4730         friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
   4731 
   4732         bool isHidden() const;
   4733         bool throws() const;
   4734         bool okToFail() const;
   4735         bool expectedToFail() const;
   4736 
   4737         std::string tagsAsString() const;
   4738 
   4739         std::string name;
   4740         std::string className;
   4741         std::string description;
   4742         std::vector<std::string> tags;
   4743         std::vector<std::string> lcaseTags;
   4744         SourceLineInfo lineInfo;
   4745         SpecialProperties properties;
   4746     };
   4747 
   4748     class TestCase : public TestCaseInfo {
   4749     public:
   4750 
   4751         TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
   4752 
   4753         TestCase withName( std::string const& _newName ) const;
   4754 
   4755         void invoke() const;
   4756 
   4757         TestCaseInfo const& getTestCaseInfo() const;
   4758 
   4759         bool operator == ( TestCase const& other ) const;
   4760         bool operator < ( TestCase const& other ) const;
   4761 
   4762     private:
   4763         std::shared_ptr<ITestInvoker> test;
   4764     };
   4765 
   4766     TestCase makeTestCase(  ITestInvoker* testCase,
   4767                             std::string const& className,
   4768                             NameAndTags const& nameAndTags,
   4769                             SourceLineInfo const& lineInfo );
   4770 }
   4771 
   4772 #ifdef __clang__
   4773 #pragma clang diagnostic pop
   4774 #endif
   4775 
   4776 // end catch_test_case_info.h
   4777 // start catch_interfaces_runner.h
   4778 
   4779 namespace Catch {
   4780 
   4781     struct IRunner {
   4782         virtual ~IRunner();
   4783         virtual bool aborting() const = 0;
   4784     };
   4785 }
   4786 
   4787 // end catch_interfaces_runner.h
   4788 
   4789 #ifdef __OBJC__
   4790 // start catch_objc.hpp
   4791 
   4792 #import <objc/runtime.h>
   4793 
   4794 #include <string>
   4795 
   4796 // NB. Any general catch headers included here must be included
   4797 // in catch.hpp first to make sure they are included by the single
   4798 // header for non obj-usage
   4799 
   4800 ///////////////////////////////////////////////////////////////////////////////
   4801 // This protocol is really only here for (self) documenting purposes, since
   4802 // all its methods are optional.
   4803 @protocol OcFixture
   4804 
   4805 @optional
   4806 
   4807 -(void) setUp;
   4808 -(void) tearDown;
   4809 
   4810 @end
   4811 
   4812 namespace Catch {
   4813 
   4814     class OcMethod : public ITestInvoker {
   4815 
   4816     public:
   4817         OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
   4818 
   4819         virtual void invoke() const {
   4820             id obj = [[m_cls alloc] init];
   4821 
   4822             performOptionalSelector( obj, @selector(setUp)  );
   4823             performOptionalSelector( obj, m_sel );
   4824             performOptionalSelector( obj, @selector(tearDown)  );
   4825 
   4826             arcSafeRelease( obj );
   4827         }
   4828     private:
   4829         virtual ~OcMethod() {}
   4830 
   4831         Class m_cls;
   4832         SEL m_sel;
   4833     };
   4834 
   4835     namespace Detail{
   4836 
   4837         inline std::string getAnnotation(   Class cls,
   4838                                             std::string const& annotationName,
   4839                                             std::string const& testCaseName ) {
   4840             NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
   4841             SEL sel = NSSelectorFromString( selStr );
   4842             arcSafeRelease( selStr );
   4843             id value = performOptionalSelector( cls, sel );
   4844             if( value )
   4845                 return [(NSString*)value UTF8String];
   4846             return "";
   4847         }
   4848     }
   4849 
   4850     inline std::size_t registerTestMethods() {
   4851         std::size_t noTestMethods = 0;
   4852         int noClasses = objc_getClassList( nullptr, 0 );
   4853 
   4854         Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
   4855         objc_getClassList( classes, noClasses );
   4856 
   4857         for( int c = 0; c < noClasses; c++ ) {
   4858             Class cls = classes[c];
   4859             {
   4860                 u_int count;
   4861                 Method* methods = class_copyMethodList( cls, &count );
   4862                 for( u_int m = 0; m < count ; m++ ) {
   4863                     SEL selector = method_getName(methods[m]);
   4864                     std::string methodName = sel_getName(selector);
   4865                     if( startsWith( methodName, "Catch_TestCase_" ) ) {
   4866                         std::string testCaseName = methodName.substr( 15 );
   4867                         std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
   4868                         std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
   4869                         const char* className = class_getName( cls );
   4870 
   4871                         getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
   4872                         noTestMethods++;
   4873                     }
   4874                 }
   4875                 free(methods);
   4876             }
   4877         }
   4878         return noTestMethods;
   4879     }
   4880 
   4881 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
   4882 
   4883     namespace Matchers {
   4884         namespace Impl {
   4885         namespace NSStringMatchers {
   4886 
   4887             struct StringHolder : MatcherBase<NSString*>{
   4888                 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
   4889                 StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
   4890                 StringHolder() {
   4891                     arcSafeRelease( m_substr );
   4892                 }
   4893 
   4894                 bool match( NSString* str ) const override {
   4895                     return false;
   4896                 }
   4897 
   4898                 NSString* CATCH_ARC_STRONG m_substr;
   4899             };
   4900 
   4901             struct Equals : StringHolder {
   4902                 Equals( NSString* substr ) : StringHolder( substr ){}
   4903 
   4904                 bool match( NSString* str ) const override {
   4905                     return  (str != nil || m_substr == nil ) &&
   4906                             [str isEqualToString:m_substr];
   4907                 }
   4908 
   4909                 std::string describe() const override {
   4910                     return "equals string: " + Catch::Detail::stringify( m_substr );
   4911                 }
   4912             };
   4913 
   4914             struct Contains : StringHolder {
   4915                 Contains( NSString* substr ) : StringHolder( substr ){}
   4916 
   4917                 bool match( NSString* str ) const override {
   4918                     return  (str != nil || m_substr == nil ) &&
   4919                             [str rangeOfString:m_substr].location != NSNotFound;
   4920                 }
   4921 
   4922                 std::string describe() const override {
   4923                     return "contains string: " + Catch::Detail::stringify( m_substr );
   4924                 }
   4925             };
   4926 
   4927             struct StartsWith : StringHolder {
   4928                 StartsWith( NSString* substr ) : StringHolder( substr ){}
   4929 
   4930                 bool match( NSString* str ) const override {
   4931                     return  (str != nil || m_substr == nil ) &&
   4932                             [str rangeOfString:m_substr].location == 0;
   4933                 }
   4934 
   4935                 std::string describe() const override {
   4936                     return "starts with: " + Catch::Detail::stringify( m_substr );
   4937                 }
   4938             };
   4939             struct EndsWith : StringHolder {
   4940                 EndsWith( NSString* substr ) : StringHolder( substr ){}
   4941 
   4942                 bool match( NSString* str ) const override {
   4943                     return  (str != nil || m_substr == nil ) &&
   4944                             [str rangeOfString:m_substr].location == [str length] - [m_substr length];
   4945                 }
   4946 
   4947                 std::string describe() const override {
   4948                     return "ends with: " + Catch::Detail::stringify( m_substr );
   4949                 }
   4950             };
   4951 
   4952         } // namespace NSStringMatchers
   4953         } // namespace Impl
   4954 
   4955         inline Impl::NSStringMatchers::Equals
   4956             Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
   4957 
   4958         inline Impl::NSStringMatchers::Contains
   4959             Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
   4960 
   4961         inline Impl::NSStringMatchers::StartsWith
   4962             StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
   4963 
   4964         inline Impl::NSStringMatchers::EndsWith
   4965             EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
   4966 
   4967     } // namespace Matchers
   4968 
   4969     using namespace Matchers;
   4970 
   4971 #endif // CATCH_CONFIG_DISABLE_MATCHERS
   4972 
   4973 } // namespace Catch
   4974 
   4975 ///////////////////////////////////////////////////////////////////////////////
   4976 #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
   4977 #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
   4978 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
   4979 { \
   4980 return @ name; \
   4981 } \
   4982 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
   4983 { \
   4984 return @ desc; \
   4985 } \
   4986 -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
   4987 
   4988 #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
   4989 
   4990 // end catch_objc.hpp
   4991 #endif
   4992 
   4993 // Benchmarking needs the externally-facing parts of reporters to work
   4994 #if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   4995 // start catch_external_interfaces.h
   4996 
   4997 // start catch_reporter_bases.hpp
   4998 
   4999 // start catch_interfaces_reporter.h
   5000 
   5001 // start catch_config.hpp
   5002 
   5003 // start catch_test_spec_parser.h
   5004 
   5005 #ifdef __clang__
   5006 #pragma clang diagnostic push
   5007 #pragma clang diagnostic ignored "-Wpadded"
   5008 #endif
   5009 
   5010 // start catch_test_spec.h
   5011 
   5012 #ifdef __clang__
   5013 #pragma clang diagnostic push
   5014 #pragma clang diagnostic ignored "-Wpadded"
   5015 #endif
   5016 
   5017 // start catch_wildcard_pattern.h
   5018 
   5019 namespace Catch
   5020 {
   5021     class WildcardPattern {
   5022         enum WildcardPosition {
   5023             NoWildcard = 0,
   5024             WildcardAtStart = 1,
   5025             WildcardAtEnd = 2,
   5026             WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
   5027         };
   5028 
   5029     public:
   5030 
   5031         WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
   5032         virtual ~WildcardPattern() = default;
   5033         virtual bool matches( std::string const& str ) const;
   5034 
   5035     private:
   5036         std::string normaliseString( std::string const& str ) const;
   5037         CaseSensitive::Choice m_caseSensitivity;
   5038         WildcardPosition m_wildcard = NoWildcard;
   5039         std::string m_pattern;
   5040     };
   5041 }
   5042 
   5043 // end catch_wildcard_pattern.h
   5044 #include <string>
   5045 #include <vector>
   5046 #include <memory>
   5047 
   5048 namespace Catch {
   5049 
   5050     struct IConfig;
   5051 
   5052     class TestSpec {
   5053         class Pattern {
   5054         public:
   5055             explicit Pattern( std::string const& name );
   5056             virtual ~Pattern();
   5057             virtual bool matches( TestCaseInfo const& testCase ) const = 0;
   5058             std::string const& name() const;
   5059         private:
   5060             std::string const m_name;
   5061         };
   5062         using PatternPtr = std::shared_ptr<Pattern>;
   5063 
   5064         class NamePattern : public Pattern {
   5065         public:
   5066             explicit NamePattern( std::string const& name, std::string const& filterString );
   5067             bool matches( TestCaseInfo const& testCase ) const override;
   5068         private:
   5069             WildcardPattern m_wildcardPattern;
   5070         };
   5071 
   5072         class TagPattern : public Pattern {
   5073         public:
   5074             explicit TagPattern( std::string const& tag, std::string const& filterString );
   5075             bool matches( TestCaseInfo const& testCase ) const override;
   5076         private:
   5077             std::string m_tag;
   5078         };
   5079 
   5080         class ExcludedPattern : public Pattern {
   5081         public:
   5082             explicit ExcludedPattern( PatternPtr const& underlyingPattern );
   5083             bool matches( TestCaseInfo const& testCase ) const override;
   5084         private:
   5085             PatternPtr m_underlyingPattern;
   5086         };
   5087 
   5088         struct Filter {
   5089             std::vector<PatternPtr> m_patterns;
   5090 
   5091             bool matches( TestCaseInfo const& testCase ) const;
   5092             std::string name() const;
   5093         };
   5094 
   5095     public:
   5096         struct FilterMatch {
   5097             std::string name;
   5098             std::vector<TestCase const*> tests;
   5099         };
   5100         using Matches = std::vector<FilterMatch>;
   5101         using vectorStrings = std::vector<std::string>;
   5102 
   5103         bool hasFilters() const;
   5104         bool matches( TestCaseInfo const& testCase ) const;
   5105         Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;
   5106         const vectorStrings & getInvalidArgs() const;
   5107 
   5108     private:
   5109         std::vector<Filter> m_filters;
   5110         std::vector<std::string> m_invalidArgs;
   5111         friend class TestSpecParser;
   5112     };
   5113 }
   5114 
   5115 #ifdef __clang__
   5116 #pragma clang diagnostic pop
   5117 #endif
   5118 
   5119 // end catch_test_spec.h
   5120 // start catch_interfaces_tag_alias_registry.h
   5121 
   5122 #include <string>
   5123 
   5124 namespace Catch {
   5125 
   5126     struct TagAlias;
   5127 
   5128     struct ITagAliasRegistry {
   5129         virtual ~ITagAliasRegistry();
   5130         // Nullptr if not present
   5131         virtual TagAlias const* find( std::string const& alias ) const = 0;
   5132         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
   5133 
   5134         static ITagAliasRegistry const& get();
   5135     };
   5136 
   5137 } // end namespace Catch
   5138 
   5139 // end catch_interfaces_tag_alias_registry.h
   5140 namespace Catch {
   5141 
   5142     class TestSpecParser {
   5143         enum Mode{ None, Name, QuotedName, Tag, EscapedName };
   5144         Mode m_mode = None;
   5145         Mode lastMode = None;
   5146         bool m_exclusion = false;
   5147         std::size_t m_pos = 0;
   5148         std::size_t m_realPatternPos = 0;
   5149         std::string m_arg;
   5150         std::string m_substring;
   5151         std::string m_patternName;
   5152         std::vector<std::size_t> m_escapeChars;
   5153         TestSpec::Filter m_currentFilter;
   5154         TestSpec m_testSpec;
   5155         ITagAliasRegistry const* m_tagAliases = nullptr;
   5156 
   5157     public:
   5158         TestSpecParser( ITagAliasRegistry const& tagAliases );
   5159 
   5160         TestSpecParser& parse( std::string const& arg );
   5161         TestSpec testSpec();
   5162 
   5163     private:
   5164         bool visitChar( char c );
   5165         void startNewMode( Mode mode );
   5166         bool processNoneChar( char c );
   5167         void processNameChar( char c );
   5168         bool processOtherChar( char c );
   5169         void endMode();
   5170         void escape();
   5171         bool isControlChar( char c ) const;
   5172         void saveLastMode();
   5173         void revertBackToLastMode();
   5174         void addFilter();
   5175         bool separate();
   5176 
   5177         // Handles common preprocessing of the pattern for name/tag patterns
   5178         std::string preprocessPattern();
   5179         // Adds the current pattern as a test name
   5180         void addNamePattern();
   5181         // Adds the current pattern as a tag
   5182         void addTagPattern();
   5183 
   5184         inline void addCharToPattern(char c) {
   5185             m_substring += c;
   5186             m_patternName += c;
   5187             m_realPatternPos++;
   5188         }
   5189 
   5190     };
   5191     TestSpec parseTestSpec( std::string const& arg );
   5192 
   5193 } // namespace Catch
   5194 
   5195 #ifdef __clang__
   5196 #pragma clang diagnostic pop
   5197 #endif
   5198 
   5199 // end catch_test_spec_parser.h
   5200 // Libstdc++ doesn't like incomplete classes for unique_ptr
   5201 
   5202 #include <memory>
   5203 #include <vector>
   5204 #include <string>
   5205 
   5206 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
   5207 #define CATCH_CONFIG_CONSOLE_WIDTH 80
   5208 #endif
   5209 
   5210 namespace Catch {
   5211 
   5212     struct IStream;
   5213 
   5214     struct ConfigData {
   5215         bool listTests = false;
   5216         bool listTags = false;
   5217         bool listReporters = false;
   5218         bool listTestNamesOnly = false;
   5219 
   5220         bool showSuccessfulTests = false;
   5221         bool shouldDebugBreak = false;
   5222         bool noThrow = false;
   5223         bool showHelp = false;
   5224         bool showInvisibles = false;
   5225         bool filenamesAsTags = false;
   5226         bool libIdentify = false;
   5227 
   5228         int abortAfter = -1;
   5229         unsigned int rngSeed = 0;
   5230 
   5231         bool benchmarkNoAnalysis = false;
   5232         unsigned int benchmarkSamples = 100;
   5233         double benchmarkConfidenceInterval = 0.95;
   5234         unsigned int benchmarkResamples = 100000;
   5235 
   5236         Verbosity verbosity = Verbosity::Normal;
   5237         WarnAbout::What warnings = WarnAbout::Nothing;
   5238         ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
   5239         RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
   5240         UseColour::YesOrNo useColour = UseColour::Auto;
   5241         WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
   5242 
   5243         std::string outputFilename;
   5244         std::string name;
   5245         std::string processName;
   5246 #ifndef CATCH_CONFIG_DEFAULT_REPORTER
   5247 #define CATCH_CONFIG_DEFAULT_REPORTER "console"
   5248 #endif
   5249         std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
   5250 #undef CATCH_CONFIG_DEFAULT_REPORTER
   5251 
   5252         std::vector<std::string> testsOrTags;
   5253         std::vector<std::string> sectionsToRun;
   5254     };
   5255 
   5256     class Config : public IConfig {
   5257     public:
   5258 
   5259         Config() = default;
   5260         Config( ConfigData const& data );
   5261         virtual ~Config() = default;
   5262 
   5263         std::string const& getFilename() const;
   5264 
   5265         bool listTests() const;
   5266         bool listTestNamesOnly() const;
   5267         bool listTags() const;
   5268         bool listReporters() const;
   5269 
   5270         std::string getProcessName() const;
   5271         std::string const& getReporterName() const;
   5272 
   5273         std::vector<std::string> const& getTestsOrTags() const override;
   5274         std::vector<std::string> const& getSectionsToRun() const override;
   5275 
   5276         TestSpec const& testSpec() const override;
   5277         bool hasTestFilters() const override;
   5278 
   5279         bool showHelp() const;
   5280 
   5281         // IConfig interface
   5282         bool allowThrows() const override;
   5283         std::ostream& stream() const override;
   5284         std::string name() const override;
   5285         bool includeSuccessfulResults() const override;
   5286         bool warnAboutMissingAssertions() const override;
   5287         bool warnAboutNoTests() const override;
   5288         ShowDurations::OrNot showDurations() const override;
   5289         RunTests::InWhatOrder runOrder() const override;
   5290         unsigned int rngSeed() const override;
   5291         UseColour::YesOrNo useColour() const override;
   5292         bool shouldDebugBreak() const override;
   5293         int abortAfter() const override;
   5294         bool showInvisibles() const override;
   5295         Verbosity verbosity() const override;
   5296         bool benchmarkNoAnalysis() const override;
   5297         int benchmarkSamples() const override;
   5298         double benchmarkConfidenceInterval() const override;
   5299         unsigned int benchmarkResamples() const override;
   5300 
   5301     private:
   5302 
   5303         IStream const* openStream();
   5304         ConfigData m_data;
   5305 
   5306         std::unique_ptr<IStream const> m_stream;
   5307         TestSpec m_testSpec;
   5308         bool m_hasTestFilters = false;
   5309     };
   5310 
   5311 } // end namespace Catch
   5312 
   5313 // end catch_config.hpp
   5314 // start catch_assertionresult.h
   5315 
   5316 #include <string>
   5317 
   5318 namespace Catch {
   5319 
   5320     struct AssertionResultData
   5321     {
   5322         AssertionResultData() = delete;
   5323 
   5324         AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
   5325 
   5326         std::string message;
   5327         mutable std::string reconstructedExpression;
   5328         LazyExpression lazyExpression;
   5329         ResultWas::OfType resultType;
   5330 
   5331         std::string reconstructExpression() const;
   5332     };
   5333 
   5334     class AssertionResult {
   5335     public:
   5336         AssertionResult() = delete;
   5337         AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
   5338 
   5339         bool isOk() const;
   5340         bool succeeded() const;
   5341         ResultWas::OfType getResultType() const;
   5342         bool hasExpression() const;
   5343         bool hasMessage() const;
   5344         std::string getExpression() const;
   5345         std::string getExpressionInMacro() const;
   5346         bool hasExpandedExpression() const;
   5347         std::string getExpandedExpression() const;
   5348         std::string getMessage() const;
   5349         SourceLineInfo getSourceInfo() const;
   5350         StringRef getTestMacroName() const;
   5351 
   5352     //protected:
   5353         AssertionInfo m_info;
   5354         AssertionResultData m_resultData;
   5355     };
   5356 
   5357 } // end namespace Catch
   5358 
   5359 // end catch_assertionresult.h
   5360 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   5361 // start catch_estimate.hpp
   5362 
   5363  // Statistics estimates
   5364 
   5365 
   5366 namespace Catch {
   5367     namespace Benchmark {
   5368         template <typename Duration>
   5369         struct Estimate {
   5370             Duration point;
   5371             Duration lower_bound;
   5372             Duration upper_bound;
   5373             double confidence_interval;
   5374 
   5375             template <typename Duration2>
   5376             operator Estimate<Duration2>() const {
   5377                 return { point, lower_bound, upper_bound, confidence_interval };
   5378             }
   5379         };
   5380     } // namespace Benchmark
   5381 } // namespace Catch
   5382 
   5383 // end catch_estimate.hpp
   5384 // start catch_outlier_classification.hpp
   5385 
   5386 // Outlier information
   5387 
   5388 namespace Catch {
   5389     namespace Benchmark {
   5390         struct OutlierClassification {
   5391             int samples_seen = 0;
   5392             int low_severe = 0;     // more than 3 times IQR below Q1
   5393             int low_mild = 0;       // 1.5 to 3 times IQR below Q1
   5394             int high_mild = 0;      // 1.5 to 3 times IQR above Q3
   5395             int high_severe = 0;    // more than 3 times IQR above Q3
   5396 
   5397             int total() const {
   5398                 return low_severe + low_mild + high_mild + high_severe;
   5399             }
   5400         };
   5401     } // namespace Benchmark
   5402 } // namespace Catch
   5403 
   5404 // end catch_outlier_classification.hpp
   5405 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   5406 
   5407 #include <string>
   5408 #include <iosfwd>
   5409 #include <map>
   5410 #include <set>
   5411 #include <memory>
   5412 #include <algorithm>
   5413 
   5414 namespace Catch {
   5415 
   5416     struct ReporterConfig {
   5417         explicit ReporterConfig( IConfigPtr const& _fullConfig );
   5418 
   5419         ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
   5420 
   5421         std::ostream& stream() const;
   5422         IConfigPtr fullConfig() const;
   5423 
   5424     private:
   5425         std::ostream* m_stream;
   5426         IConfigPtr m_fullConfig;
   5427     };
   5428 
   5429     struct ReporterPreferences {
   5430         bool shouldRedirectStdOut = false;
   5431         bool shouldReportAllAssertions = false;
   5432     };
   5433 
   5434     template<typename T>
   5435     struct LazyStat : Option<T> {
   5436         LazyStat& operator=( T const& _value ) {
   5437             Option<T>::operator=( _value );
   5438             used = false;
   5439             return *this;
   5440         }
   5441         void reset() {
   5442             Option<T>::reset();
   5443             used = false;
   5444         }
   5445         bool used = false;
   5446     };
   5447 
   5448     struct TestRunInfo {
   5449         TestRunInfo( std::string const& _name );
   5450         std::string name;
   5451     };
   5452     struct GroupInfo {
   5453         GroupInfo(  std::string const& _name,
   5454                     std::size_t _groupIndex,
   5455                     std::size_t _groupsCount );
   5456 
   5457         std::string name;
   5458         std::size_t groupIndex;
   5459         std::size_t groupsCounts;
   5460     };
   5461 
   5462     struct AssertionStats {
   5463         AssertionStats( AssertionResult const& _assertionResult,
   5464                         std::vector<MessageInfo> const& _infoMessages,
   5465                         Totals const& _totals );
   5466 
   5467         AssertionStats( AssertionStats const& )              = default;
   5468         AssertionStats( AssertionStats && )                  = default;
   5469         AssertionStats& operator = ( AssertionStats const& ) = delete;
   5470         AssertionStats& operator = ( AssertionStats && )     = delete;
   5471         virtual ~AssertionStats();
   5472 
   5473         AssertionResult assertionResult;
   5474         std::vector<MessageInfo> infoMessages;
   5475         Totals totals;
   5476     };
   5477 
   5478     struct SectionStats {
   5479         SectionStats(   SectionInfo const& _sectionInfo,
   5480                         Counts const& _assertions,
   5481                         double _durationInSeconds,
   5482                         bool _missingAssertions );
   5483         SectionStats( SectionStats const& )              = default;
   5484         SectionStats( SectionStats && )                  = default;
   5485         SectionStats& operator = ( SectionStats const& ) = default;
   5486         SectionStats& operator = ( SectionStats && )     = default;
   5487         virtual ~SectionStats();
   5488 
   5489         SectionInfo sectionInfo;
   5490         Counts assertions;
   5491         double durationInSeconds;
   5492         bool missingAssertions;
   5493     };
   5494 
   5495     struct TestCaseStats {
   5496         TestCaseStats(  TestCaseInfo const& _testInfo,
   5497                         Totals const& _totals,
   5498                         std::string const& _stdOut,
   5499                         std::string const& _stdErr,
   5500                         bool _aborting );
   5501 
   5502         TestCaseStats( TestCaseStats const& )              = default;
   5503         TestCaseStats( TestCaseStats && )                  = default;
   5504         TestCaseStats& operator = ( TestCaseStats const& ) = default;
   5505         TestCaseStats& operator = ( TestCaseStats && )     = default;
   5506         virtual ~TestCaseStats();
   5507 
   5508         TestCaseInfo testInfo;
   5509         Totals totals;
   5510         std::string stdOut;
   5511         std::string stdErr;
   5512         bool aborting;
   5513     };
   5514 
   5515     struct TestGroupStats {
   5516         TestGroupStats( GroupInfo const& _groupInfo,
   5517                         Totals const& _totals,
   5518                         bool _aborting );
   5519         TestGroupStats( GroupInfo const& _groupInfo );
   5520 
   5521         TestGroupStats( TestGroupStats const& )              = default;
   5522         TestGroupStats( TestGroupStats && )                  = default;
   5523         TestGroupStats& operator = ( TestGroupStats const& ) = default;
   5524         TestGroupStats& operator = ( TestGroupStats && )     = default;
   5525         virtual ~TestGroupStats();
   5526 
   5527         GroupInfo groupInfo;
   5528         Totals totals;
   5529         bool aborting;
   5530     };
   5531 
   5532     struct TestRunStats {
   5533         TestRunStats(   TestRunInfo const& _runInfo,
   5534                         Totals const& _totals,
   5535                         bool _aborting );
   5536 
   5537         TestRunStats( TestRunStats const& )              = default;
   5538         TestRunStats( TestRunStats && )                  = default;
   5539         TestRunStats& operator = ( TestRunStats const& ) = default;
   5540         TestRunStats& operator = ( TestRunStats && )     = default;
   5541         virtual ~TestRunStats();
   5542 
   5543         TestRunInfo runInfo;
   5544         Totals totals;
   5545         bool aborting;
   5546     };
   5547 
   5548 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   5549     struct BenchmarkInfo {
   5550         std::string name;
   5551         double estimatedDuration;
   5552         int iterations;
   5553         int samples;
   5554         unsigned int resamples;
   5555         double clockResolution;
   5556         double clockCost;
   5557     };
   5558 
   5559     template <class Duration>
   5560     struct BenchmarkStats {
   5561         BenchmarkInfo info;
   5562 
   5563         std::vector<Duration> samples;
   5564         Benchmark::Estimate<Duration> mean;
   5565         Benchmark::Estimate<Duration> standardDeviation;
   5566         Benchmark::OutlierClassification outliers;
   5567         double outlierVariance;
   5568 
   5569         template <typename Duration2>
   5570         operator BenchmarkStats<Duration2>() const {
   5571             std::vector<Duration2> samples2;
   5572             samples2.reserve(samples.size());
   5573             std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
   5574             return {
   5575                 info,
   5576                 std::move(samples2),
   5577                 mean,
   5578                 standardDeviation,
   5579                 outliers,
   5580                 outlierVariance,
   5581             };
   5582         }
   5583     };
   5584 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   5585 
   5586     struct IStreamingReporter {
   5587         virtual ~IStreamingReporter() = default;
   5588 
   5589         // Implementing class must also provide the following static methods:
   5590         // static std::string getDescription();
   5591         // static std::set<Verbosity> getSupportedVerbosities()
   5592 
   5593         virtual ReporterPreferences getPreferences() const = 0;
   5594 
   5595         virtual void noMatchingTestCases( std::string const& spec ) = 0;
   5596 
   5597         virtual void reportInvalidArguments(std::string const&) {}
   5598 
   5599         virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
   5600         virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
   5601 
   5602         virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
   5603         virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
   5604 
   5605 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   5606         virtual void benchmarkPreparing( std::string const& ) {}
   5607         virtual void benchmarkStarting( BenchmarkInfo const& ) {}
   5608         virtual void benchmarkEnded( BenchmarkStats<> const& ) {}
   5609         virtual void benchmarkFailed( std::string const& ) {}
   5610 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   5611 
   5612         virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
   5613 
   5614         // The return value indicates if the messages buffer should be cleared:
   5615         virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
   5616 
   5617         virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
   5618         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
   5619         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
   5620         virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
   5621 
   5622         virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
   5623 
   5624         // Default empty implementation provided
   5625         virtual void fatalErrorEncountered( StringRef name );
   5626 
   5627         virtual bool isMulti() const;
   5628     };
   5629     using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
   5630 
   5631     struct IReporterFactory {
   5632         virtual ~IReporterFactory();
   5633         virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
   5634         virtual std::string getDescription() const = 0;
   5635     };
   5636     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
   5637 
   5638     struct IReporterRegistry {
   5639         using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
   5640         using Listeners = std::vector<IReporterFactoryPtr>;
   5641 
   5642         virtual ~IReporterRegistry();
   5643         virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
   5644         virtual FactoryMap const& getFactories() const = 0;
   5645         virtual Listeners const& getListeners() const = 0;
   5646     };
   5647 
   5648 } // end namespace Catch
   5649 
   5650 // end catch_interfaces_reporter.h
   5651 #include <algorithm>
   5652 #include <cstring>
   5653 #include <cfloat>
   5654 #include <cstdio>
   5655 #include <cassert>
   5656 #include <memory>
   5657 #include <ostream>
   5658 
   5659 namespace Catch {
   5660     void prepareExpandedExpression(AssertionResult& result);
   5661 
   5662     // Returns double formatted as %.3f (format expected on output)
   5663     std::string getFormattedDuration( double duration );
   5664 
   5665     std::string serializeFilters( std::vector<std::string> const& container );
   5666 
   5667     template<typename DerivedT>
   5668     struct StreamingReporterBase : IStreamingReporter {
   5669 
   5670         StreamingReporterBase( ReporterConfig const& _config )
   5671         :   m_config( _config.fullConfig() ),
   5672             stream( _config.stream() )
   5673         {
   5674             m_reporterPrefs.shouldRedirectStdOut = false;
   5675             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
   5676                 CATCH_ERROR( "Verbosity level not supported by this reporter" );
   5677         }
   5678 
   5679         ReporterPreferences getPreferences() const override {
   5680             return m_reporterPrefs;
   5681         }
   5682 
   5683         static std::set<Verbosity> getSupportedVerbosities() {
   5684             return { Verbosity::Normal };
   5685         }
   5686 
   5687         ~StreamingReporterBase() override = default;
   5688 
   5689         void noMatchingTestCases(std::string const&) override {}
   5690 
   5691         void reportInvalidArguments(std::string const&) override {}
   5692 
   5693         void testRunStarting(TestRunInfo const& _testRunInfo) override {
   5694             currentTestRunInfo = _testRunInfo;
   5695         }
   5696 
   5697         void testGroupStarting(GroupInfo const& _groupInfo) override {
   5698             currentGroupInfo = _groupInfo;
   5699         }
   5700 
   5701         void testCaseStarting(TestCaseInfo const& _testInfo) override  {
   5702             currentTestCaseInfo = _testInfo;
   5703         }
   5704         void sectionStarting(SectionInfo const& _sectionInfo) override {
   5705             m_sectionStack.push_back(_sectionInfo);
   5706         }
   5707 
   5708         void sectionEnded(SectionStats const& /* _sectionStats */) override {
   5709             m_sectionStack.pop_back();
   5710         }
   5711         void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
   5712             currentTestCaseInfo.reset();
   5713         }
   5714         void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
   5715             currentGroupInfo.reset();
   5716         }
   5717         void testRunEnded(TestRunStats const& /* _testRunStats */) override {
   5718             currentTestCaseInfo.reset();
   5719             currentGroupInfo.reset();
   5720             currentTestRunInfo.reset();
   5721         }
   5722 
   5723         void skipTest(TestCaseInfo const&) override {
   5724             // Don't do anything with this by default.
   5725             // It can optionally be overridden in the derived class.
   5726         }
   5727 
   5728         IConfigPtr m_config;
   5729         std::ostream& stream;
   5730 
   5731         LazyStat<TestRunInfo> currentTestRunInfo;
   5732         LazyStat<GroupInfo> currentGroupInfo;
   5733         LazyStat<TestCaseInfo> currentTestCaseInfo;
   5734 
   5735         std::vector<SectionInfo> m_sectionStack;
   5736         ReporterPreferences m_reporterPrefs;
   5737     };
   5738 
   5739     template<typename DerivedT>
   5740     struct CumulativeReporterBase : IStreamingReporter {
   5741         template<typename T, typename ChildNodeT>
   5742         struct Node {
   5743             explicit Node( T const& _value ) : value( _value ) {}
   5744             virtual ~Node() {}
   5745 
   5746             using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
   5747             T value;
   5748             ChildNodes children;
   5749         };
   5750         struct SectionNode {
   5751             explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
   5752             virtual ~SectionNode() = default;
   5753 
   5754             bool operator == (SectionNode const& other) const {
   5755                 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
   5756             }
   5757             bool operator == (std::shared_ptr<SectionNode> const& other) const {
   5758                 return operator==(*other);
   5759             }
   5760 
   5761             SectionStats stats;
   5762             using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
   5763             using Assertions = std::vector<AssertionStats>;
   5764             ChildSections childSections;
   5765             Assertions assertions;
   5766             std::string stdOut;
   5767             std::string stdErr;
   5768         };
   5769 
   5770         struct BySectionInfo {
   5771             BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
   5772             BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
   5773             bool operator() (std::shared_ptr<SectionNode> const& node) const {
   5774                 return ((node->stats.sectionInfo.name == m_other.name) &&
   5775                         (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
   5776             }
   5777             void operator=(BySectionInfo const&) = delete;
   5778 
   5779         private:
   5780             SectionInfo const& m_other;
   5781         };
   5782 
   5783         using TestCaseNode = Node<TestCaseStats, SectionNode>;
   5784         using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
   5785         using TestRunNode = Node<TestRunStats, TestGroupNode>;
   5786 
   5787         CumulativeReporterBase( ReporterConfig const& _config )
   5788         :   m_config( _config.fullConfig() ),
   5789             stream( _config.stream() )
   5790         {
   5791             m_reporterPrefs.shouldRedirectStdOut = false;
   5792             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
   5793                 CATCH_ERROR( "Verbosity level not supported by this reporter" );
   5794         }
   5795         ~CumulativeReporterBase() override = default;
   5796 
   5797         ReporterPreferences getPreferences() const override {
   5798             return m_reporterPrefs;
   5799         }
   5800 
   5801         static std::set<Verbosity> getSupportedVerbosities() {
   5802             return { Verbosity::Normal };
   5803         }
   5804 
   5805         void testRunStarting( TestRunInfo const& ) override {}
   5806         void testGroupStarting( GroupInfo const& ) override {}
   5807 
   5808         void testCaseStarting( TestCaseInfo const& ) override {}
   5809 
   5810         void sectionStarting( SectionInfo const& sectionInfo ) override {
   5811             SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
   5812             std::shared_ptr<SectionNode> node;
   5813             if( m_sectionStack.empty() ) {
   5814                 if( !m_rootSection )
   5815                     m_rootSection = std::make_shared<SectionNode>( incompleteStats );
   5816                 node = m_rootSection;
   5817             }
   5818             else {
   5819                 SectionNode& parentNode = *m_sectionStack.back();
   5820                 auto it =
   5821                     std::find_if(   parentNode.childSections.begin(),
   5822                                     parentNode.childSections.end(),
   5823                                     BySectionInfo( sectionInfo ) );
   5824                 if( it == parentNode.childSections.end() ) {
   5825                     node = std::make_shared<SectionNode>( incompleteStats );
   5826                     parentNode.childSections.push_back( node );
   5827                 }
   5828                 else
   5829                     node = *it;
   5830             }
   5831             m_sectionStack.push_back( node );
   5832             m_deepestSection = std::move(node);
   5833         }
   5834 
   5835         void assertionStarting(AssertionInfo const&) override {}
   5836 
   5837         bool assertionEnded(AssertionStats const& assertionStats) override {
   5838             assert(!m_sectionStack.empty());
   5839             // AssertionResult holds a pointer to a temporary DecomposedExpression,
   5840             // which getExpandedExpression() calls to build the expression string.
   5841             // Our section stack copy of the assertionResult will likely outlive the
   5842             // temporary, so it must be expanded or discarded now to avoid calling
   5843             // a destroyed object later.
   5844             prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
   5845             SectionNode& sectionNode = *m_sectionStack.back();
   5846             sectionNode.assertions.push_back(assertionStats);
   5847             return true;
   5848         }
   5849         void sectionEnded(SectionStats const& sectionStats) override {
   5850             assert(!m_sectionStack.empty());
   5851             SectionNode& node = *m_sectionStack.back();
   5852             node.stats = sectionStats;
   5853             m_sectionStack.pop_back();
   5854         }
   5855         void testCaseEnded(TestCaseStats const& testCaseStats) override {
   5856             auto node = std::make_shared<TestCaseNode>(testCaseStats);
   5857             assert(m_sectionStack.size() == 0);
   5858             node->children.push_back(m_rootSection);
   5859             m_testCases.push_back(node);
   5860             m_rootSection.reset();
   5861 
   5862             assert(m_deepestSection);
   5863             m_deepestSection->stdOut = testCaseStats.stdOut;
   5864             m_deepestSection->stdErr = testCaseStats.stdErr;
   5865         }
   5866         void testGroupEnded(TestGroupStats const& testGroupStats) override {
   5867             auto node = std::make_shared<TestGroupNode>(testGroupStats);
   5868             node->children.swap(m_testCases);
   5869             m_testGroups.push_back(node);
   5870         }
   5871         void testRunEnded(TestRunStats const& testRunStats) override {
   5872             auto node = std::make_shared<TestRunNode>(testRunStats);
   5873             node->children.swap(m_testGroups);
   5874             m_testRuns.push_back(node);
   5875             testRunEndedCumulative();
   5876         }
   5877         virtual void testRunEndedCumulative() = 0;
   5878 
   5879         void skipTest(TestCaseInfo const&) override {}
   5880 
   5881         IConfigPtr m_config;
   5882         std::ostream& stream;
   5883         std::vector<AssertionStats> m_assertions;
   5884         std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
   5885         std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
   5886         std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
   5887 
   5888         std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
   5889 
   5890         std::shared_ptr<SectionNode> m_rootSection;
   5891         std::shared_ptr<SectionNode> m_deepestSection;
   5892         std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
   5893         ReporterPreferences m_reporterPrefs;
   5894     };
   5895 
   5896     template<char C>
   5897     char const* getLineOfChars() {
   5898         static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
   5899         if( !*line ) {
   5900             std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
   5901             line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
   5902         }
   5903         return line;
   5904     }
   5905 
   5906     struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
   5907         TestEventListenerBase( ReporterConfig const& _config );
   5908 
   5909         static std::set<Verbosity> getSupportedVerbosities();
   5910 
   5911         void assertionStarting(AssertionInfo const&) override;
   5912         bool assertionEnded(AssertionStats const&) override;
   5913     };
   5914 
   5915 } // end namespace Catch
   5916 
   5917 // end catch_reporter_bases.hpp
   5918 // start catch_console_colour.h
   5919 
   5920 namespace Catch {
   5921 
   5922     struct Colour {
   5923         enum Code {
   5924             None = 0,
   5925 
   5926             White,
   5927             Red,
   5928             Green,
   5929             Blue,
   5930             Cyan,
   5931             Yellow,
   5932             Grey,
   5933 
   5934             Bright = 0x10,
   5935 
   5936             BrightRed = Bright | Red,
   5937             BrightGreen = Bright | Green,
   5938             LightGrey = Bright | Grey,
   5939             BrightWhite = Bright | White,
   5940             BrightYellow = Bright | Yellow,
   5941 
   5942             // By intention
   5943             FileName = LightGrey,
   5944             Warning = BrightYellow,
   5945             ResultError = BrightRed,
   5946             ResultSuccess = BrightGreen,
   5947             ResultExpectedFailure = Warning,
   5948 
   5949             Error = BrightRed,
   5950             Success = Green,
   5951 
   5952             OriginalExpression = Cyan,
   5953             ReconstructedExpression = BrightYellow,
   5954 
   5955             SecondaryText = LightGrey,
   5956             Headers = White
   5957         };
   5958 
   5959         // Use constructed object for RAII guard
   5960         Colour( Code _colourCode );
   5961         Colour( Colour&& other ) noexcept;
   5962         Colour& operator=( Colour&& other ) noexcept;
   5963         ~Colour();
   5964 
   5965         // Use static method for one-shot changes
   5966         static void use( Code _colourCode );
   5967 
   5968     private:
   5969         bool m_moved = false;
   5970     };
   5971 
   5972     std::ostream& operator << ( std::ostream& os, Colour const& );
   5973 
   5974 } // end namespace Catch
   5975 
   5976 // end catch_console_colour.h
   5977 // start catch_reporter_registrars.hpp
   5978 
   5979 
   5980 namespace Catch {
   5981 
   5982     template<typename T>
   5983     class ReporterRegistrar {
   5984 
   5985         class ReporterFactory : public IReporterFactory {
   5986 
   5987             IStreamingReporterPtr create( ReporterConfig const& config ) const override {
   5988                 return std::unique_ptr<T>( new T( config ) );
   5989             }
   5990 
   5991             std::string getDescription() const override {
   5992                 return T::getDescription();
   5993             }
   5994         };
   5995 
   5996     public:
   5997 
   5998         explicit ReporterRegistrar( std::string const& name ) {
   5999             getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
   6000         }
   6001     };
   6002 
   6003     template<typename T>
   6004     class ListenerRegistrar {
   6005 
   6006         class ListenerFactory : public IReporterFactory {
   6007 
   6008             IStreamingReporterPtr create( ReporterConfig const& config ) const override {
   6009                 return std::unique_ptr<T>( new T( config ) );
   6010             }
   6011             std::string getDescription() const override {
   6012                 return std::string();
   6013             }
   6014         };
   6015 
   6016     public:
   6017 
   6018         ListenerRegistrar() {
   6019             getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
   6020         }
   6021     };
   6022 }
   6023 
   6024 #if !defined(CATCH_CONFIG_DISABLE)
   6025 
   6026 #define CATCH_REGISTER_REPORTER( name, reporterType ) \
   6027     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION         \
   6028     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \
   6029     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
   6030     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   6031 
   6032 #define CATCH_REGISTER_LISTENER( listenerType ) \
   6033     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION   \
   6034     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS    \
   6035     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
   6036     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   6037 #else // CATCH_CONFIG_DISABLE
   6038 
   6039 #define CATCH_REGISTER_REPORTER(name, reporterType)
   6040 #define CATCH_REGISTER_LISTENER(listenerType)
   6041 
   6042 #endif // CATCH_CONFIG_DISABLE
   6043 
   6044 // end catch_reporter_registrars.hpp
   6045 // Allow users to base their work off existing reporters
   6046 // start catch_reporter_compact.h
   6047 
   6048 namespace Catch {
   6049 
   6050     struct CompactReporter : StreamingReporterBase<CompactReporter> {
   6051 
   6052         using StreamingReporterBase::StreamingReporterBase;
   6053 
   6054         ~CompactReporter() override;
   6055 
   6056         static std::string getDescription();
   6057 
   6058         ReporterPreferences getPreferences() const override;
   6059 
   6060         void noMatchingTestCases(std::string const& spec) override;
   6061 
   6062         void assertionStarting(AssertionInfo const&) override;
   6063 
   6064         bool assertionEnded(AssertionStats const& _assertionStats) override;
   6065 
   6066         void sectionEnded(SectionStats const& _sectionStats) override;
   6067 
   6068         void testRunEnded(TestRunStats const& _testRunStats) override;
   6069 
   6070     };
   6071 
   6072 } // end namespace Catch
   6073 
   6074 // end catch_reporter_compact.h
   6075 // start catch_reporter_console.h
   6076 
   6077 #if defined(_MSC_VER)
   6078 #pragma warning(push)
   6079 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
   6080                               // Note that 4062 (not all labels are handled
   6081                               // and default is missing) is enabled
   6082 #endif
   6083 
   6084 namespace Catch {
   6085     // Fwd decls
   6086     struct SummaryColumn;
   6087     class TablePrinter;
   6088 
   6089     struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
   6090         std::unique_ptr<TablePrinter> m_tablePrinter;
   6091 
   6092         ConsoleReporter(ReporterConfig const& config);
   6093         ~ConsoleReporter() override;
   6094         static std::string getDescription();
   6095 
   6096         void noMatchingTestCases(std::string const& spec) override;
   6097 
   6098         void reportInvalidArguments(std::string const&arg) override;
   6099 
   6100         void assertionStarting(AssertionInfo const&) override;
   6101 
   6102         bool assertionEnded(AssertionStats const& _assertionStats) override;
   6103 
   6104         void sectionStarting(SectionInfo const& _sectionInfo) override;
   6105         void sectionEnded(SectionStats const& _sectionStats) override;
   6106 
   6107 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   6108         void benchmarkPreparing(std::string const& name) override;
   6109         void benchmarkStarting(BenchmarkInfo const& info) override;
   6110         void benchmarkEnded(BenchmarkStats<> const& stats) override;
   6111         void benchmarkFailed(std::string const& error) override;
   6112 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   6113 
   6114         void testCaseEnded(TestCaseStats const& _testCaseStats) override;
   6115         void testGroupEnded(TestGroupStats const& _testGroupStats) override;
   6116         void testRunEnded(TestRunStats const& _testRunStats) override;
   6117         void testRunStarting(TestRunInfo const& _testRunInfo) override;
   6118     private:
   6119 
   6120         void lazyPrint();
   6121 
   6122         void lazyPrintWithoutClosingBenchmarkTable();
   6123         void lazyPrintRunInfo();
   6124         void lazyPrintGroupInfo();
   6125         void printTestCaseAndSectionHeader();
   6126 
   6127         void printClosedHeader(std::string const& _name);
   6128         void printOpenHeader(std::string const& _name);
   6129 
   6130         // if string has a : in first line will set indent to follow it on
   6131         // subsequent lines
   6132         void printHeaderString(std::string const& _string, std::size_t indent = 0);
   6133 
   6134         void printTotals(Totals const& totals);
   6135         void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
   6136 
   6137         void printTotalsDivider(Totals const& totals);
   6138         void printSummaryDivider();
   6139         void printTestFilters();
   6140 
   6141     private:
   6142         bool m_headerPrinted = false;
   6143     };
   6144 
   6145 } // end namespace Catch
   6146 
   6147 #if defined(_MSC_VER)
   6148 #pragma warning(pop)
   6149 #endif
   6150 
   6151 // end catch_reporter_console.h
   6152 // start catch_reporter_junit.h
   6153 
   6154 // start catch_xmlwriter.h
   6155 
   6156 #include <vector>
   6157 
   6158 namespace Catch {
   6159     enum class XmlFormatting {
   6160         None = 0x00,
   6161         Indent = 0x01,
   6162         Newline = 0x02,
   6163     };
   6164 
   6165     XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs);
   6166     XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs);
   6167 
   6168     class XmlEncode {
   6169     public:
   6170         enum ForWhat { ForTextNodes, ForAttributes };
   6171 
   6172         XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
   6173 
   6174         void encodeTo( std::ostream& os ) const;
   6175 
   6176         friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
   6177 
   6178     private:
   6179         std::string m_str;
   6180         ForWhat m_forWhat;
   6181     };
   6182 
   6183     class XmlWriter {
   6184     public:
   6185 
   6186         class ScopedElement {
   6187         public:
   6188             ScopedElement( XmlWriter* writer, XmlFormatting fmt );
   6189 
   6190             ScopedElement( ScopedElement&& other ) noexcept;
   6191             ScopedElement& operator=( ScopedElement&& other ) noexcept;
   6192 
   6193             ~ScopedElement();
   6194 
   6195             ScopedElement& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent );
   6196 
   6197             template<typename T>
   6198             ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
   6199                 m_writer->writeAttribute( name, attribute );
   6200                 return *this;
   6201             }
   6202 
   6203         private:
   6204             mutable XmlWriter* m_writer = nullptr;
   6205             XmlFormatting m_fmt;
   6206         };
   6207 
   6208         XmlWriter( std::ostream& os = Catch::cout() );
   6209         ~XmlWriter();
   6210 
   6211         XmlWriter( XmlWriter const& ) = delete;
   6212         XmlWriter& operator=( XmlWriter const& ) = delete;
   6213 
   6214         XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
   6215 
   6216         ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
   6217 
   6218         XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
   6219 
   6220         XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
   6221 
   6222         XmlWriter& writeAttribute( std::string const& name, bool attribute );
   6223 
   6224         template<typename T>
   6225         XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
   6226             ReusableStringStream rss;
   6227             rss << attribute;
   6228             return writeAttribute( name, rss.str() );
   6229         }
   6230 
   6231         XmlWriter& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
   6232 
   6233         XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
   6234 
   6235         void writeStylesheetRef( std::string const& url );
   6236 
   6237         XmlWriter& writeBlankLine();
   6238 
   6239         void ensureTagClosed();
   6240 
   6241     private:
   6242 
   6243         void applyFormatting(XmlFormatting fmt);
   6244 
   6245         void writeDeclaration();
   6246 
   6247         void newlineIfNecessary();
   6248 
   6249         bool m_tagIsOpen = false;
   6250         bool m_needsNewline = false;
   6251         std::vector<std::string> m_tags;
   6252         std::string m_indent;
   6253         std::ostream& m_os;
   6254     };
   6255 
   6256 }
   6257 
   6258 // end catch_xmlwriter.h
   6259 namespace Catch {
   6260 
   6261     class JunitReporter : public CumulativeReporterBase<JunitReporter> {
   6262     public:
   6263         JunitReporter(ReporterConfig const& _config);
   6264 
   6265         ~JunitReporter() override;
   6266 
   6267         static std::string getDescription();
   6268 
   6269         void noMatchingTestCases(std::string const& /*spec*/) override;
   6270 
   6271         void testRunStarting(TestRunInfo const& runInfo) override;
   6272 
   6273         void testGroupStarting(GroupInfo const& groupInfo) override;
   6274 
   6275         void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
   6276         bool assertionEnded(AssertionStats const& assertionStats) override;
   6277 
   6278         void testCaseEnded(TestCaseStats const& testCaseStats) override;
   6279 
   6280         void testGroupEnded(TestGroupStats const& testGroupStats) override;
   6281 
   6282         void testRunEndedCumulative() override;
   6283 
   6284         void writeGroup(TestGroupNode const& groupNode, double suiteTime);
   6285 
   6286         void writeTestCase(TestCaseNode const& testCaseNode);
   6287 
   6288         void writeSection(std::string const& className,
   6289                           std::string const& rootName,
   6290                           SectionNode const& sectionNode);
   6291 
   6292         void writeAssertions(SectionNode const& sectionNode);
   6293         void writeAssertion(AssertionStats const& stats);
   6294 
   6295         XmlWriter xml;
   6296         Timer suiteTimer;
   6297         std::string stdOutForSuite;
   6298         std::string stdErrForSuite;
   6299         unsigned int unexpectedExceptions = 0;
   6300         bool m_okToFail = false;
   6301     };
   6302 
   6303 } // end namespace Catch
   6304 
   6305 // end catch_reporter_junit.h
   6306 // start catch_reporter_xml.h
   6307 
   6308 namespace Catch {
   6309     class XmlReporter : public StreamingReporterBase<XmlReporter> {
   6310     public:
   6311         XmlReporter(ReporterConfig const& _config);
   6312 
   6313         ~XmlReporter() override;
   6314 
   6315         static std::string getDescription();
   6316 
   6317         virtual std::string getStylesheetRef() const;
   6318 
   6319         void writeSourceInfo(SourceLineInfo const& sourceInfo);
   6320 
   6321     public: // StreamingReporterBase
   6322 
   6323         void noMatchingTestCases(std::string const& s) override;
   6324 
   6325         void testRunStarting(TestRunInfo const& testInfo) override;
   6326 
   6327         void testGroupStarting(GroupInfo const& groupInfo) override;
   6328 
   6329         void testCaseStarting(TestCaseInfo const& testInfo) override;
   6330 
   6331         void sectionStarting(SectionInfo const& sectionInfo) override;
   6332 
   6333         void assertionStarting(AssertionInfo const&) override;
   6334 
   6335         bool assertionEnded(AssertionStats const& assertionStats) override;
   6336 
   6337         void sectionEnded(SectionStats const& sectionStats) override;
   6338 
   6339         void testCaseEnded(TestCaseStats const& testCaseStats) override;
   6340 
   6341         void testGroupEnded(TestGroupStats const& testGroupStats) override;
   6342 
   6343         void testRunEnded(TestRunStats const& testRunStats) override;
   6344 
   6345 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   6346         void benchmarkPreparing(std::string const& name) override;
   6347         void benchmarkStarting(BenchmarkInfo const&) override;
   6348         void benchmarkEnded(BenchmarkStats<> const&) override;
   6349         void benchmarkFailed(std::string const&) override;
   6350 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   6351 
   6352     private:
   6353         Timer m_testCaseTimer;
   6354         XmlWriter m_xml;
   6355         int m_sectionDepth = 0;
   6356     };
   6357 
   6358 } // end namespace Catch
   6359 
   6360 // end catch_reporter_xml.h
   6361 
   6362 // end catch_external_interfaces.h
   6363 #endif
   6364 
   6365 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   6366 // start catch_benchmarking_all.hpp
   6367 
   6368 // A proxy header that includes all of the benchmarking headers to allow
   6369 // concise include of the benchmarking features. You should prefer the
   6370 // individual includes in standard use.
   6371 
   6372 // start catch_benchmark.hpp
   6373 
   6374  // Benchmark
   6375 
   6376 // start catch_chronometer.hpp
   6377 
   6378 // User-facing chronometer
   6379 
   6380 
   6381 // start catch_clock.hpp
   6382 
   6383 // Clocks
   6384 
   6385 
   6386 #include <chrono>
   6387 #include <ratio>
   6388 
   6389 namespace Catch {
   6390     namespace Benchmark {
   6391         template <typename Clock>
   6392         using ClockDuration = typename Clock::duration;
   6393         template <typename Clock>
   6394         using FloatDuration = std::chrono::duration<double, typename Clock::period>;
   6395 
   6396         template <typename Clock>
   6397         using TimePoint = typename Clock::time_point;
   6398 
   6399         using default_clock = std::chrono::steady_clock;
   6400 
   6401         template <typename Clock>
   6402         struct now {
   6403             TimePoint<Clock> operator()() const {
   6404                 return Clock::now();
   6405             }
   6406         };
   6407 
   6408         using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
   6409     } // namespace Benchmark
   6410 } // namespace Catch
   6411 
   6412 // end catch_clock.hpp
   6413 // start catch_optimizer.hpp
   6414 
   6415  // Hinting the optimizer
   6416 
   6417 
   6418 #if defined(_MSC_VER)
   6419 #   include <atomic> // atomic_thread_fence
   6420 #endif
   6421 
   6422 namespace Catch {
   6423     namespace Benchmark {
   6424 #if defined(__GNUC__) || defined(__clang__)
   6425         template <typename T>
   6426         inline void keep_memory(T* p) {
   6427             asm volatile("" : : "g"(p) : "memory");
   6428         }
   6429         inline void keep_memory() {
   6430             asm volatile("" : : : "memory");
   6431         }
   6432 
   6433         namespace Detail {
   6434             inline void optimizer_barrier() { keep_memory(); }
   6435         } // namespace Detail
   6436 #elif defined(_MSC_VER)
   6437 
   6438 #pragma optimize("", off)
   6439         template <typename T>
   6440         inline void keep_memory(T* p) {
   6441             // thanks @milleniumbug
   6442             *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
   6443         }
   6444         // TODO equivalent keep_memory()
   6445 #pragma optimize("", on)
   6446 
   6447         namespace Detail {
   6448             inline void optimizer_barrier() {
   6449                 std::atomic_thread_fence(std::memory_order_seq_cst);
   6450             }
   6451         } // namespace Detail
   6452 
   6453 #endif
   6454 
   6455         template <typename T>
   6456         inline void deoptimize_value(T&& x) {
   6457             keep_memory(&x);
   6458         }
   6459 
   6460         template <typename Fn, typename... Args>
   6461         inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
   6462             deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));
   6463         }
   6464 
   6465         template <typename Fn, typename... Args>
   6466         inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
   6467             std::forward<Fn>(fn) (std::forward<Args...>(args...));
   6468         }
   6469     } // namespace Benchmark
   6470 } // namespace Catch
   6471 
   6472 // end catch_optimizer.hpp
   6473 // start catch_complete_invoke.hpp
   6474 
   6475 // Invoke with a special case for void
   6476 
   6477 
   6478 #include <type_traits>
   6479 #include <utility>
   6480 
   6481 namespace Catch {
   6482     namespace Benchmark {
   6483         namespace Detail {
   6484             template <typename T>
   6485             struct CompleteType { using type = T; };
   6486             template <>
   6487             struct CompleteType<void> { struct type {}; };
   6488 
   6489             template <typename T>
   6490             using CompleteType_t = typename CompleteType<T>::type;
   6491 
   6492             template <typename Result>
   6493             struct CompleteInvoker {
   6494                 template <typename Fun, typename... Args>
   6495                 static Result invoke(Fun&& fun, Args&&... args) {
   6496                     return std::forward<Fun>(fun)(std::forward<Args>(args)...);
   6497                 }
   6498             };
   6499             template <>
   6500             struct CompleteInvoker<void> {
   6501                 template <typename Fun, typename... Args>
   6502                 static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
   6503                     std::forward<Fun>(fun)(std::forward<Args>(args)...);
   6504                     return {};
   6505                 }
   6506             };
   6507             template <typename Sig>
   6508             using ResultOf_t = typename std::result_of<Sig>::type;
   6509 
   6510             // invoke and not return void :(
   6511             template <typename Fun, typename... Args>
   6512             CompleteType_t<ResultOf_t<Fun(Args...)>> complete_invoke(Fun&& fun, Args&&... args) {
   6513                 return CompleteInvoker<ResultOf_t<Fun(Args...)>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
   6514             }
   6515 
   6516             const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
   6517         } // namespace Detail
   6518 
   6519         template <typename Fun>
   6520         Detail::CompleteType_t<Detail::ResultOf_t<Fun()>> user_code(Fun&& fun) {
   6521             CATCH_TRY{
   6522                 return Detail::complete_invoke(std::forward<Fun>(fun));
   6523             } CATCH_CATCH_ALL{
   6524                 getResultCapture().benchmarkFailed(translateActiveException());
   6525                 CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
   6526             }
   6527         }
   6528     } // namespace Benchmark
   6529 } // namespace Catch
   6530 
   6531 // end catch_complete_invoke.hpp
   6532 namespace Catch {
   6533     namespace Benchmark {
   6534         namespace Detail {
   6535             struct ChronometerConcept {
   6536                 virtual void start() = 0;
   6537                 virtual void finish() = 0;
   6538                 virtual ~ChronometerConcept() = default;
   6539             };
   6540             template <typename Clock>
   6541             struct ChronometerModel final : public ChronometerConcept {
   6542                 void start() override { started = Clock::now(); }
   6543                 void finish() override { finished = Clock::now(); }
   6544 
   6545                 ClockDuration<Clock> elapsed() const { return finished - started; }
   6546 
   6547                 TimePoint<Clock> started;
   6548                 TimePoint<Clock> finished;
   6549             };
   6550         } // namespace Detail
   6551 
   6552         struct Chronometer {
   6553         public:
   6554             template <typename Fun>
   6555             void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
   6556 
   6557             int runs() const { return k; }
   6558 
   6559             Chronometer(Detail::ChronometerConcept& meter, int k)
   6560                 : impl(&meter)
   6561                 , k(k) {}
   6562 
   6563         private:
   6564             template <typename Fun>
   6565             void measure(Fun&& fun, std::false_type) {
   6566                 measure([&fun](int) { return fun(); }, std::true_type());
   6567             }
   6568 
   6569             template <typename Fun>
   6570             void measure(Fun&& fun, std::true_type) {
   6571                 Detail::optimizer_barrier();
   6572                 impl->start();
   6573                 for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);
   6574                 impl->finish();
   6575                 Detail::optimizer_barrier();
   6576             }
   6577 
   6578             Detail::ChronometerConcept* impl;
   6579             int k;
   6580         };
   6581     } // namespace Benchmark
   6582 } // namespace Catch
   6583 
   6584 // end catch_chronometer.hpp
   6585 // start catch_environment.hpp
   6586 
   6587 // Environment information
   6588 
   6589 
   6590 namespace Catch {
   6591     namespace Benchmark {
   6592         template <typename Duration>
   6593         struct EnvironmentEstimate {
   6594             Duration mean;
   6595             OutlierClassification outliers;
   6596 
   6597             template <typename Duration2>
   6598             operator EnvironmentEstimate<Duration2>() const {
   6599                 return { mean, outliers };
   6600             }
   6601         };
   6602         template <typename Clock>
   6603         struct Environment {
   6604             using clock_type = Clock;
   6605             EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
   6606             EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
   6607         };
   6608     } // namespace Benchmark
   6609 } // namespace Catch
   6610 
   6611 // end catch_environment.hpp
   6612 // start catch_execution_plan.hpp
   6613 
   6614  // Execution plan
   6615 
   6616 
   6617 // start catch_benchmark_function.hpp
   6618 
   6619  // Dumb std::function implementation for consistent call overhead
   6620 
   6621 
   6622 #include <cassert>
   6623 #include <type_traits>
   6624 #include <utility>
   6625 #include <memory>
   6626 
   6627 namespace Catch {
   6628     namespace Benchmark {
   6629         namespace Detail {
   6630             template <typename T>
   6631             using Decay = typename std::decay<T>::type;
   6632             template <typename T, typename U>
   6633             struct is_related
   6634                 : std::is_same<Decay<T>, Decay<U>> {};
   6635 
   6636             /// We need to reinvent std::function because every piece of code that might add overhead
   6637             /// in a measurement context needs to have consistent performance characteristics so that we
   6638             /// can account for it in the measurement.
   6639             /// Implementations of std::function with optimizations that aren't always applicable, like
   6640             /// small buffer optimizations, are not uncommon.
   6641             /// This is effectively an implementation of std::function without any such optimizations;
   6642             /// it may be slow, but it is consistently slow.
   6643             struct BenchmarkFunction {
   6644             private:
   6645                 struct callable {
   6646                     virtual void call(Chronometer meter) const = 0;
   6647                     virtual callable* clone() const = 0;
   6648                     virtual ~callable() = default;
   6649                 };
   6650                 template <typename Fun>
   6651                 struct model : public callable {
   6652                     model(Fun&& fun) : fun(std::move(fun)) {}
   6653                     model(Fun const& fun) : fun(fun) {}
   6654 
   6655                     model<Fun>* clone() const override { return new model<Fun>(*this); }
   6656 
   6657                     void call(Chronometer meter) const override {
   6658                         call(meter, is_callable<Fun(Chronometer)>());
   6659                     }
   6660                     void call(Chronometer meter, std::true_type) const {
   6661                         fun(meter);
   6662                     }
   6663                     void call(Chronometer meter, std::false_type) const {
   6664                         meter.measure(fun);
   6665                     }
   6666 
   6667                     Fun fun;
   6668                 };
   6669 
   6670                 struct do_nothing { void operator()() const {} };
   6671 
   6672                 template <typename T>
   6673                 BenchmarkFunction(model<T>* c) : f(c) {}
   6674 
   6675             public:
   6676                 BenchmarkFunction()
   6677                     : f(new model<do_nothing>{ {} }) {}
   6678 
   6679                 template <typename Fun,
   6680                     typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
   6681                     BenchmarkFunction(Fun&& fun)
   6682                     : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}
   6683 
   6684                 BenchmarkFunction(BenchmarkFunction&& that)
   6685                     : f(std::move(that.f)) {}
   6686 
   6687                 BenchmarkFunction(BenchmarkFunction const& that)
   6688                     : f(that.f->clone()) {}
   6689 
   6690                 BenchmarkFunction& operator=(BenchmarkFunction&& that) {
   6691                     f = std::move(that.f);
   6692                     return *this;
   6693                 }
   6694 
   6695                 BenchmarkFunction& operator=(BenchmarkFunction const& that) {
   6696                     f.reset(that.f->clone());
   6697                     return *this;
   6698                 }
   6699 
   6700                 void operator()(Chronometer meter) const { f->call(meter); }
   6701 
   6702             private:
   6703                 std::unique_ptr<callable> f;
   6704             };
   6705         } // namespace Detail
   6706     } // namespace Benchmark
   6707 } // namespace Catch
   6708 
   6709 // end catch_benchmark_function.hpp
   6710 // start catch_repeat.hpp
   6711 
   6712 // repeat algorithm
   6713 
   6714 
   6715 #include <type_traits>
   6716 #include <utility>
   6717 
   6718 namespace Catch {
   6719     namespace Benchmark {
   6720         namespace Detail {
   6721             template <typename Fun>
   6722             struct repeater {
   6723                 void operator()(int k) const {
   6724                     for (int i = 0; i < k; ++i) {
   6725                         fun();
   6726                     }
   6727                 }
   6728                 Fun fun;
   6729             };
   6730             template <typename Fun>
   6731             repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {
   6732                 return { std::forward<Fun>(fun) };
   6733             }
   6734         } // namespace Detail
   6735     } // namespace Benchmark
   6736 } // namespace Catch
   6737 
   6738 // end catch_repeat.hpp
   6739 // start catch_run_for_at_least.hpp
   6740 
   6741 // Run a function for a minimum amount of time
   6742 
   6743 
   6744 // start catch_measure.hpp
   6745 
   6746 // Measure
   6747 
   6748 
   6749 // start catch_timing.hpp
   6750 
   6751 // Timing
   6752 
   6753 
   6754 #include <tuple>
   6755 #include <type_traits>
   6756 
   6757 namespace Catch {
   6758     namespace Benchmark {
   6759         template <typename Duration, typename Result>
   6760         struct Timing {
   6761             Duration elapsed;
   6762             Result result;
   6763             int iterations;
   6764         };
   6765         template <typename Clock, typename Sig>
   6766         using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<Detail::ResultOf_t<Sig>>>;
   6767     } // namespace Benchmark
   6768 } // namespace Catch
   6769 
   6770 // end catch_timing.hpp
   6771 #include <utility>
   6772 
   6773 namespace Catch {
   6774     namespace Benchmark {
   6775         namespace Detail {
   6776             template <typename Clock, typename Fun, typename... Args>
   6777             TimingOf<Clock, Fun(Args...)> measure(Fun&& fun, Args&&... args) {
   6778                 auto start = Clock::now();
   6779                 auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
   6780                 auto end = Clock::now();
   6781                 auto delta = end - start;
   6782                 return { delta, std::forward<decltype(r)>(r), 1 };
   6783             }
   6784         } // namespace Detail
   6785     } // namespace Benchmark
   6786 } // namespace Catch
   6787 
   6788 // end catch_measure.hpp
   6789 #include <utility>
   6790 #include <type_traits>
   6791 
   6792 namespace Catch {
   6793     namespace Benchmark {
   6794         namespace Detail {
   6795             template <typename Clock, typename Fun>
   6796             TimingOf<Clock, Fun(int)> measure_one(Fun&& fun, int iters, std::false_type) {
   6797                 return Detail::measure<Clock>(fun, iters);
   6798             }
   6799             template <typename Clock, typename Fun>
   6800             TimingOf<Clock, Fun(Chronometer)> measure_one(Fun&& fun, int iters, std::true_type) {
   6801                 Detail::ChronometerModel<Clock> meter;
   6802                 auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
   6803 
   6804                 return { meter.elapsed(), std::move(result), iters };
   6805             }
   6806 
   6807             template <typename Clock, typename Fun>
   6808             using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
   6809 
   6810             struct optimized_away_error : std::exception {
   6811                 const char* what() const noexcept override {
   6812                     return "could not measure benchmark, maybe it was optimized away";
   6813                 }
   6814             };
   6815 
   6816             template <typename Clock, typename Fun>
   6817             TimingOf<Clock, Fun(run_for_at_least_argument_t<Clock, Fun>)> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
   6818                 auto iters = seed;
   6819                 while (iters < (1 << 30)) {
   6820                     auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
   6821 
   6822                     if (Timing.elapsed >= how_long) {
   6823                         return { Timing.elapsed, std::move(Timing.result), iters };
   6824                     }
   6825                     iters *= 2;
   6826                 }
   6827                 throw optimized_away_error{};
   6828             }
   6829         } // namespace Detail
   6830     } // namespace Benchmark
   6831 } // namespace Catch
   6832 
   6833 // end catch_run_for_at_least.hpp
   6834 #include <algorithm>
   6835 
   6836 namespace Catch {
   6837     namespace Benchmark {
   6838         template <typename Duration>
   6839         struct ExecutionPlan {
   6840             int iterations_per_sample;
   6841             Duration estimated_duration;
   6842             Detail::BenchmarkFunction benchmark;
   6843             Duration warmup_time;
   6844             int warmup_iterations;
   6845 
   6846             template <typename Duration2>
   6847             operator ExecutionPlan<Duration2>() const {
   6848                 return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
   6849             }
   6850 
   6851             template <typename Clock>
   6852             std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
   6853                 // warmup a bit
   6854                 Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
   6855 
   6856                 std::vector<FloatDuration<Clock>> times;
   6857                 times.reserve(cfg.benchmarkSamples());
   6858                 std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
   6859                     Detail::ChronometerModel<Clock> model;
   6860                     this->benchmark(Chronometer(model, iterations_per_sample));
   6861                     auto sample_time = model.elapsed() - env.clock_cost.mean;
   6862                     if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
   6863                     return sample_time / iterations_per_sample;
   6864                 });
   6865                 return times;
   6866             }
   6867         };
   6868     } // namespace Benchmark
   6869 } // namespace Catch
   6870 
   6871 // end catch_execution_plan.hpp
   6872 // start catch_estimate_clock.hpp
   6873 
   6874  // Environment measurement
   6875 
   6876 
   6877 // start catch_stats.hpp
   6878 
   6879 // Statistical analysis tools
   6880 
   6881 
   6882 #include <algorithm>
   6883 #include <functional>
   6884 #include <vector>
   6885 #include <numeric>
   6886 #include <tuple>
   6887 #include <cmath>
   6888 #include <utility>
   6889 #include <cstddef>
   6890 
   6891 namespace Catch {
   6892     namespace Benchmark {
   6893         namespace Detail {
   6894             using sample = std::vector<double>;
   6895 
   6896             double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
   6897 
   6898             template <typename Iterator>
   6899             OutlierClassification classify_outliers(Iterator first, Iterator last) {
   6900                 std::vector<double> copy(first, last);
   6901 
   6902                 auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
   6903                 auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
   6904                 auto iqr = q3 - q1;
   6905                 auto los = q1 - (iqr * 3.);
   6906                 auto lom = q1 - (iqr * 1.5);
   6907                 auto him = q3 + (iqr * 1.5);
   6908                 auto his = q3 + (iqr * 3.);
   6909 
   6910                 OutlierClassification o;
   6911                 for (; first != last; ++first) {
   6912                     auto&& t = *first;
   6913                     if (t < los) ++o.low_severe;
   6914                     else if (t < lom) ++o.low_mild;
   6915                     else if (t > his) ++o.high_severe;
   6916                     else if (t > him) ++o.high_mild;
   6917                     ++o.samples_seen;
   6918                 }
   6919                 return o;
   6920             }
   6921 
   6922             template <typename Iterator>
   6923             double mean(Iterator first, Iterator last) {
   6924                 auto count = last - first;
   6925                 double sum = std::accumulate(first, last, 0.);
   6926                 return sum / count;
   6927             }
   6928 
   6929             template <typename URng, typename Iterator, typename Estimator>
   6930             sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {
   6931                 auto n = last - first;
   6932                 std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
   6933 
   6934                 sample out;
   6935                 out.reserve(resamples);
   6936                 std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
   6937                     std::vector<double> resampled;
   6938                     resampled.reserve(n);
   6939                     std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
   6940                     return estimator(resampled.begin(), resampled.end());
   6941                 });
   6942                 std::sort(out.begin(), out.end());
   6943                 return out;
   6944             }
   6945 
   6946             template <typename Estimator, typename Iterator>
   6947             sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
   6948                 auto n = last - first;
   6949                 auto second = std::next(first);
   6950                 sample results;
   6951                 results.reserve(n);
   6952 
   6953                 for (auto it = first; it != last; ++it) {
   6954                     std::iter_swap(it, first);
   6955                     results.push_back(estimator(second, last));
   6956                 }
   6957 
   6958                 return results;
   6959             }
   6960 
   6961             inline double normal_cdf(double x) {
   6962                 return std::erfc(-x / std::sqrt(2.0)) / 2.0;
   6963             }
   6964 
   6965             double erfc_inv(double x);
   6966 
   6967             double normal_quantile(double p);
   6968 
   6969             template <typename Iterator, typename Estimator>
   6970             Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
   6971                 auto n_samples = last - first;
   6972 
   6973                 double point = estimator(first, last);
   6974                 // Degenerate case with a single sample
   6975                 if (n_samples == 1) return { point, point, point, confidence_level };
   6976 
   6977                 sample jack = jackknife(estimator, first, last);
   6978                 double jack_mean = mean(jack.begin(), jack.end());
   6979                 double sum_squares, sum_cubes;
   6980                 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> {
   6981                     auto d = jack_mean - x;
   6982                     auto d2 = d * d;
   6983                     auto d3 = d2 * d;
   6984                     return { sqcb.first + d2, sqcb.second + d3 };
   6985                 });
   6986 
   6987                 double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
   6988                 int n = static_cast<int>(resample.size());
   6989                 double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
   6990                 // degenerate case with uniform samples
   6991                 if (prob_n == 0) return { point, point, point, confidence_level };
   6992 
   6993                 double bias = normal_quantile(prob_n);
   6994                 double z1 = normal_quantile((1. - confidence_level) / 2.);
   6995 
   6996                 auto cumn = [n](double x) -> int {
   6997                     return std::lround(normal_cdf(x) * n); };
   6998                 auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
   6999                 double b1 = bias + z1;
   7000                 double b2 = bias - z1;
   7001                 double a1 = a(b1);
   7002                 double a2 = a(b2);
   7003                 auto lo = std::max(cumn(a1), 0);
   7004                 auto hi = std::min(cumn(a2), n - 1);
   7005 
   7006                 return { point, resample[lo], resample[hi], confidence_level };
   7007             }
   7008 
   7009             double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
   7010 
   7011             struct bootstrap_analysis {
   7012                 Estimate<double> mean;
   7013                 Estimate<double> standard_deviation;
   7014                 double outlier_variance;
   7015             };
   7016 
   7017             bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
   7018         } // namespace Detail
   7019     } // namespace Benchmark
   7020 } // namespace Catch
   7021 
   7022 // end catch_stats.hpp
   7023 #include <algorithm>
   7024 #include <iterator>
   7025 #include <tuple>
   7026 #include <vector>
   7027 #include <cmath>
   7028 
   7029 namespace Catch {
   7030     namespace Benchmark {
   7031         namespace Detail {
   7032             template <typename Clock>
   7033             std::vector<double> resolution(int k) {
   7034                 std::vector<TimePoint<Clock>> times;
   7035                 times.reserve(k + 1);
   7036                 std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
   7037 
   7038                 std::vector<double> deltas;
   7039                 deltas.reserve(k);
   7040                 std::transform(std::next(times.begin()), times.end(), times.begin(),
   7041                     std::back_inserter(deltas),
   7042                     [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
   7043 
   7044                 return deltas;
   7045             }
   7046 
   7047             const auto warmup_iterations = 10000;
   7048             const auto warmup_time = std::chrono::milliseconds(100);
   7049             const auto minimum_ticks = 1000;
   7050             const auto warmup_seed = 10000;
   7051             const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
   7052             const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
   7053             const auto clock_cost_estimation_tick_limit = 100000;
   7054             const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
   7055             const auto clock_cost_estimation_iterations = 10000;
   7056 
   7057             template <typename Clock>
   7058             int warmup() {
   7059                 return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)
   7060                     .iterations;
   7061             }
   7062             template <typename Clock>
   7063             EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
   7064                 auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
   7065                     .result;
   7066                 return {
   7067                     FloatDuration<Clock>(mean(r.begin(), r.end())),
   7068                     classify_outliers(r.begin(), r.end()),
   7069                 };
   7070             }
   7071             template <typename Clock>
   7072             EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
   7073                 auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
   7074                 auto time_clock = [](int k) {
   7075                     return Detail::measure<Clock>([k] {
   7076                         for (int i = 0; i < k; ++i) {
   7077                             volatile auto ignored = Clock::now();
   7078                             (void)ignored;
   7079                         }
   7080                     }).elapsed;
   7081                 };
   7082                 time_clock(1);
   7083                 int iters = clock_cost_estimation_iterations;
   7084                 auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
   7085                 std::vector<double> times;
   7086                 int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
   7087                 times.reserve(nsamples);
   7088                 std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
   7089                     return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
   7090                 });
   7091                 return {
   7092                     FloatDuration<Clock>(mean(times.begin(), times.end())),
   7093                     classify_outliers(times.begin(), times.end()),
   7094                 };
   7095             }
   7096 
   7097             template <typename Clock>
   7098             Environment<FloatDuration<Clock>> measure_environment() {
   7099                 static Environment<FloatDuration<Clock>>* env = nullptr;
   7100                 if (env) {
   7101                     return *env;
   7102                 }
   7103 
   7104                 auto iters = Detail::warmup<Clock>();
   7105                 auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
   7106                 auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
   7107 
   7108                 env = new Environment<FloatDuration<Clock>>{ resolution, cost };
   7109                 return *env;
   7110             }
   7111         } // namespace Detail
   7112     } // namespace Benchmark
   7113 } // namespace Catch
   7114 
   7115 // end catch_estimate_clock.hpp
   7116 // start catch_analyse.hpp
   7117 
   7118  // Run and analyse one benchmark
   7119 
   7120 
   7121 // start catch_sample_analysis.hpp
   7122 
   7123 // Benchmark results
   7124 
   7125 
   7126 #include <algorithm>
   7127 #include <vector>
   7128 #include <string>
   7129 #include <iterator>
   7130 
   7131 namespace Catch {
   7132     namespace Benchmark {
   7133         template <typename Duration>
   7134         struct SampleAnalysis {
   7135             std::vector<Duration> samples;
   7136             Estimate<Duration> mean;
   7137             Estimate<Duration> standard_deviation;
   7138             OutlierClassification outliers;
   7139             double outlier_variance;
   7140 
   7141             template <typename Duration2>
   7142             operator SampleAnalysis<Duration2>() const {
   7143                 std::vector<Duration2> samples2;
   7144                 samples2.reserve(samples.size());
   7145                 std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
   7146                 return {
   7147                     std::move(samples2),
   7148                     mean,
   7149                     standard_deviation,
   7150                     outliers,
   7151                     outlier_variance,
   7152                 };
   7153             }
   7154         };
   7155     } // namespace Benchmark
   7156 } // namespace Catch
   7157 
   7158 // end catch_sample_analysis.hpp
   7159 #include <algorithm>
   7160 #include <iterator>
   7161 #include <vector>
   7162 
   7163 namespace Catch {
   7164     namespace Benchmark {
   7165         namespace Detail {
   7166             template <typename Duration, typename Iterator>
   7167             SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
   7168                 if (!cfg.benchmarkNoAnalysis()) {
   7169                     std::vector<double> samples;
   7170                     samples.reserve(last - first);
   7171                     std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
   7172 
   7173                     auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
   7174                     auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
   7175 
   7176                     auto wrap_estimate = [](Estimate<double> e) {
   7177                         return Estimate<Duration> {
   7178                             Duration(e.point),
   7179                                 Duration(e.lower_bound),
   7180                                 Duration(e.upper_bound),
   7181                                 e.confidence_interval,
   7182                         };
   7183                     };
   7184                     std::vector<Duration> samples2;
   7185                     samples2.reserve(samples.size());
   7186                     std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
   7187                     return {
   7188                         std::move(samples2),
   7189                         wrap_estimate(analysis.mean),
   7190                         wrap_estimate(analysis.standard_deviation),
   7191                         outliers,
   7192                         analysis.outlier_variance,
   7193                     };
   7194                 } else {
   7195                     std::vector<Duration> samples;
   7196                     samples.reserve(last - first);
   7197 
   7198                     Duration mean = Duration(0);
   7199                     int i = 0;
   7200                     for (auto it = first; it < last; ++it, ++i) {
   7201                         samples.push_back(Duration(*it));
   7202                         mean += Duration(*it);
   7203                     }
   7204                     mean /= i;
   7205 
   7206                     return {
   7207                         std::move(samples),
   7208                         Estimate<Duration>{mean, mean, mean, 0.0},
   7209                         Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
   7210                         OutlierClassification{},
   7211                         0.0
   7212                     };
   7213                 }
   7214             }
   7215         } // namespace Detail
   7216     } // namespace Benchmark
   7217 } // namespace Catch
   7218 
   7219 // end catch_analyse.hpp
   7220 #include <algorithm>
   7221 #include <functional>
   7222 #include <string>
   7223 #include <vector>
   7224 #include <cmath>
   7225 
   7226 namespace Catch {
   7227     namespace Benchmark {
   7228         struct Benchmark {
   7229             Benchmark(std::string &&name)
   7230                 : name(std::move(name)) {}
   7231 
   7232             template <class FUN>
   7233             Benchmark(std::string &&name, FUN &&func)
   7234                 : fun(std::move(func)), name(std::move(name)) {}
   7235 
   7236             template <typename Clock>
   7237             ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
   7238                 auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
   7239                 auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(Detail::warmup_time));
   7240                 auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
   7241                 int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
   7242                 return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(Detail::warmup_time), Detail::warmup_iterations };
   7243             }
   7244 
   7245             template <typename Clock = default_clock>
   7246             void run() {
   7247                 IConfigPtr cfg = getCurrentContext().getConfig();
   7248 
   7249                 auto env = Detail::measure_environment<Clock>();
   7250 
   7251                 getResultCapture().benchmarkPreparing(name);
   7252                 CATCH_TRY{
   7253                     auto plan = user_code([&] {
   7254                         return prepare<Clock>(*cfg, env);
   7255                     });
   7256 
   7257                     BenchmarkInfo info {
   7258                         name,
   7259                         plan.estimated_duration.count(),
   7260                         plan.iterations_per_sample,
   7261                         cfg->benchmarkSamples(),
   7262                         cfg->benchmarkResamples(),
   7263                         env.clock_resolution.mean.count(),
   7264                         env.clock_cost.mean.count()
   7265                     };
   7266 
   7267                     getResultCapture().benchmarkStarting(info);
   7268 
   7269                     auto samples = user_code([&] {
   7270                         return plan.template run<Clock>(*cfg, env);
   7271                     });
   7272 
   7273                     auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
   7274                     BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
   7275                     getResultCapture().benchmarkEnded(stats);
   7276 
   7277                 } CATCH_CATCH_ALL{
   7278                     if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
   7279                         std::rethrow_exception(std::current_exception());
   7280                 }
   7281             }
   7282 
   7283             // sets lambda to be used in fun *and* executes benchmark!
   7284             template <typename Fun,
   7285                 typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
   7286                 Benchmark & operator=(Fun func) {
   7287                 fun = Detail::BenchmarkFunction(func);
   7288                 run();
   7289                 return *this;
   7290             }
   7291 
   7292             explicit operator bool() {
   7293                 return true;
   7294             }
   7295 
   7296         private:
   7297             Detail::BenchmarkFunction fun;
   7298             std::string name;
   7299         };
   7300     }
   7301 } // namespace Catch
   7302 
   7303 #define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
   7304 #define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
   7305 
   7306 #define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
   7307     if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
   7308         BenchmarkName = [&](int benchmarkIndex)
   7309 
   7310 #define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
   7311     if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
   7312         BenchmarkName = [&]
   7313 
   7314 // end catch_benchmark.hpp
   7315 // start catch_constructor.hpp
   7316 
   7317 // Constructor and destructor helpers
   7318 
   7319 
   7320 #include <type_traits>
   7321 
   7322 namespace Catch {
   7323     namespace Detail {
   7324         template <typename T, bool Destruct>
   7325         struct ObjectStorage
   7326         {
   7327             using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
   7328 
   7329             ObjectStorage() : data() {}
   7330 
   7331             ObjectStorage(const ObjectStorage& other)
   7332             {
   7333                 new(&data) T(other.stored_object());
   7334             }
   7335 
   7336             ObjectStorage(ObjectStorage&& other)
   7337             {
   7338                 new(&data) T(std::move(other.stored_object()));
   7339             }
   7340 
   7341             ~ObjectStorage() { destruct_on_exit<T>(); }
   7342 
   7343             template <typename... Args>
   7344             void construct(Args&&... args)
   7345             {
   7346                 new (&data) T(std::forward<Args>(args)...);
   7347             }
   7348 
   7349             template <bool AllowManualDestruction = !Destruct>
   7350             typename std::enable_if<AllowManualDestruction>::type destruct()
   7351             {
   7352                 stored_object().~T();
   7353             }
   7354 
   7355         private:
   7356             // If this is a constructor benchmark, destruct the underlying object
   7357             template <typename U>
   7358             void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
   7359             // Otherwise, don't
   7360             template <typename U>
   7361             void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
   7362 
   7363             T& stored_object()
   7364             {
   7365                 return *static_cast<T*>(static_cast<void*>(&data));
   7366             }
   7367 
   7368             TStorage data;
   7369         };
   7370     }
   7371 
   7372     template <typename T>
   7373     using storage_for = Detail::ObjectStorage<T, true>;
   7374 
   7375     template <typename T>
   7376     using destructable_object = Detail::ObjectStorage<T, false>;
   7377 }
   7378 
   7379 // end catch_constructor.hpp
   7380 // end catch_benchmarking_all.hpp
   7381 #endif
   7382 
   7383 #endif // ! CATCH_CONFIG_IMPL_ONLY
   7384 
   7385 #ifdef CATCH_IMPL
   7386 // start catch_impl.hpp
   7387 
   7388 #ifdef __clang__
   7389 #pragma clang diagnostic push
   7390 #pragma clang diagnostic ignored "-Wweak-vtables"
   7391 #endif
   7392 
   7393 // Keep these here for external reporters
   7394 // start catch_test_case_tracker.h
   7395 
   7396 #include <string>
   7397 #include <vector>
   7398 #include <memory>
   7399 
   7400 namespace Catch {
   7401 namespace TestCaseTracking {
   7402 
   7403     struct NameAndLocation {
   7404         std::string name;
   7405         SourceLineInfo location;
   7406 
   7407         NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
   7408     };
   7409 
   7410     struct ITracker;
   7411 
   7412     using ITrackerPtr = std::shared_ptr<ITracker>;
   7413 
   7414     struct ITracker {
   7415         virtual ~ITracker();
   7416 
   7417         // static queries
   7418         virtual NameAndLocation const& nameAndLocation() const = 0;
   7419 
   7420         // dynamic queries
   7421         virtual bool isComplete() const = 0; // Successfully completed or failed
   7422         virtual bool isSuccessfullyCompleted() const = 0;
   7423         virtual bool isOpen() const = 0; // Started but not complete
   7424         virtual bool hasChildren() const = 0;
   7425 
   7426         virtual ITracker& parent() = 0;
   7427 
   7428         // actions
   7429         virtual void close() = 0; // Successfully complete
   7430         virtual void fail() = 0;
   7431         virtual void markAsNeedingAnotherRun() = 0;
   7432 
   7433         virtual void addChild( ITrackerPtr const& child ) = 0;
   7434         virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
   7435         virtual void openChild() = 0;
   7436 
   7437         // Debug/ checking
   7438         virtual bool isSectionTracker() const = 0;
   7439         virtual bool isGeneratorTracker() const = 0;
   7440     };
   7441 
   7442     class TrackerContext {
   7443 
   7444         enum RunState {
   7445             NotStarted,
   7446             Executing,
   7447             CompletedCycle
   7448         };
   7449 
   7450         ITrackerPtr m_rootTracker;
   7451         ITracker* m_currentTracker = nullptr;
   7452         RunState m_runState = NotStarted;
   7453 
   7454     public:
   7455 
   7456         ITracker& startRun();
   7457         void endRun();
   7458 
   7459         void startCycle();
   7460         void completeCycle();
   7461 
   7462         bool completedCycle() const;
   7463         ITracker& currentTracker();
   7464         void setCurrentTracker( ITracker* tracker );
   7465     };
   7466 
   7467     class TrackerBase : public ITracker {
   7468     protected:
   7469         enum CycleState {
   7470             NotStarted,
   7471             Executing,
   7472             ExecutingChildren,
   7473             NeedsAnotherRun,
   7474             CompletedSuccessfully,
   7475             Failed
   7476         };
   7477 
   7478         using Children = std::vector<ITrackerPtr>;
   7479         NameAndLocation m_nameAndLocation;
   7480         TrackerContext& m_ctx;
   7481         ITracker* m_parent;
   7482         Children m_children;
   7483         CycleState m_runState = NotStarted;
   7484 
   7485     public:
   7486         TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
   7487 
   7488         NameAndLocation const& nameAndLocation() const override;
   7489         bool isComplete() const override;
   7490         bool isSuccessfullyCompleted() const override;
   7491         bool isOpen() const override;
   7492         bool hasChildren() const override;
   7493 
   7494         void addChild( ITrackerPtr const& child ) override;
   7495 
   7496         ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
   7497         ITracker& parent() override;
   7498 
   7499         void openChild() override;
   7500 
   7501         bool isSectionTracker() const override;
   7502         bool isGeneratorTracker() const override;
   7503 
   7504         void open();
   7505 
   7506         void close() override;
   7507         void fail() override;
   7508         void markAsNeedingAnotherRun() override;
   7509 
   7510     private:
   7511         void moveToParent();
   7512         void moveToThis();
   7513     };
   7514 
   7515     class SectionTracker : public TrackerBase {
   7516         std::vector<std::string> m_filters;
   7517         std::string m_trimmed_name;
   7518     public:
   7519         SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
   7520 
   7521         bool isSectionTracker() const override;
   7522 
   7523         bool isComplete() const override;
   7524 
   7525         static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
   7526 
   7527         void tryOpen();
   7528 
   7529         void addInitialFilters( std::vector<std::string> const& filters );
   7530         void addNextFilters( std::vector<std::string> const& filters );
   7531     };
   7532 
   7533 } // namespace TestCaseTracking
   7534 
   7535 using TestCaseTracking::ITracker;
   7536 using TestCaseTracking::TrackerContext;
   7537 using TestCaseTracking::SectionTracker;
   7538 
   7539 } // namespace Catch
   7540 
   7541 // end catch_test_case_tracker.h
   7542 
   7543 // start catch_leak_detector.h
   7544 
   7545 namespace Catch {
   7546 
   7547     struct LeakDetector {
   7548         LeakDetector();
   7549         ~LeakDetector();
   7550     };
   7551 
   7552 }
   7553 // end catch_leak_detector.h
   7554 // Cpp files will be included in the single-header file here
   7555 // start catch_stats.cpp
   7556 
   7557 // Statistical analysis tools
   7558 
   7559 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   7560 
   7561 #include <cassert>
   7562 #include <random>
   7563 
   7564 #if defined(CATCH_CONFIG_USE_ASYNC)
   7565 #include <future>
   7566 #endif
   7567 
   7568 namespace {
   7569     double erf_inv(double x) {
   7570         // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
   7571         double w, p;
   7572 
   7573         w = -log((1.0 - x) * (1.0 + x));
   7574 
   7575         if (w < 6.250000) {
   7576             w = w - 3.125000;
   7577             p = -3.6444120640178196996e-21;
   7578             p = -1.685059138182016589e-19 + p * w;
   7579             p = 1.2858480715256400167e-18 + p * w;
   7580             p = 1.115787767802518096e-17 + p * w;
   7581             p = -1.333171662854620906e-16 + p * w;
   7582             p = 2.0972767875968561637e-17 + p * w;
   7583             p = 6.6376381343583238325e-15 + p * w;
   7584             p = -4.0545662729752068639e-14 + p * w;
   7585             p = -8.1519341976054721522e-14 + p * w;
   7586             p = 2.6335093153082322977e-12 + p * w;
   7587             p = -1.2975133253453532498e-11 + p * w;
   7588             p = -5.4154120542946279317e-11 + p * w;
   7589             p = 1.051212273321532285e-09 + p * w;
   7590             p = -4.1126339803469836976e-09 + p * w;
   7591             p = -2.9070369957882005086e-08 + p * w;
   7592             p = 4.2347877827932403518e-07 + p * w;
   7593             p = -1.3654692000834678645e-06 + p * w;
   7594             p = -1.3882523362786468719e-05 + p * w;
   7595             p = 0.0001867342080340571352 + p * w;
   7596             p = -0.00074070253416626697512 + p * w;
   7597             p = -0.0060336708714301490533 + p * w;
   7598             p = 0.24015818242558961693 + p * w;
   7599             p = 1.6536545626831027356 + p * w;
   7600         } else if (w < 16.000000) {
   7601             w = sqrt(w) - 3.250000;
   7602             p = 2.2137376921775787049e-09;
   7603             p = 9.0756561938885390979e-08 + p * w;
   7604             p = -2.7517406297064545428e-07 + p * w;
   7605             p = 1.8239629214389227755e-08 + p * w;
   7606             p = 1.5027403968909827627e-06 + p * w;
   7607             p = -4.013867526981545969e-06 + p * w;
   7608             p = 2.9234449089955446044e-06 + p * w;
   7609             p = 1.2475304481671778723e-05 + p * w;
   7610             p = -4.7318229009055733981e-05 + p * w;
   7611             p = 6.8284851459573175448e-05 + p * w;
   7612             p = 2.4031110387097893999e-05 + p * w;
   7613             p = -0.0003550375203628474796 + p * w;
   7614             p = 0.00095328937973738049703 + p * w;
   7615             p = -0.0016882755560235047313 + p * w;
   7616             p = 0.0024914420961078508066 + p * w;
   7617             p = -0.0037512085075692412107 + p * w;
   7618             p = 0.005370914553590063617 + p * w;
   7619             p = 1.0052589676941592334 + p * w;
   7620             p = 3.0838856104922207635 + p * w;
   7621         } else {
   7622             w = sqrt(w) - 5.000000;
   7623             p = -2.7109920616438573243e-11;
   7624             p = -2.5556418169965252055e-10 + p * w;
   7625             p = 1.5076572693500548083e-09 + p * w;
   7626             p = -3.7894654401267369937e-09 + p * w;
   7627             p = 7.6157012080783393804e-09 + p * w;
   7628             p = -1.4960026627149240478e-08 + p * w;
   7629             p = 2.9147953450901080826e-08 + p * w;
   7630             p = -6.7711997758452339498e-08 + p * w;
   7631             p = 2.2900482228026654717e-07 + p * w;
   7632             p = -9.9298272942317002539e-07 + p * w;
   7633             p = 4.5260625972231537039e-06 + p * w;
   7634             p = -1.9681778105531670567e-05 + p * w;
   7635             p = 7.5995277030017761139e-05 + p * w;
   7636             p = -0.00021503011930044477347 + p * w;
   7637             p = -0.00013871931833623122026 + p * w;
   7638             p = 1.0103004648645343977 + p * w;
   7639             p = 4.8499064014085844221 + p * w;
   7640         }
   7641         return p * x;
   7642     }
   7643 
   7644     double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
   7645         auto m = Catch::Benchmark::Detail::mean(first, last);
   7646         double variance = std::accumulate(first, last, 0., [m](double a, double b) {
   7647             double diff = b - m;
   7648             return a + diff * diff;
   7649             }) / (last - first);
   7650             return std::sqrt(variance);
   7651     }
   7652 
   7653 }
   7654 
   7655 namespace Catch {
   7656     namespace Benchmark {
   7657         namespace Detail {
   7658 
   7659             double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
   7660                 auto count = last - first;
   7661                 double idx = (count - 1) * k / static_cast<double>(q);
   7662                 int j = static_cast<int>(idx);
   7663                 double g = idx - j;
   7664                 std::nth_element(first, first + j, last);
   7665                 auto xj = first[j];
   7666                 if (g == 0) return xj;
   7667 
   7668                 auto xj1 = *std::min_element(first + (j + 1), last);
   7669                 return xj + g * (xj1 - xj);
   7670             }
   7671 
   7672             double erfc_inv(double x) {
   7673                 return erf_inv(1.0 - x);
   7674             }
   7675 
   7676             double normal_quantile(double p) {
   7677                 static const double ROOT_TWO = std::sqrt(2.0);
   7678 
   7679                 double result = 0.0;
   7680                 assert(p >= 0 && p <= 1);
   7681                 if (p < 0 || p > 1) {
   7682                     return result;
   7683                 }
   7684 
   7685                 result = -erfc_inv(2.0 * p);
   7686                 // result *= normal distribution standard deviation (1.0) * sqrt(2)
   7687                 result *= /*sd * */ ROOT_TWO;
   7688                 // result += normal disttribution mean (0)
   7689                 return result;
   7690             }
   7691 
   7692             double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
   7693                 double sb = stddev.point;
   7694                 double mn = mean.point / n;
   7695                 double mg_min = mn / 2.;
   7696                 double sg = std::min(mg_min / 4., sb / std::sqrt(n));
   7697                 double sg2 = sg * sg;
   7698                 double sb2 = sb * sb;
   7699 
   7700                 auto c_max = [n, mn, sb2, sg2](double x) -> double {
   7701                     double k = mn - x;
   7702                     double d = k * k;
   7703                     double nd = n * d;
   7704                     double k0 = -n * nd;
   7705                     double k1 = sb2 - n * sg2 + nd;
   7706                     double det = k1 * k1 - 4 * sg2 * k0;
   7707                     return (int)(-2. * k0 / (k1 + std::sqrt(det)));
   7708                 };
   7709 
   7710                 auto var_out = [n, sb2, sg2](double c) {
   7711                     double nc = n - c;
   7712                     return (nc / n) * (sb2 - nc * sg2);
   7713                 };
   7714 
   7715                 return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2;
   7716             }
   7717 
   7718             bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
   7719                 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
   7720                 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
   7721                 static std::random_device entropy;
   7722                 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
   7723 
   7724                 auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
   7725 
   7726                 auto mean = &Detail::mean<std::vector<double>::iterator>;
   7727                 auto stddev = &standard_deviation;
   7728 
   7729 #if defined(CATCH_CONFIG_USE_ASYNC)
   7730                 auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
   7731                     auto seed = entropy();
   7732                     return std::async(std::launch::async, [=] {
   7733                         std::mt19937 rng(seed);
   7734                         auto resampled = resample(rng, n_resamples, first, last, f);
   7735                         return bootstrap(confidence_level, first, last, resampled, f);
   7736                     });
   7737                 };
   7738 
   7739                 auto mean_future = Estimate(mean);
   7740                 auto stddev_future = Estimate(stddev);
   7741 
   7742                 auto mean_estimate = mean_future.get();
   7743                 auto stddev_estimate = stddev_future.get();
   7744 #else
   7745                 auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
   7746                     auto seed = entropy();
   7747                     std::mt19937 rng(seed);
   7748                     auto resampled = resample(rng, n_resamples, first, last, f);
   7749                     return bootstrap(confidence_level, first, last, resampled, f);
   7750                 };
   7751 
   7752                 auto mean_estimate = Estimate(mean);
   7753                 auto stddev_estimate = Estimate(stddev);
   7754 #endif // CATCH_USE_ASYNC
   7755 
   7756                 double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
   7757 
   7758                 return { mean_estimate, stddev_estimate, outlier_variance };
   7759             }
   7760         } // namespace Detail
   7761     } // namespace Benchmark
   7762 } // namespace Catch
   7763 
   7764 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   7765 // end catch_stats.cpp
   7766 // start catch_approx.cpp
   7767 
   7768 #include <cmath>
   7769 #include <limits>
   7770 
   7771 namespace {
   7772 
   7773 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
   7774 // But without the subtraction to allow for INFINITY in comparison
   7775 bool marginComparison(double lhs, double rhs, double margin) {
   7776     return (lhs + margin >= rhs) && (rhs + margin >= lhs);
   7777 }
   7778 
   7779 }
   7780 
   7781 namespace Catch {
   7782 namespace Detail {
   7783 
   7784     Approx::Approx ( double value )
   7785     :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
   7786         m_margin( 0.0 ),
   7787         m_scale( 0.0 ),
   7788         m_value( value )
   7789     {}
   7790 
   7791     Approx Approx::custom() {
   7792         return Approx( 0 );
   7793     }
   7794 
   7795     Approx Approx::operator-() const {
   7796         auto temp(*this);
   7797         temp.m_value = -temp.m_value;
   7798         return temp;
   7799     }
   7800 
   7801     std::string Approx::toString() const {
   7802         ReusableStringStream rss;
   7803         rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
   7804         return rss.str();
   7805     }
   7806 
   7807     bool Approx::equalityComparisonImpl(const double other) const {
   7808         // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
   7809         // Thanks to Richard Harris for his help refining the scaled margin value
   7810         return marginComparison(m_value, other, m_margin)
   7811             || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
   7812     }
   7813 
   7814     void Approx::setMargin(double newMargin) {
   7815         CATCH_ENFORCE(newMargin >= 0,
   7816             "Invalid Approx::margin: " << newMargin << '.'
   7817             << " Approx::Margin has to be non-negative.");
   7818         m_margin = newMargin;
   7819     }
   7820 
   7821     void Approx::setEpsilon(double newEpsilon) {
   7822         CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
   7823             "Invalid Approx::epsilon: " << newEpsilon << '.'
   7824             << " Approx::epsilon has to be in [0, 1]");
   7825         m_epsilon = newEpsilon;
   7826     }
   7827 
   7828 } // end namespace Detail
   7829 
   7830 namespace literals {
   7831     Detail::Approx operator "" _a(long double val) {
   7832         return Detail::Approx(val);
   7833     }
   7834     Detail::Approx operator "" _a(unsigned long long val) {
   7835         return Detail::Approx(val);
   7836     }
   7837 } // end namespace literals
   7838 
   7839 std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
   7840     return value.toString();
   7841 }
   7842 
   7843 } // end namespace Catch
   7844 // end catch_approx.cpp
   7845 // start catch_assertionhandler.cpp
   7846 
   7847 // start catch_debugger.h
   7848 
   7849 namespace Catch {
   7850     bool isDebuggerActive();
   7851 }
   7852 
   7853 #ifdef CATCH_PLATFORM_MAC
   7854 
   7855     #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
   7856 
   7857 #elif defined(CATCH_PLATFORM_LINUX)
   7858     // If we can use inline assembler, do it because this allows us to break
   7859     // directly at the location of the failing check instead of breaking inside
   7860     // raise() called from it, i.e. one stack frame below.
   7861     #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
   7862         #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
   7863     #else // Fall back to the generic way.
   7864         #include <signal.h>
   7865 
   7866         #define CATCH_TRAP() raise(SIGTRAP)
   7867     #endif
   7868 #elif defined(_MSC_VER)
   7869     #define CATCH_TRAP() __debugbreak()
   7870 #elif defined(__MINGW32__)
   7871     extern "C" __declspec(dllimport) void __stdcall DebugBreak();
   7872     #define CATCH_TRAP() DebugBreak()
   7873 #endif
   7874 
   7875 #ifdef CATCH_TRAP
   7876     #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
   7877 #else
   7878     #define CATCH_BREAK_INTO_DEBUGGER() []{}()
   7879 #endif
   7880 
   7881 // end catch_debugger.h
   7882 // start catch_run_context.h
   7883 
   7884 // start catch_fatal_condition.h
   7885 
   7886 // start catch_windows_h_proxy.h
   7887 
   7888 
   7889 #if defined(CATCH_PLATFORM_WINDOWS)
   7890 
   7891 #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
   7892 #  define CATCH_DEFINED_NOMINMAX
   7893 #  define NOMINMAX
   7894 #endif
   7895 #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
   7896 #  define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
   7897 #  define WIN32_LEAN_AND_MEAN
   7898 #endif
   7899 
   7900 #ifdef __AFXDLL
   7901 #include <AfxWin.h>
   7902 #else
   7903 #include <windows.h>
   7904 #endif
   7905 
   7906 #ifdef CATCH_DEFINED_NOMINMAX
   7907 #  undef NOMINMAX
   7908 #endif
   7909 #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
   7910 #  undef WIN32_LEAN_AND_MEAN
   7911 #endif
   7912 
   7913 #endif // defined(CATCH_PLATFORM_WINDOWS)
   7914 
   7915 // end catch_windows_h_proxy.h
   7916 #if defined( CATCH_CONFIG_WINDOWS_SEH )
   7917 
   7918 namespace Catch {
   7919 
   7920     struct FatalConditionHandler {
   7921 
   7922         static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
   7923         FatalConditionHandler();
   7924         static void reset();
   7925         ~FatalConditionHandler();
   7926 
   7927     private:
   7928         static bool isSet;
   7929         static ULONG guaranteeSize;
   7930         static PVOID exceptionHandlerHandle;
   7931     };
   7932 
   7933 } // namespace Catch
   7934 
   7935 #elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
   7936 
   7937 #include <signal.h>
   7938 
   7939 namespace Catch {
   7940 
   7941     struct FatalConditionHandler {
   7942 
   7943         static bool isSet;
   7944         static struct sigaction oldSigActions[];
   7945         static stack_t oldSigStack;
   7946         static char altStackMem[];
   7947 
   7948         static void handleSignal( int sig );
   7949 
   7950         FatalConditionHandler();
   7951         ~FatalConditionHandler();
   7952         static void reset();
   7953     };
   7954 
   7955 } // namespace Catch
   7956 
   7957 #else
   7958 
   7959 namespace Catch {
   7960     struct FatalConditionHandler {
   7961         void reset();
   7962     };
   7963 }
   7964 
   7965 #endif
   7966 
   7967 // end catch_fatal_condition.h
   7968 #include <string>
   7969 
   7970 namespace Catch {
   7971 
   7972     struct IMutableContext;
   7973 
   7974     ///////////////////////////////////////////////////////////////////////////
   7975 
   7976     class RunContext : public IResultCapture, public IRunner {
   7977 
   7978     public:
   7979         RunContext( RunContext const& ) = delete;
   7980         RunContext& operator =( RunContext const& ) = delete;
   7981 
   7982         explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
   7983 
   7984         ~RunContext() override;
   7985 
   7986         void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
   7987         void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
   7988 
   7989         Totals runTest(TestCase const& testCase);
   7990 
   7991         IConfigPtr config() const;
   7992         IStreamingReporter& reporter() const;
   7993 
   7994     public: // IResultCapture
   7995 
   7996         // Assertion handlers
   7997         void handleExpr
   7998                 (   AssertionInfo const& info,
   7999                     ITransientExpression const& expr,
   8000                     AssertionReaction& reaction ) override;
   8001         void handleMessage
   8002                 (   AssertionInfo const& info,
   8003                     ResultWas::OfType resultType,
   8004                     StringRef const& message,
   8005                     AssertionReaction& reaction ) override;
   8006         void handleUnexpectedExceptionNotThrown
   8007                 (   AssertionInfo const& info,
   8008                     AssertionReaction& reaction ) override;
   8009         void handleUnexpectedInflightException
   8010                 (   AssertionInfo const& info,
   8011                     std::string const& message,
   8012                     AssertionReaction& reaction ) override;
   8013         void handleIncomplete
   8014                 (   AssertionInfo const& info ) override;
   8015         void handleNonExpr
   8016                 (   AssertionInfo const &info,
   8017                     ResultWas::OfType resultType,
   8018                     AssertionReaction &reaction ) override;
   8019 
   8020         bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
   8021 
   8022         void sectionEnded( SectionEndInfo const& endInfo ) override;
   8023         void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
   8024 
   8025         auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
   8026 
   8027 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
   8028         void benchmarkPreparing( std::string const& name ) override;
   8029         void benchmarkStarting( BenchmarkInfo const& info ) override;
   8030         void benchmarkEnded( BenchmarkStats<> const& stats ) override;
   8031         void benchmarkFailed( std::string const& error ) override;
   8032 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
   8033 
   8034         void pushScopedMessage( MessageInfo const& message ) override;
   8035         void popScopedMessage( MessageInfo const& message ) override;
   8036 
   8037         void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
   8038 
   8039         std::string getCurrentTestName() const override;
   8040 
   8041         const AssertionResult* getLastResult() const override;
   8042 
   8043         void exceptionEarlyReported() override;
   8044 
   8045         void handleFatalErrorCondition( StringRef message ) override;
   8046 
   8047         bool lastAssertionPassed() override;
   8048 
   8049         void assertionPassed() override;
   8050 
   8051     public:
   8052         // !TBD We need to do this another way!
   8053         bool aborting() const final;
   8054 
   8055     private:
   8056 
   8057         void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
   8058         void invokeActiveTestCase();
   8059 
   8060         void resetAssertionInfo();
   8061         bool testForMissingAssertions( Counts& assertions );
   8062 
   8063         void assertionEnded( AssertionResult const& result );
   8064         void reportExpr
   8065                 (   AssertionInfo const &info,
   8066                     ResultWas::OfType resultType,
   8067                     ITransientExpression const *expr,
   8068                     bool negated );
   8069 
   8070         void populateReaction( AssertionReaction& reaction );
   8071 
   8072     private:
   8073 
   8074         void handleUnfinishedSections();
   8075 
   8076         TestRunInfo m_runInfo;
   8077         IMutableContext& m_context;
   8078         TestCase const* m_activeTestCase = nullptr;
   8079         ITracker* m_testCaseTracker = nullptr;
   8080         Option<AssertionResult> m_lastResult;
   8081 
   8082         IConfigPtr m_config;
   8083         Totals m_totals;
   8084         IStreamingReporterPtr m_reporter;
   8085         std::vector<MessageInfo> m_messages;
   8086         std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
   8087         AssertionInfo m_lastAssertionInfo;
   8088         std::vector<SectionEndInfo> m_unfinishedSections;
   8089         std::vector<ITracker*> m_activeSections;
   8090         TrackerContext m_trackerContext;
   8091         bool m_lastAssertionPassed = false;
   8092         bool m_shouldReportUnexpected = true;
   8093         bool m_includeSuccessfulResults;
   8094     };
   8095 
   8096     void seedRng(IConfig const& config);
   8097     unsigned int rngSeed();
   8098 } // end namespace Catch
   8099 
   8100 // end catch_run_context.h
   8101 namespace Catch {
   8102 
   8103     namespace {
   8104         auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
   8105             expr.streamReconstructedExpression( os );
   8106             return os;
   8107         }
   8108     }
   8109 
   8110     LazyExpression::LazyExpression( bool isNegated )
   8111     :   m_isNegated( isNegated )
   8112     {}
   8113 
   8114     LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
   8115 
   8116     LazyExpression::operator bool() const {
   8117         return m_transientExpression != nullptr;
   8118     }
   8119 
   8120     auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
   8121         if( lazyExpr.m_isNegated )
   8122             os << "!";
   8123 
   8124         if( lazyExpr ) {
   8125             if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
   8126                 os << "(" << *lazyExpr.m_transientExpression << ")";
   8127             else
   8128                 os << *lazyExpr.m_transientExpression;
   8129         }
   8130         else {
   8131             os << "{** error - unchecked empty expression requested **}";
   8132         }
   8133         return os;
   8134     }
   8135 
   8136     AssertionHandler::AssertionHandler
   8137         (   StringRef const& macroName,
   8138             SourceLineInfo const& lineInfo,
   8139             StringRef capturedExpression,
   8140             ResultDisposition::Flags resultDisposition )
   8141     :   m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
   8142         m_resultCapture( getResultCapture() )
   8143     {}
   8144 
   8145     void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
   8146         m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
   8147     }
   8148     void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
   8149         m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
   8150     }
   8151 
   8152     auto AssertionHandler::allowThrows() const -> bool {
   8153         return getCurrentContext().getConfig()->allowThrows();
   8154     }
   8155 
   8156     void AssertionHandler::complete() {
   8157         setCompleted();
   8158         if( m_reaction.shouldDebugBreak ) {
   8159 
   8160             // If you find your debugger stopping you here then go one level up on the
   8161             // call-stack for the code that caused it (typically a failed assertion)
   8162 
   8163             // (To go back to the test and change execution, jump over the throw, next)
   8164             CATCH_BREAK_INTO_DEBUGGER();
   8165         }
   8166         if (m_reaction.shouldThrow) {
   8167 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
   8168             throw Catch::TestFailureException();
   8169 #else
   8170             CATCH_ERROR( "Test failure requires aborting test!" );
   8171 #endif
   8172         }
   8173     }
   8174     void AssertionHandler::setCompleted() {
   8175         m_completed = true;
   8176     }
   8177 
   8178     void AssertionHandler::handleUnexpectedInflightException() {
   8179         m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
   8180     }
   8181 
   8182     void AssertionHandler::handleExceptionThrownAsExpected() {
   8183         m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
   8184     }
   8185     void AssertionHandler::handleExceptionNotThrownAsExpected() {
   8186         m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
   8187     }
   8188 
   8189     void AssertionHandler::handleUnexpectedExceptionNotThrown() {
   8190         m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
   8191     }
   8192 
   8193     void AssertionHandler::handleThrowingCallSkipped() {
   8194         m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
   8195     }
   8196 
   8197     // This is the overload that takes a string and infers the Equals matcher from it
   8198     // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
   8199     void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString  ) {
   8200         handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
   8201     }
   8202 
   8203 } // namespace Catch
   8204 // end catch_assertionhandler.cpp
   8205 // start catch_assertionresult.cpp
   8206 
   8207 namespace Catch {
   8208     AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
   8209         lazyExpression(_lazyExpression),
   8210         resultType(_resultType) {}
   8211 
   8212     std::string AssertionResultData::reconstructExpression() const {
   8213 
   8214         if( reconstructedExpression.empty() ) {
   8215             if( lazyExpression ) {
   8216                 ReusableStringStream rss;
   8217                 rss << lazyExpression;
   8218                 reconstructedExpression = rss.str();
   8219             }
   8220         }
   8221         return reconstructedExpression;
   8222     }
   8223 
   8224     AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
   8225     :   m_info( info ),
   8226         m_resultData( data )
   8227     {}
   8228 
   8229     // Result was a success
   8230     bool AssertionResult::succeeded() const {
   8231         return Catch::isOk( m_resultData.resultType );
   8232     }
   8233 
   8234     // Result was a success, or failure is suppressed
   8235     bool AssertionResult::isOk() const {
   8236         return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
   8237     }
   8238 
   8239     ResultWas::OfType AssertionResult::getResultType() const {
   8240         return m_resultData.resultType;
   8241     }
   8242 
   8243     bool AssertionResult::hasExpression() const {
   8244         return !m_info.capturedExpression.empty();
   8245     }
   8246 
   8247     bool AssertionResult::hasMessage() const {
   8248         return !m_resultData.message.empty();
   8249     }
   8250 
   8251     std::string AssertionResult::getExpression() const {
   8252         // Possibly overallocating by 3 characters should be basically free
   8253         std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);
   8254         if (isFalseTest(m_info.resultDisposition)) {
   8255             expr += "!(";
   8256         }
   8257         expr += m_info.capturedExpression;
   8258         if (isFalseTest(m_info.resultDisposition)) {
   8259             expr += ')';
   8260         }
   8261         return expr;
   8262     }
   8263 
   8264     std::string AssertionResult::getExpressionInMacro() const {
   8265         std::string expr;
   8266         if( m_info.macroName.empty() )
   8267             expr = static_cast<std::string>(m_info.capturedExpression);
   8268         else {
   8269             expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
   8270             expr += m_info.macroName;
   8271             expr += "( ";
   8272             expr += m_info.capturedExpression;
   8273             expr += " )";
   8274         }
   8275         return expr;
   8276     }
   8277 
   8278     bool AssertionResult::hasExpandedExpression() const {
   8279         return hasExpression() && getExpandedExpression() != getExpression();
   8280     }
   8281 
   8282     std::string AssertionResult::getExpandedExpression() const {
   8283         std::string expr = m_resultData.reconstructExpression();
   8284         return expr.empty()
   8285                 ? getExpression()
   8286                 : expr;
   8287     }
   8288 
   8289     std::string AssertionResult::getMessage() const {
   8290         return m_resultData.message;
   8291     }
   8292     SourceLineInfo AssertionResult::getSourceInfo() const {
   8293         return m_info.lineInfo;
   8294     }
   8295 
   8296     StringRef AssertionResult::getTestMacroName() const {
   8297         return m_info.macroName;
   8298     }
   8299 
   8300 } // end namespace Catch
   8301 // end catch_assertionresult.cpp
   8302 // start catch_capture_matchers.cpp
   8303 
   8304 namespace Catch {
   8305 
   8306     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
   8307 
   8308     // This is the general overload that takes a any string matcher
   8309     // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
   8310     // the Equals matcher (so the header does not mention matchers)
   8311     void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  ) {
   8312         std::string exceptionMessage = Catch::translateActiveException();
   8313         MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
   8314         handler.handleExpr( expr );
   8315     }
   8316 
   8317 } // namespace Catch
   8318 // end catch_capture_matchers.cpp
   8319 // start catch_commandline.cpp
   8320 
   8321 // start catch_commandline.h
   8322 
   8323 // start catch_clara.h
   8324 
   8325 // Use Catch's value for console width (store Clara's off to the side, if present)
   8326 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
   8327 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
   8328 #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
   8329 #endif
   8330 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
   8331 
   8332 #ifdef __clang__
   8333 #pragma clang diagnostic push
   8334 #pragma clang diagnostic ignored "-Wweak-vtables"
   8335 #pragma clang diagnostic ignored "-Wexit-time-destructors"
   8336 #pragma clang diagnostic ignored "-Wshadow"
   8337 #endif
   8338 
   8339 // start clara.hpp
   8340 // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
   8341 //
   8342 // Distributed under the Boost Software License, Version 1.0. (See accompanying
   8343 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
   8344 //
   8345 // See https://github.com/philsquared/Clara for more details
   8346 
   8347 // Clara v1.1.5
   8348 
   8349 
   8350 #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
   8351 #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
   8352 #endif
   8353 
   8354 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
   8355 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
   8356 #endif
   8357 
   8358 #ifndef CLARA_CONFIG_OPTIONAL_TYPE
   8359 #ifdef __has_include
   8360 #if __has_include(<optional>) && __cplusplus >= 201703L
   8361 #include <optional>
   8362 #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
   8363 #endif
   8364 #endif
   8365 #endif
   8366 
   8367 // ----------- #included from clara_textflow.hpp -----------
   8368 
   8369 // TextFlowCpp
   8370 //
   8371 // A single-header library for wrapping and laying out basic text, by Phil Nash
   8372 //
   8373 // Distributed under the Boost Software License, Version 1.0. (See accompanying
   8374 // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
   8375 //
   8376 // This project is hosted at https://github.com/philsquared/textflowcpp
   8377 
   8378 
   8379 #include <cassert>
   8380 #include <ostream>
   8381 #include <sstream>
   8382 #include <vector>
   8383 
   8384 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
   8385 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
   8386 #endif
   8387 
   8388 namespace Catch {
   8389 namespace clara {
   8390 namespace TextFlow {
   8391 
   8392 inline auto isWhitespace(char c) -> bool {
   8393 	static std::string chars = " \t\n\r";
   8394 	return chars.find(c) != std::string::npos;
   8395 }
   8396 inline auto isBreakableBefore(char c) -> bool {
   8397 	static std::string chars = "[({<|";
   8398 	return chars.find(c) != std::string::npos;
   8399 }
   8400 inline auto isBreakableAfter(char c) -> bool {
   8401 	static std::string chars = "])}>.,:;*+-=&/\\";
   8402 	return chars.find(c) != std::string::npos;
   8403 }
   8404 
   8405 class Columns;
   8406 
   8407 class Column {
   8408 	std::vector<std::string> m_strings;
   8409 	size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
   8410 	size_t m_indent = 0;
   8411 	size_t m_initialIndent = std::string::npos;
   8412 
   8413 public:
   8414 	class iterator {
   8415 		friend Column;
   8416 
   8417 		Column const& m_column;
   8418 		size_t m_stringIndex = 0;
   8419 		size_t m_pos = 0;
   8420 
   8421 		size_t m_len = 0;
   8422 		size_t m_end = 0;
   8423 		bool m_suffix = false;
   8424 
   8425 		iterator(Column const& column, size_t stringIndex)
   8426 			: m_column(column),
   8427 			m_stringIndex(stringIndex) {}
   8428 
   8429 		auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
   8430 
   8431 		auto isBoundary(size_t at) const -> bool {
   8432 			assert(at > 0);
   8433 			assert(at <= line().size());
   8434 
   8435 			return at == line().size() ||
   8436 				(isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
   8437 				isBreakableBefore(line()[at]) ||
   8438 				isBreakableAfter(line()[at - 1]);
   8439 		}
   8440 
   8441 		void calcLength() {
   8442 			assert(m_stringIndex < m_column.m_strings.size());
   8443 
   8444 			m_suffix = false;
   8445 			auto width = m_column.m_width - indent();
   8446 			m_end = m_pos;
   8447 			if (line()[m_pos] == '\n') {
   8448 				++m_end;
   8449 			}
   8450 			while (m_end < line().size() && line()[m_end] != '\n')
   8451 				++m_end;
   8452 
   8453 			if (m_end < m_pos + width) {
   8454 				m_len = m_end - m_pos;
   8455 			} else {
   8456 				size_t len = width;
   8457 				while (len > 0 && !isBoundary(m_pos + len))
   8458 					--len;
   8459 				while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
   8460 					--len;
   8461 
   8462 				if (len > 0) {
   8463 					m_len = len;
   8464 				} else {
   8465 					m_suffix = true;
   8466 					m_len = width - 1;
   8467 				}
   8468 			}
   8469 		}
   8470 
   8471 		auto indent() const -> size_t {
   8472 			auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
   8473 			return initial == std::string::npos ? m_column.m_indent : initial;
   8474 		}
   8475 
   8476 		auto addIndentAndSuffix(std::string const &plain) const -> std::string {
   8477 			return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
   8478 		}
   8479 
   8480 	public:
   8481 		using difference_type = std::ptrdiff_t;
   8482 		using value_type = std::string;
   8483 		using pointer = value_type * ;
   8484 		using reference = value_type & ;
   8485 		using iterator_category = std::forward_iterator_tag;
   8486 
   8487 		explicit iterator(Column const& column) : m_column(column) {
   8488 			assert(m_column.m_width > m_column.m_indent);
   8489 			assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
   8490 			calcLength();
   8491 			if (m_len == 0)
   8492 				m_stringIndex++; // Empty string
   8493 		}
   8494 
   8495 		auto operator *() const -> std::string {
   8496 			assert(m_stringIndex < m_column.m_strings.size());
   8497 			assert(m_pos <= m_end);
   8498 			return addIndentAndSuffix(line().substr(m_pos, m_len));
   8499 		}
   8500 
   8501 		auto operator ++() -> iterator& {
   8502 			m_pos += m_len;
   8503 			if (m_pos < line().size() && line()[m_pos] == '\n')
   8504 				m_pos += 1;
   8505 			else
   8506 				while (m_pos < line().size() && isWhitespace(line()[m_pos]))
   8507 					++m_pos;
   8508 
   8509 			if (m_pos == line().size()) {
   8510 				m_pos = 0;
   8511 				++m_stringIndex;
   8512 			}
   8513 			if (m_stringIndex < m_column.m_strings.size())
   8514 				calcLength();
   8515 			return *this;
   8516 		}
   8517 		auto operator ++(int) -> iterator {
   8518 			iterator prev(*this);
   8519 			operator++();
   8520 			return prev;
   8521 		}
   8522 
   8523 		auto operator ==(iterator const& other) const -> bool {
   8524 			return
   8525 				m_pos == other.m_pos &&
   8526 				m_stringIndex == other.m_stringIndex &&
   8527 				&m_column == &other.m_column;
   8528 		}
   8529 		auto operator !=(iterator const& other) const -> bool {
   8530 			return !operator==(other);
   8531 		}
   8532 	};
   8533 	using const_iterator = iterator;
   8534 
   8535 	explicit Column(std::string const& text) { m_strings.push_back(text); }
   8536 
   8537 	auto width(size_t newWidth) -> Column& {
   8538 		assert(newWidth > 0);
   8539 		m_width = newWidth;
   8540 		return *this;
   8541 	}
   8542 	auto indent(size_t newIndent) -> Column& {
   8543 		m_indent = newIndent;
   8544 		return *this;
   8545 	}
   8546 	auto initialIndent(size_t newIndent) -> Column& {
   8547 		m_initialIndent = newIndent;
   8548 		return *this;
   8549 	}
   8550 
   8551 	auto width() const -> size_t { return m_width; }
   8552 	auto begin() const -> iterator { return iterator(*this); }
   8553 	auto end() const -> iterator { return { *this, m_strings.size() }; }
   8554 
   8555 	inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
   8556 		bool first = true;
   8557 		for (auto line : col) {
   8558 			if (first)
   8559 				first = false;
   8560 			else
   8561 				os << "\n";
   8562 			os << line;
   8563 		}
   8564 		return os;
   8565 	}
   8566 
   8567 	auto operator + (Column const& other)->Columns;
   8568 
   8569 	auto toString() const -> std::string {
   8570 		std::ostringstream oss;
   8571 		oss << *this;
   8572 		return oss.str();
   8573 	}
   8574 };
   8575 
   8576 class Spacer : public Column {
   8577 
   8578 public:
   8579 	explicit Spacer(size_t spaceWidth) : Column("") {
   8580 		width(spaceWidth);
   8581 	}
   8582 };
   8583 
   8584 class Columns {
   8585 	std::vector<Column> m_columns;
   8586 
   8587 public:
   8588 
   8589 	class iterator {
   8590 		friend Columns;
   8591 		struct EndTag {};
   8592 
   8593 		std::vector<Column> const& m_columns;
   8594 		std::vector<Column::iterator> m_iterators;
   8595 		size_t m_activeIterators;
   8596 
   8597 		iterator(Columns const& columns, EndTag)
   8598 			: m_columns(columns.m_columns),
   8599 			m_activeIterators(0) {
   8600 			m_iterators.reserve(m_columns.size());
   8601 
   8602 			for (auto const& col : m_columns)
   8603 				m_iterators.push_back(col.end());
   8604 		}
   8605 
   8606 	public:
   8607 		using difference_type = std::ptrdiff_t;
   8608 		using value_type = std::string;
   8609 		using pointer = value_type * ;
   8610 		using reference = value_type & ;
   8611 		using iterator_category = std::forward_iterator_tag;
   8612 
   8613 		explicit iterator(Columns const& columns)
   8614 			: m_columns(columns.m_columns),
   8615 			m_activeIterators(m_columns.size()) {
   8616 			m_iterators.reserve(m_columns.size());
   8617 
   8618 			for (auto const& col : m_columns)
   8619 				m_iterators.push_back(col.begin());
   8620 		}
   8621 
   8622 		auto operator ==(iterator const& other) const -> bool {
   8623 			return m_iterators == other.m_iterators;
   8624 		}
   8625 		auto operator !=(iterator const& other) const -> bool {
   8626 			return m_iterators != other.m_iterators;
   8627 		}
   8628 		auto operator *() const -> std::string {
   8629 			std::string row, padding;
   8630 
   8631 			for (size_t i = 0; i < m_columns.size(); ++i) {
   8632 				auto width = m_columns[i].width();
   8633 				if (m_iterators[i] != m_columns[i].end()) {
   8634 					std::string col = *m_iterators[i];
   8635 					row += padding + col;
   8636 					if (col.size() < width)
   8637 						padding = std::string(width - col.size(), ' ');
   8638 					else
   8639 						padding = "";
   8640 				} else {
   8641 					padding += std::string(width, ' ');
   8642 				}
   8643 			}
   8644 			return row;
   8645 		}
   8646 		auto operator ++() -> iterator& {
   8647 			for (size_t i = 0; i < m_columns.size(); ++i) {
   8648 				if (m_iterators[i] != m_columns[i].end())
   8649 					++m_iterators[i];
   8650 			}
   8651 			return *this;
   8652 		}
   8653 		auto operator ++(int) -> iterator {
   8654 			iterator prev(*this);
   8655 			operator++();
   8656 			return prev;
   8657 		}
   8658 	};
   8659 	using const_iterator = iterator;
   8660 
   8661 	auto begin() const -> iterator { return iterator(*this); }
   8662 	auto end() const -> iterator { return { *this, iterator::EndTag() }; }
   8663 
   8664 	auto operator += (Column const& col) -> Columns& {
   8665 		m_columns.push_back(col);
   8666 		return *this;
   8667 	}
   8668 	auto operator + (Column const& col) -> Columns {
   8669 		Columns combined = *this;
   8670 		combined += col;
   8671 		return combined;
   8672 	}
   8673 
   8674 	inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
   8675 
   8676 		bool first = true;
   8677 		for (auto line : cols) {
   8678 			if (first)
   8679 				first = false;
   8680 			else
   8681 				os << "\n";
   8682 			os << line;
   8683 		}
   8684 		return os;
   8685 	}
   8686 
   8687 	auto toString() const -> std::string {
   8688 		std::ostringstream oss;
   8689 		oss << *this;
   8690 		return oss.str();
   8691 	}
   8692 };
   8693 
   8694 inline auto Column::operator + (Column const& other) -> Columns {
   8695 	Columns cols;
   8696 	cols += *this;
   8697 	cols += other;
   8698 	return cols;
   8699 }
   8700 }
   8701 
   8702 }
   8703 }
   8704 
   8705 // ----------- end of #include from clara_textflow.hpp -----------
   8706 // ........... back in clara.hpp
   8707 
   8708 #include <cctype>
   8709 #include <string>
   8710 #include <memory>
   8711 #include <set>
   8712 #include <algorithm>
   8713 
   8714 #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
   8715 #define CATCH_PLATFORM_WINDOWS
   8716 #endif
   8717 
   8718 namespace Catch { namespace clara {
   8719 namespace detail {
   8720 
   8721     // Traits for extracting arg and return type of lambdas (for single argument lambdas)
   8722     template<typename L>
   8723     struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
   8724 
   8725     template<typename ClassT, typename ReturnT, typename... Args>
   8726     struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
   8727         static const bool isValid = false;
   8728     };
   8729 
   8730     template<typename ClassT, typename ReturnT, typename ArgT>
   8731     struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
   8732         static const bool isValid = true;
   8733         using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
   8734         using ReturnType = ReturnT;
   8735     };
   8736 
   8737     class TokenStream;
   8738 
   8739     // Transport for raw args (copied from main args, or supplied via init list for testing)
   8740     class Args {
   8741         friend TokenStream;
   8742         std::string m_exeName;
   8743         std::vector<std::string> m_args;
   8744 
   8745     public:
   8746         Args( int argc, char const* const* argv )
   8747             : m_exeName(argv[0]),
   8748               m_args(argv + 1, argv + argc) {}
   8749 
   8750         Args( std::initializer_list<std::string> args )
   8751         :   m_exeName( *args.begin() ),
   8752             m_args( args.begin()+1, args.end() )
   8753         {}
   8754 
   8755         auto exeName() const -> std::string {
   8756             return m_exeName;
   8757         }
   8758     };
   8759 
   8760     // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
   8761     // may encode an option + its argument if the : or = form is used
   8762     enum class TokenType {
   8763         Option, Argument
   8764     };
   8765     struct Token {
   8766         TokenType type;
   8767         std::string token;
   8768     };
   8769 
   8770     inline auto isOptPrefix( char c ) -> bool {
   8771         return c == '-'
   8772 #ifdef CATCH_PLATFORM_WINDOWS
   8773             || c == '/'
   8774 #endif
   8775         ;
   8776     }
   8777 
   8778     // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
   8779     class TokenStream {
   8780         using Iterator = std::vector<std::string>::const_iterator;
   8781         Iterator it;
   8782         Iterator itEnd;
   8783         std::vector<Token> m_tokenBuffer;
   8784 
   8785         void loadBuffer() {
   8786             m_tokenBuffer.resize( 0 );
   8787 
   8788             // Skip any empty strings
   8789             while( it != itEnd && it->empty() )
   8790                 ++it;
   8791 
   8792             if( it != itEnd ) {
   8793                 auto const &next = *it;
   8794                 if( isOptPrefix( next[0] ) ) {
   8795                     auto delimiterPos = next.find_first_of( " :=" );
   8796                     if( delimiterPos != std::string::npos ) {
   8797                         m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
   8798                         m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
   8799                     } else {
   8800                         if( next[1] != '-' && next.size() > 2 ) {
   8801                             std::string opt = "- ";
   8802                             for( size_t i = 1; i < next.size(); ++i ) {
   8803                                 opt[1] = next[i];
   8804                                 m_tokenBuffer.push_back( { TokenType::Option, opt } );
   8805                             }
   8806                         } else {
   8807                             m_tokenBuffer.push_back( { TokenType::Option, next } );
   8808                         }
   8809                     }
   8810                 } else {
   8811                     m_tokenBuffer.push_back( { TokenType::Argument, next } );
   8812                 }
   8813             }
   8814         }
   8815 
   8816     public:
   8817         explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
   8818 
   8819         TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
   8820             loadBuffer();
   8821         }
   8822 
   8823         explicit operator bool() const {
   8824             return !m_tokenBuffer.empty() || it != itEnd;
   8825         }
   8826 
   8827         auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
   8828 
   8829         auto operator*() const -> Token {
   8830             assert( !m_tokenBuffer.empty() );
   8831             return m_tokenBuffer.front();
   8832         }
   8833 
   8834         auto operator->() const -> Token const * {
   8835             assert( !m_tokenBuffer.empty() );
   8836             return &m_tokenBuffer.front();
   8837         }
   8838 
   8839         auto operator++() -> TokenStream & {
   8840             if( m_tokenBuffer.size() >= 2 ) {
   8841                 m_tokenBuffer.erase( m_tokenBuffer.begin() );
   8842             } else {
   8843                 if( it != itEnd )
   8844                     ++it;
   8845                 loadBuffer();
   8846             }
   8847             return *this;
   8848         }
   8849     };
   8850 
   8851     class ResultBase {
   8852     public:
   8853         enum Type {
   8854             Ok, LogicError, RuntimeError
   8855         };
   8856 
   8857     protected:
   8858         ResultBase( Type type ) : m_type( type ) {}
   8859         virtual ~ResultBase() = default;
   8860 
   8861         virtual void enforceOk() const = 0;
   8862 
   8863         Type m_type;
   8864     };
   8865 
   8866     template<typename T>
   8867     class ResultValueBase : public ResultBase {
   8868     public:
   8869         auto value() const -> T const & {
   8870             enforceOk();
   8871             return m_value;
   8872         }
   8873 
   8874     protected:
   8875         ResultValueBase( Type type ) : ResultBase( type ) {}
   8876 
   8877         ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
   8878             if( m_type == ResultBase::Ok )
   8879                 new( &m_value ) T( other.m_value );
   8880         }
   8881 
   8882         ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
   8883             new( &m_value ) T( value );
   8884         }
   8885 
   8886         auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
   8887             if( m_type == ResultBase::Ok )
   8888                 m_value.~T();
   8889             ResultBase::operator=(other);
   8890             if( m_type == ResultBase::Ok )
   8891                 new( &m_value ) T( other.m_value );
   8892             return *this;
   8893         }
   8894 
   8895         ~ResultValueBase() override {
   8896             if( m_type == Ok )
   8897                 m_value.~T();
   8898         }
   8899 
   8900         union {
   8901             T m_value;
   8902         };
   8903     };
   8904 
   8905     template<>
   8906     class ResultValueBase<void> : public ResultBase {
   8907     protected:
   8908         using ResultBase::ResultBase;
   8909     };
   8910 
   8911     template<typename T = void>
   8912     class BasicResult : public ResultValueBase<T> {
   8913     public:
   8914         template<typename U>
   8915         explicit BasicResult( BasicResult<U> const &other )
   8916         :   ResultValueBase<T>( other.type() ),
   8917             m_errorMessage( other.errorMessage() )
   8918         {
   8919             assert( type() != ResultBase::Ok );
   8920         }
   8921 
   8922         template<typename U>
   8923         static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
   8924         static auto ok() -> BasicResult { return { ResultBase::Ok }; }
   8925         static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
   8926         static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
   8927 
   8928         explicit operator bool() const { return m_type == ResultBase::Ok; }
   8929         auto type() const -> ResultBase::Type { return m_type; }
   8930         auto errorMessage() const -> std::string { return m_errorMessage; }
   8931 
   8932     protected:
   8933         void enforceOk() const override {
   8934 
   8935             // Errors shouldn't reach this point, but if they do
   8936             // the actual error message will be in m_errorMessage
   8937             assert( m_type != ResultBase::LogicError );
   8938             assert( m_type != ResultBase::RuntimeError );
   8939             if( m_type != ResultBase::Ok )
   8940                 std::abort();
   8941         }
   8942 
   8943         std::string m_errorMessage; // Only populated if resultType is an error
   8944 
   8945         BasicResult( ResultBase::Type type, std::string const &message )
   8946         :   ResultValueBase<T>(type),
   8947             m_errorMessage(message)
   8948         {
   8949             assert( m_type != ResultBase::Ok );
   8950         }
   8951 
   8952         using ResultValueBase<T>::ResultValueBase;
   8953         using ResultBase::m_type;
   8954     };
   8955 
   8956     enum class ParseResultType {
   8957         Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
   8958     };
   8959 
   8960     class ParseState {
   8961     public:
   8962 
   8963         ParseState( ParseResultType type, TokenStream const &remainingTokens )
   8964         : m_type(type),
   8965           m_remainingTokens( remainingTokens )
   8966         {}
   8967 
   8968         auto type() const -> ParseResultType { return m_type; }
   8969         auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
   8970 
   8971     private:
   8972         ParseResultType m_type;
   8973         TokenStream m_remainingTokens;
   8974     };
   8975 
   8976     using Result = BasicResult<void>;
   8977     using ParserResult = BasicResult<ParseResultType>;
   8978     using InternalParseResult = BasicResult<ParseState>;
   8979 
   8980     struct HelpColumns {
   8981         std::string left;
   8982         std::string right;
   8983     };
   8984 
   8985     template<typename T>
   8986     inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
   8987         std::stringstream ss;
   8988         ss << source;
   8989         ss >> target;
   8990         if( ss.fail() )
   8991             return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
   8992         else
   8993             return ParserResult::ok( ParseResultType::Matched );
   8994     }
   8995     inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
   8996         target = source;
   8997         return ParserResult::ok( ParseResultType::Matched );
   8998     }
   8999     inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
   9000         std::string srcLC = source;
   9001         std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( std::tolower(c) ); } );
   9002         if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
   9003             target = true;
   9004         else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
   9005             target = false;
   9006         else
   9007             return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
   9008         return ParserResult::ok( ParseResultType::Matched );
   9009     }
   9010 #ifdef CLARA_CONFIG_OPTIONAL_TYPE
   9011     template<typename T>
   9012     inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
   9013         T temp;
   9014         auto result = convertInto( source, temp );
   9015         if( result )
   9016             target = std::move(temp);
   9017         return result;
   9018     }
   9019 #endif // CLARA_CONFIG_OPTIONAL_TYPE
   9020 
   9021     struct NonCopyable {
   9022         NonCopyable() = default;
   9023         NonCopyable( NonCopyable const & ) = delete;
   9024         NonCopyable( NonCopyable && ) = delete;
   9025         NonCopyable &operator=( NonCopyable const & ) = delete;
   9026         NonCopyable &operator=( NonCopyable && ) = delete;
   9027     };
   9028 
   9029     struct BoundRef : NonCopyable {
   9030         virtual ~BoundRef() = default;
   9031         virtual auto isContainer() const -> bool { return false; }
   9032         virtual auto isFlag() const -> bool { return false; }
   9033     };
   9034     struct BoundValueRefBase : BoundRef {
   9035         virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
   9036     };
   9037     struct BoundFlagRefBase : BoundRef {
   9038         virtual auto setFlag( bool flag ) -> ParserResult = 0;
   9039         virtual auto isFlag() const -> bool { return true; }
   9040     };
   9041 
   9042     template<typename T>
   9043     struct BoundValueRef : BoundValueRefBase {
   9044         T &m_ref;
   9045 
   9046         explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
   9047 
   9048         auto setValue( std::string const &arg ) -> ParserResult override {
   9049             return convertInto( arg, m_ref );
   9050         }
   9051     };
   9052 
   9053     template<typename T>
   9054     struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
   9055         std::vector<T> &m_ref;
   9056 
   9057         explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
   9058 
   9059         auto isContainer() const -> bool override { return true; }
   9060 
   9061         auto setValue( std::string const &arg ) -> ParserResult override {
   9062             T temp;
   9063             auto result = convertInto( arg, temp );
   9064             if( result )
   9065                 m_ref.push_back( temp );
   9066             return result;
   9067         }
   9068     };
   9069 
   9070     struct BoundFlagRef : BoundFlagRefBase {
   9071         bool &m_ref;
   9072 
   9073         explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
   9074 
   9075         auto setFlag( bool flag ) -> ParserResult override {
   9076             m_ref = flag;
   9077             return ParserResult::ok( ParseResultType::Matched );
   9078         }
   9079     };
   9080 
   9081     template<typename ReturnType>
   9082     struct LambdaInvoker {
   9083         static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
   9084 
   9085         template<typename L, typename ArgType>
   9086         static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
   9087             return lambda( arg );
   9088         }
   9089     };
   9090 
   9091     template<>
   9092     struct LambdaInvoker<void> {
   9093         template<typename L, typename ArgType>
   9094         static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
   9095             lambda( arg );
   9096             return ParserResult::ok( ParseResultType::Matched );
   9097         }
   9098     };
   9099 
   9100     template<typename ArgType, typename L>
   9101     inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
   9102         ArgType temp{};
   9103         auto result = convertInto( arg, temp );
   9104         return !result
   9105            ? result
   9106            : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
   9107     }
   9108 
   9109     template<typename L>
   9110     struct BoundLambda : BoundValueRefBase {
   9111         L m_lambda;
   9112 
   9113         static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
   9114         explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
   9115 
   9116         auto setValue( std::string const &arg ) -> ParserResult override {
   9117             return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
   9118         }
   9119     };
   9120 
   9121     template<typename L>
   9122     struct BoundFlagLambda : BoundFlagRefBase {
   9123         L m_lambda;
   9124 
   9125         static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
   9126         static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
   9127 
   9128         explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
   9129 
   9130         auto setFlag( bool flag ) -> ParserResult override {
   9131             return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
   9132         }
   9133     };
   9134 
   9135     enum class Optionality { Optional, Required };
   9136 
   9137     struct Parser;
   9138 
   9139     class ParserBase {
   9140     public:
   9141         virtual ~ParserBase() = default;
   9142         virtual auto validate() const -> Result { return Result::ok(); }
   9143         virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult  = 0;
   9144         virtual auto cardinality() const -> size_t { return 1; }
   9145 
   9146         auto parse( Args const &args ) const -> InternalParseResult {
   9147             return parse( args.exeName(), TokenStream( args ) );
   9148         }
   9149     };
   9150 
   9151     template<typename DerivedT>
   9152     class ComposableParserImpl : public ParserBase {
   9153     public:
   9154         template<typename T>
   9155         auto operator|( T const &other ) const -> Parser;
   9156 
   9157 		template<typename T>
   9158         auto operator+( T const &other ) const -> Parser;
   9159     };
   9160 
   9161     // Common code and state for Args and Opts
   9162     template<typename DerivedT>
   9163     class ParserRefImpl : public ComposableParserImpl<DerivedT> {
   9164     protected:
   9165         Optionality m_optionality = Optionality::Optional;
   9166         std::shared_ptr<BoundRef> m_ref;
   9167         std::string m_hint;
   9168         std::string m_description;
   9169 
   9170         explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
   9171 
   9172     public:
   9173         template<typename T>
   9174         ParserRefImpl( T &ref, std::string const &hint )
   9175         :   m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
   9176             m_hint( hint )
   9177         {}
   9178 
   9179         template<typename LambdaT>
   9180         ParserRefImpl( LambdaT const &ref, std::string const &hint )
   9181         :   m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
   9182             m_hint(hint)
   9183         {}
   9184 
   9185         auto operator()( std::string const &description ) -> DerivedT & {
   9186             m_description = description;
   9187             return static_cast<DerivedT &>( *this );
   9188         }
   9189 
   9190         auto optional() -> DerivedT & {
   9191             m_optionality = Optionality::Optional;
   9192             return static_cast<DerivedT &>( *this );
   9193         };
   9194 
   9195         auto required() -> DerivedT & {
   9196             m_optionality = Optionality::Required;
   9197             return static_cast<DerivedT &>( *this );
   9198         };
   9199 
   9200         auto isOptional() const -> bool {
   9201             return m_optionality == Optionality::Optional;
   9202         }
   9203 
   9204         auto cardinality() const -> size_t override {
   9205             if( m_ref->isContainer() )
   9206                 return 0;
   9207             else
   9208                 return 1;
   9209         }
   9210 
   9211         auto hint() const -> std::string { return m_hint; }
   9212     };
   9213 
   9214     class ExeName : public ComposableParserImpl<ExeName> {
   9215         std::shared_ptr<std::string> m_name;
   9216         std::shared_ptr<BoundValueRefBase> m_ref;
   9217 
   9218         template<typename LambdaT>
   9219         static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
   9220             return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
   9221         }
   9222 
   9223     public:
   9224         ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
   9225 
   9226         explicit ExeName( std::string &ref ) : ExeName() {
   9227             m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
   9228         }
   9229 
   9230         template<typename LambdaT>
   9231         explicit ExeName( LambdaT const& lambda ) : ExeName() {
   9232             m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
   9233         }
   9234 
   9235         // The exe name is not parsed out of the normal tokens, but is handled specially
   9236         auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
   9237             return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
   9238         }
   9239 
   9240         auto name() const -> std::string { return *m_name; }
   9241         auto set( std::string const& newName ) -> ParserResult {
   9242 
   9243             auto lastSlash = newName.find_last_of( "\\/" );
   9244             auto filename = ( lastSlash == std::string::npos )
   9245                     ? newName
   9246                     : newName.substr( lastSlash+1 );
   9247 
   9248             *m_name = filename;
   9249             if( m_ref )
   9250                 return m_ref->setValue( filename );
   9251             else
   9252                 return ParserResult::ok( ParseResultType::Matched );
   9253         }
   9254     };
   9255 
   9256     class Arg : public ParserRefImpl<Arg> {
   9257     public:
   9258         using ParserRefImpl::ParserRefImpl;
   9259 
   9260         auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
   9261             auto validationResult = validate();
   9262             if( !validationResult )
   9263                 return InternalParseResult( validationResult );
   9264 
   9265             auto remainingTokens = tokens;
   9266             auto const &token = *remainingTokens;
   9267             if( token.type != TokenType::Argument )
   9268                 return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
   9269 
   9270             assert( !m_ref->isFlag() );
   9271             auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
   9272 
   9273             auto result = valueRef->setValue( remainingTokens->token );
   9274             if( !result )
   9275                 return InternalParseResult( result );
   9276             else
   9277                 return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
   9278         }
   9279     };
   9280 
   9281     inline auto normaliseOpt( std::string const &optName ) -> std::string {
   9282 #ifdef CATCH_PLATFORM_WINDOWS
   9283         if( optName[0] == '/' )
   9284             return "-" + optName.substr( 1 );
   9285         else
   9286 #endif
   9287             return optName;
   9288     }
   9289 
   9290     class Opt : public ParserRefImpl<Opt> {
   9291     protected:
   9292         std::vector<std::string> m_optNames;
   9293 
   9294     public:
   9295         template<typename LambdaT>
   9296         explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
   9297 
   9298         explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
   9299 
   9300         template<typename LambdaT>
   9301         Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
   9302 
   9303         template<typename T>
   9304         Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
   9305 
   9306         auto operator[]( std::string const &optName ) -> Opt & {
   9307             m_optNames.push_back( optName );
   9308             return *this;
   9309         }
   9310 
   9311         auto getHelpColumns() const -> std::vector<HelpColumns> {
   9312             std::ostringstream oss;
   9313             bool first = true;
   9314             for( auto const &opt : m_optNames ) {
   9315                 if (first)
   9316                     first = false;
   9317                 else
   9318                     oss << ", ";
   9319                 oss << opt;
   9320             }
   9321             if( !m_hint.empty() )
   9322                 oss << " <" << m_hint << ">";
   9323             return { { oss.str(), m_description } };
   9324         }
   9325 
   9326         auto isMatch( std::string const &optToken ) const -> bool {
   9327             auto normalisedToken = normaliseOpt( optToken );
   9328             for( auto const &name : m_optNames ) {
   9329                 if( normaliseOpt( name ) == normalisedToken )
   9330                     return true;
   9331             }
   9332             return false;
   9333         }
   9334 
   9335         using ParserBase::parse;
   9336 
   9337         auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
   9338             auto validationResult = validate();
   9339             if( !validationResult )
   9340                 return InternalParseResult( validationResult );
   9341 
   9342             auto remainingTokens = tokens;
   9343             if( remainingTokens && remainingTokens->type == TokenType::Option ) {
   9344                 auto const &token = *remainingTokens;
   9345                 if( isMatch(token.token ) ) {
   9346                     if( m_ref->isFlag() ) {
   9347                         auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
   9348                         auto result = flagRef->setFlag( true );
   9349                         if( !result )
   9350                             return InternalParseResult( result );
   9351                         if( result.value() == ParseResultType::ShortCircuitAll )
   9352                             return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
   9353                     } else {
   9354                         auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
   9355                         ++remainingTokens;
   9356                         if( !remainingTokens )
   9357                             return InternalParseResult::runtimeError( "Expected argument following " + token.token );
   9358                         auto const &argToken = *remainingTokens;
   9359                         if( argToken.type != TokenType::Argument )
   9360                             return InternalParseResult::runtimeError( "Expected argument following " + token.token );
   9361                         auto result = valueRef->setValue( argToken.token );
   9362                         if( !result )
   9363                             return InternalParseResult( result );
   9364                         if( result.value() == ParseResultType::ShortCircuitAll )
   9365                             return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
   9366                     }
   9367                     return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
   9368                 }
   9369             }
   9370             return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
   9371         }
   9372 
   9373         auto validate() const -> Result override {
   9374             if( m_optNames.empty() )
   9375                 return Result::logicError( "No options supplied to Opt" );
   9376             for( auto const &name : m_optNames ) {
   9377                 if( name.empty() )
   9378                     return Result::logicError( "Option name cannot be empty" );
   9379 #ifdef CATCH_PLATFORM_WINDOWS
   9380                 if( name[0] != '-' && name[0] != '/' )
   9381                     return Result::logicError( "Option name must begin with '-' or '/'" );
   9382 #else
   9383                 if( name[0] != '-' )
   9384                     return Result::logicError( "Option name must begin with '-'" );
   9385 #endif
   9386             }
   9387             return ParserRefImpl::validate();
   9388         }
   9389     };
   9390 
   9391     struct Help : Opt {
   9392         Help( bool &showHelpFlag )
   9393         :   Opt([&]( bool flag ) {
   9394                 showHelpFlag = flag;
   9395                 return ParserResult::ok( ParseResultType::ShortCircuitAll );
   9396             })
   9397         {
   9398             static_cast<Opt &>( *this )
   9399                     ("display usage information")
   9400                     ["-?"]["-h"]["--help"]
   9401                     .optional();
   9402         }
   9403     };
   9404 
   9405     struct Parser : ParserBase {
   9406 
   9407         mutable ExeName m_exeName;
   9408         std::vector<Opt> m_options;
   9409         std::vector<Arg> m_args;
   9410 
   9411         auto operator|=( ExeName const &exeName ) -> Parser & {
   9412             m_exeName = exeName;
   9413             return *this;
   9414         }
   9415 
   9416         auto operator|=( Arg const &arg ) -> Parser & {
   9417             m_args.push_back(arg);
   9418             return *this;
   9419         }
   9420 
   9421         auto operator|=( Opt const &opt ) -> Parser & {
   9422             m_options.push_back(opt);
   9423             return *this;
   9424         }
   9425 
   9426         auto operator|=( Parser const &other ) -> Parser & {
   9427             m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
   9428             m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
   9429             return *this;
   9430         }
   9431 
   9432         template<typename T>
   9433         auto operator|( T const &other ) const -> Parser {
   9434             return Parser( *this ) |= other;
   9435         }
   9436 
   9437         // Forward deprecated interface with '+' instead of '|'
   9438         template<typename T>
   9439         auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
   9440         template<typename T>
   9441         auto operator+( T const &other ) const -> Parser { return operator|( other ); }
   9442 
   9443         auto getHelpColumns() const -> std::vector<HelpColumns> {
   9444             std::vector<HelpColumns> cols;
   9445             for (auto const &o : m_options) {
   9446                 auto childCols = o.getHelpColumns();
   9447                 cols.insert( cols.end(), childCols.begin(), childCols.end() );
   9448             }
   9449             return cols;
   9450         }
   9451 
   9452         void writeToStream( std::ostream &os ) const {
   9453             if (!m_exeName.name().empty()) {
   9454                 os << "usage:\n" << "  " << m_exeName.name() << " ";
   9455                 bool required = true, first = true;
   9456                 for( auto const &arg : m_args ) {
   9457                     if (first)
   9458                         first = false;
   9459                     else
   9460                         os << " ";
   9461                     if( arg.isOptional() && required ) {
   9462                         os << "[";
   9463                         required = false;
   9464                     }
   9465                     os << "<" << arg.hint() << ">";
   9466                     if( arg.cardinality() == 0 )
   9467                         os << " ... ";
   9468                 }
   9469                 if( !required )
   9470                     os << "]";
   9471                 if( !m_options.empty() )
   9472                     os << " options";
   9473                 os << "\n\nwhere options are:" << std::endl;
   9474             }
   9475 
   9476             auto rows = getHelpColumns();
   9477             size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
   9478             size_t optWidth = 0;
   9479             for( auto const &cols : rows )
   9480                 optWidth = (std::max)(optWidth, cols.left.size() + 2);
   9481 
   9482             optWidth = (std::min)(optWidth, consoleWidth/2);
   9483 
   9484             for( auto const &cols : rows ) {
   9485                 auto row =
   9486                         TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
   9487                         TextFlow::Spacer(4) +
   9488                         TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
   9489                 os << row << std::endl;
   9490             }
   9491         }
   9492 
   9493         friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
   9494             parser.writeToStream( os );
   9495             return os;
   9496         }
   9497 
   9498         auto validate() const -> Result override {
   9499             for( auto const &opt : m_options ) {
   9500                 auto result = opt.validate();
   9501                 if( !result )
   9502                     return result;
   9503             }
   9504             for( auto const &arg : m_args ) {
   9505                 auto result = arg.validate();
   9506                 if( !result )
   9507                     return result;
   9508             }
   9509             return Result::ok();
   9510         }
   9511 
   9512         using ParserBase::parse;
   9513 
   9514         auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
   9515 
   9516             struct ParserInfo {
   9517                 ParserBase const* parser = nullptr;
   9518                 size_t count = 0;
   9519             };
   9520             const size_t totalParsers = m_options.size() + m_args.size();
   9521             assert( totalParsers < 512 );
   9522             // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
   9523             ParserInfo parseInfos[512];
   9524 
   9525             {
   9526                 size_t i = 0;
   9527                 for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
   9528                 for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
   9529             }
   9530 
   9531             m_exeName.set( exeName );
   9532 
   9533             auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
   9534             while( result.value().remainingTokens() ) {
   9535                 bool tokenParsed = false;
   9536 
   9537                 for( size_t i = 0; i < totalParsers; ++i ) {
   9538                     auto&  parseInfo = parseInfos[i];
   9539                     if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
   9540                         result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
   9541                         if (!result)
   9542                             return result;
   9543                         if (result.value().type() != ParseResultType::NoMatch) {
   9544                             tokenParsed = true;
   9545                             ++parseInfo.count;
   9546                             break;
   9547                         }
   9548                     }
   9549                 }
   9550 
   9551                 if( result.value().type() == ParseResultType::ShortCircuitAll )
   9552                     return result;
   9553                 if( !tokenParsed )
   9554                     return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
   9555             }
   9556             // !TBD Check missing required options
   9557             return result;
   9558         }
   9559     };
   9560 
   9561     template<typename DerivedT>
   9562     template<typename T>
   9563     auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
   9564         return Parser() | static_cast<DerivedT const &>( *this ) | other;
   9565     }
   9566 } // namespace detail
   9567 
   9568 // A Combined parser
   9569 using detail::Parser;
   9570 
   9571 // A parser for options
   9572 using detail::Opt;
   9573 
   9574 // A parser for arguments
   9575 using detail::Arg;
   9576 
   9577 // Wrapper for argc, argv from main()
   9578 using detail::Args;
   9579 
   9580 // Specifies the name of the executable
   9581 using detail::ExeName;
   9582 
   9583 // Convenience wrapper for option parser that specifies the help option
   9584 using detail::Help;
   9585 
   9586 // enum of result types from a parse
   9587 using detail::ParseResultType;
   9588 
   9589 // Result type for parser operation
   9590 using detail::ParserResult;
   9591 
   9592 }} // namespace Catch::clara
   9593 
   9594 // end clara.hpp
   9595 #ifdef __clang__
   9596 #pragma clang diagnostic pop
   9597 #endif
   9598 
   9599 // Restore Clara's value for console width, if present
   9600 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
   9601 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
   9602 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
   9603 #endif
   9604 
   9605 // end catch_clara.h
   9606 namespace Catch {
   9607 
   9608     clara::Parser makeCommandLineParser( ConfigData& config );
   9609 
   9610 } // end namespace Catch
   9611 
   9612 // end catch_commandline.h
   9613 #include <fstream>
   9614 #include <ctime>
   9615 
   9616 namespace Catch {
   9617 
   9618     clara::Parser makeCommandLineParser( ConfigData& config ) {
   9619 
   9620         using namespace clara;
   9621 
   9622         auto const setWarning = [&]( std::string const& warning ) {
   9623                 auto warningSet = [&]() {
   9624                     if( warning == "NoAssertions" )
   9625                         return WarnAbout::NoAssertions;
   9626 
   9627                     if ( warning == "NoTests" )
   9628                         return WarnAbout::NoTests;
   9629 
   9630                     return WarnAbout::Nothing;
   9631                 }();
   9632 
   9633                 if (warningSet == WarnAbout::Nothing)
   9634                     return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
   9635                 config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
   9636                 return ParserResult::ok( ParseResultType::Matched );
   9637             };
   9638         auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
   9639                 std::ifstream f( filename.c_str() );
   9640                 if( !f.is_open() )
   9641                     return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
   9642 
   9643                 std::string line;
   9644                 while( std::getline( f, line ) ) {
   9645                     line = trim(line);
   9646                     if( !line.empty() && !startsWith( line, '#' ) ) {
   9647                         if( !startsWith( line, '"' ) )
   9648                             line = '"' + line + '"';
   9649                         config.testsOrTags.push_back( line );
   9650                         config.testsOrTags.push_back( "," );
   9651 
   9652                     }
   9653                 }
   9654                 //Remove comma in the end
   9655                 if(!config.testsOrTags.empty())
   9656                     config.testsOrTags.erase( config.testsOrTags.end()-1 );
   9657 
   9658                 return ParserResult::ok( ParseResultType::Matched );
   9659             };
   9660         auto const setTestOrder = [&]( std::string const& order ) {
   9661                 if( startsWith( "declared", order ) )
   9662                     config.runOrder = RunTests::InDeclarationOrder;
   9663                 else if( startsWith( "lexical", order ) )
   9664                     config.runOrder = RunTests::InLexicographicalOrder;
   9665                 else if( startsWith( "random", order ) )
   9666                     config.runOrder = RunTests::InRandomOrder;
   9667                 else
   9668                     return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
   9669                 return ParserResult::ok( ParseResultType::Matched );
   9670             };
   9671         auto const setRngSeed = [&]( std::string const& seed ) {
   9672                 if( seed != "time" )
   9673                     return clara::detail::convertInto( seed, config.rngSeed );
   9674                 config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
   9675                 return ParserResult::ok( ParseResultType::Matched );
   9676             };
   9677         auto const setColourUsage = [&]( std::string const& useColour ) {
   9678                     auto mode = toLower( useColour );
   9679 
   9680                     if( mode == "yes" )
   9681                         config.useColour = UseColour::Yes;
   9682                     else if( mode == "no" )
   9683                         config.useColour = UseColour::No;
   9684                     else if( mode == "auto" )
   9685                         config.useColour = UseColour::Auto;
   9686                     else
   9687                         return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
   9688                 return ParserResult::ok( ParseResultType::Matched );
   9689             };
   9690         auto const setWaitForKeypress = [&]( std::string const& keypress ) {
   9691                 auto keypressLc = toLower( keypress );
   9692                 if( keypressLc == "start" )
   9693                     config.waitForKeypress = WaitForKeypress::BeforeStart;
   9694                 else if( keypressLc == "exit" )
   9695                     config.waitForKeypress = WaitForKeypress::BeforeExit;
   9696                 else if( keypressLc == "both" )
   9697                     config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
   9698                 else
   9699                     return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
   9700             return ParserResult::ok( ParseResultType::Matched );
   9701             };
   9702         auto const setVerbosity = [&]( std::string const& verbosity ) {
   9703             auto lcVerbosity = toLower( verbosity );
   9704             if( lcVerbosity == "quiet" )
   9705                 config.verbosity = Verbosity::Quiet;
   9706             else if( lcVerbosity == "normal" )
   9707                 config.verbosity = Verbosity::Normal;
   9708             else if( lcVerbosity == "high" )
   9709                 config.verbosity = Verbosity::High;
   9710             else
   9711                 return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
   9712             return ParserResult::ok( ParseResultType::Matched );
   9713         };
   9714         auto const setReporter = [&]( std::string const& reporter ) {
   9715             IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
   9716 
   9717             auto lcReporter = toLower( reporter );
   9718             auto result = factories.find( lcReporter );
   9719 
   9720             if( factories.end() != result )
   9721                 config.reporterName = lcReporter;
   9722             else
   9723                 return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
   9724             return ParserResult::ok( ParseResultType::Matched );
   9725         };
   9726 
   9727         auto cli
   9728             = ExeName( config.processName )
   9729             | Help( config.showHelp )
   9730             | Opt( config.listTests )
   9731                 ["-l"]["--list-tests"]
   9732                 ( "list all/matching test cases" )
   9733             | Opt( config.listTags )
   9734                 ["-t"]["--list-tags"]
   9735                 ( "list all/matching tags" )
   9736             | Opt( config.showSuccessfulTests )
   9737                 ["-s"]["--success"]
   9738                 ( "include successful tests in output" )
   9739             | Opt( config.shouldDebugBreak )
   9740                 ["-b"]["--break"]
   9741                 ( "break into debugger on failure" )
   9742             | Opt( config.noThrow )
   9743                 ["-e"]["--nothrow"]
   9744                 ( "skip exception tests" )
   9745             | Opt( config.showInvisibles )
   9746                 ["-i"]["--invisibles"]
   9747                 ( "show invisibles (tabs, newlines)" )
   9748             | Opt( config.outputFilename, "filename" )
   9749                 ["-o"]["--out"]
   9750                 ( "output filename" )
   9751             | Opt( setReporter, "name" )
   9752                 ["-r"]["--reporter"]
   9753                 ( "reporter to use (defaults to console)" )
   9754             | Opt( config.name, "name" )
   9755                 ["-n"]["--name"]
   9756                 ( "suite name" )
   9757             | Opt( [&]( bool ){ config.abortAfter = 1; } )
   9758                 ["-a"]["--abort"]
   9759                 ( "abort at first failure" )
   9760             | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
   9761                 ["-x"]["--abortx"]
   9762                 ( "abort after x failures" )
   9763             | Opt( setWarning, "warning name" )
   9764                 ["-w"]["--warn"]
   9765                 ( "enable warnings" )
   9766             | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
   9767                 ["-d"]["--durations"]
   9768                 ( "show test durations" )
   9769             | Opt( loadTestNamesFromFile, "filename" )
   9770                 ["-f"]["--input-file"]
   9771                 ( "load test names to run from a file" )
   9772             | Opt( config.filenamesAsTags )
   9773                 ["-#"]["--filenames-as-tags"]
   9774                 ( "adds a tag for the filename" )
   9775             | Opt( config.sectionsToRun, "section name" )
   9776                 ["-c"]["--section"]
   9777                 ( "specify section to run" )
   9778             | Opt( setVerbosity, "quiet|normal|high" )
   9779                 ["-v"]["--verbosity"]
   9780                 ( "set output verbosity" )
   9781             | Opt( config.listTestNamesOnly )
   9782                 ["--list-test-names-only"]
   9783                 ( "list all/matching test cases names only" )
   9784             | Opt( config.listReporters )
   9785                 ["--list-reporters"]
   9786                 ( "list all reporters" )
   9787             | Opt( setTestOrder, "decl|lex|rand" )
   9788                 ["--order"]
   9789                 ( "test case order (defaults to decl)" )
   9790             | Opt( setRngSeed, "'time'|number" )
   9791                 ["--rng-seed"]
   9792                 ( "set a specific seed for random numbers" )
   9793             | Opt( setColourUsage, "yes|no" )
   9794                 ["--use-colour"]
   9795                 ( "should output be colourised" )
   9796             | Opt( config.libIdentify )
   9797                 ["--libidentify"]
   9798                 ( "report name and version according to libidentify standard" )
   9799             | Opt( setWaitForKeypress, "start|exit|both" )
   9800                 ["--wait-for-keypress"]
   9801                 ( "waits for a keypress before exiting" )
   9802             | Opt( config.benchmarkSamples, "samples" )
   9803                 ["--benchmark-samples"]
   9804                 ( "number of samples to collect (default: 100)" )
   9805             | Opt( config.benchmarkResamples, "resamples" )
   9806                 ["--benchmark-resamples"]
   9807                 ( "number of resamples for the bootstrap (default: 100000)" )
   9808             | Opt( config.benchmarkConfidenceInterval, "confidence interval" )
   9809                 ["--benchmark-confidence-interval"]
   9810                 ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" )
   9811             | Opt( config.benchmarkNoAnalysis )
   9812                 ["--benchmark-no-analysis"]
   9813                 ( "perform only measurements; do not perform any analysis" )
   9814 			| Arg( config.testsOrTags, "test name|pattern|tags" )
   9815                 ( "which test or tests to use" );
   9816 
   9817         return cli;
   9818     }
   9819 
   9820 } // end namespace Catch
   9821 // end catch_commandline.cpp
   9822 // start catch_common.cpp
   9823 
   9824 #include <cstring>
   9825 #include <ostream>
   9826 
   9827 namespace Catch {
   9828 
   9829     bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
   9830         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
   9831     }
   9832     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
   9833         // We can assume that the same file will usually have the same pointer.
   9834         // Thus, if the pointers are the same, there is no point in calling the strcmp
   9835         return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
   9836     }
   9837 
   9838     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
   9839 #ifndef __GNUG__
   9840         os << info.file << '(' << info.line << ')';
   9841 #else
   9842         os << info.file << ':' << info.line;
   9843 #endif
   9844         return os;
   9845     }
   9846 
   9847     std::string StreamEndStop::operator+() const {
   9848         return std::string();
   9849     }
   9850 
   9851     NonCopyable::NonCopyable() = default;
   9852     NonCopyable::~NonCopyable() = default;
   9853 
   9854 }
   9855 // end catch_common.cpp
   9856 // start catch_config.cpp
   9857 
   9858 namespace Catch {
   9859 
   9860     Config::Config( ConfigData const& data )
   9861     :   m_data( data ),
   9862         m_stream( openStream() )
   9863     {
   9864         // We need to trim filter specs to avoid trouble with superfluous
   9865         // whitespace (esp. important for bdd macros, as those are manually
   9866         // aligned with whitespace).
   9867 
   9868         for (auto& elem : m_data.testsOrTags) {
   9869             elem = trim(elem);
   9870         }
   9871         for (auto& elem : m_data.sectionsToRun) {
   9872             elem = trim(elem);
   9873         }
   9874 
   9875         TestSpecParser parser(ITagAliasRegistry::get());
   9876         if (!m_data.testsOrTags.empty()) {
   9877             m_hasTestFilters = true;
   9878             for (auto const& testOrTags : m_data.testsOrTags) {
   9879                 parser.parse(testOrTags);
   9880             }
   9881         }
   9882         m_testSpec = parser.testSpec();
   9883     }
   9884 
   9885     std::string const& Config::getFilename() const {
   9886         return m_data.outputFilename ;
   9887     }
   9888 
   9889     bool Config::listTests() const          { return m_data.listTests; }
   9890     bool Config::listTestNamesOnly() const  { return m_data.listTestNamesOnly; }
   9891     bool Config::listTags() const           { return m_data.listTags; }
   9892     bool Config::listReporters() const      { return m_data.listReporters; }
   9893 
   9894     std::string Config::getProcessName() const { return m_data.processName; }
   9895     std::string const& Config::getReporterName() const { return m_data.reporterName; }
   9896 
   9897     std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
   9898     std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
   9899 
   9900     TestSpec const& Config::testSpec() const { return m_testSpec; }
   9901     bool Config::hasTestFilters() const { return m_hasTestFilters; }
   9902 
   9903     bool Config::showHelp() const { return m_data.showHelp; }
   9904 
   9905     // IConfig interface
   9906     bool Config::allowThrows() const                   { return !m_data.noThrow; }
   9907     std::ostream& Config::stream() const               { return m_stream->stream(); }
   9908     std::string Config::name() const                   { return m_data.name.empty() ? m_data.processName : m_data.name; }
   9909     bool Config::includeSuccessfulResults() const      { return m_data.showSuccessfulTests; }
   9910     bool Config::warnAboutMissingAssertions() const    { return !!(m_data.warnings & WarnAbout::NoAssertions); }
   9911     bool Config::warnAboutNoTests() const              { return !!(m_data.warnings & WarnAbout::NoTests); }
   9912     ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
   9913     RunTests::InWhatOrder Config::runOrder() const     { return m_data.runOrder; }
   9914     unsigned int Config::rngSeed() const               { return m_data.rngSeed; }
   9915     UseColour::YesOrNo Config::useColour() const       { return m_data.useColour; }
   9916     bool Config::shouldDebugBreak() const              { return m_data.shouldDebugBreak; }
   9917     int Config::abortAfter() const                     { return m_data.abortAfter; }
   9918     bool Config::showInvisibles() const                { return m_data.showInvisibles; }
   9919     Verbosity Config::verbosity() const                { return m_data.verbosity; }
   9920 
   9921     bool Config::benchmarkNoAnalysis() const           { return m_data.benchmarkNoAnalysis; }
   9922     int Config::benchmarkSamples() const               { return m_data.benchmarkSamples; }
   9923     double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
   9924     unsigned int Config::benchmarkResamples() const    { return m_data.benchmarkResamples; }
   9925 
   9926     IStream const* Config::openStream() {
   9927         return Catch::makeStream(m_data.outputFilename);
   9928     }
   9929 
   9930 } // end namespace Catch
   9931 // end catch_config.cpp
   9932 // start catch_console_colour.cpp
   9933 
   9934 #if defined(__clang__)
   9935 #    pragma clang diagnostic push
   9936 #    pragma clang diagnostic ignored "-Wexit-time-destructors"
   9937 #endif
   9938 
   9939 // start catch_errno_guard.h
   9940 
   9941 namespace Catch {
   9942 
   9943     class ErrnoGuard {
   9944     public:
   9945         ErrnoGuard();
   9946         ~ErrnoGuard();
   9947     private:
   9948         int m_oldErrno;
   9949     };
   9950 
   9951 }
   9952 
   9953 // end catch_errno_guard.h
   9954 #include <sstream>
   9955 
   9956 namespace Catch {
   9957     namespace {
   9958 
   9959         struct IColourImpl {
   9960             virtual ~IColourImpl() = default;
   9961             virtual void use( Colour::Code _colourCode ) = 0;
   9962         };
   9963 
   9964         struct NoColourImpl : IColourImpl {
   9965             void use( Colour::Code ) {}
   9966 
   9967             static IColourImpl* instance() {
   9968                 static NoColourImpl s_instance;
   9969                 return &s_instance;
   9970             }
   9971         };
   9972 
   9973     } // anon namespace
   9974 } // namespace Catch
   9975 
   9976 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
   9977 #   ifdef CATCH_PLATFORM_WINDOWS
   9978 #       define CATCH_CONFIG_COLOUR_WINDOWS
   9979 #   else
   9980 #       define CATCH_CONFIG_COLOUR_ANSI
   9981 #   endif
   9982 #endif
   9983 
   9984 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
   9985 
   9986 namespace Catch {
   9987 namespace {
   9988 
   9989     class Win32ColourImpl : public IColourImpl {
   9990     public:
   9991         Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
   9992         {
   9993             CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
   9994             GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
   9995             originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
   9996             originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
   9997         }
   9998 
   9999         void use( Colour::Code _colourCode ) override {
  10000             switch( _colourCode ) {
  10001                 case Colour::None:      return setTextAttribute( originalForegroundAttributes );
  10002                 case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
  10003                 case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
  10004                 case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
  10005                 case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
  10006                 case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
  10007                 case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
  10008                 case Colour::Grey:      return setTextAttribute( 0 );
  10009 
  10010                 case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
  10011                 case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
  10012                 case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
  10013                 case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
  10014                 case Colour::BrightYellow:  return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
  10015 
  10016                 case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
  10017 
  10018                 default:
  10019                     CATCH_ERROR( "Unknown colour requested" );
  10020             }
  10021         }
  10022 
  10023     private:
  10024         void setTextAttribute( WORD _textAttribute ) {
  10025             SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
  10026         }
  10027         HANDLE stdoutHandle;
  10028         WORD originalForegroundAttributes;
  10029         WORD originalBackgroundAttributes;
  10030     };
  10031 
  10032     IColourImpl* platformColourInstance() {
  10033         static Win32ColourImpl s_instance;
  10034 
  10035         IConfigPtr config = getCurrentContext().getConfig();
  10036         UseColour::YesOrNo colourMode = config
  10037             ? config->useColour()
  10038             : UseColour::Auto;
  10039         if( colourMode == UseColour::Auto )
  10040             colourMode = UseColour::Yes;
  10041         return colourMode == UseColour::Yes
  10042             ? &s_instance
  10043             : NoColourImpl::instance();
  10044     }
  10045 
  10046 } // end anon namespace
  10047 } // end namespace Catch
  10048 
  10049 #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
  10050 
  10051 #include <unistd.h>
  10052 
  10053 namespace Catch {
  10054 namespace {
  10055 
  10056     // use POSIX/ ANSI console terminal codes
  10057     // Thanks to Adam Strzelecki for original contribution
  10058     // (http://github.com/nanoant)
  10059     // https://github.com/philsquared/Catch/pull/131
  10060     class PosixColourImpl : public IColourImpl {
  10061     public:
  10062         void use( Colour::Code _colourCode ) override {
  10063             switch( _colourCode ) {
  10064                 case Colour::None:
  10065                 case Colour::White:     return setColour( "[0m" );
  10066                 case Colour::Red:       return setColour( "[0;31m" );
  10067                 case Colour::Green:     return setColour( "[0;32m" );
  10068                 case Colour::Blue:      return setColour( "[0;34m" );
  10069                 case Colour::Cyan:      return setColour( "[0;36m" );
  10070                 case Colour::Yellow:    return setColour( "[0;33m" );
  10071                 case Colour::Grey:      return setColour( "[1;30m" );
  10072 
  10073                 case Colour::LightGrey:     return setColour( "[0;37m" );
  10074                 case Colour::BrightRed:     return setColour( "[1;31m" );
  10075                 case Colour::BrightGreen:   return setColour( "[1;32m" );
  10076                 case Colour::BrightWhite:   return setColour( "[1;37m" );
  10077                 case Colour::BrightYellow:  return setColour( "[1;33m" );
  10078 
  10079                 case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
  10080                 default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
  10081             }
  10082         }
  10083         static IColourImpl* instance() {
  10084             static PosixColourImpl s_instance;
  10085             return &s_instance;
  10086         }
  10087 
  10088     private:
  10089         void setColour( const char* _escapeCode ) {
  10090             getCurrentContext().getConfig()->stream()
  10091                 << '\033' << _escapeCode;
  10092         }
  10093     };
  10094 
  10095     bool useColourOnPlatform() {
  10096         return
  10097 #ifdef CATCH_PLATFORM_MAC
  10098             !isDebuggerActive() &&
  10099 #endif
  10100 #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
  10101             isatty(STDOUT_FILENO)
  10102 #else
  10103             false
  10104 #endif
  10105             ;
  10106     }
  10107     IColourImpl* platformColourInstance() {
  10108         ErrnoGuard guard;
  10109         IConfigPtr config = getCurrentContext().getConfig();
  10110         UseColour::YesOrNo colourMode = config
  10111             ? config->useColour()
  10112             : UseColour::Auto;
  10113         if( colourMode == UseColour::Auto )
  10114             colourMode = useColourOnPlatform()
  10115                 ? UseColour::Yes
  10116                 : UseColour::No;
  10117         return colourMode == UseColour::Yes
  10118             ? PosixColourImpl::instance()
  10119             : NoColourImpl::instance();
  10120     }
  10121 
  10122 } // end anon namespace
  10123 } // end namespace Catch
  10124 
  10125 #else  // not Windows or ANSI ///////////////////////////////////////////////
  10126 
  10127 namespace Catch {
  10128 
  10129     static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
  10130 
  10131 } // end namespace Catch
  10132 
  10133 #endif // Windows/ ANSI/ None
  10134 
  10135 namespace Catch {
  10136 
  10137     Colour::Colour( Code _colourCode ) { use( _colourCode ); }
  10138     Colour::Colour( Colour&& rhs ) noexcept {
  10139         m_moved = rhs.m_moved;
  10140         rhs.m_moved = true;
  10141     }
  10142     Colour& Colour::operator=( Colour&& rhs ) noexcept {
  10143         m_moved = rhs.m_moved;
  10144         rhs.m_moved  = true;
  10145         return *this;
  10146     }
  10147 
  10148     Colour::~Colour(){ if( !m_moved ) use( None ); }
  10149 
  10150     void Colour::use( Code _colourCode ) {
  10151         static IColourImpl* impl = platformColourInstance();
  10152         // Strictly speaking, this cannot possibly happen.
  10153         // However, under some conditions it does happen (see #1626),
  10154         // and this change is small enough that we can let practicality
  10155         // triumph over purity in this case.
  10156         if (impl != NULL) {
  10157             impl->use( _colourCode );
  10158         }
  10159     }
  10160 
  10161     std::ostream& operator << ( std::ostream& os, Colour const& ) {
  10162         return os;
  10163     }
  10164 
  10165 } // end namespace Catch
  10166 
  10167 #if defined(__clang__)
  10168 #    pragma clang diagnostic pop
  10169 #endif
  10170 
  10171 // end catch_console_colour.cpp
  10172 // start catch_context.cpp
  10173 
  10174 namespace Catch {
  10175 
  10176     class Context : public IMutableContext, NonCopyable {
  10177 
  10178     public: // IContext
  10179         IResultCapture* getResultCapture() override {
  10180             return m_resultCapture;
  10181         }
  10182         IRunner* getRunner() override {
  10183             return m_runner;
  10184         }
  10185 
  10186         IConfigPtr const& getConfig() const override {
  10187             return m_config;
  10188         }
  10189 
  10190         ~Context() override;
  10191 
  10192     public: // IMutableContext
  10193         void setResultCapture( IResultCapture* resultCapture ) override {
  10194             m_resultCapture = resultCapture;
  10195         }
  10196         void setRunner( IRunner* runner ) override {
  10197             m_runner = runner;
  10198         }
  10199         void setConfig( IConfigPtr const& config ) override {
  10200             m_config = config;
  10201         }
  10202 
  10203         friend IMutableContext& getCurrentMutableContext();
  10204 
  10205     private:
  10206         IConfigPtr m_config;
  10207         IRunner* m_runner = nullptr;
  10208         IResultCapture* m_resultCapture = nullptr;
  10209     };
  10210 
  10211     IMutableContext *IMutableContext::currentContext = nullptr;
  10212 
  10213     void IMutableContext::createContext()
  10214     {
  10215         currentContext = new Context();
  10216     }
  10217 
  10218     void cleanUpContext() {
  10219         delete IMutableContext::currentContext;
  10220         IMutableContext::currentContext = nullptr;
  10221     }
  10222     IContext::~IContext() = default;
  10223     IMutableContext::~IMutableContext() = default;
  10224     Context::~Context() = default;
  10225 
  10226     SimplePcg32& rng() {
  10227         static SimplePcg32 s_rng;
  10228         return s_rng;
  10229     }
  10230 
  10231 }
  10232 // end catch_context.cpp
  10233 // start catch_debug_console.cpp
  10234 
  10235 // start catch_debug_console.h
  10236 
  10237 #include <string>
  10238 
  10239 namespace Catch {
  10240     void writeToDebugConsole( std::string const& text );
  10241 }
  10242 
  10243 // end catch_debug_console.h
  10244 #if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
  10245 #include <android/log.h>
  10246 
  10247     namespace Catch {
  10248         void writeToDebugConsole( std::string const& text ) {
  10249             __android_log_write( ANDROID_LOG_DEBUG, "Catch", text.c_str() );
  10250         }
  10251     }
  10252 
  10253 #elif defined(CATCH_PLATFORM_WINDOWS)
  10254 
  10255     namespace Catch {
  10256         void writeToDebugConsole( std::string const& text ) {
  10257             ::OutputDebugStringA( text.c_str() );
  10258         }
  10259     }
  10260 
  10261 #else
  10262 
  10263     namespace Catch {
  10264         void writeToDebugConsole( std::string const& text ) {
  10265             // !TBD: Need a version for Mac/ XCode and other IDEs
  10266             Catch::cout() << text;
  10267         }
  10268     }
  10269 
  10270 #endif // Platform
  10271 // end catch_debug_console.cpp
  10272 // start catch_debugger.cpp
  10273 
  10274 #ifdef CATCH_PLATFORM_MAC
  10275 
  10276 #  include <assert.h>
  10277 #  include <stdbool.h>
  10278 #  include <sys/types.h>
  10279 #  include <unistd.h>
  10280 #  include <cstddef>
  10281 #  include <ostream>
  10282 
  10283 #ifdef __apple_build_version__
  10284     // These headers will only compile with AppleClang (XCode)
  10285     // For other compilers (Clang, GCC, ... ) we need to exclude them
  10286 #  include <sys/sysctl.h>
  10287 #endif
  10288 
  10289     namespace Catch {
  10290         #ifdef __apple_build_version__
  10291         // The following function is taken directly from the following technical note:
  10292         // https://developer.apple.com/library/archive/qa/qa1361/_index.html
  10293 
  10294         // Returns true if the current process is being debugged (either
  10295         // running under the debugger or has a debugger attached post facto).
  10296         bool isDebuggerActive(){
  10297             int                 mib[4];
  10298             struct kinfo_proc   info;
  10299             std::size_t         size;
  10300 
  10301             // Initialize the flags so that, if sysctl fails for some bizarre
  10302             // reason, we get a predictable result.
  10303 
  10304             info.kp_proc.p_flag = 0;
  10305 
  10306             // Initialize mib, which tells sysctl the info we want, in this case
  10307             // we're looking for information about a specific process ID.
  10308 
  10309             mib[0] = CTL_KERN;
  10310             mib[1] = KERN_PROC;
  10311             mib[2] = KERN_PROC_PID;
  10312             mib[3] = getpid();
  10313 
  10314             // Call sysctl.
  10315 
  10316             size = sizeof(info);
  10317             if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
  10318                 Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
  10319                 return false;
  10320             }
  10321 
  10322             // We're being debugged if the P_TRACED flag is set.
  10323 
  10324             return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
  10325         }
  10326         #else
  10327         bool isDebuggerActive() {
  10328             // We need to find another way to determine this for non-appleclang compilers on macOS
  10329             return false;
  10330         }
  10331         #endif
  10332     } // namespace Catch
  10333 
  10334 #elif defined(CATCH_PLATFORM_LINUX)
  10335     #include <fstream>
  10336     #include <string>
  10337 
  10338     namespace Catch{
  10339         // The standard POSIX way of detecting a debugger is to attempt to
  10340         // ptrace() the process, but this needs to be done from a child and not
  10341         // this process itself to still allow attaching to this process later
  10342         // if wanted, so is rather heavy. Under Linux we have the PID of the
  10343         // "debugger" (which doesn't need to be gdb, of course, it could also
  10344         // be strace, for example) in /proc/$PID/status, so just get it from
  10345         // there instead.
  10346         bool isDebuggerActive(){
  10347             // Libstdc++ has a bug, where std::ifstream sets errno to 0
  10348             // This way our users can properly assert over errno values
  10349             ErrnoGuard guard;
  10350             std::ifstream in("/proc/self/status");
  10351             for( std::string line; std::getline(in, line); ) {
  10352                 static const int PREFIX_LEN = 11;
  10353                 if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
  10354                     // We're traced if the PID is not 0 and no other PID starts
  10355                     // with 0 digit, so it's enough to check for just a single
  10356                     // character.
  10357                     return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
  10358                 }
  10359             }
  10360 
  10361             return false;
  10362         }
  10363     } // namespace Catch
  10364 #elif defined(_MSC_VER)
  10365     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  10366     namespace Catch {
  10367         bool isDebuggerActive() {
  10368             return IsDebuggerPresent() != 0;
  10369         }
  10370     }
  10371 #elif defined(__MINGW32__)
  10372     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  10373     namespace Catch {
  10374         bool isDebuggerActive() {
  10375             return IsDebuggerPresent() != 0;
  10376         }
  10377     }
  10378 #else
  10379     namespace Catch {
  10380        bool isDebuggerActive() { return false; }
  10381     }
  10382 #endif // Platform
  10383 // end catch_debugger.cpp
  10384 // start catch_decomposer.cpp
  10385 
  10386 namespace Catch {
  10387 
  10388     ITransientExpression::~ITransientExpression() = default;
  10389 
  10390     void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
  10391         if( lhs.size() + rhs.size() < 40 &&
  10392                 lhs.find('\n') == std::string::npos &&
  10393                 rhs.find('\n') == std::string::npos )
  10394             os << lhs << " " << op << " " << rhs;
  10395         else
  10396             os << lhs << "\n" << op << "\n" << rhs;
  10397     }
  10398 }
  10399 // end catch_decomposer.cpp
  10400 // start catch_enforce.cpp
  10401 
  10402 #include <stdexcept>
  10403 
  10404 namespace Catch {
  10405 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
  10406     [[noreturn]]
  10407     void throw_exception(std::exception const& e) {
  10408         Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
  10409                       << "The message was: " << e.what() << '\n';
  10410         std::terminate();
  10411     }
  10412 #endif
  10413 
  10414     [[noreturn]]
  10415     void throw_logic_error(std::string const& msg) {
  10416         throw_exception(std::logic_error(msg));
  10417     }
  10418 
  10419     [[noreturn]]
  10420     void throw_domain_error(std::string const& msg) {
  10421         throw_exception(std::domain_error(msg));
  10422     }
  10423 
  10424     [[noreturn]]
  10425     void throw_runtime_error(std::string const& msg) {
  10426         throw_exception(std::runtime_error(msg));
  10427     }
  10428 
  10429 } // namespace Catch;
  10430 // end catch_enforce.cpp
  10431 // start catch_enum_values_registry.cpp
  10432 // start catch_enum_values_registry.h
  10433 
  10434 #include <vector>
  10435 #include <memory>
  10436 
  10437 namespace Catch {
  10438 
  10439     namespace Detail {
  10440 
  10441         std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
  10442 
  10443         class EnumValuesRegistry : public IMutableEnumValuesRegistry {
  10444 
  10445             std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
  10446 
  10447             EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
  10448         };
  10449 
  10450         std::vector<StringRef> parseEnums( StringRef enums );
  10451 
  10452     } // Detail
  10453 
  10454 } // Catch
  10455 
  10456 // end catch_enum_values_registry.h
  10457 
  10458 #include <map>
  10459 #include <cassert>
  10460 
  10461 namespace Catch {
  10462 
  10463     IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
  10464 
  10465     namespace Detail {
  10466 
  10467         namespace {
  10468             // Extracts the actual name part of an enum instance
  10469             // In other words, it returns the Blue part of Bikeshed::Colour::Blue
  10470             StringRef extractInstanceName(StringRef enumInstance) {
  10471                 // Find last occurence of ":"
  10472                 size_t name_start = enumInstance.size();
  10473                 while (name_start > 0 && enumInstance[name_start - 1] != ':') {
  10474                     --name_start;
  10475                 }
  10476                 return enumInstance.substr(name_start, enumInstance.size() - name_start);
  10477             }
  10478         }
  10479 
  10480         std::vector<StringRef> parseEnums( StringRef enums ) {
  10481             auto enumValues = splitStringRef( enums, ',' );
  10482             std::vector<StringRef> parsed;
  10483             parsed.reserve( enumValues.size() );
  10484             for( auto const& enumValue : enumValues ) {
  10485                 parsed.push_back(trim(extractInstanceName(enumValue)));
  10486             }
  10487             return parsed;
  10488         }
  10489 
  10490         EnumInfo::~EnumInfo() {}
  10491 
  10492         StringRef EnumInfo::lookup( int value ) const {
  10493             for( auto const& valueToName : m_values ) {
  10494                 if( valueToName.first == value )
  10495                     return valueToName.second;
  10496             }
  10497             return "{** unexpected enum value **}"_sr;
  10498         }
  10499 
  10500         std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
  10501             std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );
  10502             enumInfo->m_name = enumName;
  10503             enumInfo->m_values.reserve( values.size() );
  10504 
  10505             const auto valueNames = Catch::Detail::parseEnums( allValueNames );
  10506             assert( valueNames.size() == values.size() );
  10507             std::size_t i = 0;
  10508             for( auto value : values )
  10509                 enumInfo->m_values.push_back({ value, valueNames[i++] });
  10510 
  10511             return enumInfo;
  10512         }
  10513 
  10514         EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
  10515             m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
  10516             return *m_enumInfos.back();
  10517         }
  10518 
  10519     } // Detail
  10520 } // Catch
  10521 
  10522 // end catch_enum_values_registry.cpp
  10523 // start catch_errno_guard.cpp
  10524 
  10525 #include <cerrno>
  10526 
  10527 namespace Catch {
  10528         ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
  10529         ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
  10530 }
  10531 // end catch_errno_guard.cpp
  10532 // start catch_exception_translator_registry.cpp
  10533 
  10534 // start catch_exception_translator_registry.h
  10535 
  10536 #include <vector>
  10537 #include <string>
  10538 #include <memory>
  10539 
  10540 namespace Catch {
  10541 
  10542     class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
  10543     public:
  10544         ~ExceptionTranslatorRegistry();
  10545         virtual void registerTranslator( const IExceptionTranslator* translator );
  10546         std::string translateActiveException() const override;
  10547         std::string tryTranslators() const;
  10548 
  10549     private:
  10550         std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
  10551     };
  10552 }
  10553 
  10554 // end catch_exception_translator_registry.h
  10555 #ifdef __OBJC__
  10556 #import "Foundation/Foundation.h"
  10557 #endif
  10558 
  10559 namespace Catch {
  10560 
  10561     ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
  10562     }
  10563 
  10564     void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
  10565         m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
  10566     }
  10567 
  10568 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  10569     std::string ExceptionTranslatorRegistry::translateActiveException() const {
  10570         try {
  10571 #ifdef __OBJC__
  10572             // In Objective-C try objective-c exceptions first
  10573             @try {
  10574                 return tryTranslators();
  10575             }
  10576             @catch (NSException *exception) {
  10577                 return Catch::Detail::stringify( [exception description] );
  10578             }
  10579 #else
  10580             // Compiling a mixed mode project with MSVC means that CLR
  10581             // exceptions will be caught in (...) as well. However, these
  10582             // do not fill-in std::current_exception and thus lead to crash
  10583             // when attempting rethrow.
  10584             // /EHa switch also causes structured exceptions to be caught
  10585             // here, but they fill-in current_exception properly, so
  10586             // at worst the output should be a little weird, instead of
  10587             // causing a crash.
  10588             if (std::current_exception() == nullptr) {
  10589                 return "Non C++ exception. Possibly a CLR exception.";
  10590             }
  10591             return tryTranslators();
  10592 #endif
  10593         }
  10594         catch( TestFailureException& ) {
  10595             std::rethrow_exception(std::current_exception());
  10596         }
  10597         catch( std::exception& ex ) {
  10598             return ex.what();
  10599         }
  10600         catch( std::string& msg ) {
  10601             return msg;
  10602         }
  10603         catch( const char* msg ) {
  10604             return msg;
  10605         }
  10606         catch(...) {
  10607             return "Unknown exception";
  10608         }
  10609     }
  10610 
  10611     std::string ExceptionTranslatorRegistry::tryTranslators() const {
  10612         if (m_translators.empty()) {
  10613             std::rethrow_exception(std::current_exception());
  10614         } else {
  10615             return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
  10616         }
  10617     }
  10618 
  10619 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
  10620     std::string ExceptionTranslatorRegistry::translateActiveException() const {
  10621         CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
  10622     }
  10623 
  10624     std::string ExceptionTranslatorRegistry::tryTranslators() const {
  10625         CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
  10626     }
  10627 #endif
  10628 
  10629 }
  10630 // end catch_exception_translator_registry.cpp
  10631 // start catch_fatal_condition.cpp
  10632 
  10633 #if defined(__GNUC__)
  10634 #    pragma GCC diagnostic push
  10635 #    pragma GCC diagnostic ignored "-Wmissing-field-initializers"
  10636 #endif
  10637 
  10638 #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
  10639 
  10640 namespace {
  10641     // Report the error condition
  10642     void reportFatal( char const * const message ) {
  10643         Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
  10644     }
  10645 }
  10646 
  10647 #endif // signals/SEH handling
  10648 
  10649 #if defined( CATCH_CONFIG_WINDOWS_SEH )
  10650 
  10651 namespace Catch {
  10652     struct SignalDefs { DWORD id; const char* name; };
  10653 
  10654     // There is no 1-1 mapping between signals and windows exceptions.
  10655     // Windows can easily distinguish between SO and SigSegV,
  10656     // but SigInt, SigTerm, etc are handled differently.
  10657     static SignalDefs signalDefs[] = {
  10658         { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),  "SIGILL - Illegal instruction signal" },
  10659         { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
  10660         { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
  10661         { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
  10662     };
  10663 
  10664     LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
  10665         for (auto const& def : signalDefs) {
  10666             if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
  10667                 reportFatal(def.name);
  10668             }
  10669         }
  10670         // If its not an exception we care about, pass it along.
  10671         // This stops us from eating debugger breaks etc.
  10672         return EXCEPTION_CONTINUE_SEARCH;
  10673     }
  10674 
  10675     FatalConditionHandler::FatalConditionHandler() {
  10676         isSet = true;
  10677         // 32k seems enough for Catch to handle stack overflow,
  10678         // but the value was found experimentally, so there is no strong guarantee
  10679         guaranteeSize = 32 * 1024;
  10680         exceptionHandlerHandle = nullptr;
  10681         // Register as first handler in current chain
  10682         exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
  10683         // Pass in guarantee size to be filled
  10684         SetThreadStackGuarantee(&guaranteeSize);
  10685     }
  10686 
  10687     void FatalConditionHandler::reset() {
  10688         if (isSet) {
  10689             RemoveVectoredExceptionHandler(exceptionHandlerHandle);
  10690             SetThreadStackGuarantee(&guaranteeSize);
  10691             exceptionHandlerHandle = nullptr;
  10692             isSet = false;
  10693         }
  10694     }
  10695 
  10696     FatalConditionHandler::~FatalConditionHandler() {
  10697         reset();
  10698     }
  10699 
  10700 bool FatalConditionHandler::isSet = false;
  10701 ULONG FatalConditionHandler::guaranteeSize = 0;
  10702 PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
  10703 
  10704 } // namespace Catch
  10705 
  10706 #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
  10707 
  10708 namespace Catch {
  10709 
  10710     struct SignalDefs {
  10711         int id;
  10712         const char* name;
  10713     };
  10714 
  10715     // 32kb for the alternate stack seems to be sufficient. However, this value
  10716     // is experimentally determined, so that's not guaranteed.
  10717     static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
  10718 
  10719     static SignalDefs signalDefs[] = {
  10720         { SIGINT,  "SIGINT - Terminal interrupt signal" },
  10721         { SIGILL,  "SIGILL - Illegal instruction signal" },
  10722         { SIGFPE,  "SIGFPE - Floating point error signal" },
  10723         { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
  10724         { SIGTERM, "SIGTERM - Termination request signal" },
  10725         { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
  10726     };
  10727 
  10728     void FatalConditionHandler::handleSignal( int sig ) {
  10729         char const * name = "<unknown signal>";
  10730         for (auto const& def : signalDefs) {
  10731             if (sig == def.id) {
  10732                 name = def.name;
  10733                 break;
  10734             }
  10735         }
  10736         reset();
  10737         reportFatal(name);
  10738         raise( sig );
  10739     }
  10740 
  10741     FatalConditionHandler::FatalConditionHandler() {
  10742         isSet = true;
  10743         stack_t sigStack;
  10744         sigStack.ss_sp = altStackMem;
  10745         sigStack.ss_size = sigStackSize;
  10746         sigStack.ss_flags = 0;
  10747         sigaltstack(&sigStack, &oldSigStack);
  10748         struct sigaction sa = { };
  10749 
  10750         sa.sa_handler = handleSignal;
  10751         sa.sa_flags = SA_ONSTACK;
  10752         for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
  10753             sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
  10754         }
  10755     }
  10756 
  10757     FatalConditionHandler::~FatalConditionHandler() {
  10758         reset();
  10759     }
  10760 
  10761     void FatalConditionHandler::reset() {
  10762         if( isSet ) {
  10763             // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
  10764             for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
  10765                 sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
  10766             }
  10767             // Return the old stack
  10768             sigaltstack(&oldSigStack, nullptr);
  10769             isSet = false;
  10770         }
  10771     }
  10772 
  10773     bool FatalConditionHandler::isSet = false;
  10774     struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
  10775     stack_t FatalConditionHandler::oldSigStack = {};
  10776     char FatalConditionHandler::altStackMem[sigStackSize] = {};
  10777 
  10778 } // namespace Catch
  10779 
  10780 #else
  10781 
  10782 namespace Catch {
  10783     void FatalConditionHandler::reset() {}
  10784 }
  10785 
  10786 #endif // signals/SEH handling
  10787 
  10788 #if defined(__GNUC__)
  10789 #    pragma GCC diagnostic pop
  10790 #endif
  10791 // end catch_fatal_condition.cpp
  10792 // start catch_generators.cpp
  10793 
  10794 #include <limits>
  10795 #include <set>
  10796 
  10797 namespace Catch {
  10798 
  10799 IGeneratorTracker::~IGeneratorTracker() {}
  10800 
  10801 const char* GeneratorException::what() const noexcept {
  10802     return m_msg;
  10803 }
  10804 
  10805 namespace Generators {
  10806 
  10807     GeneratorUntypedBase::~GeneratorUntypedBase() {}
  10808 
  10809     auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
  10810         return getResultCapture().acquireGeneratorTracker( lineInfo );
  10811     }
  10812 
  10813 } // namespace Generators
  10814 } // namespace Catch
  10815 // end catch_generators.cpp
  10816 // start catch_interfaces_capture.cpp
  10817 
  10818 namespace Catch {
  10819     IResultCapture::~IResultCapture() = default;
  10820 }
  10821 // end catch_interfaces_capture.cpp
  10822 // start catch_interfaces_config.cpp
  10823 
  10824 namespace Catch {
  10825     IConfig::~IConfig() = default;
  10826 }
  10827 // end catch_interfaces_config.cpp
  10828 // start catch_interfaces_exception.cpp
  10829 
  10830 namespace Catch {
  10831     IExceptionTranslator::~IExceptionTranslator() = default;
  10832     IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
  10833 }
  10834 // end catch_interfaces_exception.cpp
  10835 // start catch_interfaces_registry_hub.cpp
  10836 
  10837 namespace Catch {
  10838     IRegistryHub::~IRegistryHub() = default;
  10839     IMutableRegistryHub::~IMutableRegistryHub() = default;
  10840 }
  10841 // end catch_interfaces_registry_hub.cpp
  10842 // start catch_interfaces_reporter.cpp
  10843 
  10844 // start catch_reporter_listening.h
  10845 
  10846 namespace Catch {
  10847 
  10848     class ListeningReporter : public IStreamingReporter {
  10849         using Reporters = std::vector<IStreamingReporterPtr>;
  10850         Reporters m_listeners;
  10851         IStreamingReporterPtr m_reporter = nullptr;
  10852         ReporterPreferences m_preferences;
  10853 
  10854     public:
  10855         ListeningReporter();
  10856 
  10857         void addListener( IStreamingReporterPtr&& listener );
  10858         void addReporter( IStreamingReporterPtr&& reporter );
  10859 
  10860     public: // IStreamingReporter
  10861 
  10862         ReporterPreferences getPreferences() const override;
  10863 
  10864         void noMatchingTestCases( std::string const& spec ) override;
  10865 
  10866         void reportInvalidArguments(std::string const&arg) override;
  10867 
  10868         static std::set<Verbosity> getSupportedVerbosities();
  10869 
  10870 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  10871         void benchmarkPreparing(std::string const& name) override;
  10872         void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
  10873         void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
  10874         void benchmarkFailed(std::string const&) override;
  10875 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  10876 
  10877         void testRunStarting( TestRunInfo const& testRunInfo ) override;
  10878         void testGroupStarting( GroupInfo const& groupInfo ) override;
  10879         void testCaseStarting( TestCaseInfo const& testInfo ) override;
  10880         void sectionStarting( SectionInfo const& sectionInfo ) override;
  10881         void assertionStarting( AssertionInfo const& assertionInfo ) override;
  10882 
  10883         // The return value indicates if the messages buffer should be cleared:
  10884         bool assertionEnded( AssertionStats const& assertionStats ) override;
  10885         void sectionEnded( SectionStats const& sectionStats ) override;
  10886         void testCaseEnded( TestCaseStats const& testCaseStats ) override;
  10887         void testGroupEnded( TestGroupStats const& testGroupStats ) override;
  10888         void testRunEnded( TestRunStats const& testRunStats ) override;
  10889 
  10890         void skipTest( TestCaseInfo const& testInfo ) override;
  10891         bool isMulti() const override;
  10892 
  10893     };
  10894 
  10895 } // end namespace Catch
  10896 
  10897 // end catch_reporter_listening.h
  10898 namespace Catch {
  10899 
  10900     ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
  10901     :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
  10902 
  10903     ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
  10904     :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
  10905 
  10906     std::ostream& ReporterConfig::stream() const { return *m_stream; }
  10907     IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
  10908 
  10909     TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
  10910 
  10911     GroupInfo::GroupInfo(  std::string const& _name,
  10912                            std::size_t _groupIndex,
  10913                            std::size_t _groupsCount )
  10914     :   name( _name ),
  10915         groupIndex( _groupIndex ),
  10916         groupsCounts( _groupsCount )
  10917     {}
  10918 
  10919      AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
  10920                                      std::vector<MessageInfo> const& _infoMessages,
  10921                                      Totals const& _totals )
  10922     :   assertionResult( _assertionResult ),
  10923         infoMessages( _infoMessages ),
  10924         totals( _totals )
  10925     {
  10926         assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
  10927 
  10928         if( assertionResult.hasMessage() ) {
  10929             // Copy message into messages list.
  10930             // !TBD This should have been done earlier, somewhere
  10931             MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
  10932             builder << assertionResult.getMessage();
  10933             builder.m_info.message = builder.m_stream.str();
  10934 
  10935             infoMessages.push_back( builder.m_info );
  10936         }
  10937     }
  10938 
  10939      AssertionStats::~AssertionStats() = default;
  10940 
  10941     SectionStats::SectionStats(  SectionInfo const& _sectionInfo,
  10942                                  Counts const& _assertions,
  10943                                  double _durationInSeconds,
  10944                                  bool _missingAssertions )
  10945     :   sectionInfo( _sectionInfo ),
  10946         assertions( _assertions ),
  10947         durationInSeconds( _durationInSeconds ),
  10948         missingAssertions( _missingAssertions )
  10949     {}
  10950 
  10951     SectionStats::~SectionStats() = default;
  10952 
  10953     TestCaseStats::TestCaseStats(  TestCaseInfo const& _testInfo,
  10954                                    Totals const& _totals,
  10955                                    std::string const& _stdOut,
  10956                                    std::string const& _stdErr,
  10957                                    bool _aborting )
  10958     : testInfo( _testInfo ),
  10959         totals( _totals ),
  10960         stdOut( _stdOut ),
  10961         stdErr( _stdErr ),
  10962         aborting( _aborting )
  10963     {}
  10964 
  10965     TestCaseStats::~TestCaseStats() = default;
  10966 
  10967     TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
  10968                                     Totals const& _totals,
  10969                                     bool _aborting )
  10970     :   groupInfo( _groupInfo ),
  10971         totals( _totals ),
  10972         aborting( _aborting )
  10973     {}
  10974 
  10975     TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
  10976     :   groupInfo( _groupInfo ),
  10977         aborting( false )
  10978     {}
  10979 
  10980     TestGroupStats::~TestGroupStats() = default;
  10981 
  10982     TestRunStats::TestRunStats(   TestRunInfo const& _runInfo,
  10983                     Totals const& _totals,
  10984                     bool _aborting )
  10985     :   runInfo( _runInfo ),
  10986         totals( _totals ),
  10987         aborting( _aborting )
  10988     {}
  10989 
  10990     TestRunStats::~TestRunStats() = default;
  10991 
  10992     void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
  10993     bool IStreamingReporter::isMulti() const { return false; }
  10994 
  10995     IReporterFactory::~IReporterFactory() = default;
  10996     IReporterRegistry::~IReporterRegistry() = default;
  10997 
  10998 } // end namespace Catch
  10999 // end catch_interfaces_reporter.cpp
  11000 // start catch_interfaces_runner.cpp
  11001 
  11002 namespace Catch {
  11003     IRunner::~IRunner() = default;
  11004 }
  11005 // end catch_interfaces_runner.cpp
  11006 // start catch_interfaces_testcase.cpp
  11007 
  11008 namespace Catch {
  11009     ITestInvoker::~ITestInvoker() = default;
  11010     ITestCaseRegistry::~ITestCaseRegistry() = default;
  11011 }
  11012 // end catch_interfaces_testcase.cpp
  11013 // start catch_leak_detector.cpp
  11014 
  11015 #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
  11016 #include <crtdbg.h>
  11017 
  11018 namespace Catch {
  11019 
  11020     LeakDetector::LeakDetector() {
  11021         int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  11022         flag |= _CRTDBG_LEAK_CHECK_DF;
  11023         flag |= _CRTDBG_ALLOC_MEM_DF;
  11024         _CrtSetDbgFlag(flag);
  11025         _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
  11026         _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  11027         // Change this to leaking allocation's number to break there
  11028         _CrtSetBreakAlloc(-1);
  11029     }
  11030 }
  11031 
  11032 #else
  11033 
  11034     Catch::LeakDetector::LeakDetector() {}
  11035 
  11036 #endif
  11037 
  11038 Catch::LeakDetector::~LeakDetector() {
  11039     Catch::cleanUp();
  11040 }
  11041 // end catch_leak_detector.cpp
  11042 // start catch_list.cpp
  11043 
  11044 // start catch_list.h
  11045 
  11046 #include <set>
  11047 
  11048 namespace Catch {
  11049 
  11050     std::size_t listTests( Config const& config );
  11051 
  11052     std::size_t listTestsNamesOnly( Config const& config );
  11053 
  11054     struct TagInfo {
  11055         void add( std::string const& spelling );
  11056         std::string all() const;
  11057 
  11058         std::set<std::string> spellings;
  11059         std::size_t count = 0;
  11060     };
  11061 
  11062     std::size_t listTags( Config const& config );
  11063 
  11064     std::size_t listReporters();
  11065 
  11066     Option<std::size_t> list( std::shared_ptr<Config> const& config );
  11067 
  11068 } // end namespace Catch
  11069 
  11070 // end catch_list.h
  11071 // start catch_text.h
  11072 
  11073 namespace Catch {
  11074     using namespace clara::TextFlow;
  11075 }
  11076 
  11077 // end catch_text.h
  11078 #include <limits>
  11079 #include <algorithm>
  11080 #include <iomanip>
  11081 
  11082 namespace Catch {
  11083 
  11084     std::size_t listTests( Config const& config ) {
  11085         TestSpec testSpec = config.testSpec();
  11086         if( config.hasTestFilters() )
  11087             Catch::cout() << "Matching test cases:\n";
  11088         else {
  11089             Catch::cout() << "All available test cases:\n";
  11090         }
  11091 
  11092         auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  11093         for( auto const& testCaseInfo : matchedTestCases ) {
  11094             Colour::Code colour = testCaseInfo.isHidden()
  11095                 ? Colour::SecondaryText
  11096                 : Colour::None;
  11097             Colour colourGuard( colour );
  11098 
  11099             Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
  11100             if( config.verbosity() >= Verbosity::High ) {
  11101                 Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
  11102                 std::string description = testCaseInfo.description;
  11103                 if( description.empty() )
  11104                     description = "(NO DESCRIPTION)";
  11105                 Catch::cout() << Column( description ).indent(4) << std::endl;
  11106             }
  11107             if( !testCaseInfo.tags.empty() )
  11108                 Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
  11109         }
  11110 
  11111         if( !config.hasTestFilters() )
  11112             Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
  11113         else
  11114             Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
  11115         return matchedTestCases.size();
  11116     }
  11117 
  11118     std::size_t listTestsNamesOnly( Config const& config ) {
  11119         TestSpec testSpec = config.testSpec();
  11120         std::size_t matchedTests = 0;
  11121         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  11122         for( auto const& testCaseInfo : matchedTestCases ) {
  11123             matchedTests++;
  11124             if( startsWith( testCaseInfo.name, '#' ) )
  11125                Catch::cout() << '"' << testCaseInfo.name << '"';
  11126             else
  11127                Catch::cout() << testCaseInfo.name;
  11128             if ( config.verbosity() >= Verbosity::High )
  11129                 Catch::cout() << "\t@" << testCaseInfo.lineInfo;
  11130             Catch::cout() << std::endl;
  11131         }
  11132         return matchedTests;
  11133     }
  11134 
  11135     void TagInfo::add( std::string const& spelling ) {
  11136         ++count;
  11137         spellings.insert( spelling );
  11138     }
  11139 
  11140     std::string TagInfo::all() const {
  11141         size_t size = 0;
  11142         for (auto const& spelling : spellings) {
  11143             // Add 2 for the brackes
  11144             size += spelling.size() + 2;
  11145         }
  11146 
  11147         std::string out; out.reserve(size);
  11148         for (auto const& spelling : spellings) {
  11149             out += '[';
  11150             out += spelling;
  11151             out += ']';
  11152         }
  11153         return out;
  11154     }
  11155 
  11156     std::size_t listTags( Config const& config ) {
  11157         TestSpec testSpec = config.testSpec();
  11158         if( config.hasTestFilters() )
  11159             Catch::cout() << "Tags for matching test cases:\n";
  11160         else {
  11161             Catch::cout() << "All available tags:\n";
  11162         }
  11163 
  11164         std::map<std::string, TagInfo> tagCounts;
  11165 
  11166         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  11167         for( auto const& testCase : matchedTestCases ) {
  11168             for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
  11169                 std::string lcaseTagName = toLower( tagName );
  11170                 auto countIt = tagCounts.find( lcaseTagName );
  11171                 if( countIt == tagCounts.end() )
  11172                     countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
  11173                 countIt->second.add( tagName );
  11174             }
  11175         }
  11176 
  11177         for( auto const& tagCount : tagCounts ) {
  11178             ReusableStringStream rss;
  11179             rss << "  " << std::setw(2) << tagCount.second.count << "  ";
  11180             auto str = rss.str();
  11181             auto wrapper = Column( tagCount.second.all() )
  11182                                                     .initialIndent( 0 )
  11183                                                     .indent( str.size() )
  11184                                                     .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
  11185             Catch::cout() << str << wrapper << '\n';
  11186         }
  11187         Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
  11188         return tagCounts.size();
  11189     }
  11190 
  11191     std::size_t listReporters() {
  11192         Catch::cout() << "Available reporters:\n";
  11193         IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
  11194         std::size_t maxNameLen = 0;
  11195         for( auto const& factoryKvp : factories )
  11196             maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
  11197 
  11198         for( auto const& factoryKvp : factories ) {
  11199             Catch::cout()
  11200                     << Column( factoryKvp.first + ":" )
  11201                             .indent(2)
  11202                             .width( 5+maxNameLen )
  11203                     +  Column( factoryKvp.second->getDescription() )
  11204                             .initialIndent(0)
  11205                             .indent(2)
  11206                             .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
  11207                     << "\n";
  11208         }
  11209         Catch::cout() << std::endl;
  11210         return factories.size();
  11211     }
  11212 
  11213     Option<std::size_t> list( std::shared_ptr<Config> const& config ) {
  11214         Option<std::size_t> listedCount;
  11215         getCurrentMutableContext().setConfig( config );
  11216         if( config->listTests() )
  11217             listedCount = listedCount.valueOr(0) + listTests( *config );
  11218         if( config->listTestNamesOnly() )
  11219             listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );
  11220         if( config->listTags() )
  11221             listedCount = listedCount.valueOr(0) + listTags( *config );
  11222         if( config->listReporters() )
  11223             listedCount = listedCount.valueOr(0) + listReporters();
  11224         return listedCount;
  11225     }
  11226 
  11227 } // end namespace Catch
  11228 // end catch_list.cpp
  11229 // start catch_matchers.cpp
  11230 
  11231 namespace Catch {
  11232 namespace Matchers {
  11233     namespace Impl {
  11234 
  11235         std::string MatcherUntypedBase::toString() const {
  11236             if( m_cachedToString.empty() )
  11237                 m_cachedToString = describe();
  11238             return m_cachedToString;
  11239         }
  11240 
  11241         MatcherUntypedBase::~MatcherUntypedBase() = default;
  11242 
  11243     } // namespace Impl
  11244 } // namespace Matchers
  11245 
  11246 using namespace Matchers;
  11247 using Matchers::Impl::MatcherBase;
  11248 
  11249 } // namespace Catch
  11250 // end catch_matchers.cpp
  11251 // start catch_matchers_exception.cpp
  11252 
  11253 namespace Catch {
  11254 namespace Matchers {
  11255 namespace Exception {
  11256 
  11257 bool ExceptionMessageMatcher::match(std::exception const& ex) const {
  11258     return ex.what() == m_message;
  11259 }
  11260 
  11261 std::string ExceptionMessageMatcher::describe() const {
  11262     return "exception message matches \"" + m_message + "\"";
  11263 }
  11264 
  11265 }
  11266 Exception::ExceptionMessageMatcher Message(std::string const& message) {
  11267     return Exception::ExceptionMessageMatcher(message);
  11268 }
  11269 
  11270 // namespace Exception
  11271 } // namespace Matchers
  11272 } // namespace Catch
  11273 // end catch_matchers_exception.cpp
  11274 // start catch_matchers_floating.cpp
  11275 
  11276 // start catch_polyfills.hpp
  11277 
  11278 namespace Catch {
  11279     bool isnan(float f);
  11280     bool isnan(double d);
  11281 }
  11282 
  11283 // end catch_polyfills.hpp
  11284 // start catch_to_string.hpp
  11285 
  11286 #include <string>
  11287 
  11288 namespace Catch {
  11289     template <typename T>
  11290     std::string to_string(T const& t) {
  11291 #if defined(CATCH_CONFIG_CPP11_TO_STRING)
  11292         return std::to_string(t);
  11293 #else
  11294         ReusableStringStream rss;
  11295         rss << t;
  11296         return rss.str();
  11297 #endif
  11298     }
  11299 } // end namespace Catch
  11300 
  11301 // end catch_to_string.hpp
  11302 #include <algorithm>
  11303 #include <cmath>
  11304 #include <cstdlib>
  11305 #include <cstdint>
  11306 #include <cstring>
  11307 #include <sstream>
  11308 #include <type_traits>
  11309 #include <iomanip>
  11310 #include <limits>
  11311 
  11312 namespace Catch {
  11313 namespace {
  11314 
  11315     int32_t convert(float f) {
  11316         static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
  11317         int32_t i;
  11318         std::memcpy(&i, &f, sizeof(f));
  11319         return i;
  11320     }
  11321 
  11322     int64_t convert(double d) {
  11323         static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
  11324         int64_t i;
  11325         std::memcpy(&i, &d, sizeof(d));
  11326         return i;
  11327     }
  11328 
  11329     template <typename FP>
  11330     bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
  11331         // Comparison with NaN should always be false.
  11332         // This way we can rule it out before getting into the ugly details
  11333         if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
  11334             return false;
  11335         }
  11336 
  11337         auto lc = convert(lhs);
  11338         auto rc = convert(rhs);
  11339 
  11340         if ((lc < 0) != (rc < 0)) {
  11341             // Potentially we can have +0 and -0
  11342             return lhs == rhs;
  11343         }
  11344 
  11345         auto ulpDiff = std::abs(lc - rc);
  11346         return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
  11347     }
  11348 
  11349 } //end anonymous namespace
  11350 
  11351 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
  11352 
  11353 #if defined(__clang__)
  11354 #pragma clang diagnostic push
  11355 // The long double overload is currently unused
  11356 #pragma clang diagnostic ignored "-Wunused-function"
  11357 #endif
  11358 
  11359     float nextafter(float x, float y) {
  11360         return ::nextafterf(x, y);
  11361     }
  11362 
  11363     double nextafter(double x, double y) {
  11364         return ::nextafter(x, y);
  11365     }
  11366 
  11367     long double nextafter(long double x, long double y) {
  11368         return ::nextafterl(x, y);
  11369     }
  11370 
  11371 #if defined(__clang__)
  11372 #pragma clang diagnostic pop
  11373 #endif
  11374 
  11375 #endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
  11376 
  11377 namespace {
  11378 
  11379 template <typename FP>
  11380 FP step(FP start, FP direction, uint64_t steps) {
  11381     for (uint64_t i = 0; i < steps; ++i) {
  11382 #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
  11383         start = Catch::nextafter(start, direction);
  11384 #else
  11385         start = std::nextafter(start, direction);
  11386 #endif
  11387     }
  11388     return start;
  11389 }
  11390 
  11391 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
  11392 // But without the subtraction to allow for INFINITY in comparison
  11393 bool marginComparison(double lhs, double rhs, double margin) {
  11394     return (lhs + margin >= rhs) && (rhs + margin >= lhs);
  11395 }
  11396 
  11397 template <typename FloatingPoint>
  11398 void write(std::ostream& out, FloatingPoint num) {
  11399     out << std::scientific
  11400         << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)
  11401         << num;
  11402 }
  11403 
  11404 } // end anonymous namespace
  11405 
  11406 namespace Matchers {
  11407 namespace Floating {
  11408 
  11409     enum class FloatingPointKind : uint8_t {
  11410         Float,
  11411         Double
  11412     };
  11413 
  11414     WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
  11415         :m_target{ target }, m_margin{ margin } {
  11416         CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
  11417             << " Margin has to be non-negative.");
  11418     }
  11419 
  11420     // Performs equivalent check of std::fabs(lhs - rhs) <= margin
  11421     // But without the subtraction to allow for INFINITY in comparison
  11422     bool WithinAbsMatcher::match(double const& matchee) const {
  11423         return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
  11424     }
  11425 
  11426     std::string WithinAbsMatcher::describe() const {
  11427         return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
  11428     }
  11429 
  11430     WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
  11431         :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
  11432         CATCH_ENFORCE(m_type == FloatingPointKind::Double
  11433                    || m_ulps < (std::numeric_limits<uint32_t>::max)(),
  11434             "Provided ULP is impossibly large for a float comparison.");
  11435     }
  11436 
  11437 #if defined(__clang__)
  11438 #pragma clang diagnostic push
  11439 // Clang <3.5 reports on the default branch in the switch below
  11440 #pragma clang diagnostic ignored "-Wunreachable-code"
  11441 #endif
  11442 
  11443     bool WithinUlpsMatcher::match(double const& matchee) const {
  11444         switch (m_type) {
  11445         case FloatingPointKind::Float:
  11446             return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
  11447         case FloatingPointKind::Double:
  11448             return almostEqualUlps<double>(matchee, m_target, m_ulps);
  11449         default:
  11450             CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
  11451         }
  11452     }
  11453 
  11454 #if defined(__clang__)
  11455 #pragma clang diagnostic pop
  11456 #endif
  11457 
  11458     std::string WithinUlpsMatcher::describe() const {
  11459         std::stringstream ret;
  11460 
  11461         ret << "is within " << m_ulps << " ULPs of ";
  11462 
  11463         if (m_type == FloatingPointKind::Float) {
  11464             write(ret, static_cast<float>(m_target));
  11465             ret << 'f';
  11466         } else {
  11467             write(ret, m_target);
  11468         }
  11469 
  11470         ret << " ([";
  11471         if (m_type == FloatingPointKind::Double) {
  11472             write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
  11473             ret << ", ";
  11474             write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
  11475         } else {
  11476             // We have to cast INFINITY to float because of MinGW, see #1782
  11477             write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
  11478             ret << ", ";
  11479             write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));
  11480         }
  11481         ret << "])";
  11482 
  11483         return ret.str();
  11484     }
  11485 
  11486     WithinRelMatcher::WithinRelMatcher(double target, double epsilon):
  11487         m_target(target),
  11488         m_epsilon(epsilon){
  11489         CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon <  0 does not make sense.");
  11490         CATCH_ENFORCE(m_epsilon  < 1., "Relative comparison with epsilon >= 1 does not make sense.");
  11491     }
  11492 
  11493     bool WithinRelMatcher::match(double const& matchee) const {
  11494         const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
  11495         return marginComparison(matchee, m_target,
  11496                                 std::isinf(relMargin)? 0 : relMargin);
  11497     }
  11498 
  11499     std::string WithinRelMatcher::describe() const {
  11500         Catch::ReusableStringStream sstr;
  11501         sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
  11502         return sstr.str();
  11503     }
  11504 
  11505 }// namespace Floating
  11506 
  11507 Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
  11508     return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
  11509 }
  11510 
  11511 Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
  11512     return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
  11513 }
  11514 
  11515 Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
  11516     return Floating::WithinAbsMatcher(target, margin);
  11517 }
  11518 
  11519 Floating::WithinRelMatcher WithinRel(double target, double eps) {
  11520     return Floating::WithinRelMatcher(target, eps);
  11521 }
  11522 
  11523 Floating::WithinRelMatcher WithinRel(double target) {
  11524     return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
  11525 }
  11526 
  11527 Floating::WithinRelMatcher WithinRel(float target, float eps) {
  11528     return Floating::WithinRelMatcher(target, eps);
  11529 }
  11530 
  11531 Floating::WithinRelMatcher WithinRel(float target) {
  11532     return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
  11533 }
  11534 
  11535 } // namespace Matchers
  11536 } // namespace Catch
  11537 
  11538 // end catch_matchers_floating.cpp
  11539 // start catch_matchers_generic.cpp
  11540 
  11541 std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
  11542     if (desc.empty()) {
  11543         return "matches undescribed predicate";
  11544     } else {
  11545         return "matches predicate: \"" + desc + '"';
  11546     }
  11547 }
  11548 // end catch_matchers_generic.cpp
  11549 // start catch_matchers_string.cpp
  11550 
  11551 #include <regex>
  11552 
  11553 namespace Catch {
  11554 namespace Matchers {
  11555 
  11556     namespace StdString {
  11557 
  11558         CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
  11559         :   m_caseSensitivity( caseSensitivity ),
  11560             m_str( adjustString( str ) )
  11561         {}
  11562         std::string CasedString::adjustString( std::string const& str ) const {
  11563             return m_caseSensitivity == CaseSensitive::No
  11564                    ? toLower( str )
  11565                    : str;
  11566         }
  11567         std::string CasedString::caseSensitivitySuffix() const {
  11568             return m_caseSensitivity == CaseSensitive::No
  11569                    ? " (case insensitive)"
  11570                    : std::string();
  11571         }
  11572 
  11573         StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
  11574         : m_comparator( comparator ),
  11575           m_operation( operation ) {
  11576         }
  11577 
  11578         std::string StringMatcherBase::describe() const {
  11579             std::string description;
  11580             description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
  11581                                         m_comparator.caseSensitivitySuffix().size());
  11582             description += m_operation;
  11583             description += ": \"";
  11584             description += m_comparator.m_str;
  11585             description += "\"";
  11586             description += m_comparator.caseSensitivitySuffix();
  11587             return description;
  11588         }
  11589 
  11590         EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
  11591 
  11592         bool EqualsMatcher::match( std::string const& source ) const {
  11593             return m_comparator.adjustString( source ) == m_comparator.m_str;
  11594         }
  11595 
  11596         ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
  11597 
  11598         bool ContainsMatcher::match( std::string const& source ) const {
  11599             return contains( m_comparator.adjustString( source ), m_comparator.m_str );
  11600         }
  11601 
  11602         StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
  11603 
  11604         bool StartsWithMatcher::match( std::string const& source ) const {
  11605             return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
  11606         }
  11607 
  11608         EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
  11609 
  11610         bool EndsWithMatcher::match( std::string const& source ) const {
  11611             return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
  11612         }
  11613 
  11614         RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
  11615 
  11616         bool RegexMatcher::match(std::string const& matchee) const {
  11617             auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
  11618             if (m_caseSensitivity == CaseSensitive::Choice::No) {
  11619                 flags |= std::regex::icase;
  11620             }
  11621             auto reg = std::regex(m_regex, flags);
  11622             return std::regex_match(matchee, reg);
  11623         }
  11624 
  11625         std::string RegexMatcher::describe() const {
  11626             return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
  11627         }
  11628 
  11629     } // namespace StdString
  11630 
  11631     StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  11632         return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
  11633     }
  11634     StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  11635         return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
  11636     }
  11637     StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  11638         return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
  11639     }
  11640     StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  11641         return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
  11642     }
  11643 
  11644     StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
  11645         return StdString::RegexMatcher(regex, caseSensitivity);
  11646     }
  11647 
  11648 } // namespace Matchers
  11649 } // namespace Catch
  11650 // end catch_matchers_string.cpp
  11651 // start catch_message.cpp
  11652 
  11653 // start catch_uncaught_exceptions.h
  11654 
  11655 namespace Catch {
  11656     bool uncaught_exceptions();
  11657 } // end namespace Catch
  11658 
  11659 // end catch_uncaught_exceptions.h
  11660 #include <cassert>
  11661 #include <stack>
  11662 
  11663 namespace Catch {
  11664 
  11665     MessageInfo::MessageInfo(   StringRef const& _macroName,
  11666                                 SourceLineInfo const& _lineInfo,
  11667                                 ResultWas::OfType _type )
  11668     :   macroName( _macroName ),
  11669         lineInfo( _lineInfo ),
  11670         type( _type ),
  11671         sequence( ++globalCount )
  11672     {}
  11673 
  11674     bool MessageInfo::operator==( MessageInfo const& other ) const {
  11675         return sequence == other.sequence;
  11676     }
  11677 
  11678     bool MessageInfo::operator<( MessageInfo const& other ) const {
  11679         return sequence < other.sequence;
  11680     }
  11681 
  11682     // This may need protecting if threading support is added
  11683     unsigned int MessageInfo::globalCount = 0;
  11684 
  11685     ////////////////////////////////////////////////////////////////////////////
  11686 
  11687     Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
  11688                                            SourceLineInfo const& lineInfo,
  11689                                            ResultWas::OfType type )
  11690         :m_info(macroName, lineInfo, type) {}
  11691 
  11692     ////////////////////////////////////////////////////////////////////////////
  11693 
  11694     ScopedMessage::ScopedMessage( MessageBuilder const& builder )
  11695     : m_info( builder.m_info ), m_moved()
  11696     {
  11697         m_info.message = builder.m_stream.str();
  11698         getResultCapture().pushScopedMessage( m_info );
  11699     }
  11700 
  11701     ScopedMessage::ScopedMessage( ScopedMessage&& old )
  11702     : m_info( old.m_info ), m_moved()
  11703     {
  11704         old.m_moved = true;
  11705     }
  11706 
  11707     ScopedMessage::~ScopedMessage() {
  11708         if ( !uncaught_exceptions() && !m_moved ){
  11709             getResultCapture().popScopedMessage(m_info);
  11710         }
  11711     }
  11712 
  11713     Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
  11714         auto trimmed = [&] (size_t start, size_t end) {
  11715             while (names[start] == ',' || isspace(names[start])) {
  11716                 ++start;
  11717             }
  11718             while (names[end] == ',' || isspace(names[end])) {
  11719                 --end;
  11720             }
  11721             return names.substr(start, end - start + 1);
  11722         };
  11723         auto skipq = [&] (size_t start, char quote) {
  11724             for (auto i = start + 1; i < names.size() ; ++i) {
  11725                 if (names[i] == quote)
  11726                     return i;
  11727                 if (names[i] == '\\')
  11728                     ++i;
  11729             }
  11730             CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
  11731         };
  11732 
  11733         size_t start = 0;
  11734         std::stack<char> openings;
  11735         for (size_t pos = 0; pos < names.size(); ++pos) {
  11736             char c = names[pos];
  11737             switch (c) {
  11738             case '[':
  11739             case '{':
  11740             case '(':
  11741             // It is basically impossible to disambiguate between
  11742             // comparison and start of template args in this context
  11743 //            case '<':
  11744                 openings.push(c);
  11745                 break;
  11746             case ']':
  11747             case '}':
  11748             case ')':
  11749 //           case '>':
  11750                 openings.pop();
  11751                 break;
  11752             case '"':
  11753             case '\'':
  11754                 pos = skipq(pos, c);
  11755                 break;
  11756             case ',':
  11757                 if (start != pos && openings.size() == 0) {
  11758                     m_messages.emplace_back(macroName, lineInfo, resultType);
  11759                     m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
  11760                     m_messages.back().message += " := ";
  11761                     start = pos;
  11762                 }
  11763             }
  11764         }
  11765         assert(openings.size() == 0 && "Mismatched openings");
  11766         m_messages.emplace_back(macroName, lineInfo, resultType);
  11767         m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
  11768         m_messages.back().message += " := ";
  11769     }
  11770     Capturer::~Capturer() {
  11771         if ( !uncaught_exceptions() ){
  11772             assert( m_captured == m_messages.size() );
  11773             for( size_t i = 0; i < m_captured; ++i  )
  11774                 m_resultCapture.popScopedMessage( m_messages[i] );
  11775         }
  11776     }
  11777 
  11778     void Capturer::captureValue( size_t index, std::string const& value ) {
  11779         assert( index < m_messages.size() );
  11780         m_messages[index].message += value;
  11781         m_resultCapture.pushScopedMessage( m_messages[index] );
  11782         m_captured++;
  11783     }
  11784 
  11785 } // end namespace Catch
  11786 // end catch_message.cpp
  11787 // start catch_output_redirect.cpp
  11788 
  11789 // start catch_output_redirect.h
  11790 #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
  11791 #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
  11792 
  11793 #include <cstdio>
  11794 #include <iosfwd>
  11795 #include <string>
  11796 
  11797 namespace Catch {
  11798 
  11799     class RedirectedStream {
  11800         std::ostream& m_originalStream;
  11801         std::ostream& m_redirectionStream;
  11802         std::streambuf* m_prevBuf;
  11803 
  11804     public:
  11805         RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
  11806         ~RedirectedStream();
  11807     };
  11808 
  11809     class RedirectedStdOut {
  11810         ReusableStringStream m_rss;
  11811         RedirectedStream m_cout;
  11812     public:
  11813         RedirectedStdOut();
  11814         auto str() const -> std::string;
  11815     };
  11816 
  11817     // StdErr has two constituent streams in C++, std::cerr and std::clog
  11818     // This means that we need to redirect 2 streams into 1 to keep proper
  11819     // order of writes
  11820     class RedirectedStdErr {
  11821         ReusableStringStream m_rss;
  11822         RedirectedStream m_cerr;
  11823         RedirectedStream m_clog;
  11824     public:
  11825         RedirectedStdErr();
  11826         auto str() const -> std::string;
  11827     };
  11828 
  11829     class RedirectedStreams {
  11830     public:
  11831         RedirectedStreams(RedirectedStreams const&) = delete;
  11832         RedirectedStreams& operator=(RedirectedStreams const&) = delete;
  11833         RedirectedStreams(RedirectedStreams&&) = delete;
  11834         RedirectedStreams& operator=(RedirectedStreams&&) = delete;
  11835 
  11836         RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
  11837         ~RedirectedStreams();
  11838     private:
  11839         std::string& m_redirectedCout;
  11840         std::string& m_redirectedCerr;
  11841         RedirectedStdOut m_redirectedStdOut;
  11842         RedirectedStdErr m_redirectedStdErr;
  11843     };
  11844 
  11845 #if defined(CATCH_CONFIG_NEW_CAPTURE)
  11846 
  11847     // Windows's implementation of std::tmpfile is terrible (it tries
  11848     // to create a file inside system folder, thus requiring elevated
  11849     // privileges for the binary), so we have to use tmpnam(_s) and
  11850     // create the file ourselves there.
  11851     class TempFile {
  11852     public:
  11853         TempFile(TempFile const&) = delete;
  11854         TempFile& operator=(TempFile const&) = delete;
  11855         TempFile(TempFile&&) = delete;
  11856         TempFile& operator=(TempFile&&) = delete;
  11857 
  11858         TempFile();
  11859         ~TempFile();
  11860 
  11861         std::FILE* getFile();
  11862         std::string getContents();
  11863 
  11864     private:
  11865         std::FILE* m_file = nullptr;
  11866     #if defined(_MSC_VER)
  11867         char m_buffer[L_tmpnam] = { 0 };
  11868     #endif
  11869     };
  11870 
  11871     class OutputRedirect {
  11872     public:
  11873         OutputRedirect(OutputRedirect const&) = delete;
  11874         OutputRedirect& operator=(OutputRedirect const&) = delete;
  11875         OutputRedirect(OutputRedirect&&) = delete;
  11876         OutputRedirect& operator=(OutputRedirect&&) = delete;
  11877 
  11878         OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
  11879         ~OutputRedirect();
  11880 
  11881     private:
  11882         int m_originalStdout = -1;
  11883         int m_originalStderr = -1;
  11884         TempFile m_stdoutFile;
  11885         TempFile m_stderrFile;
  11886         std::string& m_stdoutDest;
  11887         std::string& m_stderrDest;
  11888     };
  11889 
  11890 #endif
  11891 
  11892 } // end namespace Catch
  11893 
  11894 #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
  11895 // end catch_output_redirect.h
  11896 #include <cstdio>
  11897 #include <cstring>
  11898 #include <fstream>
  11899 #include <sstream>
  11900 #include <stdexcept>
  11901 
  11902 #if defined(CATCH_CONFIG_NEW_CAPTURE)
  11903     #if defined(_MSC_VER)
  11904     #include <io.h>      //_dup and _dup2
  11905     #define dup _dup
  11906     #define dup2 _dup2
  11907     #define fileno _fileno
  11908     #else
  11909     #include <unistd.h>  // dup and dup2
  11910     #endif
  11911 #endif
  11912 
  11913 namespace Catch {
  11914 
  11915     RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
  11916     :   m_originalStream( originalStream ),
  11917         m_redirectionStream( redirectionStream ),
  11918         m_prevBuf( m_originalStream.rdbuf() )
  11919     {
  11920         m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
  11921     }
  11922 
  11923     RedirectedStream::~RedirectedStream() {
  11924         m_originalStream.rdbuf( m_prevBuf );
  11925     }
  11926 
  11927     RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
  11928     auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
  11929 
  11930     RedirectedStdErr::RedirectedStdErr()
  11931     :   m_cerr( Catch::cerr(), m_rss.get() ),
  11932         m_clog( Catch::clog(), m_rss.get() )
  11933     {}
  11934     auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
  11935 
  11936     RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
  11937     :   m_redirectedCout(redirectedCout),
  11938         m_redirectedCerr(redirectedCerr)
  11939     {}
  11940 
  11941     RedirectedStreams::~RedirectedStreams() {
  11942         m_redirectedCout += m_redirectedStdOut.str();
  11943         m_redirectedCerr += m_redirectedStdErr.str();
  11944     }
  11945 
  11946 #if defined(CATCH_CONFIG_NEW_CAPTURE)
  11947 
  11948 #if defined(_MSC_VER)
  11949     TempFile::TempFile() {
  11950         if (tmpnam_s(m_buffer)) {
  11951             CATCH_RUNTIME_ERROR("Could not get a temp filename");
  11952         }
  11953         if (fopen_s(&m_file, m_buffer, "w")) {
  11954             char buffer[100];
  11955             if (strerror_s(buffer, errno)) {
  11956                 CATCH_RUNTIME_ERROR("Could not translate errno to a string");
  11957             }
  11958             CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
  11959         }
  11960     }
  11961 #else
  11962     TempFile::TempFile() {
  11963         m_file = std::tmpfile();
  11964         if (!m_file) {
  11965             CATCH_RUNTIME_ERROR("Could not create a temp file.");
  11966         }
  11967     }
  11968 
  11969 #endif
  11970 
  11971     TempFile::~TempFile() {
  11972          // TBD: What to do about errors here?
  11973          std::fclose(m_file);
  11974          // We manually create the file on Windows only, on Linux
  11975          // it will be autodeleted
  11976 #if defined(_MSC_VER)
  11977          std::remove(m_buffer);
  11978 #endif
  11979     }
  11980 
  11981     FILE* TempFile::getFile() {
  11982         return m_file;
  11983     }
  11984 
  11985     std::string TempFile::getContents() {
  11986         std::stringstream sstr;
  11987         char buffer[100] = {};
  11988         std::rewind(m_file);
  11989         while (std::fgets(buffer, sizeof(buffer), m_file)) {
  11990             sstr << buffer;
  11991         }
  11992         return sstr.str();
  11993     }
  11994 
  11995     OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
  11996         m_originalStdout(dup(1)),
  11997         m_originalStderr(dup(2)),
  11998         m_stdoutDest(stdout_dest),
  11999         m_stderrDest(stderr_dest) {
  12000         dup2(fileno(m_stdoutFile.getFile()), 1);
  12001         dup2(fileno(m_stderrFile.getFile()), 2);
  12002     }
  12003 
  12004     OutputRedirect::~OutputRedirect() {
  12005         Catch::cout() << std::flush;
  12006         fflush(stdout);
  12007         // Since we support overriding these streams, we flush cerr
  12008         // even though std::cerr is unbuffered
  12009         Catch::cerr() << std::flush;
  12010         Catch::clog() << std::flush;
  12011         fflush(stderr);
  12012 
  12013         dup2(m_originalStdout, 1);
  12014         dup2(m_originalStderr, 2);
  12015 
  12016         m_stdoutDest += m_stdoutFile.getContents();
  12017         m_stderrDest += m_stderrFile.getContents();
  12018     }
  12019 
  12020 #endif // CATCH_CONFIG_NEW_CAPTURE
  12021 
  12022 } // namespace Catch
  12023 
  12024 #if defined(CATCH_CONFIG_NEW_CAPTURE)
  12025     #if defined(_MSC_VER)
  12026     #undef dup
  12027     #undef dup2
  12028     #undef fileno
  12029     #endif
  12030 #endif
  12031 // end catch_output_redirect.cpp
  12032 // start catch_polyfills.cpp
  12033 
  12034 #include <cmath>
  12035 
  12036 namespace Catch {
  12037 
  12038 #if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
  12039     bool isnan(float f) {
  12040         return std::isnan(f);
  12041     }
  12042     bool isnan(double d) {
  12043         return std::isnan(d);
  12044     }
  12045 #else
  12046     // For now we only use this for embarcadero
  12047     bool isnan(float f) {
  12048         return std::_isnan(f);
  12049     }
  12050     bool isnan(double d) {
  12051         return std::_isnan(d);
  12052     }
  12053 #endif
  12054 
  12055 } // end namespace Catch
  12056 // end catch_polyfills.cpp
  12057 // start catch_random_number_generator.cpp
  12058 
  12059 namespace Catch {
  12060 
  12061 namespace {
  12062 
  12063 #if defined(_MSC_VER)
  12064 #pragma warning(push)
  12065 #pragma warning(disable:4146) // we negate uint32 during the rotate
  12066 #endif
  12067         // Safe rotr implementation thanks to John Regehr
  12068         uint32_t rotate_right(uint32_t val, uint32_t count) {
  12069             const uint32_t mask = 31;
  12070             count &= mask;
  12071             return (val >> count) | (val << (-count & mask));
  12072         }
  12073 
  12074 #if defined(_MSC_VER)
  12075 #pragma warning(pop)
  12076 #endif
  12077 
  12078 }
  12079 
  12080     SimplePcg32::SimplePcg32(result_type seed_) {
  12081         seed(seed_);
  12082     }
  12083 
  12084     void SimplePcg32::seed(result_type seed_) {
  12085         m_state = 0;
  12086         (*this)();
  12087         m_state += seed_;
  12088         (*this)();
  12089     }
  12090 
  12091     void SimplePcg32::discard(uint64_t skip) {
  12092         // We could implement this to run in O(log n) steps, but this
  12093         // should suffice for our use case.
  12094         for (uint64_t s = 0; s < skip; ++s) {
  12095             static_cast<void>((*this)());
  12096         }
  12097     }
  12098 
  12099     SimplePcg32::result_type SimplePcg32::operator()() {
  12100         // prepare the output value
  12101         const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
  12102         const auto output = rotate_right(xorshifted, m_state >> 59u);
  12103 
  12104         // advance state
  12105         m_state = m_state * 6364136223846793005ULL + s_inc;
  12106 
  12107         return output;
  12108     }
  12109 
  12110     bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
  12111         return lhs.m_state == rhs.m_state;
  12112     }
  12113 
  12114     bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
  12115         return lhs.m_state != rhs.m_state;
  12116     }
  12117 }
  12118 // end catch_random_number_generator.cpp
  12119 // start catch_registry_hub.cpp
  12120 
  12121 // start catch_test_case_registry_impl.h
  12122 
  12123 #include <vector>
  12124 #include <set>
  12125 #include <algorithm>
  12126 #include <ios>
  12127 
  12128 namespace Catch {
  12129 
  12130     class TestCase;
  12131     struct IConfig;
  12132 
  12133     std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
  12134 
  12135     bool isThrowSafe( TestCase const& testCase, IConfig const& config );
  12136     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
  12137 
  12138     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
  12139 
  12140     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
  12141     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
  12142 
  12143     class TestRegistry : public ITestCaseRegistry {
  12144     public:
  12145         virtual ~TestRegistry() = default;
  12146 
  12147         virtual void registerTest( TestCase const& testCase );
  12148 
  12149         std::vector<TestCase> const& getAllTests() const override;
  12150         std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
  12151 
  12152     private:
  12153         std::vector<TestCase> m_functions;
  12154         mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
  12155         mutable std::vector<TestCase> m_sortedFunctions;
  12156         std::size_t m_unnamedCount = 0;
  12157         std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
  12158     };
  12159 
  12160     ///////////////////////////////////////////////////////////////////////////
  12161 
  12162     class TestInvokerAsFunction : public ITestInvoker {
  12163         void(*m_testAsFunction)();
  12164     public:
  12165         TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
  12166 
  12167         void invoke() const override;
  12168     };
  12169 
  12170     std::string extractClassName( StringRef const& classOrQualifiedMethodName );
  12171 
  12172     ///////////////////////////////////////////////////////////////////////////
  12173 
  12174 } // end namespace Catch
  12175 
  12176 // end catch_test_case_registry_impl.h
  12177 // start catch_reporter_registry.h
  12178 
  12179 #include <map>
  12180 
  12181 namespace Catch {
  12182 
  12183     class ReporterRegistry : public IReporterRegistry {
  12184 
  12185     public:
  12186 
  12187         ~ReporterRegistry() override;
  12188 
  12189         IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
  12190 
  12191         void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
  12192         void registerListener( IReporterFactoryPtr const& factory );
  12193 
  12194         FactoryMap const& getFactories() const override;
  12195         Listeners const& getListeners() const override;
  12196 
  12197     private:
  12198         FactoryMap m_factories;
  12199         Listeners m_listeners;
  12200     };
  12201 }
  12202 
  12203 // end catch_reporter_registry.h
  12204 // start catch_tag_alias_registry.h
  12205 
  12206 // start catch_tag_alias.h
  12207 
  12208 #include <string>
  12209 
  12210 namespace Catch {
  12211 
  12212     struct TagAlias {
  12213         TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
  12214 
  12215         std::string tag;
  12216         SourceLineInfo lineInfo;
  12217     };
  12218 
  12219 } // end namespace Catch
  12220 
  12221 // end catch_tag_alias.h
  12222 #include <map>
  12223 
  12224 namespace Catch {
  12225 
  12226     class TagAliasRegistry : public ITagAliasRegistry {
  12227     public:
  12228         ~TagAliasRegistry() override;
  12229         TagAlias const* find( std::string const& alias ) const override;
  12230         std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
  12231         void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
  12232 
  12233     private:
  12234         std::map<std::string, TagAlias> m_registry;
  12235     };
  12236 
  12237 } // end namespace Catch
  12238 
  12239 // end catch_tag_alias_registry.h
  12240 // start catch_startup_exception_registry.h
  12241 
  12242 #include <vector>
  12243 #include <exception>
  12244 
  12245 namespace Catch {
  12246 
  12247     class StartupExceptionRegistry {
  12248     public:
  12249         void add(std::exception_ptr const& exception) noexcept;
  12250         std::vector<std::exception_ptr> const& getExceptions() const noexcept;
  12251     private:
  12252         std::vector<std::exception_ptr> m_exceptions;
  12253     };
  12254 
  12255 } // end namespace Catch
  12256 
  12257 // end catch_startup_exception_registry.h
  12258 // start catch_singletons.hpp
  12259 
  12260 namespace Catch {
  12261 
  12262     struct ISingleton {
  12263         virtual ~ISingleton();
  12264     };
  12265 
  12266     void addSingleton( ISingleton* singleton );
  12267     void cleanupSingletons();
  12268 
  12269     template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
  12270     class Singleton : SingletonImplT, public ISingleton {
  12271 
  12272         static auto getInternal() -> Singleton* {
  12273             static Singleton* s_instance = nullptr;
  12274             if( !s_instance ) {
  12275                 s_instance = new Singleton;
  12276                 addSingleton( s_instance );
  12277             }
  12278             return s_instance;
  12279         }
  12280 
  12281     public:
  12282         static auto get() -> InterfaceT const& {
  12283             return *getInternal();
  12284         }
  12285         static auto getMutable() -> MutableInterfaceT& {
  12286             return *getInternal();
  12287         }
  12288     };
  12289 
  12290 } // namespace Catch
  12291 
  12292 // end catch_singletons.hpp
  12293 namespace Catch {
  12294 
  12295     namespace {
  12296 
  12297         class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
  12298                             private NonCopyable {
  12299 
  12300         public: // IRegistryHub
  12301             RegistryHub() = default;
  12302             IReporterRegistry const& getReporterRegistry() const override {
  12303                 return m_reporterRegistry;
  12304             }
  12305             ITestCaseRegistry const& getTestCaseRegistry() const override {
  12306                 return m_testCaseRegistry;
  12307             }
  12308             IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
  12309                 return m_exceptionTranslatorRegistry;
  12310             }
  12311             ITagAliasRegistry const& getTagAliasRegistry() const override {
  12312                 return m_tagAliasRegistry;
  12313             }
  12314             StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
  12315                 return m_exceptionRegistry;
  12316             }
  12317 
  12318         public: // IMutableRegistryHub
  12319             void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
  12320                 m_reporterRegistry.registerReporter( name, factory );
  12321             }
  12322             void registerListener( IReporterFactoryPtr const& factory ) override {
  12323                 m_reporterRegistry.registerListener( factory );
  12324             }
  12325             void registerTest( TestCase const& testInfo ) override {
  12326                 m_testCaseRegistry.registerTest( testInfo );
  12327             }
  12328             void registerTranslator( const IExceptionTranslator* translator ) override {
  12329                 m_exceptionTranslatorRegistry.registerTranslator( translator );
  12330             }
  12331             void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
  12332                 m_tagAliasRegistry.add( alias, tag, lineInfo );
  12333             }
  12334             void registerStartupException() noexcept override {
  12335                 m_exceptionRegistry.add(std::current_exception());
  12336             }
  12337             IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
  12338                 return m_enumValuesRegistry;
  12339             }
  12340 
  12341         private:
  12342             TestRegistry m_testCaseRegistry;
  12343             ReporterRegistry m_reporterRegistry;
  12344             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
  12345             TagAliasRegistry m_tagAliasRegistry;
  12346             StartupExceptionRegistry m_exceptionRegistry;
  12347             Detail::EnumValuesRegistry m_enumValuesRegistry;
  12348         };
  12349     }
  12350 
  12351     using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
  12352 
  12353     IRegistryHub const& getRegistryHub() {
  12354         return RegistryHubSingleton::get();
  12355     }
  12356     IMutableRegistryHub& getMutableRegistryHub() {
  12357         return RegistryHubSingleton::getMutable();
  12358     }
  12359     void cleanUp() {
  12360         cleanupSingletons();
  12361         cleanUpContext();
  12362     }
  12363     std::string translateActiveException() {
  12364         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
  12365     }
  12366 
  12367 } // end namespace Catch
  12368 // end catch_registry_hub.cpp
  12369 // start catch_reporter_registry.cpp
  12370 
  12371 namespace Catch {
  12372 
  12373     ReporterRegistry::~ReporterRegistry() = default;
  12374 
  12375     IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
  12376         auto it =  m_factories.find( name );
  12377         if( it == m_factories.end() )
  12378             return nullptr;
  12379         return it->second->create( ReporterConfig( config ) );
  12380     }
  12381 
  12382     void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
  12383         m_factories.emplace(name, factory);
  12384     }
  12385     void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
  12386         m_listeners.push_back( factory );
  12387     }
  12388 
  12389     IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
  12390         return m_factories;
  12391     }
  12392     IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
  12393         return m_listeners;
  12394     }
  12395 
  12396 }
  12397 // end catch_reporter_registry.cpp
  12398 // start catch_result_type.cpp
  12399 
  12400 namespace Catch {
  12401 
  12402     bool isOk( ResultWas::OfType resultType ) {
  12403         return ( resultType & ResultWas::FailureBit ) == 0;
  12404     }
  12405     bool isJustInfo( int flags ) {
  12406         return flags == ResultWas::Info;
  12407     }
  12408 
  12409     ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
  12410         return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
  12411     }
  12412 
  12413     bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
  12414     bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
  12415 
  12416 } // end namespace Catch
  12417 // end catch_result_type.cpp
  12418 // start catch_run_context.cpp
  12419 
  12420 #include <cassert>
  12421 #include <algorithm>
  12422 #include <sstream>
  12423 
  12424 namespace Catch {
  12425 
  12426     namespace Generators {
  12427         struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
  12428             GeneratorBasePtr m_generator;
  12429 
  12430             GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
  12431             :   TrackerBase( nameAndLocation, ctx, parent )
  12432             {}
  12433             ~GeneratorTracker();
  12434 
  12435             static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
  12436                 std::shared_ptr<GeneratorTracker> tracker;
  12437 
  12438                 ITracker& currentTracker = ctx.currentTracker();
  12439                 if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
  12440                     assert( childTracker );
  12441                     assert( childTracker->isGeneratorTracker() );
  12442                     tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
  12443                 }
  12444                 else {
  12445                     tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
  12446                     currentTracker.addChild( tracker );
  12447                 }
  12448 
  12449                 if( !ctx.completedCycle() && !tracker->isComplete() ) {
  12450                     tracker->open();
  12451                 }
  12452 
  12453                 return *tracker;
  12454             }
  12455 
  12456             // TrackerBase interface
  12457             bool isGeneratorTracker() const override { return true; }
  12458             auto hasGenerator() const -> bool override {
  12459                 return !!m_generator;
  12460             }
  12461             void close() override {
  12462                 TrackerBase::close();
  12463                 // Generator interface only finds out if it has another item on atual move
  12464                 if (m_runState == CompletedSuccessfully && m_generator->next()) {
  12465                     m_children.clear();
  12466                     m_runState = Executing;
  12467                 }
  12468             }
  12469 
  12470             // IGeneratorTracker interface
  12471             auto getGenerator() const -> GeneratorBasePtr const& override {
  12472                 return m_generator;
  12473             }
  12474             void setGenerator( GeneratorBasePtr&& generator ) override {
  12475                 m_generator = std::move( generator );
  12476             }
  12477         };
  12478         GeneratorTracker::~GeneratorTracker() {}
  12479     }
  12480 
  12481     RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
  12482     :   m_runInfo(_config->name()),
  12483         m_context(getCurrentMutableContext()),
  12484         m_config(_config),
  12485         m_reporter(std::move(reporter)),
  12486         m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
  12487         m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
  12488     {
  12489         m_context.setRunner(this);
  12490         m_context.setConfig(m_config);
  12491         m_context.setResultCapture(this);
  12492         m_reporter->testRunStarting(m_runInfo);
  12493     }
  12494 
  12495     RunContext::~RunContext() {
  12496         m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
  12497     }
  12498 
  12499     void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
  12500         m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
  12501     }
  12502 
  12503     void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
  12504         m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
  12505     }
  12506 
  12507     Totals RunContext::runTest(TestCase const& testCase) {
  12508         Totals prevTotals = m_totals;
  12509 
  12510         std::string redirectedCout;
  12511         std::string redirectedCerr;
  12512 
  12513         auto const& testInfo = testCase.getTestCaseInfo();
  12514 
  12515         m_reporter->testCaseStarting(testInfo);
  12516 
  12517         m_activeTestCase = &testCase;
  12518 
  12519         ITracker& rootTracker = m_trackerContext.startRun();
  12520         assert(rootTracker.isSectionTracker());
  12521         static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
  12522         do {
  12523             m_trackerContext.startCycle();
  12524             m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
  12525             runCurrentTest(redirectedCout, redirectedCerr);
  12526         } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
  12527 
  12528         Totals deltaTotals = m_totals.delta(prevTotals);
  12529         if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
  12530             deltaTotals.assertions.failed++;
  12531             deltaTotals.testCases.passed--;
  12532             deltaTotals.testCases.failed++;
  12533         }
  12534         m_totals.testCases += deltaTotals.testCases;
  12535         m_reporter->testCaseEnded(TestCaseStats(testInfo,
  12536                                   deltaTotals,
  12537                                   redirectedCout,
  12538                                   redirectedCerr,
  12539                                   aborting()));
  12540 
  12541         m_activeTestCase = nullptr;
  12542         m_testCaseTracker = nullptr;
  12543 
  12544         return deltaTotals;
  12545     }
  12546 
  12547     IConfigPtr RunContext::config() const {
  12548         return m_config;
  12549     }
  12550 
  12551     IStreamingReporter& RunContext::reporter() const {
  12552         return *m_reporter;
  12553     }
  12554 
  12555     void RunContext::assertionEnded(AssertionResult const & result) {
  12556         if (result.getResultType() == ResultWas::Ok) {
  12557             m_totals.assertions.passed++;
  12558             m_lastAssertionPassed = true;
  12559         } else if (!result.isOk()) {
  12560             m_lastAssertionPassed = false;
  12561             if( m_activeTestCase->getTestCaseInfo().okToFail() )
  12562                 m_totals.assertions.failedButOk++;
  12563             else
  12564                 m_totals.assertions.failed++;
  12565         }
  12566         else {
  12567             m_lastAssertionPassed = true;
  12568         }
  12569 
  12570         // We have no use for the return value (whether messages should be cleared), because messages were made scoped
  12571         // and should be let to clear themselves out.
  12572         static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
  12573 
  12574         if (result.getResultType() != ResultWas::Warning)
  12575             m_messageScopes.clear();
  12576 
  12577         // Reset working state
  12578         resetAssertionInfo();
  12579         m_lastResult = result;
  12580     }
  12581     void RunContext::resetAssertionInfo() {
  12582         m_lastAssertionInfo.macroName = StringRef();
  12583         m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
  12584     }
  12585 
  12586     bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
  12587         ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
  12588         if (!sectionTracker.isOpen())
  12589             return false;
  12590         m_activeSections.push_back(&sectionTracker);
  12591 
  12592         m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
  12593 
  12594         m_reporter->sectionStarting(sectionInfo);
  12595 
  12596         assertions = m_totals.assertions;
  12597 
  12598         return true;
  12599     }
  12600     auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
  12601         using namespace Generators;
  12602         GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
  12603         assert( tracker.isOpen() );
  12604         m_lastAssertionInfo.lineInfo = lineInfo;
  12605         return tracker;
  12606     }
  12607 
  12608     bool RunContext::testForMissingAssertions(Counts& assertions) {
  12609         if (assertions.total() != 0)
  12610             return false;
  12611         if (!m_config->warnAboutMissingAssertions())
  12612             return false;
  12613         if (m_trackerContext.currentTracker().hasChildren())
  12614             return false;
  12615         m_totals.assertions.failed++;
  12616         assertions.failed++;
  12617         return true;
  12618     }
  12619 
  12620     void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
  12621         Counts assertions = m_totals.assertions - endInfo.prevAssertions;
  12622         bool missingAssertions = testForMissingAssertions(assertions);
  12623 
  12624         if (!m_activeSections.empty()) {
  12625             m_activeSections.back()->close();
  12626             m_activeSections.pop_back();
  12627         }
  12628 
  12629         m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
  12630         m_messages.clear();
  12631         m_messageScopes.clear();
  12632     }
  12633 
  12634     void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
  12635         if (m_unfinishedSections.empty())
  12636             m_activeSections.back()->fail();
  12637         else
  12638             m_activeSections.back()->close();
  12639         m_activeSections.pop_back();
  12640 
  12641         m_unfinishedSections.push_back(endInfo);
  12642     }
  12643 
  12644 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  12645     void RunContext::benchmarkPreparing(std::string const& name) {
  12646 		m_reporter->benchmarkPreparing(name);
  12647 	}
  12648     void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
  12649         m_reporter->benchmarkStarting( info );
  12650     }
  12651     void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
  12652         m_reporter->benchmarkEnded( stats );
  12653     }
  12654 	void RunContext::benchmarkFailed(std::string const & error) {
  12655 		m_reporter->benchmarkFailed(error);
  12656 	}
  12657 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  12658 
  12659     void RunContext::pushScopedMessage(MessageInfo const & message) {
  12660         m_messages.push_back(message);
  12661     }
  12662 
  12663     void RunContext::popScopedMessage(MessageInfo const & message) {
  12664         m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
  12665     }
  12666 
  12667     void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
  12668         m_messageScopes.emplace_back( builder );
  12669     }
  12670 
  12671     std::string RunContext::getCurrentTestName() const {
  12672         return m_activeTestCase
  12673             ? m_activeTestCase->getTestCaseInfo().name
  12674             : std::string();
  12675     }
  12676 
  12677     const AssertionResult * RunContext::getLastResult() const {
  12678         return &(*m_lastResult);
  12679     }
  12680 
  12681     void RunContext::exceptionEarlyReported() {
  12682         m_shouldReportUnexpected = false;
  12683     }
  12684 
  12685     void RunContext::handleFatalErrorCondition( StringRef message ) {
  12686         // First notify reporter that bad things happened
  12687         m_reporter->fatalErrorEncountered(message);
  12688 
  12689         // Don't rebuild the result -- the stringification itself can cause more fatal errors
  12690         // Instead, fake a result data.
  12691         AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
  12692         tempResult.message = static_cast<std::string>(message);
  12693         AssertionResult result(m_lastAssertionInfo, tempResult);
  12694 
  12695         assertionEnded(result);
  12696 
  12697         handleUnfinishedSections();
  12698 
  12699         // Recreate section for test case (as we will lose the one that was in scope)
  12700         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  12701         SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
  12702 
  12703         Counts assertions;
  12704         assertions.failed = 1;
  12705         SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
  12706         m_reporter->sectionEnded(testCaseSectionStats);
  12707 
  12708         auto const& testInfo = m_activeTestCase->getTestCaseInfo();
  12709 
  12710         Totals deltaTotals;
  12711         deltaTotals.testCases.failed = 1;
  12712         deltaTotals.assertions.failed = 1;
  12713         m_reporter->testCaseEnded(TestCaseStats(testInfo,
  12714                                   deltaTotals,
  12715                                   std::string(),
  12716                                   std::string(),
  12717                                   false));
  12718         m_totals.testCases.failed++;
  12719         testGroupEnded(std::string(), m_totals, 1, 1);
  12720         m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
  12721     }
  12722 
  12723     bool RunContext::lastAssertionPassed() {
  12724          return m_lastAssertionPassed;
  12725     }
  12726 
  12727     void RunContext::assertionPassed() {
  12728         m_lastAssertionPassed = true;
  12729         ++m_totals.assertions.passed;
  12730         resetAssertionInfo();
  12731         m_messageScopes.clear();
  12732     }
  12733 
  12734     bool RunContext::aborting() const {
  12735         return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
  12736     }
  12737 
  12738     void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
  12739         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  12740         SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
  12741         m_reporter->sectionStarting(testCaseSection);
  12742         Counts prevAssertions = m_totals.assertions;
  12743         double duration = 0;
  12744         m_shouldReportUnexpected = true;
  12745         m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
  12746 
  12747         seedRng(*m_config);
  12748 
  12749         Timer timer;
  12750         CATCH_TRY {
  12751             if (m_reporter->getPreferences().shouldRedirectStdOut) {
  12752 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
  12753                 RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
  12754 
  12755                 timer.start();
  12756                 invokeActiveTestCase();
  12757 #else
  12758                 OutputRedirect r(redirectedCout, redirectedCerr);
  12759                 timer.start();
  12760                 invokeActiveTestCase();
  12761 #endif
  12762             } else {
  12763                 timer.start();
  12764                 invokeActiveTestCase();
  12765             }
  12766             duration = timer.getElapsedSeconds();
  12767         } CATCH_CATCH_ANON (TestFailureException&) {
  12768             // This just means the test was aborted due to failure
  12769         } CATCH_CATCH_ALL {
  12770             // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
  12771             // are reported without translation at the point of origin.
  12772             if( m_shouldReportUnexpected ) {
  12773                 AssertionReaction dummyReaction;
  12774                 handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
  12775             }
  12776         }
  12777         Counts assertions = m_totals.assertions - prevAssertions;
  12778         bool missingAssertions = testForMissingAssertions(assertions);
  12779 
  12780         m_testCaseTracker->close();
  12781         handleUnfinishedSections();
  12782         m_messages.clear();
  12783         m_messageScopes.clear();
  12784 
  12785         SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
  12786         m_reporter->sectionEnded(testCaseSectionStats);
  12787     }
  12788 
  12789     void RunContext::invokeActiveTestCase() {
  12790         FatalConditionHandler fatalConditionHandler; // Handle signals
  12791         m_activeTestCase->invoke();
  12792         fatalConditionHandler.reset();
  12793     }
  12794 
  12795     void RunContext::handleUnfinishedSections() {
  12796         // If sections ended prematurely due to an exception we stored their
  12797         // infos here so we can tear them down outside the unwind process.
  12798         for (auto it = m_unfinishedSections.rbegin(),
  12799              itEnd = m_unfinishedSections.rend();
  12800              it != itEnd;
  12801              ++it)
  12802             sectionEnded(*it);
  12803         m_unfinishedSections.clear();
  12804     }
  12805 
  12806     void RunContext::handleExpr(
  12807         AssertionInfo const& info,
  12808         ITransientExpression const& expr,
  12809         AssertionReaction& reaction
  12810     ) {
  12811         m_reporter->assertionStarting( info );
  12812 
  12813         bool negated = isFalseTest( info.resultDisposition );
  12814         bool result = expr.getResult() != negated;
  12815 
  12816         if( result ) {
  12817             if (!m_includeSuccessfulResults) {
  12818                 assertionPassed();
  12819             }
  12820             else {
  12821                 reportExpr(info, ResultWas::Ok, &expr, negated);
  12822             }
  12823         }
  12824         else {
  12825             reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
  12826             populateReaction( reaction );
  12827         }
  12828     }
  12829     void RunContext::reportExpr(
  12830             AssertionInfo const &info,
  12831             ResultWas::OfType resultType,
  12832             ITransientExpression const *expr,
  12833             bool negated ) {
  12834 
  12835         m_lastAssertionInfo = info;
  12836         AssertionResultData data( resultType, LazyExpression( negated ) );
  12837 
  12838         AssertionResult assertionResult{ info, data };
  12839         assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
  12840 
  12841         assertionEnded( assertionResult );
  12842     }
  12843 
  12844     void RunContext::handleMessage(
  12845             AssertionInfo const& info,
  12846             ResultWas::OfType resultType,
  12847             StringRef const& message,
  12848             AssertionReaction& reaction
  12849     ) {
  12850         m_reporter->assertionStarting( info );
  12851 
  12852         m_lastAssertionInfo = info;
  12853 
  12854         AssertionResultData data( resultType, LazyExpression( false ) );
  12855         data.message = static_cast<std::string>(message);
  12856         AssertionResult assertionResult{ m_lastAssertionInfo, data };
  12857         assertionEnded( assertionResult );
  12858         if( !assertionResult.isOk() )
  12859             populateReaction( reaction );
  12860     }
  12861     void RunContext::handleUnexpectedExceptionNotThrown(
  12862             AssertionInfo const& info,
  12863             AssertionReaction& reaction
  12864     ) {
  12865         handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
  12866     }
  12867 
  12868     void RunContext::handleUnexpectedInflightException(
  12869             AssertionInfo const& info,
  12870             std::string const& message,
  12871             AssertionReaction& reaction
  12872     ) {
  12873         m_lastAssertionInfo = info;
  12874 
  12875         AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
  12876         data.message = message;
  12877         AssertionResult assertionResult{ info, data };
  12878         assertionEnded( assertionResult );
  12879         populateReaction( reaction );
  12880     }
  12881 
  12882     void RunContext::populateReaction( AssertionReaction& reaction ) {
  12883         reaction.shouldDebugBreak = m_config->shouldDebugBreak();
  12884         reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
  12885     }
  12886 
  12887     void RunContext::handleIncomplete(
  12888             AssertionInfo const& info
  12889     ) {
  12890         m_lastAssertionInfo = info;
  12891 
  12892         AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
  12893         data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
  12894         AssertionResult assertionResult{ info, data };
  12895         assertionEnded( assertionResult );
  12896     }
  12897     void RunContext::handleNonExpr(
  12898             AssertionInfo const &info,
  12899             ResultWas::OfType resultType,
  12900             AssertionReaction &reaction
  12901     ) {
  12902         m_lastAssertionInfo = info;
  12903 
  12904         AssertionResultData data( resultType, LazyExpression( false ) );
  12905         AssertionResult assertionResult{ info, data };
  12906         assertionEnded( assertionResult );
  12907 
  12908         if( !assertionResult.isOk() )
  12909             populateReaction( reaction );
  12910     }
  12911 
  12912     IResultCapture& getResultCapture() {
  12913         if (auto* capture = getCurrentContext().getResultCapture())
  12914             return *capture;
  12915         else
  12916             CATCH_INTERNAL_ERROR("No result capture instance");
  12917     }
  12918 
  12919     void seedRng(IConfig const& config) {
  12920         if (config.rngSeed() != 0) {
  12921             std::srand(config.rngSeed());
  12922             rng().seed(config.rngSeed());
  12923         }
  12924     }
  12925 
  12926     unsigned int rngSeed() {
  12927         return getCurrentContext().getConfig()->rngSeed();
  12928     }
  12929 
  12930 }
  12931 // end catch_run_context.cpp
  12932 // start catch_section.cpp
  12933 
  12934 namespace Catch {
  12935 
  12936     Section::Section( SectionInfo const& info )
  12937     :   m_info( info ),
  12938         m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
  12939     {
  12940         m_timer.start();
  12941     }
  12942 
  12943     Section::~Section() {
  12944         if( m_sectionIncluded ) {
  12945             SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
  12946             if( uncaught_exceptions() )
  12947                 getResultCapture().sectionEndedEarly( endInfo );
  12948             else
  12949                 getResultCapture().sectionEnded( endInfo );
  12950         }
  12951     }
  12952 
  12953     // This indicates whether the section should be executed or not
  12954     Section::operator bool() const {
  12955         return m_sectionIncluded;
  12956     }
  12957 
  12958 } // end namespace Catch
  12959 // end catch_section.cpp
  12960 // start catch_section_info.cpp
  12961 
  12962 namespace Catch {
  12963 
  12964     SectionInfo::SectionInfo
  12965         (   SourceLineInfo const& _lineInfo,
  12966             std::string const& _name )
  12967     :   name( _name ),
  12968         lineInfo( _lineInfo )
  12969     {}
  12970 
  12971 } // end namespace Catch
  12972 // end catch_section_info.cpp
  12973 // start catch_session.cpp
  12974 
  12975 // start catch_session.h
  12976 
  12977 #include <memory>
  12978 
  12979 namespace Catch {
  12980 
  12981     class Session : NonCopyable {
  12982     public:
  12983 
  12984         Session();
  12985         ~Session() override;
  12986 
  12987         void showHelp() const;
  12988         void libIdentify();
  12989 
  12990         int applyCommandLine( int argc, char const * const * argv );
  12991     #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
  12992         int applyCommandLine( int argc, wchar_t const * const * argv );
  12993     #endif
  12994 
  12995         void useConfigData( ConfigData const& configData );
  12996 
  12997         template<typename CharT>
  12998         int run(int argc, CharT const * const argv[]) {
  12999             if (m_startupExceptions)
  13000                 return 1;
  13001             int returnCode = applyCommandLine(argc, argv);
  13002             if (returnCode == 0)
  13003                 returnCode = run();
  13004             return returnCode;
  13005         }
  13006 
  13007         int run();
  13008 
  13009         clara::Parser const& cli() const;
  13010         void cli( clara::Parser const& newParser );
  13011         ConfigData& configData();
  13012         Config& config();
  13013     private:
  13014         int runInternal();
  13015 
  13016         clara::Parser m_cli;
  13017         ConfigData m_configData;
  13018         std::shared_ptr<Config> m_config;
  13019         bool m_startupExceptions = false;
  13020     };
  13021 
  13022 } // end namespace Catch
  13023 
  13024 // end catch_session.h
  13025 // start catch_version.h
  13026 
  13027 #include <iosfwd>
  13028 
  13029 namespace Catch {
  13030 
  13031     // Versioning information
  13032     struct Version {
  13033         Version( Version const& ) = delete;
  13034         Version& operator=( Version const& ) = delete;
  13035         Version(    unsigned int _majorVersion,
  13036                     unsigned int _minorVersion,
  13037                     unsigned int _patchNumber,
  13038                     char const * const _branchName,
  13039                     unsigned int _buildNumber );
  13040 
  13041         unsigned int const majorVersion;
  13042         unsigned int const minorVersion;
  13043         unsigned int const patchNumber;
  13044 
  13045         // buildNumber is only used if branchName is not null
  13046         char const * const branchName;
  13047         unsigned int const buildNumber;
  13048 
  13049         friend std::ostream& operator << ( std::ostream& os, Version const& version );
  13050     };
  13051 
  13052     Version const& libraryVersion();
  13053 }
  13054 
  13055 // end catch_version.h
  13056 #include <cstdlib>
  13057 #include <iomanip>
  13058 #include <set>
  13059 #include <iterator>
  13060 
  13061 namespace Catch {
  13062 
  13063     namespace {
  13064         const int MaxExitCode = 255;
  13065 
  13066         IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
  13067             auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
  13068             CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
  13069 
  13070             return reporter;
  13071         }
  13072 
  13073         IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
  13074             if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
  13075                 return createReporter(config->getReporterName(), config);
  13076             }
  13077 
  13078             // On older platforms, returning std::unique_ptr<ListeningReporter>
  13079             // when the return type is std::unique_ptr<IStreamingReporter>
  13080             // doesn't compile without a std::move call. However, this causes
  13081             // a warning on newer platforms. Thus, we have to work around
  13082             // it a bit and downcast the pointer manually.
  13083             auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
  13084             auto& multi = static_cast<ListeningReporter&>(*ret);
  13085             auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
  13086             for (auto const& listener : listeners) {
  13087                 multi.addListener(listener->create(Catch::ReporterConfig(config)));
  13088             }
  13089             multi.addReporter(createReporter(config->getReporterName(), config));
  13090             return ret;
  13091         }
  13092 
  13093         class TestGroup {
  13094         public:
  13095             explicit TestGroup(std::shared_ptr<Config> const& config)
  13096             : m_config{config}
  13097             , m_context{config, makeReporter(config)}
  13098             {
  13099                 auto const& allTestCases = getAllTestCasesSorted(*m_config);
  13100                 m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
  13101                 auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
  13102 
  13103                 if (m_matches.empty() && invalidArgs.empty()) {
  13104                     for (auto const& test : allTestCases)
  13105                         if (!test.isHidden())
  13106                             m_tests.emplace(&test);
  13107                 } else {
  13108                     for (auto const& match : m_matches)
  13109                         m_tests.insert(match.tests.begin(), match.tests.end());
  13110                 }
  13111             }
  13112 
  13113             Totals execute() {
  13114                 auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
  13115                 Totals totals;
  13116                 m_context.testGroupStarting(m_config->name(), 1, 1);
  13117                 for (auto const& testCase : m_tests) {
  13118                     if (!m_context.aborting())
  13119                         totals += m_context.runTest(*testCase);
  13120                     else
  13121                         m_context.reporter().skipTest(*testCase);
  13122                 }
  13123 
  13124                 for (auto const& match : m_matches) {
  13125                     if (match.tests.empty()) {
  13126                         m_context.reporter().noMatchingTestCases(match.name);
  13127                         totals.error = -1;
  13128                     }
  13129                 }
  13130 
  13131                 if (!invalidArgs.empty()) {
  13132                     for (auto const& invalidArg: invalidArgs)
  13133                          m_context.reporter().reportInvalidArguments(invalidArg);
  13134                 }
  13135 
  13136                 m_context.testGroupEnded(m_config->name(), totals, 1, 1);
  13137                 return totals;
  13138             }
  13139 
  13140         private:
  13141             using Tests = std::set<TestCase const*>;
  13142 
  13143             std::shared_ptr<Config> m_config;
  13144             RunContext m_context;
  13145             Tests m_tests;
  13146             TestSpec::Matches m_matches;
  13147         };
  13148 
  13149         void applyFilenamesAsTags(Catch::IConfig const& config) {
  13150             auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
  13151             for (auto& testCase : tests) {
  13152                 auto tags = testCase.tags;
  13153 
  13154                 std::string filename = testCase.lineInfo.file;
  13155                 auto lastSlash = filename.find_last_of("\\/");
  13156                 if (lastSlash != std::string::npos) {
  13157                     filename.erase(0, lastSlash);
  13158                     filename[0] = '#';
  13159                 }
  13160 
  13161                 auto lastDot = filename.find_last_of('.');
  13162                 if (lastDot != std::string::npos) {
  13163                     filename.erase(lastDot);
  13164                 }
  13165 
  13166                 tags.push_back(std::move(filename));
  13167                 setTags(testCase, tags);
  13168             }
  13169         }
  13170 
  13171     } // anon namespace
  13172 
  13173     Session::Session() {
  13174         static bool alreadyInstantiated = false;
  13175         if( alreadyInstantiated ) {
  13176             CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
  13177             CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
  13178         }
  13179 
  13180         // There cannot be exceptions at startup in no-exception mode.
  13181 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  13182         const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
  13183         if ( !exceptions.empty() ) {
  13184             config();
  13185             getCurrentMutableContext().setConfig(m_config);
  13186 
  13187             m_startupExceptions = true;
  13188             Colour colourGuard( Colour::Red );
  13189             Catch::cerr() << "Errors occurred during startup!" << '\n';
  13190             // iterate over all exceptions and notify user
  13191             for ( const auto& ex_ptr : exceptions ) {
  13192                 try {
  13193                     std::rethrow_exception(ex_ptr);
  13194                 } catch ( std::exception const& ex ) {
  13195                     Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
  13196                 }
  13197             }
  13198         }
  13199 #endif
  13200 
  13201         alreadyInstantiated = true;
  13202         m_cli = makeCommandLineParser( m_configData );
  13203     }
  13204     Session::~Session() {
  13205         Catch::cleanUp();
  13206     }
  13207 
  13208     void Session::showHelp() const {
  13209         Catch::cout()
  13210                 << "\nCatch v" << libraryVersion() << "\n"
  13211                 << m_cli << std::endl
  13212                 << "For more detailed usage please see the project docs\n" << std::endl;
  13213     }
  13214     void Session::libIdentify() {
  13215         Catch::cout()
  13216                 << std::left << std::setw(16) << "description: " << "A Catch2 test executable\n"
  13217                 << std::left << std::setw(16) << "category: " << "testframework\n"
  13218                 << std::left << std::setw(16) << "framework: " << "Catch Test\n"
  13219                 << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
  13220     }
  13221 
  13222     int Session::applyCommandLine( int argc, char const * const * argv ) {
  13223         if( m_startupExceptions )
  13224             return 1;
  13225 
  13226         auto result = m_cli.parse( clara::Args( argc, argv ) );
  13227         if( !result ) {
  13228             config();
  13229             getCurrentMutableContext().setConfig(m_config);
  13230             Catch::cerr()
  13231                 << Colour( Colour::Red )
  13232                 << "\nError(s) in input:\n"
  13233                 << Column( result.errorMessage() ).indent( 2 )
  13234                 << "\n\n";
  13235             Catch::cerr() << "Run with -? for usage\n" << std::endl;
  13236             return MaxExitCode;
  13237         }
  13238 
  13239         if( m_configData.showHelp )
  13240             showHelp();
  13241         if( m_configData.libIdentify )
  13242             libIdentify();
  13243         m_config.reset();
  13244         return 0;
  13245     }
  13246 
  13247 #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
  13248     int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
  13249 
  13250         char **utf8Argv = new char *[ argc ];
  13251 
  13252         for ( int i = 0; i < argc; ++i ) {
  13253             int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
  13254 
  13255             utf8Argv[ i ] = new char[ bufSize ];
  13256 
  13257             WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
  13258         }
  13259 
  13260         int returnCode = applyCommandLine( argc, utf8Argv );
  13261 
  13262         for ( int i = 0; i < argc; ++i )
  13263             delete [] utf8Argv[ i ];
  13264 
  13265         delete [] utf8Argv;
  13266 
  13267         return returnCode;
  13268     }
  13269 #endif
  13270 
  13271     void Session::useConfigData( ConfigData const& configData ) {
  13272         m_configData = configData;
  13273         m_config.reset();
  13274     }
  13275 
  13276     int Session::run() {
  13277         if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
  13278             Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
  13279             static_cast<void>(std::getchar());
  13280         }
  13281         int exitCode = runInternal();
  13282         if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
  13283             Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
  13284             static_cast<void>(std::getchar());
  13285         }
  13286         return exitCode;
  13287     }
  13288 
  13289     clara::Parser const& Session::cli() const {
  13290         return m_cli;
  13291     }
  13292     void Session::cli( clara::Parser const& newParser ) {
  13293         m_cli = newParser;
  13294     }
  13295     ConfigData& Session::configData() {
  13296         return m_configData;
  13297     }
  13298     Config& Session::config() {
  13299         if( !m_config )
  13300             m_config = std::make_shared<Config>( m_configData );
  13301         return *m_config;
  13302     }
  13303 
  13304     int Session::runInternal() {
  13305         if( m_startupExceptions )
  13306             return 1;
  13307 
  13308         if (m_configData.showHelp || m_configData.libIdentify) {
  13309             return 0;
  13310         }
  13311 
  13312         CATCH_TRY {
  13313             config(); // Force config to be constructed
  13314 
  13315             seedRng( *m_config );
  13316 
  13317             if( m_configData.filenamesAsTags )
  13318                 applyFilenamesAsTags( *m_config );
  13319 
  13320             // Handle list request
  13321             if( Option<std::size_t> listed = list( m_config ) )
  13322                 return static_cast<int>( *listed );
  13323 
  13324             TestGroup tests { m_config };
  13325             auto const totals = tests.execute();
  13326 
  13327             if( m_config->warnAboutNoTests() && totals.error == -1 )
  13328                 return 2;
  13329 
  13330             // Note that on unices only the lower 8 bits are usually used, clamping
  13331             // the return value to 255 prevents false negative when some multiple
  13332             // of 256 tests has failed
  13333             return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
  13334         }
  13335 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  13336         catch( std::exception& ex ) {
  13337             Catch::cerr() << ex.what() << std::endl;
  13338             return MaxExitCode;
  13339         }
  13340 #endif
  13341     }
  13342 
  13343 } // end namespace Catch
  13344 // end catch_session.cpp
  13345 // start catch_singletons.cpp
  13346 
  13347 #include <vector>
  13348 
  13349 namespace Catch {
  13350 
  13351     namespace {
  13352         static auto getSingletons() -> std::vector<ISingleton*>*& {
  13353             static std::vector<ISingleton*>* g_singletons = nullptr;
  13354             if( !g_singletons )
  13355                 g_singletons = new std::vector<ISingleton*>();
  13356             return g_singletons;
  13357         }
  13358     }
  13359 
  13360     ISingleton::~ISingleton() {}
  13361 
  13362     void addSingleton(ISingleton* singleton ) {
  13363         getSingletons()->push_back( singleton );
  13364     }
  13365     void cleanupSingletons() {
  13366         auto& singletons = getSingletons();
  13367         for( auto singleton : *singletons )
  13368             delete singleton;
  13369         delete singletons;
  13370         singletons = nullptr;
  13371     }
  13372 
  13373 } // namespace Catch
  13374 // end catch_singletons.cpp
  13375 // start catch_startup_exception_registry.cpp
  13376 
  13377 namespace Catch {
  13378 void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
  13379         CATCH_TRY {
  13380             m_exceptions.push_back(exception);
  13381         } CATCH_CATCH_ALL {
  13382             // If we run out of memory during start-up there's really not a lot more we can do about it
  13383             std::terminate();
  13384         }
  13385     }
  13386 
  13387     std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
  13388         return m_exceptions;
  13389     }
  13390 
  13391 } // end namespace Catch
  13392 // end catch_startup_exception_registry.cpp
  13393 // start catch_stream.cpp
  13394 
  13395 #include <cstdio>
  13396 #include <iostream>
  13397 #include <fstream>
  13398 #include <sstream>
  13399 #include <vector>
  13400 #include <memory>
  13401 
  13402 namespace Catch {
  13403 
  13404     Catch::IStream::~IStream() = default;
  13405 
  13406     namespace Detail { namespace {
  13407         template<typename WriterF, std::size_t bufferSize=256>
  13408         class StreamBufImpl : public std::streambuf {
  13409             char data[bufferSize];
  13410             WriterF m_writer;
  13411 
  13412         public:
  13413             StreamBufImpl() {
  13414                 setp( data, data + sizeof(data) );
  13415             }
  13416 
  13417             ~StreamBufImpl() noexcept {
  13418                 StreamBufImpl::sync();
  13419             }
  13420 
  13421         private:
  13422             int overflow( int c ) override {
  13423                 sync();
  13424 
  13425                 if( c != EOF ) {
  13426                     if( pbase() == epptr() )
  13427                         m_writer( std::string( 1, static_cast<char>( c ) ) );
  13428                     else
  13429                         sputc( static_cast<char>( c ) );
  13430                 }
  13431                 return 0;
  13432             }
  13433 
  13434             int sync() override {
  13435                 if( pbase() != pptr() ) {
  13436                     m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
  13437                     setp( pbase(), epptr() );
  13438                 }
  13439                 return 0;
  13440             }
  13441         };
  13442 
  13443         ///////////////////////////////////////////////////////////////////////////
  13444 
  13445         struct OutputDebugWriter {
  13446 
  13447             void operator()( std::string const&str ) {
  13448                 writeToDebugConsole( str );
  13449             }
  13450         };
  13451 
  13452         ///////////////////////////////////////////////////////////////////////////
  13453 
  13454         class FileStream : public IStream {
  13455             mutable std::ofstream m_ofs;
  13456         public:
  13457             FileStream( StringRef filename ) {
  13458                 m_ofs.open( filename.c_str() );
  13459                 CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
  13460             }
  13461             ~FileStream() override = default;
  13462         public: // IStream
  13463             std::ostream& stream() const override {
  13464                 return m_ofs;
  13465             }
  13466         };
  13467 
  13468         ///////////////////////////////////////////////////////////////////////////
  13469 
  13470         class CoutStream : public IStream {
  13471             mutable std::ostream m_os;
  13472         public:
  13473             // Store the streambuf from cout up-front because
  13474             // cout may get redirected when running tests
  13475             CoutStream() : m_os( Catch::cout().rdbuf() ) {}
  13476             ~CoutStream() override = default;
  13477 
  13478         public: // IStream
  13479             std::ostream& stream() const override { return m_os; }
  13480         };
  13481 
  13482         ///////////////////////////////////////////////////////////////////////////
  13483 
  13484         class DebugOutStream : public IStream {
  13485             std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
  13486             mutable std::ostream m_os;
  13487         public:
  13488             DebugOutStream()
  13489             :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
  13490                 m_os( m_streamBuf.get() )
  13491             {}
  13492 
  13493             ~DebugOutStream() override = default;
  13494 
  13495         public: // IStream
  13496             std::ostream& stream() const override { return m_os; }
  13497         };
  13498 
  13499     }} // namespace anon::detail
  13500 
  13501     ///////////////////////////////////////////////////////////////////////////
  13502 
  13503     auto makeStream( StringRef const &filename ) -> IStream const* {
  13504         if( filename.empty() )
  13505             return new Detail::CoutStream();
  13506         else if( filename[0] == '%' ) {
  13507             if( filename == "%debug" )
  13508                 return new Detail::DebugOutStream();
  13509             else
  13510                 CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
  13511         }
  13512         else
  13513             return new Detail::FileStream( filename );
  13514     }
  13515 
  13516     // This class encapsulates the idea of a pool of ostringstreams that can be reused.
  13517     struct StringStreams {
  13518         std::vector<std::unique_ptr<std::ostringstream>> m_streams;
  13519         std::vector<std::size_t> m_unused;
  13520         std::ostringstream m_referenceStream; // Used for copy state/ flags from
  13521 
  13522         auto add() -> std::size_t {
  13523             if( m_unused.empty() ) {
  13524                 m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
  13525                 return m_streams.size()-1;
  13526             }
  13527             else {
  13528                 auto index = m_unused.back();
  13529                 m_unused.pop_back();
  13530                 return index;
  13531             }
  13532         }
  13533 
  13534         void release( std::size_t index ) {
  13535             m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
  13536             m_unused.push_back(index);
  13537         }
  13538     };
  13539 
  13540     ReusableStringStream::ReusableStringStream()
  13541     :   m_index( Singleton<StringStreams>::getMutable().add() ),
  13542         m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
  13543     {}
  13544 
  13545     ReusableStringStream::~ReusableStringStream() {
  13546         static_cast<std::ostringstream*>( m_oss )->str("");
  13547         m_oss->clear();
  13548         Singleton<StringStreams>::getMutable().release( m_index );
  13549     }
  13550 
  13551     auto ReusableStringStream::str() const -> std::string {
  13552         return static_cast<std::ostringstream*>( m_oss )->str();
  13553     }
  13554 
  13555     ///////////////////////////////////////////////////////////////////////////
  13556 
  13557 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
  13558     std::ostream& cout() { return std::cout; }
  13559     std::ostream& cerr() { return std::cerr; }
  13560     std::ostream& clog() { return std::clog; }
  13561 #endif
  13562 }
  13563 // end catch_stream.cpp
  13564 // start catch_string_manip.cpp
  13565 
  13566 #include <algorithm>
  13567 #include <ostream>
  13568 #include <cstring>
  13569 #include <cctype>
  13570 #include <vector>
  13571 
  13572 namespace Catch {
  13573 
  13574     namespace {
  13575         char toLowerCh(char c) {
  13576             return static_cast<char>( std::tolower( c ) );
  13577         }
  13578     }
  13579 
  13580     bool startsWith( std::string const& s, std::string const& prefix ) {
  13581         return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
  13582     }
  13583     bool startsWith( std::string const& s, char prefix ) {
  13584         return !s.empty() && s[0] == prefix;
  13585     }
  13586     bool endsWith( std::string const& s, std::string const& suffix ) {
  13587         return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
  13588     }
  13589     bool endsWith( std::string const& s, char suffix ) {
  13590         return !s.empty() && s[s.size()-1] == suffix;
  13591     }
  13592     bool contains( std::string const& s, std::string const& infix ) {
  13593         return s.find( infix ) != std::string::npos;
  13594     }
  13595     void toLowerInPlace( std::string& s ) {
  13596         std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
  13597     }
  13598     std::string toLower( std::string const& s ) {
  13599         std::string lc = s;
  13600         toLowerInPlace( lc );
  13601         return lc;
  13602     }
  13603     std::string trim( std::string const& str ) {
  13604         static char const* whitespaceChars = "\n\r\t ";
  13605         std::string::size_type start = str.find_first_not_of( whitespaceChars );
  13606         std::string::size_type end = str.find_last_not_of( whitespaceChars );
  13607 
  13608         return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
  13609     }
  13610 
  13611     StringRef trim(StringRef ref) {
  13612         const auto is_ws = [](char c) {
  13613             return c == ' ' || c == '\t' || c == '\n' || c == '\r';
  13614         };
  13615         size_t real_begin = 0;
  13616         while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }
  13617         size_t real_end = ref.size();
  13618         while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }
  13619 
  13620         return ref.substr(real_begin, real_end - real_begin);
  13621     }
  13622 
  13623     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
  13624         bool replaced = false;
  13625         std::size_t i = str.find( replaceThis );
  13626         while( i != std::string::npos ) {
  13627             replaced = true;
  13628             str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
  13629             if( i < str.size()-withThis.size() )
  13630                 i = str.find( replaceThis, i+withThis.size() );
  13631             else
  13632                 i = std::string::npos;
  13633         }
  13634         return replaced;
  13635     }
  13636 
  13637     std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
  13638         std::vector<StringRef> subStrings;
  13639         std::size_t start = 0;
  13640         for(std::size_t pos = 0; pos < str.size(); ++pos ) {
  13641             if( str[pos] == delimiter ) {
  13642                 if( pos - start > 1 )
  13643                     subStrings.push_back( str.substr( start, pos-start ) );
  13644                 start = pos+1;
  13645             }
  13646         }
  13647         if( start < str.size() )
  13648             subStrings.push_back( str.substr( start, str.size()-start ) );
  13649         return subStrings;
  13650     }
  13651 
  13652     pluralise::pluralise( std::size_t count, std::string const& label )
  13653     :   m_count( count ),
  13654         m_label( label )
  13655     {}
  13656 
  13657     std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
  13658         os << pluraliser.m_count << ' ' << pluraliser.m_label;
  13659         if( pluraliser.m_count != 1 )
  13660             os << 's';
  13661         return os;
  13662     }
  13663 
  13664 }
  13665 // end catch_string_manip.cpp
  13666 // start catch_stringref.cpp
  13667 
  13668 #include <algorithm>
  13669 #include <ostream>
  13670 #include <cstring>
  13671 #include <cstdint>
  13672 
  13673 namespace Catch {
  13674     StringRef::StringRef( char const* rawChars ) noexcept
  13675     : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
  13676     {}
  13677 
  13678     auto StringRef::c_str() const -> char const* {
  13679         CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
  13680         return m_start;
  13681     }
  13682     auto StringRef::data() const noexcept -> char const* {
  13683         return m_start;
  13684     }
  13685 
  13686     auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
  13687         if (start < m_size) {
  13688             return StringRef(m_start + start, (std::min)(m_size - start, size));
  13689         } else {
  13690             return StringRef();
  13691         }
  13692     }
  13693     auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
  13694         return m_size == other.m_size
  13695             && (std::memcmp( m_start, other.m_start, m_size ) == 0);
  13696     }
  13697 
  13698     auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
  13699         return os.write(str.data(), str.size());
  13700     }
  13701 
  13702     auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
  13703         lhs.append(rhs.data(), rhs.size());
  13704         return lhs;
  13705     }
  13706 
  13707 } // namespace Catch
  13708 // end catch_stringref.cpp
  13709 // start catch_tag_alias.cpp
  13710 
  13711 namespace Catch {
  13712     TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
  13713 }
  13714 // end catch_tag_alias.cpp
  13715 // start catch_tag_alias_autoregistrar.cpp
  13716 
  13717 namespace Catch {
  13718 
  13719     RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
  13720         CATCH_TRY {
  13721             getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
  13722         } CATCH_CATCH_ALL {
  13723             // Do not throw when constructing global objects, instead register the exception to be processed later
  13724             getMutableRegistryHub().registerStartupException();
  13725         }
  13726     }
  13727 
  13728 }
  13729 // end catch_tag_alias_autoregistrar.cpp
  13730 // start catch_tag_alias_registry.cpp
  13731 
  13732 #include <sstream>
  13733 
  13734 namespace Catch {
  13735 
  13736     TagAliasRegistry::~TagAliasRegistry() {}
  13737 
  13738     TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
  13739         auto it = m_registry.find( alias );
  13740         if( it != m_registry.end() )
  13741             return &(it->second);
  13742         else
  13743             return nullptr;
  13744     }
  13745 
  13746     std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
  13747         std::string expandedTestSpec = unexpandedTestSpec;
  13748         for( auto const& registryKvp : m_registry ) {
  13749             std::size_t pos = expandedTestSpec.find( registryKvp.first );
  13750             if( pos != std::string::npos ) {
  13751                 expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
  13752                                     registryKvp.second.tag +
  13753                                     expandedTestSpec.substr( pos + registryKvp.first.size() );
  13754             }
  13755         }
  13756         return expandedTestSpec;
  13757     }
  13758 
  13759     void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
  13760         CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
  13761                       "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
  13762 
  13763         CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
  13764                       "error: tag alias, '" << alias << "' already registered.\n"
  13765                       << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
  13766                       << "\tRedefined at: " << lineInfo );
  13767     }
  13768 
  13769     ITagAliasRegistry::~ITagAliasRegistry() {}
  13770 
  13771     ITagAliasRegistry const& ITagAliasRegistry::get() {
  13772         return getRegistryHub().getTagAliasRegistry();
  13773     }
  13774 
  13775 } // end namespace Catch
  13776 // end catch_tag_alias_registry.cpp
  13777 // start catch_test_case_info.cpp
  13778 
  13779 #include <cctype>
  13780 #include <exception>
  13781 #include <algorithm>
  13782 #include <sstream>
  13783 
  13784 namespace Catch {
  13785 
  13786     namespace {
  13787         TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
  13788             if( startsWith( tag, '.' ) ||
  13789                 tag == "!hide" )
  13790                 return TestCaseInfo::IsHidden;
  13791             else if( tag == "!throws" )
  13792                 return TestCaseInfo::Throws;
  13793             else if( tag == "!shouldfail" )
  13794                 return TestCaseInfo::ShouldFail;
  13795             else if( tag == "!mayfail" )
  13796                 return TestCaseInfo::MayFail;
  13797             else if( tag == "!nonportable" )
  13798                 return TestCaseInfo::NonPortable;
  13799             else if( tag == "!benchmark" )
  13800                 return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
  13801             else
  13802                 return TestCaseInfo::None;
  13803         }
  13804         bool isReservedTag( std::string const& tag ) {
  13805             return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
  13806         }
  13807         void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
  13808             CATCH_ENFORCE( !isReservedTag(tag),
  13809                           "Tag name: [" << tag << "] is not allowed.\n"
  13810                           << "Tag names starting with non alphanumeric characters are reserved\n"
  13811                           << _lineInfo );
  13812         }
  13813     }
  13814 
  13815     TestCase makeTestCase(  ITestInvoker* _testCase,
  13816                             std::string const& _className,
  13817                             NameAndTags const& nameAndTags,
  13818                             SourceLineInfo const& _lineInfo )
  13819     {
  13820         bool isHidden = false;
  13821 
  13822         // Parse out tags
  13823         std::vector<std::string> tags;
  13824         std::string desc, tag;
  13825         bool inTag = false;
  13826         for (char c : nameAndTags.tags) {
  13827             if( !inTag ) {
  13828                 if( c == '[' )
  13829                     inTag = true;
  13830                 else
  13831                     desc += c;
  13832             }
  13833             else {
  13834                 if( c == ']' ) {
  13835                     TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
  13836                     if( ( prop & TestCaseInfo::IsHidden ) != 0 )
  13837                         isHidden = true;
  13838                     else if( prop == TestCaseInfo::None )
  13839                         enforceNotReservedTag( tag, _lineInfo );
  13840 
  13841                     // Merged hide tags like `[.approvals]` should be added as
  13842                     // `[.][approvals]`. The `[.]` is added at later point, so
  13843                     // we only strip the prefix
  13844                     if (startsWith(tag, '.') && tag.size() > 1) {
  13845                         tag.erase(0, 1);
  13846                     }
  13847                     tags.push_back( tag );
  13848                     tag.clear();
  13849                     inTag = false;
  13850                 }
  13851                 else
  13852                     tag += c;
  13853             }
  13854         }
  13855         if( isHidden ) {
  13856             tags.push_back( "." );
  13857         }
  13858 
  13859         TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );
  13860         return TestCase( _testCase, std::move(info) );
  13861     }
  13862 
  13863     void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
  13864         std::sort(begin(tags), end(tags));
  13865         tags.erase(std::unique(begin(tags), end(tags)), end(tags));
  13866         testCaseInfo.lcaseTags.clear();
  13867 
  13868         for( auto const& tag : tags ) {
  13869             std::string lcaseTag = toLower( tag );
  13870             testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
  13871             testCaseInfo.lcaseTags.push_back( lcaseTag );
  13872         }
  13873         testCaseInfo.tags = std::move(tags);
  13874     }
  13875 
  13876     TestCaseInfo::TestCaseInfo( std::string const& _name,
  13877                                 std::string const& _className,
  13878                                 std::string const& _description,
  13879                                 std::vector<std::string> const& _tags,
  13880                                 SourceLineInfo const& _lineInfo )
  13881     :   name( _name ),
  13882         className( _className ),
  13883         description( _description ),
  13884         lineInfo( _lineInfo ),
  13885         properties( None )
  13886     {
  13887         setTags( *this, _tags );
  13888     }
  13889 
  13890     bool TestCaseInfo::isHidden() const {
  13891         return ( properties & IsHidden ) != 0;
  13892     }
  13893     bool TestCaseInfo::throws() const {
  13894         return ( properties & Throws ) != 0;
  13895     }
  13896     bool TestCaseInfo::okToFail() const {
  13897         return ( properties & (ShouldFail | MayFail ) ) != 0;
  13898     }
  13899     bool TestCaseInfo::expectedToFail() const {
  13900         return ( properties & (ShouldFail ) ) != 0;
  13901     }
  13902 
  13903     std::string TestCaseInfo::tagsAsString() const {
  13904         std::string ret;
  13905         // '[' and ']' per tag
  13906         std::size_t full_size = 2 * tags.size();
  13907         for (const auto& tag : tags) {
  13908             full_size += tag.size();
  13909         }
  13910         ret.reserve(full_size);
  13911         for (const auto& tag : tags) {
  13912             ret.push_back('[');
  13913             ret.append(tag);
  13914             ret.push_back(']');
  13915         }
  13916 
  13917         return ret;
  13918     }
  13919 
  13920     TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
  13921 
  13922     TestCase TestCase::withName( std::string const& _newName ) const {
  13923         TestCase other( *this );
  13924         other.name = _newName;
  13925         return other;
  13926     }
  13927 
  13928     void TestCase::invoke() const {
  13929         test->invoke();
  13930     }
  13931 
  13932     bool TestCase::operator == ( TestCase const& other ) const {
  13933         return  test.get() == other.test.get() &&
  13934                 name == other.name &&
  13935                 className == other.className;
  13936     }
  13937 
  13938     bool TestCase::operator < ( TestCase const& other ) const {
  13939         return name < other.name;
  13940     }
  13941 
  13942     TestCaseInfo const& TestCase::getTestCaseInfo() const
  13943     {
  13944         return *this;
  13945     }
  13946 
  13947 } // end namespace Catch
  13948 // end catch_test_case_info.cpp
  13949 // start catch_test_case_registry_impl.cpp
  13950 
  13951 #include <sstream>
  13952 
  13953 namespace Catch {
  13954 
  13955     std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
  13956 
  13957         std::vector<TestCase> sorted = unsortedTestCases;
  13958 
  13959         switch( config.runOrder() ) {
  13960             case RunTests::InLexicographicalOrder:
  13961                 std::sort( sorted.begin(), sorted.end() );
  13962                 break;
  13963             case RunTests::InRandomOrder:
  13964                 seedRng( config );
  13965                 std::shuffle( sorted.begin(), sorted.end(), rng() );
  13966                 break;
  13967             case RunTests::InDeclarationOrder:
  13968                 // already in declaration order
  13969                 break;
  13970         }
  13971         return sorted;
  13972     }
  13973 
  13974     bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {
  13975         return !testCase.throws() || config.allowThrows();
  13976     }
  13977 
  13978     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
  13979         return testSpec.matches( testCase ) && isThrowSafe( testCase, config );
  13980     }
  13981 
  13982     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
  13983         std::set<TestCase> seenFunctions;
  13984         for( auto const& function : functions ) {
  13985             auto prev = seenFunctions.insert( function );
  13986             CATCH_ENFORCE( prev.second,
  13987                     "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
  13988                     << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
  13989                     << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
  13990         }
  13991     }
  13992 
  13993     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
  13994         std::vector<TestCase> filtered;
  13995         filtered.reserve( testCases.size() );
  13996         for (auto const& testCase : testCases) {
  13997             if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
  13998                 (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
  13999                 filtered.push_back(testCase);
  14000             }
  14001         }
  14002         return filtered;
  14003     }
  14004     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
  14005         return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
  14006     }
  14007 
  14008     void TestRegistry::registerTest( TestCase const& testCase ) {
  14009         std::string name = testCase.getTestCaseInfo().name;
  14010         if( name.empty() ) {
  14011             ReusableStringStream rss;
  14012             rss << "Anonymous test case " << ++m_unnamedCount;
  14013             return registerTest( testCase.withName( rss.str() ) );
  14014         }
  14015         m_functions.push_back( testCase );
  14016     }
  14017 
  14018     std::vector<TestCase> const& TestRegistry::getAllTests() const {
  14019         return m_functions;
  14020     }
  14021     std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
  14022         if( m_sortedFunctions.empty() )
  14023             enforceNoDuplicateTestCases( m_functions );
  14024 
  14025         if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
  14026             m_sortedFunctions = sortTests( config, m_functions );
  14027             m_currentSortOrder = config.runOrder();
  14028         }
  14029         return m_sortedFunctions;
  14030     }
  14031 
  14032     ///////////////////////////////////////////////////////////////////////////
  14033     TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
  14034 
  14035     void TestInvokerAsFunction::invoke() const {
  14036         m_testAsFunction();
  14037     }
  14038 
  14039     std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
  14040         std::string className(classOrQualifiedMethodName);
  14041         if( startsWith( className, '&' ) )
  14042         {
  14043             std::size_t lastColons = className.rfind( "::" );
  14044             std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
  14045             if( penultimateColons == std::string::npos )
  14046                 penultimateColons = 1;
  14047             className = className.substr( penultimateColons, lastColons-penultimateColons );
  14048         }
  14049         return className;
  14050     }
  14051 
  14052 } // end namespace Catch
  14053 // end catch_test_case_registry_impl.cpp
  14054 // start catch_test_case_tracker.cpp
  14055 
  14056 #include <algorithm>
  14057 #include <cassert>
  14058 #include <stdexcept>
  14059 #include <memory>
  14060 #include <sstream>
  14061 
  14062 #if defined(__clang__)
  14063 #    pragma clang diagnostic push
  14064 #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  14065 #endif
  14066 
  14067 namespace Catch {
  14068 namespace TestCaseTracking {
  14069 
  14070     NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
  14071     :   name( _name ),
  14072         location( _location )
  14073     {}
  14074 
  14075     ITracker::~ITracker() = default;
  14076 
  14077     ITracker& TrackerContext::startRun() {
  14078         m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
  14079         m_currentTracker = nullptr;
  14080         m_runState = Executing;
  14081         return *m_rootTracker;
  14082     }
  14083 
  14084     void TrackerContext::endRun() {
  14085         m_rootTracker.reset();
  14086         m_currentTracker = nullptr;
  14087         m_runState = NotStarted;
  14088     }
  14089 
  14090     void TrackerContext::startCycle() {
  14091         m_currentTracker = m_rootTracker.get();
  14092         m_runState = Executing;
  14093     }
  14094     void TrackerContext::completeCycle() {
  14095         m_runState = CompletedCycle;
  14096     }
  14097 
  14098     bool TrackerContext::completedCycle() const {
  14099         return m_runState == CompletedCycle;
  14100     }
  14101     ITracker& TrackerContext::currentTracker() {
  14102         return *m_currentTracker;
  14103     }
  14104     void TrackerContext::setCurrentTracker( ITracker* tracker ) {
  14105         m_currentTracker = tracker;
  14106     }
  14107 
  14108     TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
  14109     :   m_nameAndLocation( nameAndLocation ),
  14110         m_ctx( ctx ),
  14111         m_parent( parent )
  14112     {}
  14113 
  14114     NameAndLocation const& TrackerBase::nameAndLocation() const {
  14115         return m_nameAndLocation;
  14116     }
  14117     bool TrackerBase::isComplete() const {
  14118         return m_runState == CompletedSuccessfully || m_runState == Failed;
  14119     }
  14120     bool TrackerBase::isSuccessfullyCompleted() const {
  14121         return m_runState == CompletedSuccessfully;
  14122     }
  14123     bool TrackerBase::isOpen() const {
  14124         return m_runState != NotStarted && !isComplete();
  14125     }
  14126     bool TrackerBase::hasChildren() const {
  14127         return !m_children.empty();
  14128     }
  14129 
  14130     void TrackerBase::addChild( ITrackerPtr const& child ) {
  14131         m_children.push_back( child );
  14132     }
  14133 
  14134     ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
  14135         auto it = std::find_if( m_children.begin(), m_children.end(),
  14136             [&nameAndLocation]( ITrackerPtr const& tracker ){
  14137                 return
  14138                     tracker->nameAndLocation().location == nameAndLocation.location &&
  14139                     tracker->nameAndLocation().name == nameAndLocation.name;
  14140             } );
  14141         return( it != m_children.end() )
  14142             ? *it
  14143             : nullptr;
  14144     }
  14145     ITracker& TrackerBase::parent() {
  14146         assert( m_parent ); // Should always be non-null except for root
  14147         return *m_parent;
  14148     }
  14149 
  14150     void TrackerBase::openChild() {
  14151         if( m_runState != ExecutingChildren ) {
  14152             m_runState = ExecutingChildren;
  14153             if( m_parent )
  14154                 m_parent->openChild();
  14155         }
  14156     }
  14157 
  14158     bool TrackerBase::isSectionTracker() const { return false; }
  14159     bool TrackerBase::isGeneratorTracker() const { return false; }
  14160 
  14161     void TrackerBase::open() {
  14162         m_runState = Executing;
  14163         moveToThis();
  14164         if( m_parent )
  14165             m_parent->openChild();
  14166     }
  14167 
  14168     void TrackerBase::close() {
  14169 
  14170         // Close any still open children (e.g. generators)
  14171         while( &m_ctx.currentTracker() != this )
  14172             m_ctx.currentTracker().close();
  14173 
  14174         switch( m_runState ) {
  14175             case NeedsAnotherRun:
  14176                 break;
  14177 
  14178             case Executing:
  14179                 m_runState = CompletedSuccessfully;
  14180                 break;
  14181             case ExecutingChildren:
  14182                 if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )
  14183                     m_runState = CompletedSuccessfully;
  14184                 break;
  14185 
  14186             case NotStarted:
  14187             case CompletedSuccessfully:
  14188             case Failed:
  14189                 CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
  14190 
  14191             default:
  14192                 CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
  14193         }
  14194         moveToParent();
  14195         m_ctx.completeCycle();
  14196     }
  14197     void TrackerBase::fail() {
  14198         m_runState = Failed;
  14199         if( m_parent )
  14200             m_parent->markAsNeedingAnotherRun();
  14201         moveToParent();
  14202         m_ctx.completeCycle();
  14203     }
  14204     void TrackerBase::markAsNeedingAnotherRun() {
  14205         m_runState = NeedsAnotherRun;
  14206     }
  14207 
  14208     void TrackerBase::moveToParent() {
  14209         assert( m_parent );
  14210         m_ctx.setCurrentTracker( m_parent );
  14211     }
  14212     void TrackerBase::moveToThis() {
  14213         m_ctx.setCurrentTracker( this );
  14214     }
  14215 
  14216     SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
  14217     :   TrackerBase( nameAndLocation, ctx, parent ),
  14218         m_trimmed_name(trim(nameAndLocation.name))
  14219     {
  14220         if( parent ) {
  14221             while( !parent->isSectionTracker() )
  14222                 parent = &parent->parent();
  14223 
  14224             SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
  14225             addNextFilters( parentSection.m_filters );
  14226         }
  14227     }
  14228 
  14229     bool SectionTracker::isComplete() const {
  14230         bool complete = true;
  14231 
  14232         if ((m_filters.empty() || m_filters[0] == "")
  14233             || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
  14234             complete = TrackerBase::isComplete();
  14235         }
  14236         return complete;
  14237     }
  14238 
  14239     bool SectionTracker::isSectionTracker() const { return true; }
  14240 
  14241     SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
  14242         std::shared_ptr<SectionTracker> section;
  14243 
  14244         ITracker& currentTracker = ctx.currentTracker();
  14245         if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
  14246             assert( childTracker );
  14247             assert( childTracker->isSectionTracker() );
  14248             section = std::static_pointer_cast<SectionTracker>( childTracker );
  14249         }
  14250         else {
  14251             section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
  14252             currentTracker.addChild( section );
  14253         }
  14254         if( !ctx.completedCycle() )
  14255             section->tryOpen();
  14256         return *section;
  14257     }
  14258 
  14259     void SectionTracker::tryOpen() {
  14260         if( !isComplete() )
  14261             open();
  14262     }
  14263 
  14264     void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
  14265         if( !filters.empty() ) {
  14266             m_filters.reserve( m_filters.size() + filters.size() + 2 );
  14267             m_filters.push_back(""); // Root - should never be consulted
  14268             m_filters.push_back(""); // Test Case - not a section filter
  14269             m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
  14270         }
  14271     }
  14272     void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
  14273         if( filters.size() > 1 )
  14274             m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
  14275     }
  14276 
  14277 } // namespace TestCaseTracking
  14278 
  14279 using TestCaseTracking::ITracker;
  14280 using TestCaseTracking::TrackerContext;
  14281 using TestCaseTracking::SectionTracker;
  14282 
  14283 } // namespace Catch
  14284 
  14285 #if defined(__clang__)
  14286 #    pragma clang diagnostic pop
  14287 #endif
  14288 // end catch_test_case_tracker.cpp
  14289 // start catch_test_registry.cpp
  14290 
  14291 namespace Catch {
  14292 
  14293     auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
  14294         return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
  14295     }
  14296 
  14297     NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
  14298 
  14299     AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
  14300         CATCH_TRY {
  14301             getMutableRegistryHub()
  14302                     .registerTest(
  14303                         makeTestCase(
  14304                             invoker,
  14305                             extractClassName( classOrMethod ),
  14306                             nameAndTags,
  14307                             lineInfo));
  14308         } CATCH_CATCH_ALL {
  14309             // Do not throw when constructing global objects, instead register the exception to be processed later
  14310             getMutableRegistryHub().registerStartupException();
  14311         }
  14312     }
  14313 
  14314     AutoReg::~AutoReg() = default;
  14315 }
  14316 // end catch_test_registry.cpp
  14317 // start catch_test_spec.cpp
  14318 
  14319 #include <algorithm>
  14320 #include <string>
  14321 #include <vector>
  14322 #include <memory>
  14323 
  14324 namespace Catch {
  14325 
  14326     TestSpec::Pattern::Pattern( std::string const& name )
  14327     : m_name( name )
  14328     {}
  14329 
  14330     TestSpec::Pattern::~Pattern() = default;
  14331 
  14332     std::string const& TestSpec::Pattern::name() const {
  14333         return m_name;
  14334     }
  14335 
  14336     TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )
  14337     : Pattern( filterString )
  14338     , m_wildcardPattern( toLower( name ), CaseSensitive::No )
  14339     {}
  14340 
  14341     bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
  14342         return m_wildcardPattern.matches( testCase.name );
  14343     }
  14344 
  14345     TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
  14346     : Pattern( filterString )
  14347     , m_tag( toLower( tag ) )
  14348     {}
  14349 
  14350     bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
  14351         return std::find(begin(testCase.lcaseTags),
  14352                          end(testCase.lcaseTags),
  14353                          m_tag) != end(testCase.lcaseTags);
  14354     }
  14355 
  14356     TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )
  14357     : Pattern( underlyingPattern->name() )
  14358     , m_underlyingPattern( underlyingPattern )
  14359     {}
  14360 
  14361     bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {
  14362         return !m_underlyingPattern->matches( testCase );
  14363     }
  14364 
  14365     bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
  14366         return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );
  14367     }
  14368 
  14369     std::string TestSpec::Filter::name() const {
  14370         std::string name;
  14371         for( auto const& p : m_patterns )
  14372             name += p->name();
  14373         return name;
  14374     }
  14375 
  14376     bool TestSpec::hasFilters() const {
  14377         return !m_filters.empty();
  14378     }
  14379 
  14380     bool TestSpec::matches( TestCaseInfo const& testCase ) const {
  14381         return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
  14382     }
  14383 
  14384     TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const
  14385     {
  14386         Matches matches( m_filters.size() );
  14387         std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
  14388             std::vector<TestCase const*> currentMatches;
  14389             for( auto const& test : testCases )
  14390                 if( isThrowSafe( test, config ) && filter.matches( test ) )
  14391                     currentMatches.emplace_back( &test );
  14392             return FilterMatch{ filter.name(), currentMatches };
  14393         } );
  14394         return matches;
  14395     }
  14396 
  14397     const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{
  14398         return  (m_invalidArgs);
  14399     }
  14400 
  14401 }
  14402 // end catch_test_spec.cpp
  14403 // start catch_test_spec_parser.cpp
  14404 
  14405 namespace Catch {
  14406 
  14407     TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
  14408 
  14409     TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
  14410         m_mode = None;
  14411         m_exclusion = false;
  14412         m_arg = m_tagAliases->expandAliases( arg );
  14413         m_escapeChars.clear();
  14414         m_substring.reserve(m_arg.size());
  14415         m_patternName.reserve(m_arg.size());
  14416         m_realPatternPos = 0;
  14417 
  14418         for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
  14419           //if visitChar fails
  14420            if( !visitChar( m_arg[m_pos] ) ){
  14421                m_testSpec.m_invalidArgs.push_back(arg);
  14422                break;
  14423            }
  14424         endMode();
  14425         return *this;
  14426     }
  14427     TestSpec TestSpecParser::testSpec() {
  14428         addFilter();
  14429         return m_testSpec;
  14430     }
  14431     bool TestSpecParser::visitChar( char c ) {
  14432         if( (m_mode != EscapedName) && (c == '\\') ) {
  14433             escape();
  14434             addCharToPattern(c);
  14435             return true;
  14436         }else if((m_mode != EscapedName) && (c == ',') )  {
  14437             return separate();
  14438         }
  14439 
  14440         switch( m_mode ) {
  14441         case None:
  14442             if( processNoneChar( c ) )
  14443                 return true;
  14444             break;
  14445         case Name:
  14446             processNameChar( c );
  14447             break;
  14448         case EscapedName:
  14449             endMode();
  14450             addCharToPattern(c);
  14451             return true;
  14452         default:
  14453         case Tag:
  14454         case QuotedName:
  14455             if( processOtherChar( c ) )
  14456                 return true;
  14457             break;
  14458         }
  14459 
  14460         m_substring += c;
  14461         if( !isControlChar( c ) ) {
  14462             m_patternName += c;
  14463             m_realPatternPos++;
  14464         }
  14465         return true;
  14466     }
  14467     // Two of the processing methods return true to signal the caller to return
  14468     // without adding the given character to the current pattern strings
  14469     bool TestSpecParser::processNoneChar( char c ) {
  14470         switch( c ) {
  14471         case ' ':
  14472             return true;
  14473         case '~':
  14474             m_exclusion = true;
  14475             return false;
  14476         case '[':
  14477             startNewMode( Tag );
  14478             return false;
  14479         case '"':
  14480             startNewMode( QuotedName );
  14481             return false;
  14482         default:
  14483             startNewMode( Name );
  14484             return false;
  14485         }
  14486     }
  14487     void TestSpecParser::processNameChar( char c ) {
  14488         if( c == '[' ) {
  14489             if( m_substring == "exclude:" )
  14490                 m_exclusion = true;
  14491             else
  14492                 endMode();
  14493             startNewMode( Tag );
  14494         }
  14495     }
  14496     bool TestSpecParser::processOtherChar( char c ) {
  14497         if( !isControlChar( c ) )
  14498             return false;
  14499         m_substring += c;
  14500         endMode();
  14501         return true;
  14502     }
  14503     void TestSpecParser::startNewMode( Mode mode ) {
  14504         m_mode = mode;
  14505     }
  14506     void TestSpecParser::endMode() {
  14507         switch( m_mode ) {
  14508         case Name:
  14509         case QuotedName:
  14510             return addNamePattern();
  14511         case Tag:
  14512             return addTagPattern();
  14513         case EscapedName:
  14514             revertBackToLastMode();
  14515             return;
  14516         case None:
  14517         default:
  14518             return startNewMode( None );
  14519         }
  14520     }
  14521     void TestSpecParser::escape() {
  14522         saveLastMode();
  14523         m_mode = EscapedName;
  14524         m_escapeChars.push_back(m_realPatternPos);
  14525     }
  14526     bool TestSpecParser::isControlChar( char c ) const {
  14527         switch( m_mode ) {
  14528             default:
  14529                 return false;
  14530             case None:
  14531                 return c == '~';
  14532             case Name:
  14533                 return c == '[';
  14534             case EscapedName:
  14535                 return true;
  14536             case QuotedName:
  14537                 return c == '"';
  14538             case Tag:
  14539                 return c == '[' || c == ']';
  14540         }
  14541     }
  14542 
  14543     void TestSpecParser::addFilter() {
  14544         if( !m_currentFilter.m_patterns.empty() ) {
  14545             m_testSpec.m_filters.push_back( m_currentFilter );
  14546             m_currentFilter = TestSpec::Filter();
  14547         }
  14548     }
  14549 
  14550     void TestSpecParser::saveLastMode() {
  14551       lastMode = m_mode;
  14552     }
  14553 
  14554     void TestSpecParser::revertBackToLastMode() {
  14555       m_mode = lastMode;
  14556     }
  14557 
  14558     bool TestSpecParser::separate() {
  14559       if( (m_mode==QuotedName) || (m_mode==Tag) ){
  14560          //invalid argument, signal failure to previous scope.
  14561          m_mode = None;
  14562          m_pos = m_arg.size();
  14563          m_substring.clear();
  14564          m_patternName.clear();
  14565          return false;
  14566       }
  14567       endMode();
  14568       addFilter();
  14569       return true; //success
  14570     }
  14571 
  14572     std::string TestSpecParser::preprocessPattern() {
  14573         std::string token = m_patternName;
  14574         for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
  14575             token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);
  14576         m_escapeChars.clear();
  14577         if (startsWith(token, "exclude:")) {
  14578             m_exclusion = true;
  14579             token = token.substr(8);
  14580         }
  14581 
  14582         m_patternName.clear();
  14583 
  14584         return token;
  14585     }
  14586 
  14587     void TestSpecParser::addNamePattern() {
  14588         auto token = preprocessPattern();
  14589 
  14590         if (!token.empty()) {
  14591             TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);
  14592             if (m_exclusion)
  14593                 pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
  14594             m_currentFilter.m_patterns.push_back(pattern);
  14595         }
  14596         m_substring.clear();
  14597         m_exclusion = false;
  14598         m_mode = None;
  14599     }
  14600 
  14601     void TestSpecParser::addTagPattern() {
  14602         auto token = preprocessPattern();
  14603 
  14604         if (!token.empty()) {
  14605             // If the tag pattern is the "hide and tag" shorthand (e.g. [.foo])
  14606             // we have to create a separate hide tag and shorten the real one
  14607             if (token.size() > 1 && token[0] == '.') {
  14608                 token.erase(token.begin());
  14609                 TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring);
  14610                 if (m_exclusion) {
  14611                     pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
  14612                 }
  14613                 m_currentFilter.m_patterns.push_back(pattern);
  14614             }
  14615 
  14616             TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);
  14617 
  14618             if (m_exclusion) {
  14619                 pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
  14620             }
  14621             m_currentFilter.m_patterns.push_back(pattern);
  14622         }
  14623         m_substring.clear();
  14624         m_exclusion = false;
  14625         m_mode = None;
  14626     }
  14627 
  14628     TestSpec parseTestSpec( std::string const& arg ) {
  14629         return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
  14630     }
  14631 
  14632 } // namespace Catch
  14633 // end catch_test_spec_parser.cpp
  14634 // start catch_timer.cpp
  14635 
  14636 #include <chrono>
  14637 
  14638 static const uint64_t nanosecondsInSecond = 1000000000;
  14639 
  14640 namespace Catch {
  14641 
  14642     auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
  14643         return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
  14644     }
  14645 
  14646     namespace {
  14647         auto estimateClockResolution() -> uint64_t {
  14648             uint64_t sum = 0;
  14649             static const uint64_t iterations = 1000000;
  14650 
  14651             auto startTime = getCurrentNanosecondsSinceEpoch();
  14652 
  14653             for( std::size_t i = 0; i < iterations; ++i ) {
  14654 
  14655                 uint64_t ticks;
  14656                 uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
  14657                 do {
  14658                     ticks = getCurrentNanosecondsSinceEpoch();
  14659                 } while( ticks == baseTicks );
  14660 
  14661                 auto delta = ticks - baseTicks;
  14662                 sum += delta;
  14663 
  14664                 // If we have been calibrating for over 3 seconds -- the clock
  14665                 // is terrible and we should move on.
  14666                 // TBD: How to signal that the measured resolution is probably wrong?
  14667                 if (ticks > startTime + 3 * nanosecondsInSecond) {
  14668                     return sum / ( i + 1u );
  14669                 }
  14670             }
  14671 
  14672             // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
  14673             // - and potentially do more iterations if there's a high variance.
  14674             return sum/iterations;
  14675         }
  14676     }
  14677     auto getEstimatedClockResolution() -> uint64_t {
  14678         static auto s_resolution = estimateClockResolution();
  14679         return s_resolution;
  14680     }
  14681 
  14682     void Timer::start() {
  14683        m_nanoseconds = getCurrentNanosecondsSinceEpoch();
  14684     }
  14685     auto Timer::getElapsedNanoseconds() const -> uint64_t {
  14686         return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
  14687     }
  14688     auto Timer::getElapsedMicroseconds() const -> uint64_t {
  14689         return getElapsedNanoseconds()/1000;
  14690     }
  14691     auto Timer::getElapsedMilliseconds() const -> unsigned int {
  14692         return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
  14693     }
  14694     auto Timer::getElapsedSeconds() const -> double {
  14695         return getElapsedMicroseconds()/1000000.0;
  14696     }
  14697 
  14698 } // namespace Catch
  14699 // end catch_timer.cpp
  14700 // start catch_tostring.cpp
  14701 
  14702 #if defined(__clang__)
  14703 #    pragma clang diagnostic push
  14704 #    pragma clang diagnostic ignored "-Wexit-time-destructors"
  14705 #    pragma clang diagnostic ignored "-Wglobal-constructors"
  14706 #endif
  14707 
  14708 // Enable specific decls locally
  14709 #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  14710 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  14711 #endif
  14712 
  14713 #include <cmath>
  14714 #include <iomanip>
  14715 
  14716 namespace Catch {
  14717 
  14718 namespace Detail {
  14719 
  14720     const std::string unprintableString = "{?}";
  14721 
  14722     namespace {
  14723         const int hexThreshold = 255;
  14724 
  14725         struct Endianness {
  14726             enum Arch { Big, Little };
  14727 
  14728             static Arch which() {
  14729                 int one = 1;
  14730                 // If the lowest byte we read is non-zero, we can assume
  14731                 // that little endian format is used.
  14732                 auto value = *reinterpret_cast<char*>(&one);
  14733                 return value ? Little : Big;
  14734             }
  14735         };
  14736     }
  14737 
  14738     std::string rawMemoryToString( const void *object, std::size_t size ) {
  14739         // Reverse order for little endian architectures
  14740         int i = 0, end = static_cast<int>( size ), inc = 1;
  14741         if( Endianness::which() == Endianness::Little ) {
  14742             i = end-1;
  14743             end = inc = -1;
  14744         }
  14745 
  14746         unsigned char const *bytes = static_cast<unsigned char const *>(object);
  14747         ReusableStringStream rss;
  14748         rss << "0x" << std::setfill('0') << std::hex;
  14749         for( ; i != end; i += inc )
  14750              rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
  14751        return rss.str();
  14752     }
  14753 }
  14754 
  14755 template<typename T>
  14756 std::string fpToString( T value, int precision ) {
  14757     if (Catch::isnan(value)) {
  14758         return "nan";
  14759     }
  14760 
  14761     ReusableStringStream rss;
  14762     rss << std::setprecision( precision )
  14763         << std::fixed
  14764         << value;
  14765     std::string d = rss.str();
  14766     std::size_t i = d.find_last_not_of( '0' );
  14767     if( i != std::string::npos && i != d.size()-1 ) {
  14768         if( d[i] == '.' )
  14769             i++;
  14770         d = d.substr( 0, i+1 );
  14771     }
  14772     return d;
  14773 }
  14774 
  14775 //// ======================================================= ////
  14776 //
  14777 //   Out-of-line defs for full specialization of StringMaker
  14778 //
  14779 //// ======================================================= ////
  14780 
  14781 std::string StringMaker<std::string>::convert(const std::string& str) {
  14782     if (!getCurrentContext().getConfig()->showInvisibles()) {
  14783         return '"' + str + '"';
  14784     }
  14785 
  14786     std::string s("\"");
  14787     for (char c : str) {
  14788         switch (c) {
  14789         case '\n':
  14790             s.append("\\n");
  14791             break;
  14792         case '\t':
  14793             s.append("\\t");
  14794             break;
  14795         default:
  14796             s.push_back(c);
  14797             break;
  14798         }
  14799     }
  14800     s.append("\"");
  14801     return s;
  14802 }
  14803 
  14804 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  14805 std::string StringMaker<std::string_view>::convert(std::string_view str) {
  14806     return ::Catch::Detail::stringify(std::string{ str });
  14807 }
  14808 #endif
  14809 
  14810 std::string StringMaker<char const*>::convert(char const* str) {
  14811     if (str) {
  14812         return ::Catch::Detail::stringify(std::string{ str });
  14813     } else {
  14814         return{ "{null string}" };
  14815     }
  14816 }
  14817 std::string StringMaker<char*>::convert(char* str) {
  14818     if (str) {
  14819         return ::Catch::Detail::stringify(std::string{ str });
  14820     } else {
  14821         return{ "{null string}" };
  14822     }
  14823 }
  14824 
  14825 #ifdef CATCH_CONFIG_WCHAR
  14826 std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
  14827     std::string s;
  14828     s.reserve(wstr.size());
  14829     for (auto c : wstr) {
  14830         s += (c <= 0xff) ? static_cast<char>(c) : '?';
  14831     }
  14832     return ::Catch::Detail::stringify(s);
  14833 }
  14834 
  14835 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  14836 std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
  14837     return StringMaker<std::wstring>::convert(std::wstring(str));
  14838 }
  14839 # endif
  14840 
  14841 std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
  14842     if (str) {
  14843         return ::Catch::Detail::stringify(std::wstring{ str });
  14844     } else {
  14845         return{ "{null string}" };
  14846     }
  14847 }
  14848 std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
  14849     if (str) {
  14850         return ::Catch::Detail::stringify(std::wstring{ str });
  14851     } else {
  14852         return{ "{null string}" };
  14853     }
  14854 }
  14855 #endif
  14856 
  14857 #if defined(CATCH_CONFIG_CPP17_BYTE)
  14858 #include <cstddef>
  14859 std::string StringMaker<std::byte>::convert(std::byte value) {
  14860     return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
  14861 }
  14862 #endif // defined(CATCH_CONFIG_CPP17_BYTE)
  14863 
  14864 std::string StringMaker<int>::convert(int value) {
  14865     return ::Catch::Detail::stringify(static_cast<long long>(value));
  14866 }
  14867 std::string StringMaker<long>::convert(long value) {
  14868     return ::Catch::Detail::stringify(static_cast<long long>(value));
  14869 }
  14870 std::string StringMaker<long long>::convert(long long value) {
  14871     ReusableStringStream rss;
  14872     rss << value;
  14873     if (value > Detail::hexThreshold) {
  14874         rss << " (0x" << std::hex << value << ')';
  14875     }
  14876     return rss.str();
  14877 }
  14878 
  14879 std::string StringMaker<unsigned int>::convert(unsigned int value) {
  14880     return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  14881 }
  14882 std::string StringMaker<unsigned long>::convert(unsigned long value) {
  14883     return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  14884 }
  14885 std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
  14886     ReusableStringStream rss;
  14887     rss << value;
  14888     if (value > Detail::hexThreshold) {
  14889         rss << " (0x" << std::hex << value << ')';
  14890     }
  14891     return rss.str();
  14892 }
  14893 
  14894 std::string StringMaker<bool>::convert(bool b) {
  14895     return b ? "true" : "false";
  14896 }
  14897 
  14898 std::string StringMaker<signed char>::convert(signed char value) {
  14899     if (value == '\r') {
  14900         return "'\\r'";
  14901     } else if (value == '\f') {
  14902         return "'\\f'";
  14903     } else if (value == '\n') {
  14904         return "'\\n'";
  14905     } else if (value == '\t') {
  14906         return "'\\t'";
  14907     } else if ('\0' <= value && value < ' ') {
  14908         return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
  14909     } else {
  14910         char chstr[] = "' '";
  14911         chstr[1] = value;
  14912         return chstr;
  14913     }
  14914 }
  14915 std::string StringMaker<char>::convert(char c) {
  14916     return ::Catch::Detail::stringify(static_cast<signed char>(c));
  14917 }
  14918 std::string StringMaker<unsigned char>::convert(unsigned char c) {
  14919     return ::Catch::Detail::stringify(static_cast<char>(c));
  14920 }
  14921 
  14922 std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
  14923     return "nullptr";
  14924 }
  14925 
  14926 int StringMaker<float>::precision = 5;
  14927 
  14928 std::string StringMaker<float>::convert(float value) {
  14929     return fpToString(value, precision) + 'f';
  14930 }
  14931 
  14932 int StringMaker<double>::precision = 10;
  14933 
  14934 std::string StringMaker<double>::convert(double value) {
  14935     return fpToString(value, precision);
  14936 }
  14937 
  14938 std::string ratio_string<std::atto>::symbol() { return "a"; }
  14939 std::string ratio_string<std::femto>::symbol() { return "f"; }
  14940 std::string ratio_string<std::pico>::symbol() { return "p"; }
  14941 std::string ratio_string<std::nano>::symbol() { return "n"; }
  14942 std::string ratio_string<std::micro>::symbol() { return "u"; }
  14943 std::string ratio_string<std::milli>::symbol() { return "m"; }
  14944 
  14945 } // end namespace Catch
  14946 
  14947 #if defined(__clang__)
  14948 #    pragma clang diagnostic pop
  14949 #endif
  14950 
  14951 // end catch_tostring.cpp
  14952 // start catch_totals.cpp
  14953 
  14954 namespace Catch {
  14955 
  14956     Counts Counts::operator - ( Counts const& other ) const {
  14957         Counts diff;
  14958         diff.passed = passed - other.passed;
  14959         diff.failed = failed - other.failed;
  14960         diff.failedButOk = failedButOk - other.failedButOk;
  14961         return diff;
  14962     }
  14963 
  14964     Counts& Counts::operator += ( Counts const& other ) {
  14965         passed += other.passed;
  14966         failed += other.failed;
  14967         failedButOk += other.failedButOk;
  14968         return *this;
  14969     }
  14970 
  14971     std::size_t Counts::total() const {
  14972         return passed + failed + failedButOk;
  14973     }
  14974     bool Counts::allPassed() const {
  14975         return failed == 0 && failedButOk == 0;
  14976     }
  14977     bool Counts::allOk() const {
  14978         return failed == 0;
  14979     }
  14980 
  14981     Totals Totals::operator - ( Totals const& other ) const {
  14982         Totals diff;
  14983         diff.assertions = assertions - other.assertions;
  14984         diff.testCases = testCases - other.testCases;
  14985         return diff;
  14986     }
  14987 
  14988     Totals& Totals::operator += ( Totals const& other ) {
  14989         assertions += other.assertions;
  14990         testCases += other.testCases;
  14991         return *this;
  14992     }
  14993 
  14994     Totals Totals::delta( Totals const& prevTotals ) const {
  14995         Totals diff = *this - prevTotals;
  14996         if( diff.assertions.failed > 0 )
  14997             ++diff.testCases.failed;
  14998         else if( diff.assertions.failedButOk > 0 )
  14999             ++diff.testCases.failedButOk;
  15000         else
  15001             ++diff.testCases.passed;
  15002         return diff;
  15003     }
  15004 
  15005 }
  15006 // end catch_totals.cpp
  15007 // start catch_uncaught_exceptions.cpp
  15008 
  15009 #include <exception>
  15010 
  15011 namespace Catch {
  15012     bool uncaught_exceptions() {
  15013 #if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
  15014         return std::uncaught_exceptions() > 0;
  15015 #else
  15016         return std::uncaught_exception();
  15017 #endif
  15018   }
  15019 } // end namespace Catch
  15020 // end catch_uncaught_exceptions.cpp
  15021 // start catch_version.cpp
  15022 
  15023 #include <ostream>
  15024 
  15025 namespace Catch {
  15026 
  15027     Version::Version
  15028         (   unsigned int _majorVersion,
  15029             unsigned int _minorVersion,
  15030             unsigned int _patchNumber,
  15031             char const * const _branchName,
  15032             unsigned int _buildNumber )
  15033     :   majorVersion( _majorVersion ),
  15034         minorVersion( _minorVersion ),
  15035         patchNumber( _patchNumber ),
  15036         branchName( _branchName ),
  15037         buildNumber( _buildNumber )
  15038     {}
  15039 
  15040     std::ostream& operator << ( std::ostream& os, Version const& version ) {
  15041         os  << version.majorVersion << '.'
  15042             << version.minorVersion << '.'
  15043             << version.patchNumber;
  15044         // branchName is never null -> 0th char is \0 if it is empty
  15045         if (version.branchName[0]) {
  15046             os << '-' << version.branchName
  15047                << '.' << version.buildNumber;
  15048         }
  15049         return os;
  15050     }
  15051 
  15052     Version const& libraryVersion() {
  15053         static Version version( 2, 11, 0, "", 0 );
  15054         return version;
  15055     }
  15056 
  15057 }
  15058 // end catch_version.cpp
  15059 // start catch_wildcard_pattern.cpp
  15060 
  15061 namespace Catch {
  15062 
  15063     WildcardPattern::WildcardPattern( std::string const& pattern,
  15064                                       CaseSensitive::Choice caseSensitivity )
  15065     :   m_caseSensitivity( caseSensitivity ),
  15066         m_pattern( normaliseString( pattern ) )
  15067     {
  15068         if( startsWith( m_pattern, '*' ) ) {
  15069             m_pattern = m_pattern.substr( 1 );
  15070             m_wildcard = WildcardAtStart;
  15071         }
  15072         if( endsWith( m_pattern, '*' ) ) {
  15073             m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
  15074             m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
  15075         }
  15076     }
  15077 
  15078     bool WildcardPattern::matches( std::string const& str ) const {
  15079         switch( m_wildcard ) {
  15080             case NoWildcard:
  15081                 return m_pattern == normaliseString( str );
  15082             case WildcardAtStart:
  15083                 return endsWith( normaliseString( str ), m_pattern );
  15084             case WildcardAtEnd:
  15085                 return startsWith( normaliseString( str ), m_pattern );
  15086             case WildcardAtBothEnds:
  15087                 return contains( normaliseString( str ), m_pattern );
  15088             default:
  15089                 CATCH_INTERNAL_ERROR( "Unknown enum" );
  15090         }
  15091     }
  15092 
  15093     std::string WildcardPattern::normaliseString( std::string const& str ) const {
  15094         return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );
  15095     }
  15096 }
  15097 // end catch_wildcard_pattern.cpp
  15098 // start catch_xmlwriter.cpp
  15099 
  15100 #include <iomanip>
  15101 #include <type_traits>
  15102 
  15103 using uchar = unsigned char;
  15104 
  15105 namespace Catch {
  15106 
  15107 namespace {
  15108 
  15109     size_t trailingBytes(unsigned char c) {
  15110         if ((c & 0xE0) == 0xC0) {
  15111             return 2;
  15112         }
  15113         if ((c & 0xF0) == 0xE0) {
  15114             return 3;
  15115         }
  15116         if ((c & 0xF8) == 0xF0) {
  15117             return 4;
  15118         }
  15119         CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  15120     }
  15121 
  15122     uint32_t headerValue(unsigned char c) {
  15123         if ((c & 0xE0) == 0xC0) {
  15124             return c & 0x1F;
  15125         }
  15126         if ((c & 0xF0) == 0xE0) {
  15127             return c & 0x0F;
  15128         }
  15129         if ((c & 0xF8) == 0xF0) {
  15130             return c & 0x07;
  15131         }
  15132         CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  15133     }
  15134 
  15135     void hexEscapeChar(std::ostream& os, unsigned char c) {
  15136         std::ios_base::fmtflags f(os.flags());
  15137         os << "\\x"
  15138             << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
  15139             << static_cast<int>(c);
  15140         os.flags(f);
  15141     }
  15142 
  15143     bool shouldNewline(XmlFormatting fmt) {
  15144         return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));
  15145     }
  15146 
  15147     bool shouldIndent(XmlFormatting fmt) {
  15148         return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));
  15149     }
  15150 
  15151 } // anonymous namespace
  15152 
  15153     XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) {
  15154         return static_cast<XmlFormatting>(
  15155             static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |
  15156             static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
  15157         );
  15158     }
  15159 
  15160     XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) {
  15161         return static_cast<XmlFormatting>(
  15162             static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &
  15163             static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
  15164         );
  15165     }
  15166 
  15167     XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
  15168     :   m_str( str ),
  15169         m_forWhat( forWhat )
  15170     {}
  15171 
  15172     void XmlEncode::encodeTo( std::ostream& os ) const {
  15173         // Apostrophe escaping not necessary if we always use " to write attributes
  15174         // (see: http://www.w3.org/TR/xml/#syntax)
  15175 
  15176         for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
  15177             uchar c = m_str[idx];
  15178             switch (c) {
  15179             case '<':   os << "&lt;"; break;
  15180             case '&':   os << "&amp;"; break;
  15181 
  15182             case '>':
  15183                 // See: http://www.w3.org/TR/xml/#syntax
  15184                 if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
  15185                     os << "&gt;";
  15186                 else
  15187                     os << c;
  15188                 break;
  15189 
  15190             case '\"':
  15191                 if (m_forWhat == ForAttributes)
  15192                     os << "&quot;";
  15193                 else
  15194                     os << c;
  15195                 break;
  15196 
  15197             default:
  15198                 // Check for control characters and invalid utf-8
  15199 
  15200                 // Escape control characters in standard ascii
  15201                 // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
  15202                 if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
  15203                     hexEscapeChar(os, c);
  15204                     break;
  15205                 }
  15206 
  15207                 // Plain ASCII: Write it to stream
  15208                 if (c < 0x7F) {
  15209                     os << c;
  15210                     break;
  15211                 }
  15212 
  15213                 // UTF-8 territory
  15214                 // Check if the encoding is valid and if it is not, hex escape bytes.
  15215                 // Important: We do not check the exact decoded values for validity, only the encoding format
  15216                 // First check that this bytes is a valid lead byte:
  15217                 // This means that it is not encoded as 1111 1XXX
  15218                 // Or as 10XX XXXX
  15219                 if (c <  0xC0 ||
  15220                     c >= 0xF8) {
  15221                     hexEscapeChar(os, c);
  15222                     break;
  15223                 }
  15224 
  15225                 auto encBytes = trailingBytes(c);
  15226                 // Are there enough bytes left to avoid accessing out-of-bounds memory?
  15227                 if (idx + encBytes - 1 >= m_str.size()) {
  15228                     hexEscapeChar(os, c);
  15229                     break;
  15230                 }
  15231                 // The header is valid, check data
  15232                 // The next encBytes bytes must together be a valid utf-8
  15233                 // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
  15234                 bool valid = true;
  15235                 uint32_t value = headerValue(c);
  15236                 for (std::size_t n = 1; n < encBytes; ++n) {
  15237                     uchar nc = m_str[idx + n];
  15238                     valid &= ((nc & 0xC0) == 0x80);
  15239                     value = (value << 6) | (nc & 0x3F);
  15240                 }
  15241 
  15242                 if (
  15243                     // Wrong bit pattern of following bytes
  15244                     (!valid) ||
  15245                     // Overlong encodings
  15246                     (value < 0x80) ||
  15247                     (0x80 <= value && value < 0x800   && encBytes > 2) ||
  15248                     (0x800 < value && value < 0x10000 && encBytes > 3) ||
  15249                     // Encoded value out of range
  15250                     (value >= 0x110000)
  15251                     ) {
  15252                     hexEscapeChar(os, c);
  15253                     break;
  15254                 }
  15255 
  15256                 // If we got here, this is in fact a valid(ish) utf-8 sequence
  15257                 for (std::size_t n = 0; n < encBytes; ++n) {
  15258                     os << m_str[idx + n];
  15259                 }
  15260                 idx += encBytes - 1;
  15261                 break;
  15262             }
  15263         }
  15264     }
  15265 
  15266     std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
  15267         xmlEncode.encodeTo( os );
  15268         return os;
  15269     }
  15270 
  15271     XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt )
  15272     :   m_writer( writer ),
  15273         m_fmt(fmt)
  15274     {}
  15275 
  15276     XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
  15277     :   m_writer( other.m_writer ),
  15278         m_fmt(other.m_fmt)
  15279     {
  15280         other.m_writer = nullptr;
  15281         other.m_fmt = XmlFormatting::None;
  15282     }
  15283     XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
  15284         if ( m_writer ) {
  15285             m_writer->endElement();
  15286         }
  15287         m_writer = other.m_writer;
  15288         other.m_writer = nullptr;
  15289         m_fmt = other.m_fmt;
  15290         other.m_fmt = XmlFormatting::None;
  15291         return *this;
  15292     }
  15293 
  15294     XmlWriter::ScopedElement::~ScopedElement() {
  15295         if (m_writer) {
  15296             m_writer->endElement(m_fmt);
  15297         }
  15298     }
  15299 
  15300     XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) {
  15301         m_writer->writeText( text, fmt );
  15302         return *this;
  15303     }
  15304 
  15305     XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
  15306     {
  15307         writeDeclaration();
  15308     }
  15309 
  15310     XmlWriter::~XmlWriter() {
  15311         while (!m_tags.empty()) {
  15312             endElement();
  15313         }
  15314         newlineIfNecessary();
  15315     }
  15316 
  15317     XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) {
  15318         ensureTagClosed();
  15319         newlineIfNecessary();
  15320         if (shouldIndent(fmt)) {
  15321             m_os << m_indent;
  15322             m_indent += "  ";
  15323         }
  15324         m_os << '<' << name;
  15325         m_tags.push_back( name );
  15326         m_tagIsOpen = true;
  15327         applyFormatting(fmt);
  15328         return *this;
  15329     }
  15330 
  15331     XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) {
  15332         ScopedElement scoped( this, fmt );
  15333         startElement( name, fmt );
  15334         return scoped;
  15335     }
  15336 
  15337     XmlWriter& XmlWriter::endElement(XmlFormatting fmt) {
  15338         m_indent = m_indent.substr(0, m_indent.size() - 2);
  15339 
  15340         if( m_tagIsOpen ) {
  15341             m_os << "/>";
  15342             m_tagIsOpen = false;
  15343         } else {
  15344             newlineIfNecessary();
  15345             if (shouldIndent(fmt)) {
  15346                 m_os << m_indent;
  15347             }
  15348             m_os << "</" << m_tags.back() << ">";
  15349         }
  15350         m_os << std::flush;
  15351         applyFormatting(fmt);
  15352         m_tags.pop_back();
  15353         return *this;
  15354     }
  15355 
  15356     XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
  15357         if( !name.empty() && !attribute.empty() )
  15358             m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
  15359         return *this;
  15360     }
  15361 
  15362     XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
  15363         m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
  15364         return *this;
  15365     }
  15366 
  15367     XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) {
  15368         if( !text.empty() ){
  15369             bool tagWasOpen = m_tagIsOpen;
  15370             ensureTagClosed();
  15371             if (tagWasOpen && shouldIndent(fmt)) {
  15372                 m_os << m_indent;
  15373             }
  15374             m_os << XmlEncode( text );
  15375             applyFormatting(fmt);
  15376         }
  15377         return *this;
  15378     }
  15379 
  15380     XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) {
  15381         ensureTagClosed();
  15382         if (shouldIndent(fmt)) {
  15383             m_os << m_indent;
  15384         }
  15385         m_os << "<!--" << text << "-->";
  15386         applyFormatting(fmt);
  15387         return *this;
  15388     }
  15389 
  15390     void XmlWriter::writeStylesheetRef( std::string const& url ) {
  15391         m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
  15392     }
  15393 
  15394     XmlWriter& XmlWriter::writeBlankLine() {
  15395         ensureTagClosed();
  15396         m_os << '\n';
  15397         return *this;
  15398     }
  15399 
  15400     void XmlWriter::ensureTagClosed() {
  15401         if( m_tagIsOpen ) {
  15402             m_os << '>' << std::flush;
  15403             newlineIfNecessary();
  15404             m_tagIsOpen = false;
  15405         }
  15406     }
  15407 
  15408     void XmlWriter::applyFormatting(XmlFormatting fmt) {
  15409         m_needsNewline = shouldNewline(fmt);
  15410     }
  15411 
  15412     void XmlWriter::writeDeclaration() {
  15413         m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  15414     }
  15415 
  15416     void XmlWriter::newlineIfNecessary() {
  15417         if( m_needsNewline ) {
  15418             m_os << std::endl;
  15419             m_needsNewline = false;
  15420         }
  15421     }
  15422 }
  15423 // end catch_xmlwriter.cpp
  15424 // start catch_reporter_bases.cpp
  15425 
  15426 #include <cstring>
  15427 #include <cfloat>
  15428 #include <cstdio>
  15429 #include <cassert>
  15430 #include <memory>
  15431 
  15432 namespace Catch {
  15433     void prepareExpandedExpression(AssertionResult& result) {
  15434         result.getExpandedExpression();
  15435     }
  15436 
  15437     // Because formatting using c++ streams is stateful, drop down to C is required
  15438     // Alternatively we could use stringstream, but its performance is... not good.
  15439     std::string getFormattedDuration( double duration ) {
  15440         // Max exponent + 1 is required to represent the whole part
  15441         // + 1 for decimal point
  15442         // + 3 for the 3 decimal places
  15443         // + 1 for null terminator
  15444         const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
  15445         char buffer[maxDoubleSize];
  15446 
  15447         // Save previous errno, to prevent sprintf from overwriting it
  15448         ErrnoGuard guard;
  15449 #ifdef _MSC_VER
  15450         sprintf_s(buffer, "%.3f", duration);
  15451 #else
  15452         std::sprintf(buffer, "%.3f", duration);
  15453 #endif
  15454         return std::string(buffer);
  15455     }
  15456 
  15457     std::string serializeFilters( std::vector<std::string> const& container ) {
  15458         ReusableStringStream oss;
  15459         bool first = true;
  15460         for (auto&& filter : container)
  15461         {
  15462             if (!first)
  15463                 oss << ' ';
  15464             else
  15465                 first = false;
  15466 
  15467             oss << filter;
  15468         }
  15469         return oss.str();
  15470     }
  15471 
  15472     TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
  15473         :StreamingReporterBase(_config) {}
  15474 
  15475     std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
  15476         return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };
  15477     }
  15478 
  15479     void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
  15480 
  15481     bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
  15482         return false;
  15483     }
  15484 
  15485 } // end namespace Catch
  15486 // end catch_reporter_bases.cpp
  15487 // start catch_reporter_compact.cpp
  15488 
  15489 namespace {
  15490 
  15491 #ifdef CATCH_PLATFORM_MAC
  15492     const char* failedString() { return "FAILED"; }
  15493     const char* passedString() { return "PASSED"; }
  15494 #else
  15495     const char* failedString() { return "failed"; }
  15496     const char* passedString() { return "passed"; }
  15497 #endif
  15498 
  15499     // Colour::LightGrey
  15500     Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
  15501 
  15502     std::string bothOrAll( std::size_t count ) {
  15503         return count == 1 ? std::string() :
  15504                count == 2 ? "both " : "all " ;
  15505     }
  15506 
  15507 } // anon namespace
  15508 
  15509 namespace Catch {
  15510 namespace {
  15511 // Colour, message variants:
  15512 // - white: No tests ran.
  15513 // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
  15514 // - white: Passed [both/all] N test cases (no assertions).
  15515 // -   red: Failed N tests cases, failed M assertions.
  15516 // - green: Passed [both/all] N tests cases with M assertions.
  15517 void printTotals(std::ostream& out, const Totals& totals) {
  15518     if (totals.testCases.total() == 0) {
  15519         out << "No tests ran.";
  15520     } else if (totals.testCases.failed == totals.testCases.total()) {
  15521         Colour colour(Colour::ResultError);
  15522         const std::string qualify_assertions_failed =
  15523             totals.assertions.failed == totals.assertions.total() ?
  15524             bothOrAll(totals.assertions.failed) : std::string();
  15525         out <<
  15526             "Failed " << bothOrAll(totals.testCases.failed)
  15527             << pluralise(totals.testCases.failed, "test case") << ", "
  15528             "failed " << qualify_assertions_failed <<
  15529             pluralise(totals.assertions.failed, "assertion") << '.';
  15530     } else if (totals.assertions.total() == 0) {
  15531         out <<
  15532             "Passed " << bothOrAll(totals.testCases.total())
  15533             << pluralise(totals.testCases.total(), "test case")
  15534             << " (no assertions).";
  15535     } else if (totals.assertions.failed) {
  15536         Colour colour(Colour::ResultError);
  15537         out <<
  15538             "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
  15539             "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
  15540     } else {
  15541         Colour colour(Colour::ResultSuccess);
  15542         out <<
  15543             "Passed " << bothOrAll(totals.testCases.passed)
  15544             << pluralise(totals.testCases.passed, "test case") <<
  15545             " with " << pluralise(totals.assertions.passed, "assertion") << '.';
  15546     }
  15547 }
  15548 
  15549 // Implementation of CompactReporter formatting
  15550 class AssertionPrinter {
  15551 public:
  15552     AssertionPrinter& operator= (AssertionPrinter const&) = delete;
  15553     AssertionPrinter(AssertionPrinter const&) = delete;
  15554     AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
  15555         : stream(_stream)
  15556         , result(_stats.assertionResult)
  15557         , messages(_stats.infoMessages)
  15558         , itMessage(_stats.infoMessages.begin())
  15559         , printInfoMessages(_printInfoMessages) {}
  15560 
  15561     void print() {
  15562         printSourceInfo();
  15563 
  15564         itMessage = messages.begin();
  15565 
  15566         switch (result.getResultType()) {
  15567         case ResultWas::Ok:
  15568             printResultType(Colour::ResultSuccess, passedString());
  15569             printOriginalExpression();
  15570             printReconstructedExpression();
  15571             if (!result.hasExpression())
  15572                 printRemainingMessages(Colour::None);
  15573             else
  15574                 printRemainingMessages();
  15575             break;
  15576         case ResultWas::ExpressionFailed:
  15577             if (result.isOk())
  15578                 printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
  15579             else
  15580                 printResultType(Colour::Error, failedString());
  15581             printOriginalExpression();
  15582             printReconstructedExpression();
  15583             printRemainingMessages();
  15584             break;
  15585         case ResultWas::ThrewException:
  15586             printResultType(Colour::Error, failedString());
  15587             printIssue("unexpected exception with message:");
  15588             printMessage();
  15589             printExpressionWas();
  15590             printRemainingMessages();
  15591             break;
  15592         case ResultWas::FatalErrorCondition:
  15593             printResultType(Colour::Error, failedString());
  15594             printIssue("fatal error condition with message:");
  15595             printMessage();
  15596             printExpressionWas();
  15597             printRemainingMessages();
  15598             break;
  15599         case ResultWas::DidntThrowException:
  15600             printResultType(Colour::Error, failedString());
  15601             printIssue("expected exception, got none");
  15602             printExpressionWas();
  15603             printRemainingMessages();
  15604             break;
  15605         case ResultWas::Info:
  15606             printResultType(Colour::None, "info");
  15607             printMessage();
  15608             printRemainingMessages();
  15609             break;
  15610         case ResultWas::Warning:
  15611             printResultType(Colour::None, "warning");
  15612             printMessage();
  15613             printRemainingMessages();
  15614             break;
  15615         case ResultWas::ExplicitFailure:
  15616             printResultType(Colour::Error, failedString());
  15617             printIssue("explicitly");
  15618             printRemainingMessages(Colour::None);
  15619             break;
  15620             // These cases are here to prevent compiler warnings
  15621         case ResultWas::Unknown:
  15622         case ResultWas::FailureBit:
  15623         case ResultWas::Exception:
  15624             printResultType(Colour::Error, "** internal error **");
  15625             break;
  15626         }
  15627     }
  15628 
  15629 private:
  15630     void printSourceInfo() const {
  15631         Colour colourGuard(Colour::FileName);
  15632         stream << result.getSourceInfo() << ':';
  15633     }
  15634 
  15635     void printResultType(Colour::Code colour, std::string const& passOrFail) const {
  15636         if (!passOrFail.empty()) {
  15637             {
  15638                 Colour colourGuard(colour);
  15639                 stream << ' ' << passOrFail;
  15640             }
  15641             stream << ':';
  15642         }
  15643     }
  15644 
  15645     void printIssue(std::string const& issue) const {
  15646         stream << ' ' << issue;
  15647     }
  15648 
  15649     void printExpressionWas() {
  15650         if (result.hasExpression()) {
  15651             stream << ';';
  15652             {
  15653                 Colour colour(dimColour());
  15654                 stream << " expression was:";
  15655             }
  15656             printOriginalExpression();
  15657         }
  15658     }
  15659 
  15660     void printOriginalExpression() const {
  15661         if (result.hasExpression()) {
  15662             stream << ' ' << result.getExpression();
  15663         }
  15664     }
  15665 
  15666     void printReconstructedExpression() const {
  15667         if (result.hasExpandedExpression()) {
  15668             {
  15669                 Colour colour(dimColour());
  15670                 stream << " for: ";
  15671             }
  15672             stream << result.getExpandedExpression();
  15673         }
  15674     }
  15675 
  15676     void printMessage() {
  15677         if (itMessage != messages.end()) {
  15678             stream << " '" << itMessage->message << '\'';
  15679             ++itMessage;
  15680         }
  15681     }
  15682 
  15683     void printRemainingMessages(Colour::Code colour = dimColour()) {
  15684         if (itMessage == messages.end())
  15685             return;
  15686 
  15687         const auto itEnd = messages.cend();
  15688         const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
  15689 
  15690         {
  15691             Colour colourGuard(colour);
  15692             stream << " with " << pluralise(N, "message") << ':';
  15693         }
  15694 
  15695         while (itMessage != itEnd) {
  15696             // If this assertion is a warning ignore any INFO messages
  15697             if (printInfoMessages || itMessage->type != ResultWas::Info) {
  15698                 printMessage();
  15699                 if (itMessage != itEnd) {
  15700                     Colour colourGuard(dimColour());
  15701                     stream << " and";
  15702                 }
  15703                 continue;
  15704             }
  15705             ++itMessage;
  15706         }
  15707     }
  15708 
  15709 private:
  15710     std::ostream& stream;
  15711     AssertionResult const& result;
  15712     std::vector<MessageInfo> messages;
  15713     std::vector<MessageInfo>::const_iterator itMessage;
  15714     bool printInfoMessages;
  15715 };
  15716 
  15717 } // anon namespace
  15718 
  15719         std::string CompactReporter::getDescription() {
  15720             return "Reports test results on a single line, suitable for IDEs";
  15721         }
  15722 
  15723         ReporterPreferences CompactReporter::getPreferences() const {
  15724             return m_reporterPrefs;
  15725         }
  15726 
  15727         void CompactReporter::noMatchingTestCases( std::string const& spec ) {
  15728             stream << "No test cases matched '" << spec << '\'' << std::endl;
  15729         }
  15730 
  15731         void CompactReporter::assertionStarting( AssertionInfo const& ) {}
  15732 
  15733         bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
  15734             AssertionResult const& result = _assertionStats.assertionResult;
  15735 
  15736             bool printInfoMessages = true;
  15737 
  15738             // Drop out if result was successful and we're not printing those
  15739             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
  15740                 if( result.getResultType() != ResultWas::Warning )
  15741                     return false;
  15742                 printInfoMessages = false;
  15743             }
  15744 
  15745             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
  15746             printer.print();
  15747 
  15748             stream << std::endl;
  15749             return true;
  15750         }
  15751 
  15752         void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
  15753             if (m_config->showDurations() == ShowDurations::Always) {
  15754                 stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  15755             }
  15756         }
  15757 
  15758         void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
  15759             printTotals( stream, _testRunStats.totals );
  15760             stream << '\n' << std::endl;
  15761             StreamingReporterBase::testRunEnded( _testRunStats );
  15762         }
  15763 
  15764         CompactReporter::~CompactReporter() {}
  15765 
  15766     CATCH_REGISTER_REPORTER( "compact", CompactReporter )
  15767 
  15768 } // end namespace Catch
  15769 // end catch_reporter_compact.cpp
  15770 // start catch_reporter_console.cpp
  15771 
  15772 #include <cfloat>
  15773 #include <cstdio>
  15774 
  15775 #if defined(_MSC_VER)
  15776 #pragma warning(push)
  15777 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  15778  // Note that 4062 (not all labels are handled and default is missing) is enabled
  15779 #endif
  15780 
  15781 #if defined(__clang__)
  15782 #  pragma clang diagnostic push
  15783 // For simplicity, benchmarking-only helpers are always enabled
  15784 #  pragma clang diagnostic ignored "-Wunused-function"
  15785 #endif
  15786 
  15787 namespace Catch {
  15788 
  15789 namespace {
  15790 
  15791 // Formatter impl for ConsoleReporter
  15792 class ConsoleAssertionPrinter {
  15793 public:
  15794     ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
  15795     ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
  15796     ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
  15797         : stream(_stream),
  15798         stats(_stats),
  15799         result(_stats.assertionResult),
  15800         colour(Colour::None),
  15801         message(result.getMessage()),
  15802         messages(_stats.infoMessages),
  15803         printInfoMessages(_printInfoMessages) {
  15804         switch (result.getResultType()) {
  15805         case ResultWas::Ok:
  15806             colour = Colour::Success;
  15807             passOrFail = "PASSED";
  15808             //if( result.hasMessage() )
  15809             if (_stats.infoMessages.size() == 1)
  15810                 messageLabel = "with message";
  15811             if (_stats.infoMessages.size() > 1)
  15812                 messageLabel = "with messages";
  15813             break;
  15814         case ResultWas::ExpressionFailed:
  15815             if (result.isOk()) {
  15816                 colour = Colour::Success;
  15817                 passOrFail = "FAILED - but was ok";
  15818             } else {
  15819                 colour = Colour::Error;
  15820                 passOrFail = "FAILED";
  15821             }
  15822             if (_stats.infoMessages.size() == 1)
  15823                 messageLabel = "with message";
  15824             if (_stats.infoMessages.size() > 1)
  15825                 messageLabel = "with messages";
  15826             break;
  15827         case ResultWas::ThrewException:
  15828             colour = Colour::Error;
  15829             passOrFail = "FAILED";
  15830             messageLabel = "due to unexpected exception with ";
  15831             if (_stats.infoMessages.size() == 1)
  15832                 messageLabel += "message";
  15833             if (_stats.infoMessages.size() > 1)
  15834                 messageLabel += "messages";
  15835             break;
  15836         case ResultWas::FatalErrorCondition:
  15837             colour = Colour::Error;
  15838             passOrFail = "FAILED";
  15839             messageLabel = "due to a fatal error condition";
  15840             break;
  15841         case ResultWas::DidntThrowException:
  15842             colour = Colour::Error;
  15843             passOrFail = "FAILED";
  15844             messageLabel = "because no exception was thrown where one was expected";
  15845             break;
  15846         case ResultWas::Info:
  15847             messageLabel = "info";
  15848             break;
  15849         case ResultWas::Warning:
  15850             messageLabel = "warning";
  15851             break;
  15852         case ResultWas::ExplicitFailure:
  15853             passOrFail = "FAILED";
  15854             colour = Colour::Error;
  15855             if (_stats.infoMessages.size() == 1)
  15856                 messageLabel = "explicitly with message";
  15857             if (_stats.infoMessages.size() > 1)
  15858                 messageLabel = "explicitly with messages";
  15859             break;
  15860             // These cases are here to prevent compiler warnings
  15861         case ResultWas::Unknown:
  15862         case ResultWas::FailureBit:
  15863         case ResultWas::Exception:
  15864             passOrFail = "** internal error **";
  15865             colour = Colour::Error;
  15866             break;
  15867         }
  15868     }
  15869 
  15870     void print() const {
  15871         printSourceInfo();
  15872         if (stats.totals.assertions.total() > 0) {
  15873             printResultType();
  15874             printOriginalExpression();
  15875             printReconstructedExpression();
  15876         } else {
  15877             stream << '\n';
  15878         }
  15879         printMessage();
  15880     }
  15881 
  15882 private:
  15883     void printResultType() const {
  15884         if (!passOrFail.empty()) {
  15885             Colour colourGuard(colour);
  15886             stream << passOrFail << ":\n";
  15887         }
  15888     }
  15889     void printOriginalExpression() const {
  15890         if (result.hasExpression()) {
  15891             Colour colourGuard(Colour::OriginalExpression);
  15892             stream << "  ";
  15893             stream << result.getExpressionInMacro();
  15894             stream << '\n';
  15895         }
  15896     }
  15897     void printReconstructedExpression() const {
  15898         if (result.hasExpandedExpression()) {
  15899             stream << "with expansion:\n";
  15900             Colour colourGuard(Colour::ReconstructedExpression);
  15901             stream << Column(result.getExpandedExpression()).indent(2) << '\n';
  15902         }
  15903     }
  15904     void printMessage() const {
  15905         if (!messageLabel.empty())
  15906             stream << messageLabel << ':' << '\n';
  15907         for (auto const& msg : messages) {
  15908             // If this assertion is a warning ignore any INFO messages
  15909             if (printInfoMessages || msg.type != ResultWas::Info)
  15910                 stream << Column(msg.message).indent(2) << '\n';
  15911         }
  15912     }
  15913     void printSourceInfo() const {
  15914         Colour colourGuard(Colour::FileName);
  15915         stream << result.getSourceInfo() << ": ";
  15916     }
  15917 
  15918     std::ostream& stream;
  15919     AssertionStats const& stats;
  15920     AssertionResult const& result;
  15921     Colour::Code colour;
  15922     std::string passOrFail;
  15923     std::string messageLabel;
  15924     std::string message;
  15925     std::vector<MessageInfo> messages;
  15926     bool printInfoMessages;
  15927 };
  15928 
  15929 std::size_t makeRatio(std::size_t number, std::size_t total) {
  15930     std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
  15931     return (ratio == 0 && number > 0) ? 1 : ratio;
  15932 }
  15933 
  15934 std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
  15935     if (i > j && i > k)
  15936         return i;
  15937     else if (j > k)
  15938         return j;
  15939     else
  15940         return k;
  15941 }
  15942 
  15943 struct ColumnInfo {
  15944     enum Justification { Left, Right };
  15945     std::string name;
  15946     int width;
  15947     Justification justification;
  15948 };
  15949 struct ColumnBreak {};
  15950 struct RowBreak {};
  15951 
  15952 class Duration {
  15953     enum class Unit {
  15954         Auto,
  15955         Nanoseconds,
  15956         Microseconds,
  15957         Milliseconds,
  15958         Seconds,
  15959         Minutes
  15960     };
  15961     static const uint64_t s_nanosecondsInAMicrosecond = 1000;
  15962     static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
  15963     static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
  15964     static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
  15965 
  15966     uint64_t m_inNanoseconds;
  15967     Unit m_units;
  15968 
  15969 public:
  15970 	explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
  15971         : Duration(static_cast<uint64_t>(inNanoseconds), units) {
  15972     }
  15973 
  15974     explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
  15975         : m_inNanoseconds(inNanoseconds),
  15976         m_units(units) {
  15977         if (m_units == Unit::Auto) {
  15978             if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
  15979                 m_units = Unit::Nanoseconds;
  15980             else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
  15981                 m_units = Unit::Microseconds;
  15982             else if (m_inNanoseconds < s_nanosecondsInASecond)
  15983                 m_units = Unit::Milliseconds;
  15984             else if (m_inNanoseconds < s_nanosecondsInAMinute)
  15985                 m_units = Unit::Seconds;
  15986             else
  15987                 m_units = Unit::Minutes;
  15988         }
  15989 
  15990     }
  15991 
  15992     auto value() const -> double {
  15993         switch (m_units) {
  15994         case Unit::Microseconds:
  15995             return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
  15996         case Unit::Milliseconds:
  15997             return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
  15998         case Unit::Seconds:
  15999             return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
  16000         case Unit::Minutes:
  16001             return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
  16002         default:
  16003             return static_cast<double>(m_inNanoseconds);
  16004         }
  16005     }
  16006     auto unitsAsString() const -> std::string {
  16007         switch (m_units) {
  16008         case Unit::Nanoseconds:
  16009             return "ns";
  16010         case Unit::Microseconds:
  16011             return "us";
  16012         case Unit::Milliseconds:
  16013             return "ms";
  16014         case Unit::Seconds:
  16015             return "s";
  16016         case Unit::Minutes:
  16017             return "m";
  16018         default:
  16019             return "** internal error **";
  16020         }
  16021 
  16022     }
  16023     friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
  16024         return os << duration.value() << ' ' << duration.unitsAsString();
  16025     }
  16026 };
  16027 } // end anon namespace
  16028 
  16029 class TablePrinter {
  16030     std::ostream& m_os;
  16031     std::vector<ColumnInfo> m_columnInfos;
  16032     std::ostringstream m_oss;
  16033     int m_currentColumn = -1;
  16034     bool m_isOpen = false;
  16035 
  16036 public:
  16037     TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
  16038     :   m_os( os ),
  16039         m_columnInfos( std::move( columnInfos ) ) {}
  16040 
  16041     auto columnInfos() const -> std::vector<ColumnInfo> const& {
  16042         return m_columnInfos;
  16043     }
  16044 
  16045     void open() {
  16046         if (!m_isOpen) {
  16047             m_isOpen = true;
  16048             *this << RowBreak();
  16049 
  16050 			Columns headerCols;
  16051 			Spacer spacer(2);
  16052 			for (auto const& info : m_columnInfos) {
  16053 				headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
  16054 				headerCols += spacer;
  16055 			}
  16056 			m_os << headerCols << '\n';
  16057 
  16058             m_os << Catch::getLineOfChars<'-'>() << '\n';
  16059         }
  16060     }
  16061     void close() {
  16062         if (m_isOpen) {
  16063             *this << RowBreak();
  16064             m_os << std::endl;
  16065             m_isOpen = false;
  16066         }
  16067     }
  16068 
  16069     template<typename T>
  16070     friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
  16071         tp.m_oss << value;
  16072         return tp;
  16073     }
  16074 
  16075     friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
  16076         auto colStr = tp.m_oss.str();
  16077         const auto strSize = colStr.size();
  16078         tp.m_oss.str("");
  16079         tp.open();
  16080         if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
  16081             tp.m_currentColumn = -1;
  16082             tp.m_os << '\n';
  16083         }
  16084         tp.m_currentColumn++;
  16085 
  16086         auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
  16087         auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))
  16088             ? std::string(colInfo.width - (strSize + 1), ' ')
  16089             : std::string();
  16090         if (colInfo.justification == ColumnInfo::Left)
  16091             tp.m_os << colStr << padding << ' ';
  16092         else
  16093             tp.m_os << padding << colStr << ' ';
  16094         return tp;
  16095     }
  16096 
  16097     friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
  16098         if (tp.m_currentColumn > 0) {
  16099             tp.m_os << '\n';
  16100             tp.m_currentColumn = -1;
  16101         }
  16102         return tp;
  16103     }
  16104 };
  16105 
  16106 ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
  16107     : StreamingReporterBase(config),
  16108     m_tablePrinter(new TablePrinter(config.stream(),
  16109         [&config]() -> std::vector<ColumnInfo> {
  16110         if (config.fullConfig()->benchmarkNoAnalysis())
  16111         {
  16112             return{
  16113                 { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
  16114                 { "     samples", 14, ColumnInfo::Right },
  16115                 { "  iterations", 14, ColumnInfo::Right },
  16116                 { "        mean", 14, ColumnInfo::Right }
  16117             };
  16118         }
  16119         else
  16120         {
  16121             return{
  16122                 { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
  16123                 { "samples      mean       std dev", 14, ColumnInfo::Right },
  16124                 { "iterations   low mean   low std dev", 14, ColumnInfo::Right },
  16125                 { "estimated    high mean  high std dev", 14, ColumnInfo::Right }
  16126             };
  16127         }
  16128     }())) {}
  16129 ConsoleReporter::~ConsoleReporter() = default;
  16130 
  16131 std::string ConsoleReporter::getDescription() {
  16132     return "Reports test results as plain lines of text";
  16133 }
  16134 
  16135 void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
  16136     stream << "No test cases matched '" << spec << '\'' << std::endl;
  16137 }
  16138 
  16139 void ConsoleReporter::reportInvalidArguments(std::string const&arg){
  16140     stream << "Invalid Filter: " << arg << std::endl;
  16141 }
  16142 
  16143 void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
  16144 
  16145 bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
  16146     AssertionResult const& result = _assertionStats.assertionResult;
  16147 
  16148     bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  16149 
  16150     // Drop out if result was successful but we're not printing them.
  16151     if (!includeResults && result.getResultType() != ResultWas::Warning)
  16152         return false;
  16153 
  16154     lazyPrint();
  16155 
  16156     ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
  16157     printer.print();
  16158     stream << std::endl;
  16159     return true;
  16160 }
  16161 
  16162 void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
  16163     m_tablePrinter->close();
  16164     m_headerPrinted = false;
  16165     StreamingReporterBase::sectionStarting(_sectionInfo);
  16166 }
  16167 void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
  16168     m_tablePrinter->close();
  16169     if (_sectionStats.missingAssertions) {
  16170         lazyPrint();
  16171         Colour colour(Colour::ResultError);
  16172         if (m_sectionStack.size() > 1)
  16173             stream << "\nNo assertions in section";
  16174         else
  16175             stream << "\nNo assertions in test case";
  16176         stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
  16177     }
  16178     if (m_config->showDurations() == ShowDurations::Always) {
  16179         stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  16180     }
  16181     if (m_headerPrinted) {
  16182         m_headerPrinted = false;
  16183     }
  16184     StreamingReporterBase::sectionEnded(_sectionStats);
  16185 }
  16186 
  16187 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  16188 void ConsoleReporter::benchmarkPreparing(std::string const& name) {
  16189 	lazyPrintWithoutClosingBenchmarkTable();
  16190 
  16191 	auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
  16192 
  16193 	bool firstLine = true;
  16194 	for (auto line : nameCol) {
  16195 		if (!firstLine)
  16196 			(*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
  16197 		else
  16198 			firstLine = false;
  16199 
  16200 		(*m_tablePrinter) << line << ColumnBreak();
  16201 	}
  16202 }
  16203 
  16204 void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
  16205     (*m_tablePrinter) << info.samples << ColumnBreak()
  16206         << info.iterations << ColumnBreak();
  16207     if (!m_config->benchmarkNoAnalysis())
  16208         (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
  16209 }
  16210 void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
  16211     if (m_config->benchmarkNoAnalysis())
  16212     {
  16213         (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
  16214     }
  16215     else
  16216     {
  16217         (*m_tablePrinter) << ColumnBreak()
  16218             << Duration(stats.mean.point.count()) << ColumnBreak()
  16219             << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
  16220             << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
  16221             << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
  16222             << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
  16223             << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
  16224     }
  16225 }
  16226 
  16227 void ConsoleReporter::benchmarkFailed(std::string const& error) {
  16228 	Colour colour(Colour::Red);
  16229     (*m_tablePrinter)
  16230         << "Benchmark failed (" << error << ')'
  16231         << ColumnBreak() << RowBreak();
  16232 }
  16233 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  16234 
  16235 void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
  16236     m_tablePrinter->close();
  16237     StreamingReporterBase::testCaseEnded(_testCaseStats);
  16238     m_headerPrinted = false;
  16239 }
  16240 void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
  16241     if (currentGroupInfo.used) {
  16242         printSummaryDivider();
  16243         stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
  16244         printTotals(_testGroupStats.totals);
  16245         stream << '\n' << std::endl;
  16246     }
  16247     StreamingReporterBase::testGroupEnded(_testGroupStats);
  16248 }
  16249 void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
  16250     printTotalsDivider(_testRunStats.totals);
  16251     printTotals(_testRunStats.totals);
  16252     stream << std::endl;
  16253     StreamingReporterBase::testRunEnded(_testRunStats);
  16254 }
  16255 void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
  16256     StreamingReporterBase::testRunStarting(_testInfo);
  16257     printTestFilters();
  16258 }
  16259 
  16260 void ConsoleReporter::lazyPrint() {
  16261 
  16262     m_tablePrinter->close();
  16263     lazyPrintWithoutClosingBenchmarkTable();
  16264 }
  16265 
  16266 void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
  16267 
  16268     if (!currentTestRunInfo.used)
  16269         lazyPrintRunInfo();
  16270     if (!currentGroupInfo.used)
  16271         lazyPrintGroupInfo();
  16272 
  16273     if (!m_headerPrinted) {
  16274         printTestCaseAndSectionHeader();
  16275         m_headerPrinted = true;
  16276     }
  16277 }
  16278 void ConsoleReporter::lazyPrintRunInfo() {
  16279     stream << '\n' << getLineOfChars<'~'>() << '\n';
  16280     Colour colour(Colour::SecondaryText);
  16281     stream << currentTestRunInfo->name
  16282         << " is a Catch v" << libraryVersion() << " host application.\n"
  16283         << "Run with -? for options\n\n";
  16284 
  16285     if (m_config->rngSeed() != 0)
  16286         stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
  16287 
  16288     currentTestRunInfo.used = true;
  16289 }
  16290 void ConsoleReporter::lazyPrintGroupInfo() {
  16291     if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
  16292         printClosedHeader("Group: " + currentGroupInfo->name);
  16293         currentGroupInfo.used = true;
  16294     }
  16295 }
  16296 void ConsoleReporter::printTestCaseAndSectionHeader() {
  16297     assert(!m_sectionStack.empty());
  16298     printOpenHeader(currentTestCaseInfo->name);
  16299 
  16300     if (m_sectionStack.size() > 1) {
  16301         Colour colourGuard(Colour::Headers);
  16302 
  16303         auto
  16304             it = m_sectionStack.begin() + 1, // Skip first section (test case)
  16305             itEnd = m_sectionStack.end();
  16306         for (; it != itEnd; ++it)
  16307             printHeaderString(it->name, 2);
  16308     }
  16309 
  16310     SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
  16311 
  16312     stream << getLineOfChars<'-'>() << '\n';
  16313     Colour colourGuard(Colour::FileName);
  16314     stream << lineInfo << '\n';
  16315     stream << getLineOfChars<'.'>() << '\n' << std::endl;
  16316 }
  16317 
  16318 void ConsoleReporter::printClosedHeader(std::string const& _name) {
  16319     printOpenHeader(_name);
  16320     stream << getLineOfChars<'.'>() << '\n';
  16321 }
  16322 void ConsoleReporter::printOpenHeader(std::string const& _name) {
  16323     stream << getLineOfChars<'-'>() << '\n';
  16324     {
  16325         Colour colourGuard(Colour::Headers);
  16326         printHeaderString(_name);
  16327     }
  16328 }
  16329 
  16330 // if string has a : in first line will set indent to follow it on
  16331 // subsequent lines
  16332 void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
  16333     std::size_t i = _string.find(": ");
  16334     if (i != std::string::npos)
  16335         i += 2;
  16336     else
  16337         i = 0;
  16338     stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
  16339 }
  16340 
  16341 struct SummaryColumn {
  16342 
  16343     SummaryColumn( std::string _label, Colour::Code _colour )
  16344     :   label( std::move( _label ) ),
  16345         colour( _colour ) {}
  16346     SummaryColumn addRow( std::size_t count ) {
  16347         ReusableStringStream rss;
  16348         rss << count;
  16349         std::string row = rss.str();
  16350         for (auto& oldRow : rows) {
  16351             while (oldRow.size() < row.size())
  16352                 oldRow = ' ' + oldRow;
  16353             while (oldRow.size() > row.size())
  16354                 row = ' ' + row;
  16355         }
  16356         rows.push_back(row);
  16357         return *this;
  16358     }
  16359 
  16360     std::string label;
  16361     Colour::Code colour;
  16362     std::vector<std::string> rows;
  16363 
  16364 };
  16365 
  16366 void ConsoleReporter::printTotals( Totals const& totals ) {
  16367     if (totals.testCases.total() == 0) {
  16368         stream << Colour(Colour::Warning) << "No tests ran\n";
  16369     } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
  16370         stream << Colour(Colour::ResultSuccess) << "All tests passed";
  16371         stream << " ("
  16372             << pluralise(totals.assertions.passed, "assertion") << " in "
  16373             << pluralise(totals.testCases.passed, "test case") << ')'
  16374             << '\n';
  16375     } else {
  16376 
  16377         std::vector<SummaryColumn> columns;
  16378         columns.push_back(SummaryColumn("", Colour::None)
  16379                           .addRow(totals.testCases.total())
  16380                           .addRow(totals.assertions.total()));
  16381         columns.push_back(SummaryColumn("passed", Colour::Success)
  16382                           .addRow(totals.testCases.passed)
  16383                           .addRow(totals.assertions.passed));
  16384         columns.push_back(SummaryColumn("failed", Colour::ResultError)
  16385                           .addRow(totals.testCases.failed)
  16386                           .addRow(totals.assertions.failed));
  16387         columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
  16388                           .addRow(totals.testCases.failedButOk)
  16389                           .addRow(totals.assertions.failedButOk));
  16390 
  16391         printSummaryRow("test cases", columns, 0);
  16392         printSummaryRow("assertions", columns, 1);
  16393     }
  16394 }
  16395 void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
  16396     for (auto col : cols) {
  16397         std::string value = col.rows[row];
  16398         if (col.label.empty()) {
  16399             stream << label << ": ";
  16400             if (value != "0")
  16401                 stream << value;
  16402             else
  16403                 stream << Colour(Colour::Warning) << "- none -";
  16404         } else if (value != "0") {
  16405             stream << Colour(Colour::LightGrey) << " | ";
  16406             stream << Colour(col.colour)
  16407                 << value << ' ' << col.label;
  16408         }
  16409     }
  16410     stream << '\n';
  16411 }
  16412 
  16413 void ConsoleReporter::printTotalsDivider(Totals const& totals) {
  16414     if (totals.testCases.total() > 0) {
  16415         std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
  16416         std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
  16417         std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
  16418         while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
  16419             findMax(failedRatio, failedButOkRatio, passedRatio)++;
  16420         while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
  16421             findMax(failedRatio, failedButOkRatio, passedRatio)--;
  16422 
  16423         stream << Colour(Colour::Error) << std::string(failedRatio, '=');
  16424         stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
  16425         if (totals.testCases.allPassed())
  16426             stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
  16427         else
  16428             stream << Colour(Colour::Success) << std::string(passedRatio, '=');
  16429     } else {
  16430         stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
  16431     }
  16432     stream << '\n';
  16433 }
  16434 void ConsoleReporter::printSummaryDivider() {
  16435     stream << getLineOfChars<'-'>() << '\n';
  16436 }
  16437 
  16438 void ConsoleReporter::printTestFilters() {
  16439     if (m_config->testSpec().hasFilters())
  16440         stream << Colour(Colour::BrightYellow) << "Filters: " << serializeFilters( m_config->getTestsOrTags() ) << '\n';
  16441 }
  16442 
  16443 CATCH_REGISTER_REPORTER("console", ConsoleReporter)
  16444 
  16445 } // end namespace Catch
  16446 
  16447 #if defined(_MSC_VER)
  16448 #pragma warning(pop)
  16449 #endif
  16450 
  16451 #if defined(__clang__)
  16452 #  pragma clang diagnostic pop
  16453 #endif
  16454 // end catch_reporter_console.cpp
  16455 // start catch_reporter_junit.cpp
  16456 
  16457 #include <cassert>
  16458 #include <sstream>
  16459 #include <ctime>
  16460 #include <algorithm>
  16461 
  16462 namespace Catch {
  16463 
  16464     namespace {
  16465         std::string getCurrentTimestamp() {
  16466             // Beware, this is not reentrant because of backward compatibility issues
  16467             // Also, UTC only, again because of backward compatibility (%z is C++11)
  16468             time_t rawtime;
  16469             std::time(&rawtime);
  16470             auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  16471 
  16472 #ifdef _MSC_VER
  16473             std::tm timeInfo = {};
  16474             gmtime_s(&timeInfo, &rawtime);
  16475 #else
  16476             std::tm* timeInfo;
  16477             timeInfo = std::gmtime(&rawtime);
  16478 #endif
  16479 
  16480             char timeStamp[timeStampSize];
  16481             const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
  16482 
  16483 #ifdef _MSC_VER
  16484             std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  16485 #else
  16486             std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
  16487 #endif
  16488             return std::string(timeStamp);
  16489         }
  16490 
  16491         std::string fileNameTag(const std::vector<std::string> &tags) {
  16492             auto it = std::find_if(begin(tags),
  16493                                    end(tags),
  16494                                    [] (std::string const& tag) {return tag.front() == '#'; });
  16495             if (it != tags.end())
  16496                 return it->substr(1);
  16497             return std::string();
  16498         }
  16499     } // anonymous namespace
  16500 
  16501     JunitReporter::JunitReporter( ReporterConfig const& _config )
  16502         :   CumulativeReporterBase( _config ),
  16503             xml( _config.stream() )
  16504         {
  16505             m_reporterPrefs.shouldRedirectStdOut = true;
  16506             m_reporterPrefs.shouldReportAllAssertions = true;
  16507         }
  16508 
  16509     JunitReporter::~JunitReporter() {}
  16510 
  16511     std::string JunitReporter::getDescription() {
  16512         return "Reports test results in an XML format that looks like Ant's junitreport target";
  16513     }
  16514 
  16515     void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
  16516 
  16517     void JunitReporter::testRunStarting( TestRunInfo const& runInfo )  {
  16518         CumulativeReporterBase::testRunStarting( runInfo );
  16519         xml.startElement( "testsuites" );
  16520     }
  16521 
  16522     void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
  16523         suiteTimer.start();
  16524         stdOutForSuite.clear();
  16525         stdErrForSuite.clear();
  16526         unexpectedExceptions = 0;
  16527         CumulativeReporterBase::testGroupStarting( groupInfo );
  16528     }
  16529 
  16530     void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
  16531         m_okToFail = testCaseInfo.okToFail();
  16532     }
  16533 
  16534     bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
  16535         if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
  16536             unexpectedExceptions++;
  16537         return CumulativeReporterBase::assertionEnded( assertionStats );
  16538     }
  16539 
  16540     void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
  16541         stdOutForSuite += testCaseStats.stdOut;
  16542         stdErrForSuite += testCaseStats.stdErr;
  16543         CumulativeReporterBase::testCaseEnded( testCaseStats );
  16544     }
  16545 
  16546     void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
  16547         double suiteTime = suiteTimer.getElapsedSeconds();
  16548         CumulativeReporterBase::testGroupEnded( testGroupStats );
  16549         writeGroup( *m_testGroups.back(), suiteTime );
  16550     }
  16551 
  16552     void JunitReporter::testRunEndedCumulative() {
  16553         xml.endElement();
  16554     }
  16555 
  16556     void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
  16557         XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
  16558 
  16559         TestGroupStats const& stats = groupNode.value;
  16560         xml.writeAttribute( "name", stats.groupInfo.name );
  16561         xml.writeAttribute( "errors", unexpectedExceptions );
  16562         xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
  16563         xml.writeAttribute( "tests", stats.totals.assertions.total() );
  16564         xml.writeAttribute( "hostname", "tbd" ); // !TBD
  16565         if( m_config->showDurations() == ShowDurations::Never )
  16566             xml.writeAttribute( "time", "" );
  16567         else
  16568             xml.writeAttribute( "time", suiteTime );
  16569         xml.writeAttribute( "timestamp", getCurrentTimestamp() );
  16570 
  16571         // Write properties if there are any
  16572         if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
  16573             auto properties = xml.scopedElement("properties");
  16574             if (m_config->hasTestFilters()) {
  16575                 xml.scopedElement("property")
  16576                     .writeAttribute("name", "filters")
  16577                     .writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
  16578             }
  16579             if (m_config->rngSeed() != 0) {
  16580                 xml.scopedElement("property")
  16581                     .writeAttribute("name", "random-seed")
  16582                     .writeAttribute("value", m_config->rngSeed());
  16583             }
  16584         }
  16585 
  16586         // Write test cases
  16587         for( auto const& child : groupNode.children )
  16588             writeTestCase( *child );
  16589 
  16590         xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );
  16591         xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline );
  16592     }
  16593 
  16594     void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
  16595         TestCaseStats const& stats = testCaseNode.value;
  16596 
  16597         // All test cases have exactly one section - which represents the
  16598         // test case itself. That section may have 0-n nested sections
  16599         assert( testCaseNode.children.size() == 1 );
  16600         SectionNode const& rootSection = *testCaseNode.children.front();
  16601 
  16602         std::string className = stats.testInfo.className;
  16603 
  16604         if( className.empty() ) {
  16605             className = fileNameTag(stats.testInfo.tags);
  16606             if ( className.empty() )
  16607                 className = "global";
  16608         }
  16609 
  16610         if ( !m_config->name().empty() )
  16611             className = m_config->name() + "." + className;
  16612 
  16613         writeSection( className, "", rootSection );
  16614     }
  16615 
  16616     void JunitReporter::writeSection(  std::string const& className,
  16617                         std::string const& rootName,
  16618                         SectionNode const& sectionNode ) {
  16619         std::string name = trim( sectionNode.stats.sectionInfo.name );
  16620         if( !rootName.empty() )
  16621             name = rootName + '/' + name;
  16622 
  16623         if( !sectionNode.assertions.empty() ||
  16624             !sectionNode.stdOut.empty() ||
  16625             !sectionNode.stdErr.empty() ) {
  16626             XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
  16627             if( className.empty() ) {
  16628                 xml.writeAttribute( "classname", name );
  16629                 xml.writeAttribute( "name", "root" );
  16630             }
  16631             else {
  16632                 xml.writeAttribute( "classname", className );
  16633                 xml.writeAttribute( "name", name );
  16634             }
  16635             xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
  16636 
  16637             writeAssertions( sectionNode );
  16638 
  16639             if( !sectionNode.stdOut.empty() )
  16640                 xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );
  16641             if( !sectionNode.stdErr.empty() )
  16642                 xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline );
  16643         }
  16644         for( auto const& childNode : sectionNode.childSections )
  16645             if( className.empty() )
  16646                 writeSection( name, "", *childNode );
  16647             else
  16648                 writeSection( className, name, *childNode );
  16649     }
  16650 
  16651     void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
  16652         for( auto const& assertion : sectionNode.assertions )
  16653             writeAssertion( assertion );
  16654     }
  16655 
  16656     void JunitReporter::writeAssertion( AssertionStats const& stats ) {
  16657         AssertionResult const& result = stats.assertionResult;
  16658         if( !result.isOk() ) {
  16659             std::string elementName;
  16660             switch( result.getResultType() ) {
  16661                 case ResultWas::ThrewException:
  16662                 case ResultWas::FatalErrorCondition:
  16663                     elementName = "error";
  16664                     break;
  16665                 case ResultWas::ExplicitFailure:
  16666                     elementName = "failure";
  16667                     break;
  16668                 case ResultWas::ExpressionFailed:
  16669                     elementName = "failure";
  16670                     break;
  16671                 case ResultWas::DidntThrowException:
  16672                     elementName = "failure";
  16673                     break;
  16674 
  16675                 // We should never see these here:
  16676                 case ResultWas::Info:
  16677                 case ResultWas::Warning:
  16678                 case ResultWas::Ok:
  16679                 case ResultWas::Unknown:
  16680                 case ResultWas::FailureBit:
  16681                 case ResultWas::Exception:
  16682                     elementName = "internalError";
  16683                     break;
  16684             }
  16685 
  16686             XmlWriter::ScopedElement e = xml.scopedElement( elementName );
  16687 
  16688             xml.writeAttribute( "message", result.getExpression() );
  16689             xml.writeAttribute( "type", result.getTestMacroName() );
  16690 
  16691             ReusableStringStream rss;
  16692             if (stats.totals.assertions.total() > 0) {
  16693                 rss << "FAILED" << ":\n";
  16694                 if (result.hasExpression()) {
  16695                     rss << "  ";
  16696                     rss << result.getExpressionInMacro();
  16697                     rss << '\n';
  16698                 }
  16699                 if (result.hasExpandedExpression()) {
  16700                     rss << "with expansion:\n";
  16701                     rss << Column(result.getExpandedExpression()).indent(2) << '\n';
  16702                 }
  16703             } else {
  16704                 rss << '\n';
  16705             }
  16706 
  16707             if( !result.getMessage().empty() )
  16708                 rss << result.getMessage() << '\n';
  16709             for( auto const& msg : stats.infoMessages )
  16710                 if( msg.type == ResultWas::Info )
  16711                     rss << msg.message << '\n';
  16712 
  16713             rss << "at " << result.getSourceInfo();
  16714             xml.writeText( rss.str(), XmlFormatting::Newline );
  16715         }
  16716     }
  16717 
  16718     CATCH_REGISTER_REPORTER( "junit", JunitReporter )
  16719 
  16720 } // end namespace Catch
  16721 // end catch_reporter_junit.cpp
  16722 // start catch_reporter_listening.cpp
  16723 
  16724 #include <cassert>
  16725 
  16726 namespace Catch {
  16727 
  16728     ListeningReporter::ListeningReporter() {
  16729         // We will assume that listeners will always want all assertions
  16730         m_preferences.shouldReportAllAssertions = true;
  16731     }
  16732 
  16733     void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
  16734         m_listeners.push_back( std::move( listener ) );
  16735     }
  16736 
  16737     void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
  16738         assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
  16739         m_reporter = std::move( reporter );
  16740         m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
  16741     }
  16742 
  16743     ReporterPreferences ListeningReporter::getPreferences() const {
  16744         return m_preferences;
  16745     }
  16746 
  16747     std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
  16748         return std::set<Verbosity>{ };
  16749     }
  16750 
  16751     void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
  16752         for ( auto const& listener : m_listeners ) {
  16753             listener->noMatchingTestCases( spec );
  16754         }
  16755         m_reporter->noMatchingTestCases( spec );
  16756     }
  16757 
  16758     void ListeningReporter::reportInvalidArguments(std::string const&arg){
  16759         for ( auto const& listener : m_listeners ) {
  16760             listener->reportInvalidArguments( arg );
  16761         }
  16762         m_reporter->reportInvalidArguments( arg );
  16763     }
  16764 
  16765 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  16766     void ListeningReporter::benchmarkPreparing( std::string const& name ) {
  16767 		for (auto const& listener : m_listeners) {
  16768 			listener->benchmarkPreparing(name);
  16769 		}
  16770 		m_reporter->benchmarkPreparing(name);
  16771 	}
  16772     void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
  16773         for ( auto const& listener : m_listeners ) {
  16774             listener->benchmarkStarting( benchmarkInfo );
  16775         }
  16776         m_reporter->benchmarkStarting( benchmarkInfo );
  16777     }
  16778     void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {
  16779         for ( auto const& listener : m_listeners ) {
  16780             listener->benchmarkEnded( benchmarkStats );
  16781         }
  16782         m_reporter->benchmarkEnded( benchmarkStats );
  16783     }
  16784 
  16785 	void ListeningReporter::benchmarkFailed( std::string const& error ) {
  16786 		for (auto const& listener : m_listeners) {
  16787 			listener->benchmarkFailed(error);
  16788 		}
  16789 		m_reporter->benchmarkFailed(error);
  16790 	}
  16791 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  16792 
  16793     void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
  16794         for ( auto const& listener : m_listeners ) {
  16795             listener->testRunStarting( testRunInfo );
  16796         }
  16797         m_reporter->testRunStarting( testRunInfo );
  16798     }
  16799 
  16800     void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
  16801         for ( auto const& listener : m_listeners ) {
  16802             listener->testGroupStarting( groupInfo );
  16803         }
  16804         m_reporter->testGroupStarting( groupInfo );
  16805     }
  16806 
  16807     void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
  16808         for ( auto const& listener : m_listeners ) {
  16809             listener->testCaseStarting( testInfo );
  16810         }
  16811         m_reporter->testCaseStarting( testInfo );
  16812     }
  16813 
  16814     void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
  16815         for ( auto const& listener : m_listeners ) {
  16816             listener->sectionStarting( sectionInfo );
  16817         }
  16818         m_reporter->sectionStarting( sectionInfo );
  16819     }
  16820 
  16821     void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
  16822         for ( auto const& listener : m_listeners ) {
  16823             listener->assertionStarting( assertionInfo );
  16824         }
  16825         m_reporter->assertionStarting( assertionInfo );
  16826     }
  16827 
  16828     // The return value indicates if the messages buffer should be cleared:
  16829     bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
  16830         for( auto const& listener : m_listeners ) {
  16831             static_cast<void>( listener->assertionEnded( assertionStats ) );
  16832         }
  16833         return m_reporter->assertionEnded( assertionStats );
  16834     }
  16835 
  16836     void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
  16837         for ( auto const& listener : m_listeners ) {
  16838             listener->sectionEnded( sectionStats );
  16839         }
  16840         m_reporter->sectionEnded( sectionStats );
  16841     }
  16842 
  16843     void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
  16844         for ( auto const& listener : m_listeners ) {
  16845             listener->testCaseEnded( testCaseStats );
  16846         }
  16847         m_reporter->testCaseEnded( testCaseStats );
  16848     }
  16849 
  16850     void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
  16851         for ( auto const& listener : m_listeners ) {
  16852             listener->testGroupEnded( testGroupStats );
  16853         }
  16854         m_reporter->testGroupEnded( testGroupStats );
  16855     }
  16856 
  16857     void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
  16858         for ( auto const& listener : m_listeners ) {
  16859             listener->testRunEnded( testRunStats );
  16860         }
  16861         m_reporter->testRunEnded( testRunStats );
  16862     }
  16863 
  16864     void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
  16865         for ( auto const& listener : m_listeners ) {
  16866             listener->skipTest( testInfo );
  16867         }
  16868         m_reporter->skipTest( testInfo );
  16869     }
  16870 
  16871     bool ListeningReporter::isMulti() const {
  16872         return true;
  16873     }
  16874 
  16875 } // end namespace Catch
  16876 // end catch_reporter_listening.cpp
  16877 // start catch_reporter_xml.cpp
  16878 
  16879 #if defined(_MSC_VER)
  16880 #pragma warning(push)
  16881 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  16882                               // Note that 4062 (not all labels are handled
  16883                               // and default is missing) is enabled
  16884 #endif
  16885 
  16886 namespace Catch {
  16887     XmlReporter::XmlReporter( ReporterConfig const& _config )
  16888     :   StreamingReporterBase( _config ),
  16889         m_xml(_config.stream())
  16890     {
  16891         m_reporterPrefs.shouldRedirectStdOut = true;
  16892         m_reporterPrefs.shouldReportAllAssertions = true;
  16893     }
  16894 
  16895     XmlReporter::~XmlReporter() = default;
  16896 
  16897     std::string XmlReporter::getDescription() {
  16898         return "Reports test results as an XML document";
  16899     }
  16900 
  16901     std::string XmlReporter::getStylesheetRef() const {
  16902         return std::string();
  16903     }
  16904 
  16905     void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
  16906         m_xml
  16907             .writeAttribute( "filename", sourceInfo.file )
  16908             .writeAttribute( "line", sourceInfo.line );
  16909     }
  16910 
  16911     void XmlReporter::noMatchingTestCases( std::string const& s ) {
  16912         StreamingReporterBase::noMatchingTestCases( s );
  16913     }
  16914 
  16915     void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
  16916         StreamingReporterBase::testRunStarting( testInfo );
  16917         std::string stylesheetRef = getStylesheetRef();
  16918         if( !stylesheetRef.empty() )
  16919             m_xml.writeStylesheetRef( stylesheetRef );
  16920         m_xml.startElement( "Catch" );
  16921         if( !m_config->name().empty() )
  16922             m_xml.writeAttribute( "name", m_config->name() );
  16923         if (m_config->testSpec().hasFilters())
  16924             m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) );
  16925         if( m_config->rngSeed() != 0 )
  16926             m_xml.scopedElement( "Randomness" )
  16927                 .writeAttribute( "seed", m_config->rngSeed() );
  16928     }
  16929 
  16930     void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
  16931         StreamingReporterBase::testGroupStarting( groupInfo );
  16932         m_xml.startElement( "Group" )
  16933             .writeAttribute( "name", groupInfo.name );
  16934     }
  16935 
  16936     void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
  16937         StreamingReporterBase::testCaseStarting(testInfo);
  16938         m_xml.startElement( "TestCase" )
  16939             .writeAttribute( "name", trim( testInfo.name ) )
  16940             .writeAttribute( "description", testInfo.description )
  16941             .writeAttribute( "tags", testInfo.tagsAsString() );
  16942 
  16943         writeSourceInfo( testInfo.lineInfo );
  16944 
  16945         if ( m_config->showDurations() == ShowDurations::Always )
  16946             m_testCaseTimer.start();
  16947         m_xml.ensureTagClosed();
  16948     }
  16949 
  16950     void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
  16951         StreamingReporterBase::sectionStarting( sectionInfo );
  16952         if( m_sectionDepth++ > 0 ) {
  16953             m_xml.startElement( "Section" )
  16954                 .writeAttribute( "name", trim( sectionInfo.name ) );
  16955             writeSourceInfo( sectionInfo.lineInfo );
  16956             m_xml.ensureTagClosed();
  16957         }
  16958     }
  16959 
  16960     void XmlReporter::assertionStarting( AssertionInfo const& ) { }
  16961 
  16962     bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
  16963 
  16964         AssertionResult const& result = assertionStats.assertionResult;
  16965 
  16966         bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  16967 
  16968         if( includeResults || result.getResultType() == ResultWas::Warning ) {
  16969             // Print any info messages in <Info> tags.
  16970             for( auto const& msg : assertionStats.infoMessages ) {
  16971                 if( msg.type == ResultWas::Info && includeResults ) {
  16972                     m_xml.scopedElement( "Info" )
  16973                             .writeText( msg.message );
  16974                 } else if ( msg.type == ResultWas::Warning ) {
  16975                     m_xml.scopedElement( "Warning" )
  16976                             .writeText( msg.message );
  16977                 }
  16978             }
  16979         }
  16980 
  16981         // Drop out if result was successful but we're not printing them.
  16982         if( !includeResults && result.getResultType() != ResultWas::Warning )
  16983             return true;
  16984 
  16985         // Print the expression if there is one.
  16986         if( result.hasExpression() ) {
  16987             m_xml.startElement( "Expression" )
  16988                 .writeAttribute( "success", result.succeeded() )
  16989                 .writeAttribute( "type", result.getTestMacroName() );
  16990 
  16991             writeSourceInfo( result.getSourceInfo() );
  16992 
  16993             m_xml.scopedElement( "Original" )
  16994                 .writeText( result.getExpression() );
  16995             m_xml.scopedElement( "Expanded" )
  16996                 .writeText( result.getExpandedExpression() );
  16997         }
  16998 
  16999         // And... Print a result applicable to each result type.
  17000         switch( result.getResultType() ) {
  17001             case ResultWas::ThrewException:
  17002                 m_xml.startElement( "Exception" );
  17003                 writeSourceInfo( result.getSourceInfo() );
  17004                 m_xml.writeText( result.getMessage() );
  17005                 m_xml.endElement();
  17006                 break;
  17007             case ResultWas::FatalErrorCondition:
  17008                 m_xml.startElement( "FatalErrorCondition" );
  17009                 writeSourceInfo( result.getSourceInfo() );
  17010                 m_xml.writeText( result.getMessage() );
  17011                 m_xml.endElement();
  17012                 break;
  17013             case ResultWas::Info:
  17014                 m_xml.scopedElement( "Info" )
  17015                     .writeText( result.getMessage() );
  17016                 break;
  17017             case ResultWas::Warning:
  17018                 // Warning will already have been written
  17019                 break;
  17020             case ResultWas::ExplicitFailure:
  17021                 m_xml.startElement( "Failure" );
  17022                 writeSourceInfo( result.getSourceInfo() );
  17023                 m_xml.writeText( result.getMessage() );
  17024                 m_xml.endElement();
  17025                 break;
  17026             default:
  17027                 break;
  17028         }
  17029 
  17030         if( result.hasExpression() )
  17031             m_xml.endElement();
  17032 
  17033         return true;
  17034     }
  17035 
  17036     void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
  17037         StreamingReporterBase::sectionEnded( sectionStats );
  17038         if( --m_sectionDepth > 0 ) {
  17039             XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
  17040             e.writeAttribute( "successes", sectionStats.assertions.passed );
  17041             e.writeAttribute( "failures", sectionStats.assertions.failed );
  17042             e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
  17043 
  17044             if ( m_config->showDurations() == ShowDurations::Always )
  17045                 e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
  17046 
  17047             m_xml.endElement();
  17048         }
  17049     }
  17050 
  17051     void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
  17052         StreamingReporterBase::testCaseEnded( testCaseStats );
  17053         XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
  17054         e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
  17055 
  17056         if ( m_config->showDurations() == ShowDurations::Always )
  17057             e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
  17058 
  17059         if( !testCaseStats.stdOut.empty() )
  17060             m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );
  17061         if( !testCaseStats.stdErr.empty() )
  17062             m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );
  17063 
  17064         m_xml.endElement();
  17065     }
  17066 
  17067     void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
  17068         StreamingReporterBase::testGroupEnded( testGroupStats );
  17069         // TODO: Check testGroupStats.aborting and act accordingly.
  17070         m_xml.scopedElement( "OverallResults" )
  17071             .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
  17072             .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
  17073             .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
  17074         m_xml.endElement();
  17075     }
  17076 
  17077     void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
  17078         StreamingReporterBase::testRunEnded( testRunStats );
  17079         m_xml.scopedElement( "OverallResults" )
  17080             .writeAttribute( "successes", testRunStats.totals.assertions.passed )
  17081             .writeAttribute( "failures", testRunStats.totals.assertions.failed )
  17082             .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
  17083         m_xml.endElement();
  17084     }
  17085 
  17086 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  17087     void XmlReporter::benchmarkPreparing(std::string const& name) {
  17088         m_xml.startElement("BenchmarkResults")
  17089             .writeAttribute("name", name);
  17090     }
  17091 
  17092     void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
  17093         m_xml.writeAttribute("samples", info.samples)
  17094             .writeAttribute("resamples", info.resamples)
  17095             .writeAttribute("iterations", info.iterations)
  17096             .writeAttribute("clockResolution", static_cast<uint64_t>(info.clockResolution))
  17097             .writeAttribute("estimatedDuration", static_cast<uint64_t>(info.estimatedDuration))
  17098             .writeComment("All values in nano seconds");
  17099     }
  17100 
  17101     void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
  17102         m_xml.startElement("mean")
  17103             .writeAttribute("value", static_cast<uint64_t>(benchmarkStats.mean.point.count()))
  17104             .writeAttribute("lowerBound", static_cast<uint64_t>(benchmarkStats.mean.lower_bound.count()))
  17105             .writeAttribute("upperBound", static_cast<uint64_t>(benchmarkStats.mean.upper_bound.count()))
  17106             .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
  17107         m_xml.endElement();
  17108         m_xml.startElement("standardDeviation")
  17109             .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
  17110             .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
  17111             .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
  17112             .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
  17113         m_xml.endElement();
  17114         m_xml.startElement("outliers")
  17115             .writeAttribute("variance", benchmarkStats.outlierVariance)
  17116             .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
  17117             .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
  17118             .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
  17119             .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
  17120         m_xml.endElement();
  17121         m_xml.endElement();
  17122     }
  17123 
  17124     void XmlReporter::benchmarkFailed(std::string const &error) {
  17125         m_xml.scopedElement("failed").
  17126             writeAttribute("message", error);
  17127         m_xml.endElement();
  17128     }
  17129 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  17130 
  17131     CATCH_REGISTER_REPORTER( "xml", XmlReporter )
  17132 
  17133 } // end namespace Catch
  17134 
  17135 #if defined(_MSC_VER)
  17136 #pragma warning(pop)
  17137 #endif
  17138 // end catch_reporter_xml.cpp
  17139 
  17140 namespace Catch {
  17141     LeakDetector leakDetector;
  17142 }
  17143 
  17144 #ifdef __clang__
  17145 #pragma clang diagnostic pop
  17146 #endif
  17147 
  17148 // end catch_impl.hpp
  17149 #endif
  17150 
  17151 #ifdef CATCH_CONFIG_MAIN
  17152 // start catch_default_main.hpp
  17153 
  17154 #ifndef __OBJC__
  17155 
  17156 #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
  17157 // Standard C/C++ Win32 Unicode wmain entry point
  17158 extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
  17159 #else
  17160 // Standard C/C++ main entry point
  17161 int main (int argc, char * argv[]) {
  17162 #endif
  17163 
  17164     return Catch::Session().run( argc, argv );
  17165 }
  17166 
  17167 #else // __OBJC__
  17168 
  17169 // Objective-C entry point
  17170 int main (int argc, char * const argv[]) {
  17171 #if !CATCH_ARC_ENABLED
  17172     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  17173 #endif
  17174 
  17175     Catch::registerTestMethods();
  17176     int result = Catch::Session().run( argc, (char**)argv );
  17177 
  17178 #if !CATCH_ARC_ENABLED
  17179     [pool drain];
  17180 #endif
  17181 
  17182     return result;
  17183 }
  17184 
  17185 #endif // __OBJC__
  17186 
  17187 // end catch_default_main.hpp
  17188 #endif
  17189 
  17190 #if !defined(CATCH_CONFIG_IMPL_ONLY)
  17191 
  17192 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
  17193 #  undef CLARA_CONFIG_MAIN
  17194 #endif
  17195 
  17196 #if !defined(CATCH_CONFIG_DISABLE)
  17197 //////
  17198 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  17199 #ifdef CATCH_CONFIG_PREFIX_ALL
  17200 
  17201 #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17202 #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  17203 
  17204 #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17205 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  17206 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  17207 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17208 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  17209 #endif// CATCH_CONFIG_DISABLE_MATCHERS
  17210 #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17211 
  17212 #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17213 #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  17214 #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17215 #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17216 #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  17217 
  17218 #define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17219 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  17220 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  17221 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17222 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  17223 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17224 #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17225 
  17226 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17227 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  17228 
  17229 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  17230 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17231 
  17232 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
  17233 #define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
  17234 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  17235 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
  17236 
  17237 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  17238 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17239 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  17240 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  17241 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  17242 #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
  17243 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17244 #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17245 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17246 
  17247 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  17248 
  17249 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  17250 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17251 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
  17252 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17253 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  17254 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
  17255 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
  17256 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17257 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  17258 #else
  17259 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
  17260 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
  17261 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  17262 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  17263 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
  17264 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
  17265 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  17266 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  17267 #endif
  17268 
  17269 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
  17270 #define CATCH_STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__ ,      #__VA_ARGS__ );     CATCH_SUCCEED( #__VA_ARGS__ )
  17271 #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
  17272 #else
  17273 #define CATCH_STATIC_REQUIRE( ... )       CATCH_REQUIRE( __VA_ARGS__ )
  17274 #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
  17275 #endif
  17276 
  17277 // "BDD-style" convenience wrappers
  17278 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
  17279 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  17280 #define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
  17281 #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
  17282 #define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
  17283 #define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
  17284 #define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
  17285 #define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
  17286 
  17287 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  17288 #define CATCH_BENCHMARK(...) \
  17289     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__,,))
  17290 #define CATCH_BENCHMARK_ADVANCED(name) \
  17291     INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
  17292 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  17293 
  17294 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  17295 #else
  17296 
  17297 #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__  )
  17298 #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  17299 
  17300 #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17301 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  17302 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  17303 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17304 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  17305 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17306 #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17307 
  17308 #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17309 #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  17310 #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17311 #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17312 #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  17313 
  17314 #define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17315 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  17316 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  17317 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17318 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  17319 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17320 #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17321 
  17322 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17323 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  17324 
  17325 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  17326 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17327 
  17328 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
  17329 #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
  17330 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  17331 #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
  17332 
  17333 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  17334 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17335 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  17336 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  17337 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  17338 #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
  17339 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  17340 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17341 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  17342 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  17343 
  17344 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  17345 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17346 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
  17347 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17348 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  17349 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
  17350 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
  17351 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17352 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  17353 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
  17354 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17355 #else
  17356 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
  17357 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
  17358 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  17359 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  17360 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
  17361 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
  17362 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  17363 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  17364 #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
  17365 #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  17366 #endif
  17367 
  17368 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
  17369 #define STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__,  #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
  17370 #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
  17371 #else
  17372 #define STATIC_REQUIRE( ... )       REQUIRE( __VA_ARGS__ )
  17373 #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
  17374 #endif
  17375 
  17376 #endif
  17377 
  17378 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
  17379 
  17380 // "BDD-style" convenience wrappers
  17381 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
  17382 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  17383 
  17384 #define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
  17385 #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
  17386 #define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
  17387 #define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
  17388 #define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
  17389 #define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
  17390 
  17391 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  17392 #define BENCHMARK(...) \
  17393     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__,,))
  17394 #define BENCHMARK_ADVANCED(name) \
  17395     INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
  17396 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  17397 
  17398 using Catch::Detail::Approx;
  17399 
  17400 #else // CATCH_CONFIG_DISABLE
  17401 
  17402 //////
  17403 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  17404 #ifdef CATCH_CONFIG_PREFIX_ALL
  17405 
  17406 #define CATCH_REQUIRE( ... )        (void)(0)
  17407 #define CATCH_REQUIRE_FALSE( ... )  (void)(0)
  17408 
  17409 #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
  17410 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  17411 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0)
  17412 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17413 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  17414 #endif// CATCH_CONFIG_DISABLE_MATCHERS
  17415 #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
  17416 
  17417 #define CATCH_CHECK( ... )         (void)(0)
  17418 #define CATCH_CHECK_FALSE( ... )   (void)(0)
  17419 #define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__)
  17420 #define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__))
  17421 #define CATCH_CHECK_NOFAIL( ... )  (void)(0)
  17422 
  17423 #define CATCH_CHECK_THROWS( ... )  (void)(0)
  17424 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  17425 #define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0)
  17426 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17427 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  17428 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17429 #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
  17430 
  17431 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17432 #define CATCH_CHECK_THAT( arg, matcher )   (void)(0)
  17433 
  17434 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
  17435 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17436 
  17437 #define CATCH_INFO( msg )          (void)(0)
  17438 #define CATCH_UNSCOPED_INFO( msg ) (void)(0)
  17439 #define CATCH_WARN( msg )          (void)(0)
  17440 #define CATCH_CAPTURE( msg )       (void)(0)
  17441 
  17442 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17443 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17444 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
  17445 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
  17446 #define CATCH_SECTION( ... )
  17447 #define CATCH_DYNAMIC_SECTION( ... )
  17448 #define CATCH_FAIL( ... ) (void)(0)
  17449 #define CATCH_FAIL_CHECK( ... ) (void)(0)
  17450 #define CATCH_SUCCEED( ... ) (void)(0)
  17451 
  17452 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17453 
  17454 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  17455 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
  17456 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
  17457 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
  17458 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
  17459 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17460 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17461 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17462 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17463 #else
  17464 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
  17465 #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
  17466 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
  17467 #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
  17468 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17469 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17470 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17471 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17472 #endif
  17473 
  17474 // "BDD-style" convenience wrappers
  17475 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17476 #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 )
  17477 #define CATCH_GIVEN( desc )
  17478 #define CATCH_AND_GIVEN( desc )
  17479 #define CATCH_WHEN( desc )
  17480 #define CATCH_AND_WHEN( desc )
  17481 #define CATCH_THEN( desc )
  17482 #define CATCH_AND_THEN( desc )
  17483 
  17484 #define CATCH_STATIC_REQUIRE( ... )       (void)(0)
  17485 #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
  17486 
  17487 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  17488 #else
  17489 
  17490 #define REQUIRE( ... )       (void)(0)
  17491 #define REQUIRE_FALSE( ... ) (void)(0)
  17492 
  17493 #define REQUIRE_THROWS( ... ) (void)(0)
  17494 #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  17495 #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
  17496 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17497 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  17498 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17499 #define REQUIRE_NOTHROW( ... ) (void)(0)
  17500 
  17501 #define CHECK( ... ) (void)(0)
  17502 #define CHECK_FALSE( ... ) (void)(0)
  17503 #define CHECKED_IF( ... ) if (__VA_ARGS__)
  17504 #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
  17505 #define CHECK_NOFAIL( ... ) (void)(0)
  17506 
  17507 #define CHECK_THROWS( ... )  (void)(0)
  17508 #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  17509 #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
  17510 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17511 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  17512 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17513 #define CHECK_NOTHROW( ... ) (void)(0)
  17514 
  17515 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  17516 #define CHECK_THAT( arg, matcher ) (void)(0)
  17517 
  17518 #define REQUIRE_THAT( arg, matcher ) (void)(0)
  17519 #endif // CATCH_CONFIG_DISABLE_MATCHERS
  17520 
  17521 #define INFO( msg ) (void)(0)
  17522 #define UNSCOPED_INFO( msg ) (void)(0)
  17523 #define WARN( msg ) (void)(0)
  17524 #define CAPTURE( msg ) (void)(0)
  17525 
  17526 #define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17527 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17528 #define METHOD_AS_TEST_CASE( method, ... )
  17529 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
  17530 #define SECTION( ... )
  17531 #define DYNAMIC_SECTION( ... )
  17532 #define FAIL( ... ) (void)(0)
  17533 #define FAIL_CHECK( ... ) (void)(0)
  17534 #define SUCCEED( ... ) (void)(0)
  17535 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  17536 
  17537 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  17538 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
  17539 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
  17540 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
  17541 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
  17542 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17543 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17544 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17545 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17546 #else
  17547 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
  17548 #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
  17549 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
  17550 #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
  17551 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17552 #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  17553 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17554 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  17555 #endif
  17556 
  17557 #define STATIC_REQUIRE( ... )       (void)(0)
  17558 #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
  17559 
  17560 #endif
  17561 
  17562 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
  17563 
  17564 // "BDD-style" convenience wrappers
  17565 #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
  17566 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
  17567 
  17568 #define GIVEN( desc )
  17569 #define AND_GIVEN( desc )
  17570 #define WHEN( desc )
  17571 #define AND_WHEN( desc )
  17572 #define THEN( desc )
  17573 #define AND_THEN( desc )
  17574 
  17575 using Catch::Detail::Approx;
  17576 
  17577 #endif
  17578 
  17579 #endif // ! CATCH_CONFIG_IMPL_ONLY
  17580 
  17581 // start catch_reenable_warnings.h
  17582 
  17583 
  17584 #ifdef __clang__
  17585 #    ifdef __ICC // icpc defines the __clang__ macro
  17586 #        pragma warning(pop)
  17587 #    else
  17588 #        pragma clang diagnostic pop
  17589 #    endif
  17590 #elif defined __GNUC__
  17591 #    pragma GCC diagnostic pop
  17592 #endif
  17593 
  17594 // end catch_reenable_warnings.h
  17595 // end catch.hpp
  17596 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
  17597