File indexing completed on 2025-01-30 10:02:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
0011 #define CATCH_RUN_FOR_AT_LEAST_HPP_INCLUDED
0012
0013 #include <catch2/benchmark/catch_clock.hpp>
0014 #include <catch2/benchmark/catch_chronometer.hpp>
0015 #include <catch2/benchmark/detail/catch_measure.hpp>
0016 #include <catch2/benchmark/detail/catch_complete_invoke.hpp>
0017 #include <catch2/benchmark/detail/catch_timing.hpp>
0018 #include <catch2/internal/catch_meta.hpp>
0019 #include <catch2/internal/catch_move_and_forward.hpp>
0020
0021 #include <type_traits>
0022
0023 namespace Catch {
0024 namespace Benchmark {
0025 namespace Detail {
0026 template <typename Clock, typename Fun>
0027 TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {
0028 return Detail::measure<Clock>(fun, iters);
0029 }
0030 template <typename Clock, typename Fun>
0031 TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {
0032 Detail::ChronometerModel<Clock> meter;
0033 auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
0034
0035 return { meter.elapsed(), CATCH_MOVE(result), iters };
0036 }
0037
0038 template <typename Clock, typename Fun>
0039 using run_for_at_least_argument_t = std::conditional_t<is_callable<Fun(Chronometer)>::value, Chronometer, int>;
0040
0041
0042 [[noreturn]]
0043 void throw_optimized_away_error();
0044
0045 template <typename Clock, typename Fun>
0046 TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>>
0047 run_for_at_least(ClockDuration<Clock> how_long,
0048 const int initial_iterations,
0049 Fun&& fun) {
0050 auto iters = initial_iterations;
0051 while (iters < (1 << 30)) {
0052 auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
0053
0054 if (Timing.elapsed >= how_long) {
0055 return { Timing.elapsed, CATCH_MOVE(Timing.result), iters };
0056 }
0057 iters *= 2;
0058 }
0059 throw_optimized_away_error();
0060 }
0061 }
0062 }
0063 }
0064
0065 #endif