File indexing completed on 2025-01-30 10:02:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef CATCH_CHRONOMETER_HPP_INCLUDED
0011 #define CATCH_CHRONOMETER_HPP_INCLUDED
0012
0013 #include <catch2/benchmark/catch_clock.hpp>
0014 #include <catch2/benchmark/catch_optimizer.hpp>
0015 #include <catch2/internal/catch_meta.hpp>
0016 #include <catch2/internal/catch_move_and_forward.hpp>
0017
0018 namespace Catch {
0019 namespace Benchmark {
0020 namespace Detail {
0021 struct ChronometerConcept {
0022 virtual void start() = 0;
0023 virtual void finish() = 0;
0024 virtual ~ChronometerConcept();
0025
0026 ChronometerConcept() = default;
0027 ChronometerConcept(ChronometerConcept const&) = default;
0028 ChronometerConcept& operator=(ChronometerConcept const&) = default;
0029 };
0030 template <typename Clock>
0031 struct ChronometerModel final : public ChronometerConcept {
0032 void start() override { started = Clock::now(); }
0033 void finish() override { finished = Clock::now(); }
0034
0035 ClockDuration<Clock> elapsed() const { return finished - started; }
0036
0037 TimePoint<Clock> started;
0038 TimePoint<Clock> finished;
0039 };
0040 }
0041
0042 struct Chronometer {
0043 public:
0044 template <typename Fun>
0045 void measure(Fun&& fun) { measure(CATCH_FORWARD(fun), is_callable<Fun(int)>()); }
0046
0047 int runs() const { return repeats; }
0048
0049 Chronometer(Detail::ChronometerConcept& meter, int repeats_)
0050 : impl(&meter)
0051 , repeats(repeats_) {}
0052
0053 private:
0054 template <typename Fun>
0055 void measure(Fun&& fun, std::false_type) {
0056 measure([&fun](int) { return fun(); }, std::true_type());
0057 }
0058
0059 template <typename Fun>
0060 void measure(Fun&& fun, std::true_type) {
0061 Detail::optimizer_barrier();
0062 impl->start();
0063 for (int i = 0; i < repeats; ++i) invoke_deoptimized(fun, i);
0064 impl->finish();
0065 Detail::optimizer_barrier();
0066 }
0067
0068 Detail::ChronometerConcept* impl;
0069 int repeats;
0070 };
0071 }
0072 }
0073
0074 #endif