| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 | 
							- /*
 
-  *  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)
 
-  */
 
-  // Benchmark
 
- #ifndef TWOBLUECUBES_CATCH_BENCHMARK_HPP_INCLUDED
 
- #define TWOBLUECUBES_CATCH_BENCHMARK_HPP_INCLUDED
 
- #include "../catch_config.hpp"
 
- #include "../catch_context.h"
 
- #include "../catch_interfaces_reporter.h"
 
- #include "../catch_test_registry.h"
 
- #include "catch_chronometer.hpp"
 
- #include "catch_clock.hpp"
 
- #include "catch_environment.hpp"
 
- #include "catch_execution_plan.hpp"
 
- #include "detail/catch_estimate_clock.hpp"
 
- #include "detail/catch_complete_invoke.hpp"
 
- #include "detail/catch_analyse.hpp"
 
- #include "detail/catch_benchmark_function.hpp"
 
- #include "detail/catch_run_for_at_least.hpp"
 
- #include <algorithm>
 
- #include <functional>
 
- #include <string>
 
- #include <vector>
 
- #include <cmath>
 
- namespace Catch {
 
-     namespace Benchmark {
 
-         struct Benchmark {
 
-             Benchmark(std::string &&name)
 
-                 : name(std::move(name)) {}
 
-             template <class FUN>
 
-             Benchmark(std::string &&name, FUN &&func)
 
-                 : fun(std::move(func)), name(std::move(name)) {}
 
-             template <typename Clock>
 
-             ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
 
-                 auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
 
-                 auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
 
-                 auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
 
-                 int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
 
-                 return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };
 
-             }
 
-             template <typename Clock = default_clock>
 
-             void run() {
 
-                 IConfigPtr cfg = getCurrentContext().getConfig();
 
-                 auto env = Detail::measure_environment<Clock>();
 
-                 getResultCapture().benchmarkPreparing(name);
 
-                 CATCH_TRY{
 
-                     auto plan = user_code([&] {
 
-                         return prepare<Clock>(*cfg, env);
 
-                     });
 
-                     BenchmarkInfo info {
 
-                         name,
 
-                         plan.estimated_duration.count(),
 
-                         plan.iterations_per_sample,
 
-                         cfg->benchmarkSamples(),
 
-                         cfg->benchmarkResamples(),
 
-                         env.clock_resolution.mean.count(),
 
-                         env.clock_cost.mean.count()
 
-                     };
 
-                     getResultCapture().benchmarkStarting(info);
 
-                     auto samples = user_code([&] {
 
-                         return plan.template run<Clock>(*cfg, env);
 
-                     });
 
-                     auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
 
-                     BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
 
-                     getResultCapture().benchmarkEnded(stats);
 
-                 } CATCH_CATCH_ALL{
 
-                     if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
 
-                         std::rethrow_exception(std::current_exception());
 
-                 }
 
-             }
 
-             // sets lambda to be used in fun *and* executes benchmark!
 
-             template <typename Fun,
 
-                 typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
 
-                 Benchmark & operator=(Fun func) {
 
-                 fun = Detail::BenchmarkFunction(func);
 
-                 run();
 
-                 return *this;
 
-             }
 
-             explicit operator bool() {
 
-                 return true;
 
-             }
 
-         private:
 
-             Detail::BenchmarkFunction fun;
 
-             std::string name;
 
-         };
 
-     }
 
- } // namespace Catch
 
- #define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
 
- #define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
 
- #define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
 
-     if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
 
-         BenchmarkName = [&](int benchmarkIndex)
 
- #define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
 
-     if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
 
-         BenchmarkName = [&]
 
- #endif // TWOBLUECUBES_CATCH_BENCHMARK_HPP_INCLUDED
 
 
  |