Author: Mason Wright
Email:
[email protected]
Date: Sun, 29 Jun 2025 13:33:00 -0600
include/catch_amalgamated.hpp
5e4c38ff3c212cdd9881427ef3f8c2706539a190
Reworked parseSelectorParts and tests
Clone
-
.gitignore
M
Makefile
-
include/catch_amalgamated.cpp
-
include/catch_amalgamated.hpp
M
include/grim.h
-
include/parser.h
-
index.html
-
main.cc
-
src/adapter.cc
-
src/events.cc
M
src/grim.cc
A
src/grim.cc.bak
-
src/parser.cc
-
style.css
A
tests/css_selector.cc
-
tests/html_parser.cc
Commits
b966b2a517365074e5c381dbdea05b3221dc0198
e840f1eeb0ae26af69e1ae146ea9938e28e9f1af
e4e05418a640eaed08cd1ec7cd8644eb1dbcca50
4e01ba8ad2c3361fa4be3d896288020948b58b5e
aae562ac1350480e4889aabb35899f776c5b59e9
6c3ae0e31eb0893f20e3872117f92cc6b9a942af
350e7d88bb2feb9db00c6e032cc6623f215b7adf
95e6c70d23e99ffcf70e5bbe12503496e5d8f232
e188783659b9bc3b9993a647e93ed110e7f41db6
5e4c38ff3c212cdd9881427ef3f8c2706539a190
e50ea9e1356a74af18fdd171337ef9dc931e1f4e
8f2e83556d12aaebe8e8597ea6923804b0eb7a43
1627c585128af263181053ab2cf1a4cdcd14ee21
def3513f75b325464ad88a33c741c4ca80572b77
a21501590980a905fa9b902897d700a42a08b7f0
56074a6bfe4498d092f3a227297c8c20e2bb962c
d9cf1485b7ae0614130494f0e73237921323b9a1
80f04b134ae32ad8a9d526007b33dd02f6600f05
23d6c65f9368d3c622a55a3068a6b2f1efa0c8d4
09c195df02536b6a796bd648fce9669397b96109
f2b5c8202fbc904e2ed78260e3fdbd55164799d2
4bfba076120f389994fc46a98e8b7a2622314400
e36ac5417e10ee9b9f94f340e1ccf28afc5705ea
d00dc89a86dd7e2fcfd4618bc3a1c8cfba9e3c3d
d9eef16adaf292f3748db5fb5aa98463de10d712
18ff2ec1bfc1cf9fcd17c1acb05c3b41f8f0ed83
9e7fd2980d723437ea621b78d395fa72ca3f4922
Diff
diff --git a/include/catch_amalgamated.hpp b/include/catch_amalgamated.hpp deleted file mode 100644 index 7e75a5d..0000000 --- a/include/catch_amalgamated.hpp +++ /dev/null @@ -1,13927 +0,0 @@ - -// Copyright Catch2 Authors -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE.txt or copy at -// https://www.boost.org/LICENSE_1_0.txt) - -// SPDX-License-Identifier: BSL-1.0 - -// Catch v3.5.4 -// Generated: 2024-04-10 12:03:45.785902 -// ---------------------------------------------------------- -// This file is an amalgamation of multiple different files. -// You probably shouldn't edit it directly. -// ---------------------------------------------------------- -#ifndef CATCH_AMALGAMATED_HPP_INCLUDED -#define CATCH_AMALGAMATED_HPP_INCLUDED - - -/** \file - * This is a convenience header for Catch2. It includes **all** of Catch2 headers. - * - * Generally the Catch2 users should use specific includes they need, - * but this header can be used instead for ease-of-experimentation, or - * just plain convenience, at the cost of (significantly) increased - * compilation times. - * - * When a new header is added to either the top level folder, or to the - * corresponding internal subfolder, it should be added here. Headers - * added to the various subparts (e.g. matchers, generators, etc...), - * should go their respective catch-all headers. - */ - -#ifndef CATCH_ALL_HPP_INCLUDED -#define CATCH_ALL_HPP_INCLUDED - - - -/** \file - * This is a convenience header for Catch2's benchmarking. It includes - * **all** of Catch2 headers related to benchmarking. - * - * Generally the Catch2 users should use specific includes they need, - * but this header can be used instead for ease-of-experimentation, or - * just plain convenience, at the cost of (significantly) increased - * compilation times. - * - * When a new header is added to either the `benchmark` folder, or to - * the corresponding internal (detail) subfolder, it should be added here. - */ - -#ifndef CATCH_BENCHMARK_ALL_HPP_INCLUDED -#define CATCH_BENCHMARK_ALL_HPP_INCLUDED - - - -// Adapted from donated nonius code. - -#ifndef CATCH_BENCHMARK_HPP_INCLUDED -#define CATCH_BENCHMARK_HPP_INCLUDED - - - -#ifndef CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED -#define CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED - -// Detect a number of compiler features - by compiler -// The following features are defined: -// -// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? -// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? -// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? -// **************** -// Note to maintainers: if new toggles are added please document them -// in configuration.md, too -// **************** - -// In general each macro has a _NO_
form -// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. -// Many features, at point of detection, define an _INTERNAL_ macro, so they -// can be combined, en-mass, with the _NO_ forms later. - - - -#ifndef CATCH_PLATFORM_HPP_INCLUDED -#define CATCH_PLATFORM_HPP_INCLUDED - -// See e.g.: -// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html -#ifdef __APPLE__ -# ifndef __has_extension -# define __has_extension(x) 0 -# endif -# include
-# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ - (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) -# define CATCH_PLATFORM_MAC -# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) -# define CATCH_PLATFORM_IPHONE -# endif - -#elif defined(linux) || defined(__linux) || defined(__linux__) -# define CATCH_PLATFORM_LINUX - -#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) -# define CATCH_PLATFORM_WINDOWS - -# if defined( WINAPI_FAMILY ) && ( WINAPI_FAMILY == WINAPI_FAMILY_APP ) -# define CATCH_PLATFORM_WINDOWS_UWP -# endif - -#elif defined(__ORBIS__) || defined(__PROSPERO__) -# define CATCH_PLATFORM_PLAYSTATION - -#endif - -#endif // CATCH_PLATFORM_HPP_INCLUDED - -#ifdef __cplusplus - -# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -# define CATCH_CPP17_OR_GREATER -# endif - -# if (__cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) -# define CATCH_CPP20_OR_GREATER -# endif - -#endif - -// Only GCC compiler should be used in this block, so other compilers trying to -// mask themselves as GCC should be ignored. -#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) && !defined(__NVCOMPILER) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) - -// This only works on GCC 9+. so we have to also add a global suppression of Wparentheses -// for older versions of GCC. -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" ) - -# define CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \ - _Pragma( "GCC diagnostic ignored \"-Wunused-result\"" ) - -# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \ - _Pragma( "GCC diagnostic ignored \"-Wunused-variable\"" ) - -# define CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \ - _Pragma( "GCC diagnostic ignored \"-Wuseless-cast\"" ) - -# define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \ - _Pragma( "GCC diagnostic ignored \"-Wshadow\"" ) - -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) - -#endif - -#if defined(__NVCOMPILER) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "diag push" ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "diag pop" ) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "diag_suppress declared_but_not_referenced" ) -#endif - -#if defined(__CUDACC__) && !defined(__clang__) -# ifdef __NVCC_DIAG_PRAGMA_SUPPORT__ -// New pragmas introduced in CUDA 11.5+ -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic push" ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic pop" ) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "nv_diag_suppress 177" ) -# else -# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "diag_suppress 177" ) -# endif -#endif - -// clang-cl defines _MSC_VER as well as __clang__, which could cause the -// start/stop internal suppression macros to be double defined. -#if defined(__clang__) && !defined(_MSC_VER) - -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) - -#endif // __clang__ && !_MSC_VER - -#if defined(__clang__) - -// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug -// which results in calls to destructors being emitted for each temporary, -// without a matching initialization. In practice, this can result in something -// like `std::string::~string` being called on an uninitialized value. -// -// For example, this code will likely segfault under IBM XL: -// ``` -// REQUIRE(std::string("12") + "34" == "1234") -// ``` -// -// Similarly, NVHPC's implementation of `__builtin_constant_p` has a bug which -// results in calls to the immediately evaluated lambda expressions to be -// reported as unevaluated lambdas. -// https://developer.nvidia.com/nvidia_bug/3321845. -// -// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. -# if !defined(__ibmxl__) && !defined(__CUDACC__) && !defined( __NVCOMPILER ) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ -# endif - - -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ - _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") - -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) - -# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) - -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) - -# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) - -# define CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wcomma\"" ) - -# define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wshadow\"" ) - -#endif // __clang__ - - -//////////////////////////////////////////////////////////////////////////////// -// We know some environments not to support full POSIX signals -#if defined( CATCH_PLATFORM_WINDOWS ) || \ - defined( CATCH_PLATFORM_PLAYSTATION ) || \ - defined( __CYGWIN__ ) || \ - defined( __QNX__ ) || \ - defined( __EMSCRIPTEN__ ) || \ - defined( __DJGPP__ ) || \ - defined( __OS400__ ) -# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -#else -# define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Assume that some platforms do not support getenv. -#if defined( CATCH_PLATFORM_WINDOWS_UWP ) || \ - defined( CATCH_PLATFORM_PLAYSTATION ) || \ - defined( _GAMING_XBOX ) -# define CATCH_INTERNAL_CONFIG_NO_GETENV -#else -# define CATCH_INTERNAL_CONFIG_GETENV -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Android somehow still does not support std::to_string -#if defined(__ANDROID__) -# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Not all Windows environments support SEH properly -#if defined(__MINGW32__) -# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH -#endif - -//////////////////////////////////////////////////////////////////////////////// -// PS4 -#if defined(__ORBIS__) -# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Cygwin -#ifdef __CYGWIN__ - -// Required for some versions of Cygwin to declare gettimeofday -// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin -# define _BSD_SOURCE -// some versions of cygwin (most) do not support std::to_string. Use the libstd check. -// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 -# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ - && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) - -# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING - -# endif -#endif // __CYGWIN__ - -//////////////////////////////////////////////////////////////////////////////// -// Visual C++ -#if defined(_MSC_VER) - -// We want to defer to nvcc-specific warning suppression if we are compiled -// with nvcc masquerading for MSVC. -# if !defined( __CUDACC__ ) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ - __pragma( warning( push ) ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ - __pragma( warning( pop ) ) -# endif - -// Universal Windows platform does not support SEH -// Or console colours (or console at all...) -# if defined(CATCH_PLATFORM_WINDOWS_UWP) -# define CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32 -# else -# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH -# endif - -// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ -// _MSVC_TRADITIONAL == 0 means new conformant preprocessor -// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor -# if !defined(__clang__) // Handle Clang masquerading for msvc -# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) -# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -# endif // MSVC_TRADITIONAL -# endif // __clang__ - -#endif // _MSC_VER - -#if defined(_REENTRANT) || defined(_MSC_VER) -// Enable async processing, as -pthread is specified or no additional linking is required -# define CATCH_INTERNAL_CONFIG_USE_ASYNC -#endif // _MSC_VER - -//////////////////////////////////////////////////////////////////////////////// -// Check if we are compiled with -fno-exceptions or equivalent -#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) -# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED -#endif - - -//////////////////////////////////////////////////////////////////////////////// -// Embarcadero C++Build -#if defined(__BORLANDC__) - #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN -#endif - -//////////////////////////////////////////////////////////////////////////////// - -// RTX is a special version of Windows that is real time. -// This means that it is detected as Windows, but does not provide -// the same set of capabilities as real Windows does. -#if defined(UNDER_RTSS) || defined(RTX64_BUILD) - #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH - #define CATCH_INTERNAL_CONFIG_NO_ASYNC - #define CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32 -#endif - -#if !defined(_GLIBCXX_USE_C99_MATH_TR1) -#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER -#endif - -// Various stdlib support checks that require __has_include -#if defined(__has_include) - // Check if string_view is available and usable - #if __has_include(
) && defined(CATCH_CPP17_OR_GREATER) - # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW - #endif - - // Check if optional is available and usable - # if __has_include(
) && defined(CATCH_CPP17_OR_GREATER) - # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL - # endif // __has_include(
) && defined(CATCH_CPP17_OR_GREATER) - - // Check if byte is available and usable - # if __has_include(
) && defined(CATCH_CPP17_OR_GREATER) - # include
- # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) - # define CATCH_INTERNAL_CONFIG_CPP17_BYTE - # endif - # endif // __has_include(
) && defined(CATCH_CPP17_OR_GREATER) - - // Check if variant is available and usable - # if __has_include(
) && defined(CATCH_CPP17_OR_GREATER) - # if defined(__clang__) && (__clang_major__ < 8) - // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 - // fix should be in clang 8, workaround in libstdc++ 8.2 - # include
- # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) - # define CATCH_CONFIG_NO_CPP17_VARIANT - # else - # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT - # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) - # else - # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT - # endif // defined(__clang__) && (__clang_major__ < 8) - # endif // __has_include(
) && defined(CATCH_CPP17_OR_GREATER) -#endif // defined(__has_include) - - -#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) -# define CATCH_CONFIG_WINDOWS_SEH -#endif -// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. -#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) -# define CATCH_CONFIG_POSIX_SIGNALS -#endif - -#if defined(CATCH_INTERNAL_CONFIG_GETENV) && !defined(CATCH_INTERNAL_CONFIG_NO_GETENV) && !defined(CATCH_CONFIG_NO_GETENV) && !defined(CATCH_CONFIG_GETENV) -# define CATCH_CONFIG_GETENV -#endif - -#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) -# define CATCH_CONFIG_CPP11_TO_STRING -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) -# define CATCH_CONFIG_CPP17_OPTIONAL -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) -# define CATCH_CONFIG_CPP17_STRING_VIEW -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) -# define CATCH_CONFIG_CPP17_VARIANT -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) -# define CATCH_CONFIG_CPP17_BYTE -#endif - - -#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) -# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE -#endif - -#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) -# define CATCH_CONFIG_NEW_CAPTURE -#endif - -#if !defined( CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED ) && \ - !defined( CATCH_CONFIG_DISABLE_EXCEPTIONS ) && \ - !defined( CATCH_CONFIG_NO_DISABLE_EXCEPTIONS ) -# define CATCH_CONFIG_DISABLE_EXCEPTIONS -#endif - -#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) -# define CATCH_CONFIG_POLYFILL_ISNAN -#endif - -#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) -# define CATCH_CONFIG_USE_ASYNC -#endif - -#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) -# define CATCH_CONFIG_GLOBAL_NEXTAFTER -#endif - - -// Even if we do not think the compiler has that warning, we still have -// to provide a macro that can be used by the code. -#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION -#endif -#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS -#endif -#if !defined( CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS ) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#endif -#if !defined( CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS ) -# define CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS -#endif -#if !defined( CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS ) -# define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS -#endif - - -// The goal of this macro is to avoid evaluation of the arguments, but -// still have the compiler warn on problems inside... -#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) -#endif - -#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) -# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#elif defined(__clang__) && (__clang_major__ < 5) -# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#endif - - -#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -#define CATCH_TRY if ((true)) -#define CATCH_CATCH_ALL if ((false)) -#define CATCH_CATCH_ANON(type) if ((false)) -#else -#define CATCH_TRY try -#define CATCH_CATCH_ALL catch (...) -#define CATCH_CATCH_ANON(type) catch (type) -#endif - -#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) -#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#endif - -#if defined( CATCH_PLATFORM_WINDOWS ) && \ - !defined( CATCH_CONFIG_COLOUR_WIN32 ) && \ - !defined( CATCH_CONFIG_NO_COLOUR_WIN32 ) && \ - !defined( CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32 ) -# define CATCH_CONFIG_COLOUR_WIN32 -#endif - -#if defined( CATCH_CONFIG_SHARED_LIBRARY ) && defined( _MSC_VER ) && \ - !defined( CATCH_CONFIG_STATIC ) -# ifdef Catch2_EXPORTS -# define CATCH_EXPORT //__declspec( dllexport ) // not needed -# else -# define CATCH_EXPORT __declspec( dllimport ) -# endif -#else -# define CATCH_EXPORT -#endif - -#endif // CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED - - -#ifndef CATCH_CONTEXT_HPP_INCLUDED -#define CATCH_CONTEXT_HPP_INCLUDED - - -namespace Catch { - - class IResultCapture; - class IConfig; - - class Context { - IConfig const* m_config = nullptr; - IResultCapture* m_resultCapture = nullptr; - - CATCH_EXPORT static Context* currentContext; - friend Context& getCurrentMutableContext(); - friend Context const& getCurrentContext(); - static void createContext(); - friend void cleanUpContext(); - - public: - IResultCapture* getResultCapture() const { return m_resultCapture; } - IConfig const* getConfig() const { return m_config; } - void setResultCapture( IResultCapture* resultCapture ); - void setConfig( IConfig const* config ); - }; - - Context& getCurrentMutableContext(); - - inline Context const& getCurrentContext() { - // We duplicate the logic from `getCurrentMutableContext` here, - // to avoid paying the call overhead in debug mode. - if ( !Context::currentContext ) { Context::createContext(); } - // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn) - return *Context::currentContext; - } - - void cleanUpContext(); - - class SimplePcg32; - SimplePcg32& sharedRng(); -} - -#endif // CATCH_CONTEXT_HPP_INCLUDED - - -#ifndef CATCH_MOVE_AND_FORWARD_HPP_INCLUDED -#define CATCH_MOVE_AND_FORWARD_HPP_INCLUDED - -#include
- -//! Replacement for std::move with better compile time performance -#define CATCH_MOVE(...) static_cast
&&>(__VA_ARGS__) - -//! Replacement for std::forward with better compile time performance -#define CATCH_FORWARD(...) static_cast
(__VA_ARGS__) - -#endif // CATCH_MOVE_AND_FORWARD_HPP_INCLUDED - - -#ifndef CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED -#define CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED - -namespace Catch { - - //! Used to signal that an assertion macro failed - struct TestFailureException{}; - //! Used to signal that the remainder of a test should be skipped - struct TestSkipException {}; - - /** - * Outlines throwing of `TestFailureException` into a single TU - * - * Also handles `CATCH_CONFIG_DISABLE_EXCEPTIONS` for callers. - */ - [[noreturn]] void throw_test_failure_exception(); - - /** - * Outlines throwing of `TestSkipException` into a single TU - * - * Also handles `CATCH_CONFIG_DISABLE_EXCEPTIONS` for callers. - */ - [[noreturn]] void throw_test_skip_exception(); - -} // namespace Catch - -#endif // CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED - - -#ifndef CATCH_UNIQUE_NAME_HPP_INCLUDED -#define CATCH_UNIQUE_NAME_HPP_INCLUDED - - - - -/** \file - * Wrapper for the CONFIG configuration option - * - * When generating internal unique names, there are two options. Either - * we mix in the current line number, or mix in an incrementing number. - * We prefer the latter, using `__COUNTER__`, but users might want to - * use the former. - */ - -#ifndef CATCH_CONFIG_COUNTER_HPP_INCLUDED -#define CATCH_CONFIG_COUNTER_HPP_INCLUDED - - -#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) - #define CATCH_INTERNAL_CONFIG_COUNTER -#endif - -#if defined( CATCH_INTERNAL_CONFIG_COUNTER ) && \ - !defined( CATCH_CONFIG_NO_COUNTER ) && \ - !defined( CATCH_CONFIG_COUNTER ) -# define CATCH_CONFIG_COUNTER -#endif - - -#endif // CATCH_CONFIG_COUNTER_HPP_INCLUDED -#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line -#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) -#ifdef CATCH_CONFIG_COUNTER -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) -#else -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) -#endif - -#endif // CATCH_UNIQUE_NAME_HPP_INCLUDED - - -#ifndef CATCH_INTERFACES_CAPTURE_HPP_INCLUDED -#define CATCH_INTERFACES_CAPTURE_HPP_INCLUDED - -#include
-#include
- - - -#ifndef CATCH_STRINGREF_HPP_INCLUDED -#define CATCH_STRINGREF_HPP_INCLUDED - -#include
-#include
-#include
-#include
- -#include
- -namespace Catch { - - /// A non-owning string class (similar to the forthcoming std::string_view) - /// Note that, because a StringRef may be a substring of another string, - /// it may not be null terminated. - class StringRef { - public: - using size_type = std::size_t; - using const_iterator = const char*; - - static constexpr size_type npos{ static_cast
( -1 ) }; - - private: - static constexpr char const* const s_empty = ""; - - char const* m_start = s_empty; - size_type m_size = 0; - - public: // construction - constexpr StringRef() noexcept = default; - - StringRef( char const* rawChars ) noexcept; - - constexpr StringRef( char const* rawChars, size_type size ) noexcept - : m_start( rawChars ), - m_size( size ) - {} - - StringRef( std::string const& stdString ) noexcept - : m_start( stdString.c_str() ), - m_size( stdString.size() ) - {} - - explicit operator std::string() const { - return std::string(m_start, m_size); - } - - public: // operators - auto operator == ( StringRef other ) const noexcept -> bool { - return m_size == other.m_size - && (std::memcmp( m_start, other.m_start, m_size ) == 0); - } - auto operator != (StringRef other) const noexcept -> bool { - return !(*this == other); - } - - constexpr auto operator[] ( size_type index ) const noexcept -> char { - assert(index < m_size); - return m_start[index]; - } - - bool operator<(StringRef rhs) const noexcept; - - public: // named queries - constexpr auto empty() const noexcept -> bool { - return m_size == 0; - } - constexpr auto size() const noexcept -> size_type { - return m_size; - } - - // Returns a substring of [start, start + length). - // If start + length > size(), then the substring is [start, size()). - // If start > size(), then the substring is empty. - constexpr StringRef substr(size_type start, size_type length) const noexcept { - if (start < m_size) { - const auto shortened_size = m_size - start; - return StringRef(m_start + start, (shortened_size < length) ? shortened_size : length); - } else { - return StringRef(); - } - } - - // Returns the current start pointer. May not be null-terminated. - constexpr char const* data() const noexcept { - return m_start; - } - - constexpr const_iterator begin() const { return m_start; } - constexpr const_iterator end() const { return m_start + m_size; } - - - friend std::string& operator += (std::string& lhs, StringRef rhs); - friend std::ostream& operator << (std::ostream& os, StringRef str); - friend std::string operator+(StringRef lhs, StringRef rhs); - - /** - * Provides a three-way comparison with rhs - * - * Returns negative number if lhs < rhs, 0 if lhs == rhs, and a positive - * number if lhs > rhs - */ - int compare( StringRef rhs ) const; - }; - - - constexpr auto operator ""_sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { - return StringRef( rawChars, size ); - } -} // namespace Catch - -constexpr auto operator ""_catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { - return Catch::StringRef( rawChars, size ); -} - -#endif // CATCH_STRINGREF_HPP_INCLUDED - - -#ifndef CATCH_RESULT_TYPE_HPP_INCLUDED -#define CATCH_RESULT_TYPE_HPP_INCLUDED - -namespace Catch { - - // ResultWas::OfType enum - struct ResultWas { enum OfType { - Unknown = -1, - Ok = 0, - Info = 1, - Warning = 2, - // TODO: Should explicit skip be considered "not OK" (cf. isOk)? I.e., should it have the failure bit? - ExplicitSkip = 4, - - FailureBit = 0x10, - - ExpressionFailed = FailureBit | 1, - ExplicitFailure = FailureBit | 2, - - Exception = 0x100 | FailureBit, - - ThrewException = Exception | 1, - DidntThrowException = Exception | 2, - - FatalErrorCondition = 0x200 | FailureBit - - }; }; - - bool isOk( ResultWas::OfType resultType ); - bool isJustInfo( int flags ); - - - // ResultDisposition::Flags enum - struct ResultDisposition { enum Flags { - Normal = 0x01, - - ContinueOnFailure = 0x02, // Failures fail test, but execution continues - FalseTest = 0x04, // Prefix expression with ! - SuppressFail = 0x08 // Failures are reported but do not fail the test - }; }; - - ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ); - - bool shouldContinueOnFailure( int flags ); - inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } - bool shouldSuppressFailure( int flags ); - -} // end namespace Catch - -#endif // CATCH_RESULT_TYPE_HPP_INCLUDED - - -#ifndef CATCH_UNIQUE_PTR_HPP_INCLUDED -#define CATCH_UNIQUE_PTR_HPP_INCLUDED - -#include
-#include
- - -namespace Catch { -namespace Detail { - /** - * A reimplementation of `std::unique_ptr` for improved compilation performance - * - * Does not support arrays nor custom deleters. - */ - template
- class unique_ptr { - T* m_ptr; - public: - constexpr unique_ptr(std::nullptr_t = nullptr): - m_ptr{} - {} - explicit constexpr unique_ptr(T* ptr): - m_ptr(ptr) - {} - - template
::value>> - unique_ptr(unique_ptr
&& from): - m_ptr(from.release()) - {} - - template
::value>> - unique_ptr& operator=(unique_ptr
&& from) { - reset(from.release()); - - return *this; - } - - unique_ptr(unique_ptr const&) = delete; - unique_ptr& operator=(unique_ptr const&) = delete; - - unique_ptr(unique_ptr&& rhs) noexcept: - m_ptr(rhs.m_ptr) { - rhs.m_ptr = nullptr; - } - unique_ptr& operator=(unique_ptr&& rhs) noexcept { - reset(rhs.release()); - - return *this; - } - - ~unique_ptr() { - delete m_ptr; - } - - T& operator*() { - assert(m_ptr); - return *m_ptr; - } - T const& operator*() const { - assert(m_ptr); - return *m_ptr; - } - T* operator->() noexcept { - assert(m_ptr); - return m_ptr; - } - T const* operator->() const noexcept { - assert(m_ptr); - return m_ptr; - } - - T* get() { return m_ptr; } - T const* get() const { return m_ptr; } - - void reset(T* ptr = nullptr) { - delete m_ptr; - m_ptr = ptr; - } - - T* release() { - auto temp = m_ptr; - m_ptr = nullptr; - return temp; - } - - explicit operator bool() const { - return m_ptr; - } - - friend void swap(unique_ptr& lhs, unique_ptr& rhs) { - auto temp = lhs.m_ptr; - lhs.m_ptr = rhs.m_ptr; - rhs.m_ptr = temp; - } - }; - - //! Specialization to cause compile-time error for arrays - template
- class unique_ptr
; - - template
- unique_ptr
make_unique(Args&&... args) { - return unique_ptr
(new T(CATCH_FORWARD(args)...)); - } - - -} // end namespace Detail -} // end namespace Catch - -#endif // CATCH_UNIQUE_PTR_HPP_INCLUDED - - -#ifndef CATCH_BENCHMARK_STATS_FWD_HPP_INCLUDED -#define CATCH_BENCHMARK_STATS_FWD_HPP_INCLUDED - - - -// Adapted from donated nonius code. - -#ifndef CATCH_CLOCK_HPP_INCLUDED -#define CATCH_CLOCK_HPP_INCLUDED - -#include
- -namespace Catch { - namespace Benchmark { - using IDuration = std::chrono::nanoseconds; - using FDuration = std::chrono::duration
; - - template
- using TimePoint = typename Clock::time_point; - - using default_clock = std::chrono::steady_clock; - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_CLOCK_HPP_INCLUDED - -namespace Catch { - - // We cannot forward declare the type with default template argument - // multiple times, so it is split out into a separate header so that - // we can prevent multiple declarations in dependees - template
- struct BenchmarkStats; - -} // end namespace Catch - -#endif // CATCH_BENCHMARK_STATS_FWD_HPP_INCLUDED - -namespace Catch { - - class AssertionResult; - struct AssertionInfo; - struct SectionInfo; - struct SectionEndInfo; - struct MessageInfo; - struct MessageBuilder; - struct Counts; - struct AssertionReaction; - struct SourceLineInfo; - - class ITransientExpression; - class IGeneratorTracker; - - struct BenchmarkInfo; - - namespace Generators { - class GeneratorUntypedBase; - using GeneratorBasePtr = Catch::Detail::unique_ptr
; - } - - - class IResultCapture { - public: - virtual ~IResultCapture(); - - virtual void notifyAssertionStarted( AssertionInfo const& info ) = 0; - virtual bool sectionStarted( StringRef sectionName, - SourceLineInfo const& sectionLineInfo, - Counts& assertions ) = 0; - virtual void sectionEnded( SectionEndInfo&& endInfo ) = 0; - virtual void sectionEndedEarly( SectionEndInfo&& endInfo ) = 0; - - virtual IGeneratorTracker* - acquireGeneratorTracker( StringRef generatorName, - SourceLineInfo const& lineInfo ) = 0; - virtual IGeneratorTracker* - createGeneratorTracker( StringRef generatorName, - SourceLineInfo lineInfo, - Generators::GeneratorBasePtr&& generator ) = 0; - - virtual void benchmarkPreparing( StringRef name ) = 0; - virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0; - virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0; - virtual void benchmarkFailed( StringRef error ) = 0; - - virtual void pushScopedMessage( MessageInfo const& message ) = 0; - virtual void popScopedMessage( MessageInfo const& message ) = 0; - - virtual void emplaceUnscopedMessage( MessageBuilder&& builder ) = 0; - - virtual void handleFatalErrorCondition( StringRef message ) = 0; - - virtual void handleExpr - ( AssertionInfo const& info, - ITransientExpression const& expr, - AssertionReaction& reaction ) = 0; - virtual void handleMessage - ( AssertionInfo const& info, - ResultWas::OfType resultType, - StringRef message, - AssertionReaction& reaction ) = 0; - virtual void handleUnexpectedExceptionNotThrown - ( AssertionInfo const& info, - AssertionReaction& reaction ) = 0; - virtual void handleUnexpectedInflightException - ( AssertionInfo const& info, - std::string&& message, - AssertionReaction& reaction ) = 0; - virtual void handleIncomplete - ( AssertionInfo const& info ) = 0; - virtual void handleNonExpr - ( AssertionInfo const &info, - ResultWas::OfType resultType, - AssertionReaction &reaction ) = 0; - - - - virtual bool lastAssertionPassed() = 0; - virtual void assertionPassed() = 0; - - // Deprecated, do not use: - virtual std::string getCurrentTestName() const = 0; - virtual const AssertionResult* getLastResult() const = 0; - virtual void exceptionEarlyReported() = 0; - }; - - IResultCapture& getResultCapture(); -} - -#endif // CATCH_INTERFACES_CAPTURE_HPP_INCLUDED - - -#ifndef CATCH_INTERFACES_CONFIG_HPP_INCLUDED -#define CATCH_INTERFACES_CONFIG_HPP_INCLUDED - - - -#ifndef CATCH_NONCOPYABLE_HPP_INCLUDED -#define CATCH_NONCOPYABLE_HPP_INCLUDED - -namespace Catch { - namespace Detail { - - //! Deriving classes become noncopyable and nonmovable - class NonCopyable { - NonCopyable( NonCopyable const& ) = delete; - NonCopyable( NonCopyable&& ) = delete; - NonCopyable& operator=( NonCopyable const& ) = delete; - NonCopyable& operator=( NonCopyable&& ) = delete; - - protected: - NonCopyable() noexcept = default; - }; - - } // namespace Detail -} // namespace Catch - -#endif // CATCH_NONCOPYABLE_HPP_INCLUDED - -#include
-#include
-#include
-#include
- -namespace Catch { - - enum class Verbosity { - Quiet = 0, - Normal, - High - }; - - struct WarnAbout { enum What { - Nothing = 0x00, - //! A test case or leaf section did not run any assertions - NoAssertions = 0x01, - //! A command line test spec matched no test cases - UnmatchedTestSpec = 0x02, - }; }; - - enum class ShowDurations { - DefaultForReporter, - Always, - Never - }; - enum class TestRunOrder { - Declared, - LexicographicallySorted, - Randomized - }; - enum class ColourMode : std::uint8_t { - //! Let Catch2 pick implementation based on platform detection - PlatformDefault, - //! Use ANSI colour code escapes - ANSI, - //! Use Win32 console colour API - Win32, - //! Don't use any colour - None - }; - struct WaitForKeypress { enum When { - Never, - BeforeStart = 1, - BeforeExit = 2, - BeforeStartAndExit = BeforeStart | BeforeExit - }; }; - - class TestSpec; - class IStream; - - class IConfig : public Detail::NonCopyable { - public: - virtual ~IConfig(); - - virtual bool allowThrows() const = 0; - virtual StringRef name() const = 0; - virtual bool includeSuccessfulResults() const = 0; - virtual bool shouldDebugBreak() const = 0; - virtual bool warnAboutMissingAssertions() const = 0; - virtual bool warnAboutUnmatchedTestSpecs() const = 0; - virtual bool zeroTestsCountAsSuccess() const = 0; - virtual int abortAfter() const = 0; - virtual bool showInvisibles() const = 0; - virtual ShowDurations showDurations() const = 0; - virtual double minDuration() const = 0; - virtual TestSpec const& testSpec() const = 0; - virtual bool hasTestFilters() const = 0; - virtual std::vector
const& getTestsOrTags() const = 0; - virtual TestRunOrder runOrder() const = 0; - virtual uint32_t rngSeed() const = 0; - virtual unsigned int shardCount() const = 0; - virtual unsigned int shardIndex() const = 0; - virtual ColourMode defaultColourMode() const = 0; - virtual std::vector
const& getSectionsToRun() const = 0; - virtual Verbosity verbosity() const = 0; - - virtual bool skipBenchmarks() const = 0; - virtual bool benchmarkNoAnalysis() const = 0; - virtual unsigned int benchmarkSamples() const = 0; - virtual double benchmarkConfidenceInterval() const = 0; - virtual unsigned int benchmarkResamples() const = 0; - virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0; - }; -} - -#endif // CATCH_INTERFACES_CONFIG_HPP_INCLUDED - - -#ifndef CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED -#define CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED - - -#include
- -namespace Catch { - - class TestCaseHandle; - struct TestCaseInfo; - class ITestCaseRegistry; - class IExceptionTranslatorRegistry; - class IExceptionTranslator; - class ReporterRegistry; - class IReporterFactory; - class ITagAliasRegistry; - class ITestInvoker; - class IMutableEnumValuesRegistry; - struct SourceLineInfo; - - class StartupExceptionRegistry; - class EventListenerFactory; - - using IReporterFactoryPtr = Detail::unique_ptr
; - - class IRegistryHub { - public: - virtual ~IRegistryHub(); // = default - - virtual ReporterRegistry const& getReporterRegistry() const = 0; - virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; - virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0; - virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0; - - - virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0; - }; - - class IMutableRegistryHub { - public: - virtual ~IMutableRegistryHub(); // = default - virtual void registerReporter( std::string const& name, IReporterFactoryPtr factory ) = 0; - virtual void registerListener( Detail::unique_ptr
factory ) = 0; - virtual void registerTest(Detail::unique_ptr
&& testInfo, Detail::unique_ptr
&& invoker) = 0; - virtual void registerTranslator( Detail::unique_ptr
&& translator ) = 0; - virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0; - virtual void registerStartupException() noexcept = 0; - virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0; - }; - - IRegistryHub const& getRegistryHub(); - IMutableRegistryHub& getMutableRegistryHub(); - void cleanUp(); - std::string translateActiveException(); - -} - -#endif // CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED - - -#ifndef CATCH_BENCHMARK_STATS_HPP_INCLUDED -#define CATCH_BENCHMARK_STATS_HPP_INCLUDED - - - -// Adapted from donated nonius code. - -#ifndef CATCH_ESTIMATE_HPP_INCLUDED -#define CATCH_ESTIMATE_HPP_INCLUDED - -namespace Catch { - namespace Benchmark { - template
- struct Estimate { - Type point; - Type lower_bound; - Type upper_bound; - double confidence_interval; - }; - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_ESTIMATE_HPP_INCLUDED - - -// Adapted from donated nonius code. - -#ifndef CATCH_OUTLIER_CLASSIFICATION_HPP_INCLUDED -#define CATCH_OUTLIER_CLASSIFICATION_HPP_INCLUDED - -namespace Catch { - namespace Benchmark { - struct OutlierClassification { - int samples_seen = 0; - int low_severe = 0; // more than 3 times IQR below Q1 - int low_mild = 0; // 1.5 to 3 times IQR below Q1 - int high_mild = 0; // 1.5 to 3 times IQR above Q3 - int high_severe = 0; // more than 3 times IQR above Q3 - - int total() const { - return low_severe + low_mild + high_mild + high_severe; - } - }; - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_OUTLIERS_CLASSIFICATION_HPP_INCLUDED -// The fwd decl & default specialization needs to be seen by VS2017 before -// BenchmarkStats itself, or VS2017 will report compilation error. - -#include
-#include
- -namespace Catch { - - struct BenchmarkInfo { - std::string name; - double estimatedDuration; - int iterations; - unsigned int samples; - unsigned int resamples; - double clockResolution; - double clockCost; - }; - - // We need to keep template parameter for backwards compatibility, - // but we also do not want to use the template paraneter. - template
- struct BenchmarkStats { - BenchmarkInfo info; - - std::vector
samples; - Benchmark::Estimate
mean; - Benchmark::Estimate
standardDeviation; - Benchmark::OutlierClassification outliers; - double outlierVariance; - }; - - -} // end namespace Catch - -#endif // CATCH_BENCHMARK_STATS_HPP_INCLUDED - - -// Adapted from donated nonius code. - -#ifndef CATCH_ENVIRONMENT_HPP_INCLUDED -#define CATCH_ENVIRONMENT_HPP_INCLUDED - - -namespace Catch { - namespace Benchmark { - struct EnvironmentEstimate { - FDuration mean; - OutlierClassification outliers; - }; - struct Environment { - EnvironmentEstimate clock_resolution; - EnvironmentEstimate clock_cost; - }; - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_ENVIRONMENT_HPP_INCLUDED - - -// Adapted from donated nonius code. - -#ifndef CATCH_EXECUTION_PLAN_HPP_INCLUDED -#define CATCH_EXECUTION_PLAN_HPP_INCLUDED - - - -// Adapted from donated nonius code. - -#ifndef CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED -#define CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED - - - -// Adapted from donated nonius code. - -#ifndef CATCH_CHRONOMETER_HPP_INCLUDED -#define CATCH_CHRONOMETER_HPP_INCLUDED - - - -// Adapted from donated nonius code. - -#ifndef CATCH_OPTIMIZER_HPP_INCLUDED -#define CATCH_OPTIMIZER_HPP_INCLUDED - -#if defined(_MSC_VER) || defined(__IAR_SYSTEMS_ICC__) -# include
// atomic_thread_fence -#endif - - -#include
- -namespace Catch { - namespace Benchmark { -#if defined(__GNUC__) || defined(__clang__) - template
- inline void keep_memory(T* p) { - asm volatile("" : : "g"(p) : "memory"); - } - inline void keep_memory() { - asm volatile("" : : : "memory"); - } - - namespace Detail { - inline void optimizer_barrier() { keep_memory(); } - } // namespace Detail -#elif defined(_MSC_VER) || defined(__IAR_SYSTEMS_ICC__) - -#if defined(_MSVC_VER) -#pragma optimize("", off) -#elif defined(__IAR_SYSTEMS_ICC__) -// For IAR the pragma only affects the following function -#pragma optimize=disable -#endif - template
- inline void keep_memory(T* p) { - // thanks @milleniumbug - *reinterpret_cast
(p) = *reinterpret_cast
(p); - } - // TODO equivalent keep_memory() -#if defined(_MSVC_VER) -#pragma optimize("", on) -#endif - - namespace Detail { - inline void optimizer_barrier() { - std::atomic_thread_fence(std::memory_order_seq_cst); - } - } // namespace Detail - -#endif - - template
- inline void deoptimize_value(T&& x) { - keep_memory(&x); - } - - template
- inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> std::enable_if_t::value> { - deoptimize_value(CATCH_FORWARD(fn) (CATCH_FORWARD(args)...)); - } - - template
- inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> std::enable_if_t
::value> { - CATCH_FORWARD((fn)) (CATCH_FORWARD(args)...); - } - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_OPTIMIZER_HPP_INCLUDED - - -#ifndef CATCH_META_HPP_INCLUDED -#define CATCH_META_HPP_INCLUDED - -#include
- -namespace Catch { - template
- struct true_given : std::true_type {}; - - struct is_callable_tester { - template
- static true_given
()(std::declval
()...))> test(int); - template
- static std::false_type test(...); - }; - - template
- struct is_callable; - - template
- struct is_callable
: decltype(is_callable_tester::test
(0)) {}; - - -#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703 - // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is - // replaced with std::invoke_result here. - template
- using FunctionReturnType = std::remove_reference_t
>>; -#else - template
- using FunctionReturnType = std::remove_reference_t
>>; -#endif - -} // namespace Catch - -namespace mpl_{ - struct na; -} - -#endif // CATCH_META_HPP_INCLUDED - -namespace Catch { - namespace Benchmark { - namespace Detail { - struct ChronometerConcept { - virtual void start() = 0; - virtual void finish() = 0; - virtual ~ChronometerConcept(); // = default; - - ChronometerConcept() = default; - ChronometerConcept(ChronometerConcept const&) = default; - ChronometerConcept& operator=(ChronometerConcept const&) = default; - }; - template
- struct ChronometerModel final : public ChronometerConcept { - void start() override { started = Clock::now(); } - void finish() override { finished = Clock::now(); } - - IDuration elapsed() const { - return std::chrono::duration_cast
( - finished - started ); - } - - TimePoint
started; - TimePoint
finished; - }; - } // namespace Detail - - struct Chronometer { - public: - template
- void measure(Fun&& fun) { measure(CATCH_FORWARD(fun), is_callable
()); } - - int runs() const { return repeats; } - - Chronometer(Detail::ChronometerConcept& meter, int repeats_) - : impl(&meter) - , repeats(repeats_) {} - - private: - template
- void measure(Fun&& fun, std::false_type) { - measure([&fun](int) { return fun(); }, std::true_type()); - } - - template
- void measure(Fun&& fun, std::true_type) { - Detail::optimizer_barrier(); - impl->start(); - for (int i = 0; i < repeats; ++i) invoke_deoptimized(fun, i); - impl->finish(); - Detail::optimizer_barrier(); - } - - Detail::ChronometerConcept* impl; - int repeats; - }; - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_CHRONOMETER_HPP_INCLUDED - -#include
- -namespace Catch { - namespace Benchmark { - namespace Detail { - template
- struct is_related - : std::is_same
, std::decay_t
> {}; - - /// We need to reinvent std::function because every piece of code that might add overhead - /// in a measurement context needs to have consistent performance characteristics so that we - /// can account for it in the measurement. - /// Implementations of std::function with optimizations that aren't always applicable, like - /// small buffer optimizations, are not uncommon. - /// This is effectively an implementation of std::function without any such optimizations; - /// it may be slow, but it is consistently slow. - struct BenchmarkFunction { - private: - struct callable { - virtual void call(Chronometer meter) const = 0; - virtual Catch::Detail::unique_ptr
clone() const = 0; - virtual ~callable(); // = default; - - callable() = default; - callable(callable const&) = default; - callable& operator=(callable const&) = default; - }; - template
- struct model : public callable { - model(Fun&& fun_) : fun(CATCH_MOVE(fun_)) {} - model(Fun const& fun_) : fun(fun_) {} - - Catch::Detail::unique_ptr
clone() const override { - return Catch::Detail::make_unique
>( *this ); - } - - void call(Chronometer meter) const override { - call(meter, is_callable
()); - } - void call(Chronometer meter, std::true_type) const { - fun(meter); - } - void call(Chronometer meter, std::false_type) const { - meter.measure(fun); - } - - Fun fun; - }; - - struct do_nothing { void operator()() const {} }; - - template
- BenchmarkFunction(model
* c) : f(c) {} - - public: - BenchmarkFunction() - : f(new model
{ {} }) {} - - template
::value, int> = 0> - BenchmarkFunction(Fun&& fun) - : f(new model
>(CATCH_FORWARD(fun))) {} - - BenchmarkFunction( BenchmarkFunction&& that ) noexcept: - f( CATCH_MOVE( that.f ) ) {} - - BenchmarkFunction(BenchmarkFunction const& that) - : f(that.f->clone()) {} - - BenchmarkFunction& - operator=( BenchmarkFunction&& that ) noexcept { - f = CATCH_MOVE( that.f ); - return *this; - } - - BenchmarkFunction& operator=(BenchmarkFunction const& that) { - f = that.f->clone(); - return *this; - } - - void operator()(Chronometer meter) const { f->call(meter); } - - private: - Catch::Detail::unique_ptr
f; - }; - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED - - -// Adapted from donated nonius code. - -#ifndef CATCH_REPEAT_HPP_INCLUDED -#define CATCH_REPEAT_HPP_INCLUDED - -#include
- -namespace Catch { - namespace Benchmark { - namespace Detail { - template
- struct repeater { - void operator()(int k) const { - for (int i = 0; i < k; ++i) { - fun(); - } - } - Fun fun; - }; - template
- repeater
> repeat(Fun&& fun) { - return { CATCH_FORWARD(fun) }; - } - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_REPEAT_HPP_INCLUDED - - -// Adapted from donated nonius code. - -#ifndef CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED -#define CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED - - - -// Adapted from donated nonius code. - -#ifndef CATCH_MEASURE_HPP_INCLUDED -#define CATCH_MEASURE_HPP_INCLUDED - - - -// Adapted from donated nonius code. - -#ifndef CATCH_COMPLETE_INVOKE_HPP_INCLUDED -#define CATCH_COMPLETE_INVOKE_HPP_INCLUDED - - -namespace Catch { - namespace Benchmark { - namespace Detail { - template
- struct CompleteType { using type = T; }; - template <> - struct CompleteType
{ struct type {}; }; - - template
- using CompleteType_t = typename CompleteType
::type; - - template
- struct CompleteInvoker { - template
- static Result invoke(Fun&& fun, Args&&... args) { - return CATCH_FORWARD(fun)(CATCH_FORWARD(args)...); - } - }; - template <> - struct CompleteInvoker
{ - template
- static CompleteType_t
invoke(Fun&& fun, Args&&... args) { - CATCH_FORWARD(fun)(CATCH_FORWARD(args)...); - return {}; - } - }; - - // invoke and not return void :( - template
- CompleteType_t
> complete_invoke(Fun&& fun, Args&&... args) { - return CompleteInvoker
>::invoke(CATCH_FORWARD(fun), CATCH_FORWARD(args)...); - } - - } // namespace Detail - - template
- Detail::CompleteType_t
> user_code(Fun&& fun) { - return Detail::complete_invoke(CATCH_FORWARD(fun)); - } - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_COMPLETE_INVOKE_HPP_INCLUDED - - -// Adapted from donated nonius code. - -#ifndef CATCH_TIMING_HPP_INCLUDED -#define CATCH_TIMING_HPP_INCLUDED - - -#include
- -namespace Catch { - namespace Benchmark { - template
- struct Timing { - IDuration elapsed; - Result result; - int iterations; - }; - template
- using TimingOf = Timing
>>; - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_TIMING_HPP_INCLUDED - -namespace Catch { - namespace Benchmark { - namespace Detail { - template
- TimingOf
measure(Fun&& fun, Args&&... args) { - auto start = Clock::now(); - auto&& r = Detail::complete_invoke(fun, CATCH_FORWARD(args)...); - auto end = Clock::now(); - auto delta = end - start; - return { delta, CATCH_FORWARD(r), 1 }; - } - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_MEASURE_HPP_INCLUDED - -#include
- -namespace Catch { - namespace Benchmark { - namespace Detail { - template
- TimingOf
measure_one(Fun&& fun, int iters, std::false_type) { - return Detail::measure
(fun, iters); - } - template
- TimingOf
measure_one(Fun&& fun, int iters, std::true_type) { - Detail::ChronometerModel
meter; - auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters)); - - return { meter.elapsed(), CATCH_MOVE(result), iters }; - } - - template
- using run_for_at_least_argument_t = std::conditional_t
::value, Chronometer, int>; - - - [[noreturn]] - void throw_optimized_away_error(); - - template
- TimingOf
> - run_for_at_least(IDuration how_long, - const int initial_iterations, - Fun&& fun) { - auto iters = initial_iterations; - while (iters < (1 << 30)) { - auto&& Timing = measure_one
(fun, iters, is_callable
()); - - if (Timing.elapsed >= how_long) { - return { Timing.elapsed, CATCH_MOVE(Timing.result), iters }; - } - iters *= 2; - } - throw_optimized_away_error(); - } - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED - -#include
- -namespace Catch { - namespace Benchmark { - struct ExecutionPlan { - int iterations_per_sample; - FDuration estimated_duration; - Detail::BenchmarkFunction benchmark; - FDuration warmup_time; - int warmup_iterations; - - template
- std::vector
run(const IConfig &cfg, Environment env) const { - // warmup a bit - Detail::run_for_at_least
( - std::chrono::duration_cast
( warmup_time ), - warmup_iterations, - Detail::repeat( []() { return Clock::now(); } ) - ); - - std::vector
times; - const auto num_samples = cfg.benchmarkSamples(); - times.reserve( num_samples ); - for ( size_t i = 0; i < num_samples; ++i ) { - Detail::ChronometerModel
model; - this->benchmark( Chronometer( model, iterations_per_sample ) ); - auto sample_time = model.elapsed() - env.clock_cost.mean; - if ( sample_time < FDuration::zero() ) { - sample_time = FDuration::zero(); - } - times.push_back(sample_time / iterations_per_sample); - } - return times; - } - }; - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_EXECUTION_PLAN_HPP_INCLUDED - - -// Adapted from donated nonius code. - -#ifndef CATCH_ESTIMATE_CLOCK_HPP_INCLUDED -#define CATCH_ESTIMATE_CLOCK_HPP_INCLUDED - - - -// Adapted from donated nonius code. - -#ifndef CATCH_STATS_HPP_INCLUDED -#define CATCH_STATS_HPP_INCLUDED - - -#include
- -namespace Catch { - namespace Benchmark { - namespace Detail { - using sample = std::vector
; - - double weighted_average_quantile( int k, - int q, - double* first, - double* last ); - - OutlierClassification - classify_outliers( double const* first, double const* last ); - - double mean( double const* first, double const* last ); - - double normal_cdf( double x ); - - double erfc_inv(double x); - - double normal_quantile(double p); - - Estimate
- bootstrap( double confidence_level, - double* first, - double* last, - sample const& resample, - double ( *estimator )( double const*, double const* ) ); - - struct bootstrap_analysis { - Estimate
mean; - Estimate
standard_deviation; - double outlier_variance; - }; - - bootstrap_analysis analyse_samples(double confidence_level, - unsigned int n_resamples, - double* first, - double* last); - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_STATS_HPP_INCLUDED - -#include
-#include
-#include
- -namespace Catch { - namespace Benchmark { - namespace Detail { - template
- std::vector
resolution(int k) { - std::vector
> times; - times.reserve(static_cast
(k + 1)); - for ( int i = 0; i < k + 1; ++i ) { - times.push_back( Clock::now() ); - } - - std::vector
deltas; - deltas.reserve(static_cast
(k)); - for ( size_t idx = 1; idx < times.size(); ++idx ) { - deltas.push_back( static_cast
( - ( times[idx] - times[idx - 1] ).count() ) ); - } - - return deltas; - } - - constexpr auto warmup_iterations = 10000; - constexpr auto warmup_time = std::chrono::milliseconds(100); - constexpr auto minimum_ticks = 1000; - constexpr auto warmup_seed = 10000; - constexpr auto clock_resolution_estimation_time = std::chrono::milliseconds(500); - constexpr auto clock_cost_estimation_time_limit = std::chrono::seconds(1); - constexpr auto clock_cost_estimation_tick_limit = 100000; - constexpr auto clock_cost_estimation_time = std::chrono::milliseconds(10); - constexpr auto clock_cost_estimation_iterations = 10000; - - template
- int warmup() { - return run_for_at_least
(warmup_time, warmup_seed, &resolution
) - .iterations; - } - template
- EnvironmentEstimate estimate_clock_resolution(int iterations) { - auto r = run_for_at_least
(clock_resolution_estimation_time, iterations, &resolution
) - .result; - return { - FDuration(mean(r.data(), r.data() + r.size())), - classify_outliers(r.data(), r.data() + r.size()), - }; - } - template
- EnvironmentEstimate estimate_clock_cost(FDuration resolution) { - auto time_limit = (std::min)( - resolution * clock_cost_estimation_tick_limit, - FDuration(clock_cost_estimation_time_limit)); - auto time_clock = [](int k) { - return Detail::measure
([k] { - for (int i = 0; i < k; ++i) { - volatile auto ignored = Clock::now(); - (void)ignored; - } - }).elapsed; - }; - time_clock(1); - int iters = clock_cost_estimation_iterations; - auto&& r = run_for_at_least
(clock_cost_estimation_time, iters, time_clock); - std::vector
times; - int nsamples = static_cast
(std::ceil(time_limit / r.elapsed)); - times.reserve(static_cast
(nsamples)); - for ( int s = 0; s < nsamples; ++s ) { - times.push_back( static_cast
( - ( time_clock( r.iterations ) / r.iterations ) - .count() ) ); - } - return { - FDuration(mean(times.data(), times.data() + times.size())), - classify_outliers(times.data(), times.data() + times.size()), - }; - } - - template
- Environment measure_environment() { -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wexit-time-destructors" -#endif - static Catch::Detail::unique_ptr
env; -#if defined(__clang__) -# pragma clang diagnostic pop -#endif - if (env) { - return *env; - } - - auto iters = Detail::warmup
(); - auto resolution = Detail::estimate_clock_resolution
(iters); - auto cost = Detail::estimate_clock_cost
(resolution.mean); - - env = Catch::Detail::make_unique
( Environment{resolution, cost} ); - return *env; - } - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_ESTIMATE_CLOCK_HPP_INCLUDED - - -// Adapted from donated nonius code. - -#ifndef CATCH_ANALYSE_HPP_INCLUDED -#define CATCH_ANALYSE_HPP_INCLUDED - - - -// Adapted from donated nonius code. - -#ifndef CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED -#define CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED - - -#include
- -namespace Catch { - namespace Benchmark { - struct SampleAnalysis { - std::vector
samples; - Estimate
mean; - Estimate
standard_deviation; - OutlierClassification outliers; - double outlier_variance; - }; - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED - - -namespace Catch { - class IConfig; - - namespace Benchmark { - namespace Detail { - SampleAnalysis analyse(const IConfig &cfg, FDuration* first, FDuration* last); - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_ANALYSE_HPP_INCLUDED - -#include
-#include
-#include
-#include
-#include
- -namespace Catch { - namespace Benchmark { - struct Benchmark { - Benchmark(std::string&& benchmarkName) - : name(CATCH_MOVE(benchmarkName)) {} - - template
- Benchmark(std::string&& benchmarkName , FUN &&func) - : fun(CATCH_MOVE(func)), name(CATCH_MOVE(benchmarkName)) {} - - template
- ExecutionPlan prepare(const IConfig &cfg, Environment env) const { - auto min_time = env.clock_resolution.mean * Detail::minimum_ticks; - auto run_time = std::max(min_time, std::chrono::duration_cast
(cfg.benchmarkWarmupTime())); - auto&& test = Detail::run_for_at_least
(std::chrono::duration_cast
(run_time), 1, fun); - int new_iters = static_cast
(std::ceil(min_time * test.iterations / test.elapsed)); - return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast
(cfg.benchmarkWarmupTime()), Detail::warmup_iterations }; - } - - template
- void run() { - static_assert( Clock::is_steady, - "Benchmarking clock should be steady" ); - auto const* cfg = getCurrentContext().getConfig(); - - auto env = Detail::measure_environment
(); - - getResultCapture().benchmarkPreparing(name); - CATCH_TRY{ - auto plan = user_code([&] { - return prepare
(*cfg, env); - }); - - BenchmarkInfo info { - CATCH_MOVE(name), - plan.estimated_duration.count(), - plan.iterations_per_sample, - cfg->benchmarkSamples(), - cfg->benchmarkResamples(), - env.clock_resolution.mean.count(), - env.clock_cost.mean.count() - }; - - getResultCapture().benchmarkStarting(info); - - auto samples = user_code([&] { - return plan.template run
(*cfg, env); - }); - - auto analysis = Detail::analyse(*cfg, samples.data(), samples.data() + samples.size()); - BenchmarkStats<> stats{ CATCH_MOVE(info), CATCH_MOVE(analysis.samples), analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance }; - getResultCapture().benchmarkEnded(stats); - } CATCH_CATCH_ANON (TestFailureException const&) { - getResultCapture().benchmarkFailed("Benchmark failed due to failed assertion"_sr); - } CATCH_CATCH_ALL{ - getResultCapture().benchmarkFailed(translateActiveException()); - // We let the exception go further up so that the - // test case is marked as failed. - std::rethrow_exception(std::current_exception()); - } - } - - // sets lambda to be used in fun *and* executes benchmark! - template
::value, int> = 0> - Benchmark & operator=(Fun func) { - auto const* cfg = getCurrentContext().getConfig(); - if (!cfg->skipBenchmarks()) { - fun = Detail::BenchmarkFunction(func); - run(); - } - return *this; - } - - explicit operator bool() { - return true; - } - - private: - Detail::BenchmarkFunction fun; - std::string name; - }; - } -} // namespace Catch - -#define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1 -#define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2 - -#define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\ - if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \ - BenchmarkName = [&](int benchmarkIndex) - -#define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\ - if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \ - BenchmarkName = [&] - -#if defined(CATCH_CONFIG_PREFIX_ALL) - -#define CATCH_BENCHMARK(...) \ - INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) -#define CATCH_BENCHMARK_ADVANCED(name) \ - INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), name) - -#else - -#define BENCHMARK(...) \ - INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) -#define BENCHMARK_ADVANCED(name) \ - INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(CATCH2_INTERNAL_BENCHMARK_), name) - -#endif - -#endif // CATCH_BENCHMARK_HPP_INCLUDED - - -// Adapted from donated nonius code. - -#ifndef CATCH_CONSTRUCTOR_HPP_INCLUDED -#define CATCH_CONSTRUCTOR_HPP_INCLUDED - - -#include
- -namespace Catch { - namespace Benchmark { - namespace Detail { - template
- struct ObjectStorage - { - ObjectStorage() = default; - - ObjectStorage(const ObjectStorage& other) - { - new(&data) T(other.stored_object()); - } - - ObjectStorage(ObjectStorage&& other) - { - new(data) T(CATCH_MOVE(other.stored_object())); - } - - ~ObjectStorage() { destruct_on_exit
(); } - - template
- void construct(Args&&... args) - { - new (data) T(CATCH_FORWARD(args)...); - } - - template
- std::enable_if_t
destruct() - { - stored_object().~T(); - } - - private: - // If this is a constructor benchmark, destruct the underlying object - template
- void destruct_on_exit(std::enable_if_t
* = nullptr) { destruct
(); } - // Otherwise, don't - template
- void destruct_on_exit(std::enable_if_t* = nullptr) { } - -#if defined( __GNUC__ ) && __GNUC__ <= 6 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif - T& stored_object() { return *reinterpret_cast
( data ); } - - T const& stored_object() const { - return *reinterpret_cast
( data ); - } -#if defined( __GNUC__ ) && __GNUC__ <= 6 -# pragma GCC diagnostic pop -#endif - - alignas( T ) unsigned char data[sizeof( T )]{}; - }; - } // namespace Detail - - template
- using storage_for = Detail::ObjectStorage
; - - template
- using destructable_object = Detail::ObjectStorage
; - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_CONSTRUCTOR_HPP_INCLUDED - -#endif // CATCH_BENCHMARK_ALL_HPP_INCLUDED - - -#ifndef CATCH_APPROX_HPP_INCLUDED -#define CATCH_APPROX_HPP_INCLUDED - - - -#ifndef CATCH_TOSTRING_HPP_INCLUDED -#define CATCH_TOSTRING_HPP_INCLUDED - - -#include
-#include
-#include
-#include
- - - - -/** \file - * Wrapper for the WCHAR configuration option - * - * We want to support platforms that do not provide `wchar_t`, so we - * sometimes have to disable providing wchar_t overloads through Catch2, - * e.g. the StringMaker specialization for `std::wstring`. - */ - -#ifndef CATCH_CONFIG_WCHAR_HPP_INCLUDED -#define CATCH_CONFIG_WCHAR_HPP_INCLUDED - - -// We assume that WCHAR should be enabled by default, and only disabled -// for a shortlist (so far only DJGPP) of compilers. - -#if defined(__DJGPP__) -# define CATCH_INTERNAL_CONFIG_NO_WCHAR -#endif // __DJGPP__ - -#if !defined( CATCH_INTERNAL_CONFIG_NO_WCHAR ) && \ - !defined( CATCH_CONFIG_NO_WCHAR ) && \ - !defined( CATCH_CONFIG_WCHAR ) -# define CATCH_CONFIG_WCHAR -#endif - -#endif // CATCH_CONFIG_WCHAR_HPP_INCLUDED - - -#ifndef CATCH_REUSABLE_STRING_STREAM_HPP_INCLUDED -#define CATCH_REUSABLE_STRING_STREAM_HPP_INCLUDED - - -#include
-#include
-#include
-#include
- -namespace Catch { - - class ReusableStringStream : Detail::NonCopyable { - std::size_t m_index; - std::ostream* m_oss; - public: - ReusableStringStream(); - ~ReusableStringStream(); - - //! Returns the serialized state - std::string str() const; - //! Sets internal state to `str` - void str(std::string const& str); - -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -// Old versions of GCC do not understand -Wnonnull-compare -#pragma GCC diagnostic ignored "-Wpragmas" -// Streaming a function pointer triggers Waddress and Wnonnull-compare -// on GCC, because it implicitly converts it to bool and then decides -// that the check it uses (a? true : false) is tautological and cannot -// be null... -#pragma GCC diagnostic ignored "-Waddress" -#pragma GCC diagnostic ignored "-Wnonnull-compare" -#endif - - template
- auto operator << ( T const& value ) -> ReusableStringStream& { - *m_oss << value; - return *this; - } - -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif - auto get() -> std::ostream& { return *m_oss; } - }; -} - -#endif // CATCH_REUSABLE_STRING_STREAM_HPP_INCLUDED - - -#ifndef CATCH_VOID_TYPE_HPP_INCLUDED -#define CATCH_VOID_TYPE_HPP_INCLUDED - - -namespace Catch { - namespace Detail { - - template
- struct make_void { using type = void; }; - - template
- using void_t = typename make_void
::type; - - } // namespace Detail -} // namespace Catch - - -#endif // CATCH_VOID_TYPE_HPP_INCLUDED - - -#ifndef CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED -#define CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED - - -#include
- -namespace Catch { - - namespace Detail { - struct EnumInfo { - StringRef m_name; - std::vector
> m_values; - - ~EnumInfo(); - - StringRef lookup( int value ) const; - }; - } // namespace Detail - - class IMutableEnumValuesRegistry { - public: - virtual ~IMutableEnumValuesRegistry(); // = default; - - virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector
const& values ) = 0; - - template
- Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list
values ) { - static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int"); - std::vector
intValues; - intValues.reserve( values.size() ); - for( auto enumValue : values ) - intValues.push_back( static_cast
( enumValue ) ); - return registerEnum( enumName, allEnums, intValues ); - } - }; - -} // Catch - -#endif // CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED - -#ifdef CATCH_CONFIG_CPP17_STRING_VIEW -#include
-#endif - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless -#endif - -// We need a dummy global operator<< so we can bring it into Catch namespace later -struct Catch_global_namespace_dummy{}; -std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); - -namespace Catch { - // Bring in global namespace operator<< for ADL lookup in - // `IsStreamInsertable` below. - using ::operator<<; - - namespace Detail { - - inline std::size_t catch_strnlen(const char *str, std::size_t n) { - auto ret = std::char_traits
::find(str, n, '\0'); - if (ret != nullptr) { - return static_cast
(ret - str); - } - return n; - } - - constexpr StringRef unprintableString = "{?}"_sr; - - //! Encases `string in quotes, and optionally escapes invisibles - std::string convertIntoString( StringRef string, bool escapeInvisibles ); - - //! Encases `string` in quotes, and escapes invisibles if user requested - //! it via CLI - std::string convertIntoString( StringRef string ); - - std::string rawMemoryToString( const void *object, std::size_t size ); - - template
- std::string rawMemoryToString( const T& object ) { - return rawMemoryToString( &object, sizeof(object) ); - } - - template
- class IsStreamInsertable { - template
- static auto test(int) - -> decltype(std::declval
() << std::declval
(), std::true_type()); - - template
- static auto test(...)->std::false_type; - - public: - static const bool value = decltype(test
(0))::value; - }; - - template
- std::string convertUnknownEnumToString( E e ); - - template
- std::enable_if_t< - !std::is_enum