File indexing completed on 2025-01-30 10:02:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED
0011 #define CATCH_BENCHMARK_FUNCTION_HPP_INCLUDED
0012
0013 #include <catch2/benchmark/catch_chronometer.hpp>
0014 #include <catch2/internal/catch_meta.hpp>
0015 #include <catch2/internal/catch_unique_ptr.hpp>
0016 #include <catch2/internal/catch_move_and_forward.hpp>
0017
0018 #include <type_traits>
0019
0020 namespace Catch {
0021 namespace Benchmark {
0022 namespace Detail {
0023 template <typename T, typename U>
0024 struct is_related
0025 : std::is_same<std::decay_t<T>, std::decay_t<U>> {};
0026
0027
0028
0029
0030
0031
0032
0033
0034 struct BenchmarkFunction {
0035 private:
0036 struct callable {
0037 virtual void call(Chronometer meter) const = 0;
0038 virtual Catch::Detail::unique_ptr<callable> clone() const = 0;
0039 virtual ~callable();
0040
0041 callable() = default;
0042 callable(callable const&) = default;
0043 callable& operator=(callable const&) = default;
0044 };
0045 template <typename Fun>
0046 struct model : public callable {
0047 model(Fun&& fun_) : fun(CATCH_MOVE(fun_)) {}
0048 model(Fun const& fun_) : fun(fun_) {}
0049
0050 Catch::Detail::unique_ptr<callable> clone() const override {
0051 return Catch::Detail::make_unique<model<Fun>>( *this );
0052 }
0053
0054 void call(Chronometer meter) const override {
0055 call(meter, is_callable<Fun(Chronometer)>());
0056 }
0057 void call(Chronometer meter, std::true_type) const {
0058 fun(meter);
0059 }
0060 void call(Chronometer meter, std::false_type) const {
0061 meter.measure(fun);
0062 }
0063
0064 Fun fun;
0065 };
0066
0067 struct do_nothing { void operator()() const {} };
0068
0069 template <typename T>
0070 BenchmarkFunction(model<T>* c) : f(c) {}
0071
0072 public:
0073 BenchmarkFunction()
0074 : f(new model<do_nothing>{ {} }) {}
0075
0076 template <typename Fun,
0077 std::enable_if_t<!is_related<Fun, BenchmarkFunction>::value, int> = 0>
0078 BenchmarkFunction(Fun&& fun)
0079 : f(new model<std::decay_t<Fun>>(CATCH_FORWARD(fun))) {}
0080
0081 BenchmarkFunction( BenchmarkFunction&& that ) noexcept:
0082 f( CATCH_MOVE( that.f ) ) {}
0083
0084 BenchmarkFunction(BenchmarkFunction const& that)
0085 : f(that.f->clone()) {}
0086
0087 BenchmarkFunction&
0088 operator=( BenchmarkFunction&& that ) noexcept {
0089 f = CATCH_MOVE( that.f );
0090 return *this;
0091 }
0092
0093 BenchmarkFunction& operator=(BenchmarkFunction const& that) {
0094 f = that.f->clone();
0095 return *this;
0096 }
0097
0098 void operator()(Chronometer meter) const { f->call(meter); }
0099
0100 private:
0101 Catch::Detail::unique_ptr<callable> f;
0102 };
0103 }
0104 }
0105 }
0106
0107 #endif