| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 | 
							-     /*
 
-  *  Created by Joachim on 16/04/2019.
 
-  *  Adapted from donated nonius code.
 
-  *
 
-  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
 
-  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
-  */
 
-  // Dumb std::function implementation for consistent call overhead
 
- #ifndef TWOBLUECUBES_CATCH_DETAIL_BENCHMARK_FUNCTION_HPP_INCLUDED
 
- #define TWOBLUECUBES_CATCH_DETAIL_BENCHMARK_FUNCTION_HPP_INCLUDED
 
- #include "../catch_chronometer.hpp"
 
- #include "catch_complete_invoke.hpp"
 
- #include "../../catch_meta.hpp"
 
- #include <cassert>
 
- #include <type_traits>
 
- #include <utility>
 
- #include <memory>
 
- namespace Catch {
 
-     namespace Benchmark {
 
-         namespace Detail {
 
-             template <typename T>
 
-             using Decay = typename std::decay<T>::type;
 
-             template <typename T, typename U>
 
-             struct is_related
 
-                 : std::is_same<Decay<T>, Decay<U>> {};
 
-             /// We need to reinvent std::function because every piece of code that might add overhead
 
-             /// in a measurement context needs to have consistent performance characteristics so that we
 
-             /// can account for it in the measurement.
 
-             /// Implementations of std::function with optimizations that aren't always applicable, like
 
-             /// small buffer optimizations, are not uncommon.
 
-             /// This is effectively an implementation of std::function without any such optimizations;
 
-             /// it may be slow, but it is consistently slow.
 
-             struct BenchmarkFunction {
 
-             private:
 
-                 struct callable {
 
-                     virtual void call(Chronometer meter) const = 0;
 
-                     virtual callable* clone() const = 0;
 
-                     virtual ~callable() = default;
 
-                 };
 
-                 template <typename Fun>
 
-                 struct model : public callable {
 
-                     model(Fun&& fun) : fun(std::move(fun)) {}
 
-                     model(Fun const& fun) : fun(fun) {}
 
-                     model<Fun>* clone() const override { return new model<Fun>(*this); }
 
-                     void call(Chronometer meter) const override {
 
-                         call(meter, is_callable<Fun(Chronometer)>());
 
-                     }
 
-                     void call(Chronometer meter, std::true_type) const {
 
-                         fun(meter);
 
-                     }
 
-                     void call(Chronometer meter, std::false_type) const {
 
-                         meter.measure(fun);
 
-                     }
 
-                     Fun fun;
 
-                 };
 
-                 struct do_nothing { void operator()() const {} };
 
-                 template <typename T>
 
-                 BenchmarkFunction(model<T>* c) : f(c) {}
 
-             public:
 
-                 BenchmarkFunction()
 
-                     : f(new model<do_nothing>{ {} }) {}
 
-                 template <typename Fun,
 
-                     typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
 
-                     BenchmarkFunction(Fun&& fun)
 
-                     : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}
 
-                 BenchmarkFunction(BenchmarkFunction&& that)
 
-                     : f(std::move(that.f)) {}
 
-                 BenchmarkFunction(BenchmarkFunction const& that)
 
-                     : f(that.f->clone()) {}
 
-                 BenchmarkFunction& operator=(BenchmarkFunction&& that) {
 
-                     f = std::move(that.f);
 
-                     return *this;
 
-                 }
 
-                 BenchmarkFunction& operator=(BenchmarkFunction const& that) {
 
-                     f.reset(that.f->clone());
 
-                     return *this;
 
-                 }
 
-                 void operator()(Chronometer meter) const { f->call(meter); }
 
-             private:
 
-                 std::unique_ptr<callable> f;
 
-             };
 
-         } // namespace Detail
 
-     } // namespace Benchmark
 
- } // namespace Catch
 
- #endif // TWOBLUECUBES_CATCH_DETAIL_BENCHMARK_FUNCTION_HPP_INCLUDED
 
 
  |