1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
// 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
// Adapted from donated nonius code.
#pragma once
#include <Progmasoft/Catch3/Benchmark/Clock.hpp>
#include <Progmasoft/Catch3/Benchmark/Chronometer.hpp>
#include <Progmasoft/Catch3/Benchmark/Detail/Measure.hpp>
#include <Progmasoft/Catch3/Benchmark/Detail/CompleteInvoke.hpp>
#include <Progmasoft/Catch3/Benchmark/Detail/Timing.hpp>
#include <Progmasoft/Catch3/Internal/Meta.hpp>
#include <Progmasoft/Catch3/Internal/MoveAndForward.hpp>
#include <type_traits>
namespace Catch {
namespace Benchmark {
namespace Detail {
template <typename Clock, typename Fun>
TimingOf<Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {
return Detail::measure<Clock>(fun, iters);
}
template <typename Clock, typename Fun>
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));
return { meter.elapsed(), CATCH_MOVE(result), iters };
}
template <typename Clock, typename Fun>
using run_for_at_least_argument_t = std::conditional_t<is_callable<Fun(Chronometer)>::value, Chronometer, int>;
[[noreturn]]
void throw_optimized_away_error();
template <typename Clock, typename Fun>
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;
while (iters < (1 << 30)) {
auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
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
|