diff options
| author | Martin Hořeňovský | 2023-12-11 00:55:40 +0100 |
|---|---|---|
| committer | Martin Hořeňovský | 2023-12-11 00:55:40 +0100 |
| commit | 53d0d913a422d356b23dd927547febdf69ee9081 (patch) | |
| tree | b2b624bde9ead96c0e448c8d6ba7dcba6e5ebb40 /extras/catch_amalgamated.hpp | |
| parent | 1648c30ec3ac1aedd1417d31de18801767ab0d72 (diff) | |
| download | catch3-3.5.0.tar.gz | |
v3.5.0v3.5.0
Diffstat (limited to 'extras/catch_amalgamated.hpp')
| -rw-r--r-- | extras/catch_amalgamated.hpp | 1231 |
1 files changed, 918 insertions, 313 deletions
diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp index 694fe1e4..bec588d4 100644 --- a/extras/catch_amalgamated.hpp +++ b/extras/catch_amalgamated.hpp @@ -1,3 +1,4 @@ + // Copyright Catch2 Authors // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE.txt or copy at @@ -5,8 +6,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.4.0 -// Generated: 2023-07-13 13:23:07.577770 +// Catch v3.5.0 +// Generated: 2023-12-11 00:51:06.770598 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -240,7 +241,9 @@ //////////////////////////////////////////////////////////////////////////////// // Assume that some platforms do not support getenv. -#if defined(CATCH_PLATFORM_WINDOWS_UWP) || defined(CATCH_PLATFORM_PLAYSTATION) +#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 @@ -950,14 +953,35 @@ namespace Detail { #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 <chrono> namespace Catch { + namespace Benchmark { + using IDuration = std::chrono::nanoseconds; + using FDuration = std::chrono::duration<double, std::nano>; + + template <typename Clock> + 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 <typename Duration = std::chrono::duration<double, std::nano>> + template <typename Duration = Benchmark::FDuration> struct BenchmarkStats; } // end namespace Catch @@ -1246,17 +1270,12 @@ namespace Catch { namespace Catch { namespace Benchmark { - template <typename Duration> + template <typename Type> struct Estimate { - Duration point; - Duration lower_bound; - Duration upper_bound; + Type point; + Type lower_bound; + Type upper_bound; double confidence_interval; - - template <typename Duration2> - operator Estimate<Duration2>() const { - return { point, lower_bound, upper_bound, confidence_interval }; - } }; } // namespace Benchmark } // namespace Catch @@ -1304,32 +1323,17 @@ namespace Catch { double clockCost; }; - template <class Duration> + // We need to keep template parameter for backwards compatibility, + // but we also do not want to use the template paraneter. + template <class Dummy> struct BenchmarkStats { BenchmarkInfo info; - std::vector<Duration> samples; - Benchmark::Estimate<Duration> mean; - Benchmark::Estimate<Duration> standardDeviation; + std::vector<Benchmark::FDuration> samples; + Benchmark::Estimate<Benchmark::FDuration> mean; + Benchmark::Estimate<Benchmark::FDuration> standardDeviation; Benchmark::OutlierClassification outliers; double outlierVariance; - - template <typename Duration2> - operator BenchmarkStats<Duration2>() const { - std::vector<Duration2> samples2; - samples2.reserve(samples.size()); - for (auto const& sample : samples) { - samples2.push_back(Duration2(sample)); - } - return { - info, - CATCH_MOVE(samples2), - mean, - standardDeviation, - outliers, - outlierVariance, - }; - } }; @@ -1340,61 +1344,19 @@ namespace Catch { // Adapted from donated nonius code. -#ifndef CATCH_CLOCK_HPP_INCLUDED -#define CATCH_CLOCK_HPP_INCLUDED - -#include <chrono> -#include <ratio> - -namespace Catch { - namespace Benchmark { - template <typename Clock> - using ClockDuration = typename Clock::duration; - template <typename Clock> - using FloatDuration = std::chrono::duration<double, typename Clock::period>; - - template <typename Clock> - using TimePoint = typename Clock::time_point; - - using default_clock = std::chrono::steady_clock; - - template <typename Clock> - struct now { - TimePoint<Clock> operator()() const { - return Clock::now(); - } - }; - - using fp_seconds = std::chrono::duration<double, std::ratio<1>>; - } // namespace Benchmark -} // namespace Catch - -#endif // CATCH_CLOCK_HPP_INCLUDED - - -// Adapted from donated nonius code. - #ifndef CATCH_ENVIRONMENT_HPP_INCLUDED #define CATCH_ENVIRONMENT_HPP_INCLUDED namespace Catch { namespace Benchmark { - template <typename Duration> struct EnvironmentEstimate { - Duration mean; + FDuration mean; OutlierClassification outliers; - - template <typename Duration2> - operator EnvironmentEstimate<Duration2>() const { - return { mean, outliers }; - } }; - template <typename Clock> struct Environment { - using clock_type = Clock; - EnvironmentEstimate<FloatDuration<Clock>> clock_resolution; - EnvironmentEstimate<FloatDuration<Clock>> clock_cost; + EnvironmentEstimate clock_resolution; + EnvironmentEstimate clock_cost; }; } // namespace Benchmark } // namespace Catch @@ -1487,7 +1449,7 @@ namespace Catch { template <typename Fn, typename... Args> inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> std::enable_if_t<std::is_same<void, decltype(fn(args...))>::value> { - CATCH_FORWARD(fn) (CATCH_FORWARD(args)...); + CATCH_FORWARD((fn)) (CATCH_FORWARD(args)...); } } // namespace Benchmark } // namespace Catch @@ -1553,7 +1515,10 @@ namespace Catch { void start() override { started = Clock::now(); } void finish() override { finished = Clock::now(); } - ClockDuration<Clock> elapsed() const { return finished - started; } + IDuration elapsed() const { + return std::chrono::duration_cast<std::chrono::nanoseconds>( + finished - started ); + } TimePoint<Clock> started; TimePoint<Clock> finished; @@ -1791,14 +1756,14 @@ namespace Catch { namespace Catch { namespace Benchmark { - template <typename Duration, typename Result> + template <typename Result> struct Timing { - Duration elapsed; + IDuration elapsed; Result result; int iterations; }; - template <typename Clock, typename Func, typename... Args> - using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>; + template <typename Func, typename... Args> + using TimingOf = Timing<Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>; } // namespace Benchmark } // namespace Catch @@ -1808,7 +1773,7 @@ namespace Catch { namespace Benchmark { namespace Detail { template <typename Clock, typename Fun, typename... Args> - TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) { + TimingOf<Fun, Args...> measure(Fun&& fun, Args&&... args) { auto start = Clock::now(); auto&& r = Detail::complete_invoke(fun, CATCH_FORWARD(args)...); auto end = Clock::now(); @@ -1827,11 +1792,11 @@ namespace Catch { namespace Benchmark { namespace Detail { template <typename Clock, typename Fun> - TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) { + TimingOf<Fun, int> measure_one(Fun&& fun, int iters, std::false_type) { return Detail::measure<Clock>(fun, iters); } template <typename Clock, typename Fun> - TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) { + TimingOf<Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) { Detail::ChronometerModel<Clock> meter; auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters)); @@ -1846,8 +1811,8 @@ namespace Catch { void throw_optimized_away_error(); template <typename Clock, typename Fun> - TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> - run_for_at_least(ClockDuration<Clock> how_long, + TimingOf<Fun, run_for_at_least_argument_t<Clock, Fun>> + run_for_at_least(IDuration how_long, const int initial_iterations, Fun&& fun) { auto iters = initial_iterations; @@ -1871,33 +1836,31 @@ namespace Catch { namespace Catch { namespace Benchmark { - template <typename Duration> struct ExecutionPlan { int iterations_per_sample; - Duration estimated_duration; + FDuration estimated_duration; Detail::BenchmarkFunction benchmark; - Duration warmup_time; + FDuration warmup_time; int warmup_iterations; - template <typename Duration2> - operator ExecutionPlan<Duration2>() const { - return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations }; - } - template <typename Clock> - std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const { + std::vector<FDuration> run(const IConfig &cfg, Environment env) const { // warmup a bit - Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{})); + Detail::run_for_at_least<Clock>( + std::chrono::duration_cast<IDuration>( warmup_time ), + warmup_iterations, + Detail::repeat( []() { return Clock::now(); } ) + ); - std::vector<FloatDuration<Clock>> times; + std::vector<FDuration> times; const auto num_samples = cfg.benchmarkSamples(); times.reserve( num_samples ); for ( size_t i = 0; i < num_samples; ++i ) { Detail::ChronometerModel<Clock> model; this->benchmark( Chronometer( model, iterations_per_sample ) ); auto sample_time = model.elapsed() - env.clock_cost.mean; - if ( sample_time < FloatDuration<Clock>::zero() ) { - sample_time = FloatDuration<Clock>::zero(); + if ( sample_time < FDuration::zero() ) { + sample_time = FDuration::zero(); } times.push_back(sample_time / iterations_per_sample); } @@ -1923,100 +1886,35 @@ namespace Catch { #define CATCH_STATS_HPP_INCLUDED -#include <algorithm> #include <vector> -#include <cmath> namespace Catch { namespace Benchmark { namespace Detail { using sample = std::vector<double>; - // Used when we know we want == comparison of two doubles - // to centralize warning suppression - bool directCompare( double lhs, double rhs ); - - double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last); + double weighted_average_quantile( int k, + int q, + double* first, + double* last ); OutlierClassification - classify_outliers( std::vector<double>::const_iterator first, - std::vector<double>::const_iterator last ); - - double mean( std::vector<double>::const_iterator first, - std::vector<double>::const_iterator last ); - - template <typename Estimator> - sample jackknife(Estimator&& estimator, - std::vector<double>::iterator first, - std::vector<double>::iterator last) { - auto n = static_cast<size_t>(last - first); - auto second = first; - ++second; - sample results; - results.reserve(n); - - for (auto it = first; it != last; ++it) { - std::iter_swap(it, first); - results.push_back(estimator(second, last)); - } + classify_outliers( double const* first, double const* last ); - return results; - } + double mean( double const* first, double const* last ); - inline double normal_cdf(double x) { - return std::erfc(-x / std::sqrt(2.0)) / 2.0; - } + double normal_cdf( double x ); double erfc_inv(double x); double normal_quantile(double p); - template <typename Estimator> - Estimate<double> bootstrap( double confidence_level, - std::vector<double>::iterator first, - std::vector<double>::iterator last, - sample const& resample, - Estimator&& estimator ) { - auto n_samples = last - first; - - double point = estimator(first, last); - // Degenerate case with a single sample - if (n_samples == 1) return { point, point, point, confidence_level }; - - sample jack = jackknife(estimator, first, last); - double jack_mean = mean(jack.begin(), jack.end()); - double sum_squares = 0, sum_cubes = 0; - for (double x : jack) { - auto difference = jack_mean - x; - auto square = difference * difference; - auto cube = square * difference; - sum_squares += square; sum_cubes += cube; - } - - double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5)); - long n = static_cast<long>(resample.size()); - double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / static_cast<double>(n); - // degenerate case with uniform samples - if ( directCompare( prob_n, 0. ) ) { - return { point, point, point, confidence_level }; - } - - double bias = normal_quantile(prob_n); - double z1 = normal_quantile((1. - confidence_level) / 2.); - - auto cumn = [n]( double x ) -> long { - return std::lround( normal_cdf( x ) * static_cast<double>(n) ); - }; - auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); }; - double b1 = bias + z1; - double b2 = bias - z1; - double a1 = a(b1); - double a2 = a(b2); - auto lo = static_cast<size_t>((std::max)(cumn(a1), 0l)); - auto hi = static_cast<size_t>((std::min)(cumn(a2), n - 1)); - - return { point, resample[lo], resample[hi], confidence_level }; - } + Estimate<double> + bootstrap( double confidence_level, + double* first, + double* last, + sample const& resample, + double ( *estimator )( double const*, double const* ) ); struct bootstrap_analysis { Estimate<double> mean; @@ -2026,8 +1924,8 @@ namespace Catch { bootstrap_analysis analyse_samples(double confidence_level, unsigned int n_resamples, - std::vector<double>::iterator first, - std::vector<double>::iterator last); + double* first, + double* last); } // namespace Detail } // namespace Benchmark } // namespace Catch @@ -2071,23 +1969,23 @@ namespace Catch { template <typename Clock> int warmup() { - return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>) + return run_for_at_least<Clock>(std::chrono::duration_cast<IDuration>(warmup_time), warmup_seed, &resolution<Clock>) .iterations; } template <typename Clock> - EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) { - auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>) + EnvironmentEstimate estimate_clock_resolution(int iterations) { + auto r = run_for_at_least<Clock>(std::chrono::duration_cast<IDuration>(clock_resolution_estimation_time), iterations, &resolution<Clock>) .result; return { - FloatDuration<Clock>(mean(r.begin(), r.end())), - classify_outliers(r.begin(), r.end()), + FDuration(mean(r.data(), r.data() + r.size())), + classify_outliers(r.data(), r.data() + r.size()), }; } template <typename Clock> - EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) { + EnvironmentEstimate estimate_clock_cost(FDuration resolution) { auto time_limit = (std::min)( resolution * clock_cost_estimation_tick_limit, - FloatDuration<Clock>(clock_cost_estimation_time_limit)); + FDuration(clock_cost_estimation_time_limit)); auto time_clock = [](int k) { return Detail::measure<Clock>([k] { for (int i = 0; i < k; ++i) { @@ -2098,7 +1996,7 @@ namespace Catch { }; time_clock(1); int iters = clock_cost_estimation_iterations; - auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock); + auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<IDuration>(clock_cost_estimation_time), iters, time_clock); std::vector<double> times; int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed)); times.reserve(static_cast<size_t>(nsamples)); @@ -2108,18 +2006,18 @@ namespace Catch { .count() ) ); } return { - FloatDuration<Clock>(mean(times.begin(), times.end())), - classify_outliers(times.begin(), times.end()), + FDuration(mean(times.data(), times.data() + times.size())), + classify_outliers(times.data(), times.data() + times.size()), }; } template <typename Clock> - Environment<FloatDuration<Clock>> measure_environment() { + Environment measure_environment() { #if defined(__clang__) # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wexit-time-destructors" #endif - static Catch::Detail::unique_ptr<Environment<FloatDuration<Clock>>> env; + static Catch::Detail::unique_ptr<Environment> env; #if defined(__clang__) # pragma clang diagnostic pop #endif @@ -2131,7 +2029,7 @@ namespace Catch { auto resolution = Detail::estimate_clock_resolution<Clock>(iters); auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean); - env = Catch::Detail::make_unique<Environment<FloatDuration<Clock>>>( Environment<FloatDuration<Clock>>{resolution, cost} ); + env = Catch::Detail::make_unique<Environment>( Environment{resolution, cost} ); return *env; } } // namespace Detail @@ -2158,94 +2056,25 @@ namespace Catch { namespace Catch { namespace Benchmark { - template <typename Duration> struct SampleAnalysis { - std::vector<Duration> samples; - Estimate<Duration> mean; - Estimate<Duration> standard_deviation; + std::vector<FDuration> samples; + Estimate<FDuration> mean; + Estimate<FDuration> standard_deviation; OutlierClassification outliers; double outlier_variance; - - template <typename Duration2> - operator SampleAnalysis<Duration2>() const { - std::vector<Duration2> samples2; - samples2.reserve(samples.size()); - for (auto const& d : samples) { - samples2.push_back(Duration2(d)); - } - return { - CATCH_MOVE(samples2), - mean, - standard_deviation, - outliers, - outlier_variance, - }; - } }; } // namespace Benchmark } // namespace Catch #endif // CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED -#include <vector> namespace Catch { + class IConfig; + namespace Benchmark { namespace Detail { - template <typename Duration, typename Iterator> - SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) { - if (!cfg.benchmarkNoAnalysis()) { - std::vector<double> samples; - samples.reserve(static_cast<size_t>(last - first)); - for (auto current = first; current != last; ++current) { - samples.push_back( current->count() ); - } - - auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end()); - auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end()); - - auto wrap_estimate = [](Estimate<double> e) { - return Estimate<Duration> { - Duration(e.point), - Duration(e.lower_bound), - Duration(e.upper_bound), - e.confidence_interval, - }; - }; - std::vector<Duration> samples2; - samples2.reserve(samples.size()); - for (auto s : samples) { - samples2.push_back( Duration( s ) ); - } - - return { - CATCH_MOVE(samples2), - wrap_estimate(analysis.mean), - wrap_estimate(analysis.standard_deviation), - outliers, - analysis.outlier_variance, - }; - } else { - std::vector<Duration> samples; - samples.reserve(static_cast<size_t>(last - first)); - - Duration mean = Duration(0); - int i = 0; - for (auto it = first; it < last; ++it, ++i) { - samples.push_back(Duration(*it)); - mean += Duration(*it); - } - mean /= i; - - return { - CATCH_MOVE(samples), - Estimate<Duration>{mean, mean, mean, 0.0}, - Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0}, - OutlierClassification{}, - 0.0 - }; - } - } + SampleAnalysis analyse(const IConfig &cfg, FDuration* first, FDuration* last); } // namespace Detail } // namespace Benchmark } // namespace Catch @@ -2255,9 +2084,7 @@ namespace Catch { #include <algorithm> #include <chrono> #include <exception> -#include <functional> #include <string> -#include <vector> #include <cmath> namespace Catch { @@ -2271,16 +2098,18 @@ namespace Catch { : fun(CATCH_MOVE(func)), name(CATCH_MOVE(benchmarkName)) {} template <typename Clock> - ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const { + 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<decltype(min_time)>(cfg.benchmarkWarmupTime())); - auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun); + auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<IDuration>(run_time), 1, fun); int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed)); - return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations }; + return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FDuration>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations }; } template <typename Clock = default_clock> void run() { + static_assert( Clock::is_steady, + "Benchmarking clock should be steady" ); auto const* cfg = getCurrentContext().getConfig(); auto env = Detail::measure_environment<Clock>(); @@ -2307,8 +2136,8 @@ namespace Catch { return plan.template run<Clock>(*cfg, env); }); - auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end()); - BenchmarkStats<FloatDuration<Clock>> stats{ CATCH_MOVE(info), CATCH_MOVE(analysis.samples), analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance }; + 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); @@ -2984,6 +2813,12 @@ namespace Catch { } } }; + template <> + struct StringMaker<std::nullopt_t> { + static std::string convert(const std::nullopt_t&) { + return "{ }"; + } + }; } #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER @@ -4166,6 +4001,29 @@ namespace Catch { + +/** \file + * Wrapper for the CATCH_CONFIG_PREFIX_MESSAGES configuration option + * + * CATCH_CONFIG_PREFIX_ALL can be used to avoid clashes with other macros + * by prepending CATCH_. This may not be desirable if the only clashes are with + * logger macros such as INFO and WARN. In this cases + * CATCH_CONFIG_PREFIX_MESSAGES can be used to only prefix a small subset + * of relevant macros. + * + */ + +#ifndef CATCH_CONFIG_PREFIX_MESSAGES_HPP_INCLUDED +#define CATCH_CONFIG_PREFIX_MESSAGES_HPP_INCLUDED + + +#if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_PREFIX_MESSAGES) + #define CATCH_CONFIG_PREFIX_MESSAGES +#endif + +#endif // CATCH_CONFIG_PREFIX_MESSAGES_HPP_INCLUDED + + #ifndef CATCH_STREAM_END_STOP_HPP_INCLUDED #define CATCH_STREAM_END_STOP_HPP_INCLUDED @@ -4321,28 +4179,28 @@ namespace Catch { Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ) -#if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE) +#if defined(CATCH_CONFIG_PREFIX_MESSAGES) && !defined(CATCH_CONFIG_DISABLE) #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) #define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg ) #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE", __VA_ARGS__ ) -#elif defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE) +#elif defined(CATCH_CONFIG_PREFIX_MESSAGES) && defined(CATCH_CONFIG_DISABLE) #define CATCH_INFO( msg ) (void)(0) #define CATCH_UNSCOPED_INFO( msg ) (void)(0) #define CATCH_WARN( msg ) (void)(0) #define CATCH_CAPTURE( ... ) (void)(0) -#elif !defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE) +#elif !defined(CATCH_CONFIG_PREFIX_MESSAGES) && !defined(CATCH_CONFIG_DISABLE) #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg ) #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE", __VA_ARGS__ ) -#elif !defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE) +#elif !defined(CATCH_CONFIG_PREFIX_MESSAGES) && defined(CATCH_CONFIG_DISABLE) #define INFO( msg ) (void)(0) #define UNSCOPED_INFO( msg ) (void)(0) @@ -5784,7 +5642,7 @@ namespace Catch { #else // CATCH_CONFIG_FAST_COMPILE #define INTERNAL_CATCH_TRY try -#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); } +#define INTERNAL_CATCH_CATCH( handler ) catch(...) { (handler).handleUnexpectedInflightException(); } #endif @@ -6023,7 +5881,7 @@ namespace Catch { CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \ CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \ - if ( [[maybe_unused]] int catchInternalPreviousSectionHint = \ + if ( [[maybe_unused]] const int catchInternalPreviousSectionHint = \ catchInternalSectionHint, \ catchInternalSectionHint = Catch::Detail::GetNewSectionHint(); \ catchInternalPreviousSectionHint == __LINE__ ) \ @@ -6033,7 +5891,7 @@ namespace Catch { CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \ CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \ - if ( [[maybe_unused]] int catchInternalPreviousSectionHint = \ + if ( [[maybe_unused]] const int catchInternalPreviousSectionHint = \ catchInternalSectionHint, \ catchInternalSectionHint = Catch::Detail::GetNewSectionHint(); \ catchInternalPreviousSectionHint == __LINE__ ) \ @@ -6175,7 +6033,7 @@ static int catchInternalSectionHint = 0; CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \ static const Catch::Detail::DummyUse INTERNAL_CATCH_UNIQUE_NAME( \ - dummyUser )( &fname ); \ + dummyUser )( &(fname) ); \ CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \ static void fname( [[maybe_unused]] int catchInternalSectionHint ) \ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION @@ -7374,7 +7232,7 @@ namespace Catch { #define CATCH_VERSION_MACROS_HPP_INCLUDED #define CATCH_VERSION_MAJOR 3 -#define CATCH_VERSION_MINOR 4 +#define CATCH_VERSION_MINOR 5 #define CATCH_VERSION_PATCH 0 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED @@ -8037,7 +7895,550 @@ namespace Catch { #endif // CATCH_RANDOM_NUMBER_GENERATOR_HPP_INCLUDED -#include <random> + + +#ifndef CATCH_UNIFORM_INTEGER_DISTRIBUTION_HPP_INCLUDED +#define CATCH_UNIFORM_INTEGER_DISTRIBUTION_HPP_INCLUDED + + + + +#ifndef CATCH_RANDOM_INTEGER_HELPERS_HPP_INCLUDED +#define CATCH_RANDOM_INTEGER_HELPERS_HPP_INCLUDED + +#include <climits> +#include <cstddef> +#include <cstdint> +#include <type_traits> + +namespace Catch { + namespace Detail { + + template <std::size_t> + struct SizedUnsignedType; +#define SizedUnsignedTypeHelper( TYPE ) \ + template <> \ + struct SizedUnsignedType<sizeof( TYPE )> { \ + using type = TYPE; \ + } + + SizedUnsignedTypeHelper( std::uint8_t ); + SizedUnsignedTypeHelper( std::uint16_t ); + SizedUnsignedTypeHelper( std::uint32_t ); + SizedUnsignedTypeHelper( std::uint64_t ); +#undef SizedUnsignedTypeHelper + + template <std::size_t sz> + using SizedUnsignedType_t = typename SizedUnsignedType<sz>::type; + + template <typename T> + using DoubleWidthUnsignedType_t = SizedUnsignedType_t<2 * sizeof( T )>; + + template <typename T> + struct ExtendedMultResult { + T upper; + T lower; + friend bool operator==( ExtendedMultResult const& lhs, + ExtendedMultResult const& rhs ) { + return lhs.upper == rhs.upper && lhs.lower == rhs.lower; + } + }; + + // Returns 128 bit result of multiplying lhs and rhs + constexpr ExtendedMultResult<std::uint64_t> |