Upgrade in-tree google benchmark to v1.1

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@286029 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier
2016-11-05 00:30:27 +00:00
parent e619862dbf
commit d87eb99b80
59 changed files with 2445 additions and 2487 deletions

View File

@@ -153,6 +153,7 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "macros.h"
@@ -173,7 +174,8 @@ void Initialize(int* argc, char** argv);
// report the results.
//
// The second and third overload use the specified 'console_reporter' and
// 'file_reporter' respectively. 'file_reporter' will write to the file specified
// 'file_reporter' respectively. 'file_reporter' will write to the file
// specified
// by '--benchmark_output'. If '--benchmark_output' is not given the
// 'file_reporter' is ignored.
//
@@ -183,7 +185,6 @@ size_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter);
size_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter,
BenchmarkReporter* file_reporter);
// If this routine is called, peak memory allocation past this point in the
// benchmark is reported at the end of the benchmark report line. (It is
// computed by running the benchmark once with a single iteration and a memory
@@ -196,8 +197,9 @@ class Benchmark;
class BenchmarkImp;
class BenchmarkFamilies;
template <class T> struct Voider {
typedef void type;
template <class T>
struct Voider {
typedef void type;
};
template <class T, class = void>
@@ -205,7 +207,7 @@ struct EnableIfString {};
template <class T>
struct EnableIfString<T, typename Voider<typename T::basic_string>::type> {
typedef int type;
typedef int type;
};
void UseCharPointer(char const volatile*);
@@ -218,8 +220,7 @@ Benchmark* RegisterBenchmarkInternal(Benchmark*);
int InitializeStreams();
BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();
} // end namespace internal
} // end namespace internal
// The DoNotOptimize(...) function can be used to prevent a value or
// expression from being optimized away by the compiler. This function is
@@ -228,73 +229,64 @@ BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();
#if defined(__GNUC__)
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
asm volatile("" : : "g"(value) : "memory");
asm volatile("" : : "g"(value) : "memory");
}
// Force the compiler to flush pending writes to global memory. Acts as an
// effective read/write barrier
inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
asm volatile("" : : : "memory");
asm volatile("" : : : "memory");
}
#else
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
}
// FIXME Add ClobberMemory() for non-gnu compilers
#endif
// TimeUnit is passed to a benchmark in order to specify the order of magnitude
// for the measured time.
enum TimeUnit {
kNanosecond,
kMicrosecond,
kMillisecond
};
enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond };
// BigO is passed to a benchmark in order to specify the asymptotic computational
// complexity for the benchmark. In case oAuto is selected, complexity will be
// BigO is passed to a benchmark in order to specify the asymptotic
// computational
// complexity for the benchmark. In case oAuto is selected, complexity will be
// calculated automatically to the best fit.
enum BigO {
oNone,
o1,
oN,
oNSquared,
oNCubed,
oLogN,
oNLogN,
oAuto,
oLambda
};
enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
// BigOFunc is passed to a benchmark in order to specify the asymptotic
// BigOFunc is passed to a benchmark in order to specify the asymptotic
// computational complexity for the benchmark.
typedef double(BigOFunc)(int);
namespace internal {
class ThreadTimer;
class ThreadManager;
#if defined(BENCHMARK_HAS_CXX11)
enum ReportMode : unsigned {
#else
enum ReportMode {
#endif
RM_Unspecified, // The mode has not been manually specified
RM_Default, // The mode is user-specified as default.
RM_ReportAggregatesOnly
};
}
// State is passed to a running Benchmark and contains state for the
// benchmark to use.
class State {
public:
State(size_t max_iters, const std::vector<int>& ranges,
int thread_i, int n_threads);
public:
// Returns true if the benchmark should continue through another iteration.
// NOTE: A benchmark may not return from the test until KeepRunning() has
// returned false.
bool KeepRunning() {
if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {
assert(!finished_);
started_ = true;
ResumeTiming();
StartKeepRunning();
}
bool const res = total_iterations_++ < max_iterations;
if (BENCHMARK_BUILTIN_EXPECT(!res, false)) {
assert(started_ && (!finished_ || error_occurred_));
if (!error_occurred_) {
PauseTiming();
}
// Total iterations now is one greater than max iterations. Fix this.
total_iterations_ = max_iterations;
finished_ = true;
FinishKeepRunning();
}
return res;
}
@@ -304,10 +296,11 @@ public:
// Stop the benchmark timer. If not called, the timer will be
// automatically stopped after KeepRunning() returns false for the first time.
//
// For threaded benchmarks the PauseTiming() function acts
// like a barrier. I.e., the ith call by a particular thread to this
// function will block until all active threads have made their ith call.
// The timer will stop when the last thread has called this function.
// For threaded benchmarks the PauseTiming() function only pauses the timing
// for the current thread.
//
// NOTE: The "real time" measurement is per-thread. If different threads
// report different measurements the largest one is reported.
//
// NOTE: PauseTiming()/ResumeTiming() are relatively
// heavyweight, and so their use should generally be avoided
@@ -319,11 +312,6 @@ public:
// Start the benchmark timer. The timer is NOT running on entrance to the
// benchmark function. It begins running after the first call to KeepRunning()
//
// For threaded benchmarks the ResumeTiming() function acts
// like a barrier. I.e., the ith call by a particular thread to this
// function will block until all active threads have made their ith call.
// The timer will start when the last thread has called this function.
//
// NOTE: PauseTiming()/ResumeTiming() are relatively
// heavyweight, and so their use should generally be avoided
// within each benchmark iteration, if possible.
@@ -335,10 +323,10 @@ public:
// thread and report an error with the specified 'msg'. After this call
// the user may explicitly 'return' from the benchmark.
//
// For threaded benchmarks only the current thread stops executing. If
// multiple threads report an error only the first error message is used.
// The current thread is no longer considered 'active' by
// 'PauseTiming()' and 'ResumingTiming()'.
// For threaded benchmarks only the current thread stops executing and future
// calls to `KeepRunning()` will block until all threads have completed
// the `KeepRunning()` loop. If multiple threads report an error only the
// first error message is used.
//
// NOTE: Calling 'SkipWithError(...)' does not cause the benchmark to exit
// the current scope immediately. If the function is called from within
@@ -351,10 +339,8 @@ public:
// is used instead of automatically measured time if UseManualTime() was
// specified.
//
// For threaded benchmarks the SetIterationTime() function acts
// like a barrier. I.e., the ith call by a particular thread to this
// function will block until all threads have made their ith call.
// The time will be set by the last thread to call this function.
// For threaded benchmarks the final value will be set to the largest
// reported values.
void SetIterationTime(double seconds);
// Set the number of bytes processed by the current benchmark
@@ -365,27 +351,21 @@ public:
//
// REQUIRES: a benchmark has exited its KeepRunning loop.
BENCHMARK_ALWAYS_INLINE
void SetBytesProcessed(size_t bytes) {
bytes_processed_ = bytes;
}
void SetBytesProcessed(size_t bytes) { bytes_processed_ = bytes; }
BENCHMARK_ALWAYS_INLINE
size_t bytes_processed() const {
return bytes_processed_;
}
size_t bytes_processed() const { return bytes_processed_; }
// If this routine is called with complexity_n > 0 and complexity report is requested for the
// family benchmark, then current benchmark will be part of the computation and complexity_n will
// If this routine is called with complexity_n > 0 and complexity report is
// requested for the
// family benchmark, then current benchmark will be part of the computation
// and complexity_n will
// represent the length of N.
BENCHMARK_ALWAYS_INLINE
void SetComplexityN(int complexity_n) {
complexity_n_ = complexity_n;
}
void SetComplexityN(int complexity_n) { complexity_n_ = complexity_n; }
BENCHMARK_ALWAYS_INLINE
int complexity_length_n() {
return complexity_n_;
}
int complexity_length_n() { return complexity_n_; }
// If this routine is called with items > 0, then an items/s
// label is printed on the benchmark report line for the currently
@@ -394,14 +374,10 @@ public:
//
// REQUIRES: a benchmark has exited its KeepRunning loop.
BENCHMARK_ALWAYS_INLINE
void SetItemsProcessed(size_t items) {
items_processed_ = items;
}
void SetItemsProcessed(size_t items) { items_processed_ = items; }
BENCHMARK_ALWAYS_INLINE
size_t items_processed() const {
return items_processed_;
}
size_t items_processed() const { return items_processed_; }
// If this routine is called, the specified label is printed at the
// end of the benchmark report line for the currently executing
@@ -422,7 +398,7 @@ public:
// has the nested typename `basic_string`. This typename should be provided
// as an injected class name in the case of std::string.
template <class StringType>
void SetLabel(StringType const & str,
void SetLabel(StringType const& str,
typename internal::EnableIfString<StringType>::type = 1) {
this->SetLabel(str.c_str());
}
@@ -430,8 +406,8 @@ public:
// Range arguments for this run. CHECKs if the argument has been set.
BENCHMARK_ALWAYS_INLINE
int range(std::size_t pos = 0) const {
assert(range_.size() > pos);
return range_[pos];
assert(range_.size() > pos);
return range_[pos];
}
BENCHMARK_DEPRECATED_MSG("use 'range(0)' instead")
@@ -443,7 +419,7 @@ public:
BENCHMARK_ALWAYS_INLINE
size_t iterations() const { return total_iterations_; }
private:
private:
bool started_;
bool finished_;
size_t total_iterations_;
@@ -455,17 +431,25 @@ private:
int complexity_n_;
public:
// FIXME: Make this private somehow.
bool error_occurred_;
public:
public:
// Index of the executing thread. Values from [0, threads).
const int thread_index;
// Number of threads concurrently executing the benchmark.
const int threads;
const size_t max_iterations;
private:
// TODO make me private
State(size_t max_iters, const std::vector<int>& ranges, int thread_i,
int n_threads, internal::ThreadTimer* timer,
internal::ThreadManager* manager);
private:
void StartKeepRunning();
void FinishKeepRunning();
internal::ThreadTimer* timer_;
internal::ThreadManager* manager_;
BENCHMARK_DISALLOW_COPY_AND_ASSIGN(State);
};
@@ -480,7 +464,7 @@ typedef void(Function)(State&);
// Each method returns "this" so that multiple method calls can
// chained into one expression.
class Benchmark {
public:
public:
virtual ~Benchmark();
// Note: the following methods all return "this" so that multiple
@@ -499,7 +483,8 @@ public:
// REQUIRES: The function passed to the constructor must accept an arg1.
Benchmark* Range(int start, int limit);
// Run this benchmark once for all values in the range [start..limit] with specific step
// Run this benchmark once for all values in the range [start..limit] with
// specific step
// REQUIRES: The function passed to the constructor must accept an arg1.
Benchmark* DenseRange(int start, int limit, int step = 1);
@@ -512,10 +497,10 @@ public:
// NOTE: This is a legacy C++03 interface provided for compatibility only.
// New code should use 'Args'.
Benchmark* ArgPair(int x, int y) {
std::vector<int> args;
args.push_back(x);
args.push_back(y);
return Args(args);
std::vector<int> args;
args.push_back(x);
args.push_back(y);
return Args(args);
}
// Run this benchmark once for a number of values picked from the
@@ -523,14 +508,21 @@ public:
// REQUIRES: The function passed to the constructor must accept arg1, arg2 ...
Benchmark* Ranges(const std::vector<std::pair<int, int> >& ranges);
// Equivalent to ArgNames({name})
Benchmark* ArgName(const std::string& name);
// Set the argument names to display in the benchmark name. If not called,
// only argument values will be shown.
Benchmark* ArgNames(const std::vector<std::string>& names);
// Equivalent to Ranges({{lo1, hi1}, {lo2, hi2}}).
// NOTE: This is a legacy C++03 interface provided for compatibility only.
// New code should use 'Ranges'.
Benchmark* RangePair(int lo1, int hi1, int lo2, int hi2) {
std::vector<std::pair<int, int> > ranges;
ranges.push_back(std::make_pair(lo1, hi1));
ranges.push_back(std::make_pair(lo2, hi2));
return Ranges(ranges);
std::vector<std::pair<int, int> > ranges;
ranges.push_back(std::make_pair(lo1, hi1));
ranges.push_back(std::make_pair(lo2, hi2));
return Ranges(ranges);
}
// Pass this benchmark object to *func, which can customize
@@ -538,8 +530,8 @@ public:
// Threads, etc.
Benchmark* Apply(void (*func)(Benchmark* benchmark));
// Set the range multiplier for non-dense range. If not called, the range multiplier
// kRangeMultiplier will be used.
// Set the range multiplier for non-dense range. If not called, the range
// multiplier kRangeMultiplier will be used.
Benchmark* RangeMultiplier(int multiplier);
// Set the minimum amount of time to use when running this benchmark. This
@@ -564,15 +556,17 @@ public:
// called, the cpu time used by the benchmark will be used.
Benchmark* UseRealTime();
// If a benchmark must measure time manually (e.g. if GPU execution time is being
// measured), call this method. If called, each benchmark iteration should call
// If a benchmark must measure time manually (e.g. if GPU execution time is
// being
// measured), call this method. If called, each benchmark iteration should
// call
// SetIterationTime(seconds) to report the measured time, which will be used
// to control how many iterations are run, and in the printing of items/second
// or MB/second values.
Benchmark* UseManualTime();
// Set the asymptotic computational complexity for the benchmark. If called
// the asymptotic computational complexity will be shown on the output.
// the asymptotic computational complexity will be shown on the output.
Benchmark* Complexity(BigO complexity = benchmark::oAuto);
// Set the asymptotic computational complexity for the benchmark. If called
@@ -600,6 +594,12 @@ public:
// Foo in 16 threads
Benchmark* ThreadRange(int min_threads, int max_threads);
// For each value n in the range, run this benchmark once using n threads.
// min_threads and max_threads are always included in the range.
// stride specifies the increment. E.g. DenseThreadRange(1, 8, 3) starts
// a benchmark with 1, 4, 7 and 8 threads.
Benchmark* DenseThreadRange(int min_threads, int max_threads, int stride = 1);
// Equivalent to ThreadRange(NumCPUs(), NumCPUs())
Benchmark* ThreadPerCpu();
@@ -608,25 +608,43 @@ public:
// Used inside the benchmark implementation
struct Instance;
protected:
protected:
explicit Benchmark(const char* name);
Benchmark(Benchmark const&);
void SetName(const char* name);
private:
int ArgsCnt() const;
static void AddRange(std::vector<int>* dst, int lo, int hi, int mult);
private:
friend class BenchmarkFamilies;
BenchmarkImp* imp_;
std::string name_;
ReportMode report_mode_;
std::vector<std::string> arg_names_; // Args for all benchmark runs
std::vector<std::vector<int> > args_; // Args for all benchmark runs
TimeUnit time_unit_;
int range_multiplier_;
double min_time_;
int repetitions_;
bool use_real_time_;
bool use_manual_time_;
BigO complexity_;
BigOFunc* complexity_lambda_;
std::vector<int> thread_counts_;
Benchmark& operator=(Benchmark const&);
};
} // namespace internal
} // namespace internal
// Create and register a benchmark with the specified 'name' that invokes
// the specified functor 'fn'.
//
// RETURNS: A pointer to the registered benchmark.
internal::Benchmark* RegisterBenchmark(const char* name, internal::Function* fn);
internal::Benchmark* RegisterBenchmark(const char* name,
internal::Function* fn);
#if defined(BENCHMARK_HAS_CXX11)
template <class Lambda>
@@ -637,30 +655,30 @@ namespace internal {
// The class used to hold all Benchmarks created from static function.
// (ie those created using the BENCHMARK(...) macros.
class FunctionBenchmark : public Benchmark {
public:
FunctionBenchmark(const char* name, Function* func)
: Benchmark(name), func_(func)
{}
public:
FunctionBenchmark(const char* name, Function* func)
: Benchmark(name), func_(func) {}
virtual void Run(State& st);
private:
Function* func_;
virtual void Run(State& st);
private:
Function* func_;
};
#ifdef BENCHMARK_HAS_CXX11
template <class Lambda>
class LambdaBenchmark : public Benchmark {
public:
virtual void Run(State& st) { lambda_(st); }
public:
virtual void Run(State& st) { lambda_(st); }
private:
private:
template <class OLambda>
LambdaBenchmark(const char* name, OLambda&& lam)
: Benchmark(name), lambda_(std::forward<OLambda>(lam)) {}
LambdaBenchmark(LambdaBenchmark const&) = delete;
private:
private:
template <class Lam>
friend Benchmark* ::benchmark::RegisterBenchmark(const char*, Lam&&);
@@ -670,55 +688,58 @@ private:
} // end namespace internal
inline internal::Benchmark*
RegisterBenchmark(const char* name, internal::Function* fn) {
return internal::RegisterBenchmarkInternal(
::new internal::FunctionBenchmark(name, fn));
inline internal::Benchmark* RegisterBenchmark(const char* name,
internal::Function* fn) {
return internal::RegisterBenchmarkInternal(
::new internal::FunctionBenchmark(name, fn));
}
#ifdef BENCHMARK_HAS_CXX11
template <class Lambda>
internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn) {
using BenchType = internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
return internal::RegisterBenchmarkInternal(
::new BenchType(name, std::forward<Lambda>(fn)));
using BenchType =
internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
return internal::RegisterBenchmarkInternal(
::new BenchType(name, std::forward<Lambda>(fn)));
}
#endif
#if defined(BENCHMARK_HAS_CXX11) && \
(!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409)
template <class Lambda, class ...Args>
(!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409)
template <class Lambda, class... Args>
internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn,
Args&&... args) {
return benchmark::RegisterBenchmark(name,
[=](benchmark::State& st) { fn(st, args...); });
return benchmark::RegisterBenchmark(
name, [=](benchmark::State& st) { fn(st, args...); });
}
#else
#define BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK
#endif
// The base class for all fixture tests.
class Fixture: public internal::Benchmark {
public:
Fixture() : internal::Benchmark("") {}
class Fixture : public internal::Benchmark {
public:
Fixture() : internal::Benchmark("") {}
virtual void Run(State& st) {
this->SetUp(st);
this->BenchmarkCase(st);
this->TearDown(st);
}
virtual void Run(State& st) {
this->SetUp(st);
this->BenchmarkCase(st);
this->TearDown(st);
}
virtual void SetUp(const State&) {}
virtual void TearDown(const State&) {}
// These will be deprecated ...
virtual void SetUp(const State&) {}
virtual void TearDown(const State&) {}
// ... In favor of these.
virtual void SetUp(State& st) { SetUp(const_cast<const State&>(st)); }
virtual void TearDown(State& st) { TearDown(const_cast<const State&>(st)); }
protected:
virtual void BenchmarkCase(State&) = 0;
protected:
virtual void BenchmarkCase(State&) = 0;
};
} // end namespace benchmark
// ------------------------------------------------------
// Macro to register benchmarks
@@ -733,18 +754,18 @@ protected:
// Helpers for generating unique variable names
#define BENCHMARK_PRIVATE_NAME(n) \
BENCHMARK_PRIVATE_CONCAT(_benchmark_, BENCHMARK_PRIVATE_UNIQUE_ID, n)
BENCHMARK_PRIVATE_CONCAT(_benchmark_, BENCHMARK_PRIVATE_UNIQUE_ID, n)
#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
#define BENCHMARK_PRIVATE_DECLARE(n) \
static ::benchmark::internal::Benchmark* \
BENCHMARK_PRIVATE_NAME(n) BENCHMARK_UNUSED
#define BENCHMARK_PRIVATE_DECLARE(n) \
static ::benchmark::internal::Benchmark* BENCHMARK_PRIVATE_NAME(n) \
BENCHMARK_UNUSED
#define BENCHMARK(n) \
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
new ::benchmark::internal::FunctionBenchmark(#n, n)))
#define BENCHMARK(n) \
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
new ::benchmark::internal::FunctionBenchmark(#n, n)))
// Old-style macros
#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
@@ -767,14 +788,14 @@ protected:
//}
// /* Registers a benchmark named "BM_takes_args/int_string_test` */
// BENCHMARK_CAPTURE(BM_takes_args, int_string_test, 42, std::string("abc"));
#define BENCHMARK_CAPTURE(func, test_case_name, ...) \
BENCHMARK_PRIVATE_DECLARE(func) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
new ::benchmark::internal::FunctionBenchmark( \
#func "/" #test_case_name, \
[](::benchmark::State& st) { func(st, __VA_ARGS__); })))
#define BENCHMARK_CAPTURE(func, test_case_name, ...) \
BENCHMARK_PRIVATE_DECLARE(func) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
new ::benchmark::internal::FunctionBenchmark( \
#func "/" #test_case_name, \
[](::benchmark::State& st) { func(st, __VA_ARGS__); })))
#endif // __cplusplus >= 11
#endif // __cplusplus >= 11
// This will register a benchmark for a templatized function. For example:
//
@@ -784,54 +805,54 @@ protected:
// BENCHMARK_TEMPLATE(BM_Foo, 1);
//
// will register BM_Foo<1> as a benchmark.
#define BENCHMARK_TEMPLATE1(n, a) \
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
new ::benchmark::internal::FunctionBenchmark(#n "<" #a ">", n<a>)))
#define BENCHMARK_TEMPLATE2(n, a, b) \
#define BENCHMARK_TEMPLATE1(n, a) \
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
new ::benchmark::internal::FunctionBenchmark( \
#n "<" #a "," #b ">", n<a, b>)))
new ::benchmark::internal::FunctionBenchmark(#n "<" #a ">", n<a>)))
#define BENCHMARK_TEMPLATE2(n, a, b) \
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
new ::benchmark::internal::FunctionBenchmark(#n "<" #a "," #b ">", \
n<a, b>)))
#if __cplusplus >= 201103L
#define BENCHMARK_TEMPLATE(n, ...) \
BENCHMARK_PRIVATE_DECLARE(n) = \
#define BENCHMARK_TEMPLATE(n, ...) \
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
new ::benchmark::internal::FunctionBenchmark( \
#n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>)))
new ::benchmark::internal::FunctionBenchmark( \
#n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>)))
#else
#define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a)
#endif
#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
class BaseClass##_##Method##_Benchmark : public BaseClass { \
public: \
BaseClass##_##Method##_Benchmark() : BaseClass() { \
this->SetName(#BaseClass "/" #Method); \
} \
\
protected: \
virtual void BenchmarkCase(::benchmark::State&); \
};
#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
class BaseClass##_##Method##_Benchmark : public BaseClass { \
public: \
BaseClass##_##Method##_Benchmark() : BaseClass() { \
this->SetName(#BaseClass "/" #Method);} \
protected: \
virtual void BenchmarkCase(::benchmark::State&); \
};
#define BENCHMARK_DEFINE_F(BaseClass, Method) \
BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
void BaseClass##_##Method##_Benchmark::BenchmarkCase
#define BENCHMARK_DEFINE_F(BaseClass, Method) \
BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
void BaseClass##_##Method##_Benchmark::BenchmarkCase
#define BENCHMARK_REGISTER_F(BaseClass, Method) \
BENCHMARK_PRIVATE_REGISTER_F(BaseClass##_##Method##_Benchmark)
BENCHMARK_PRIVATE_REGISTER_F(BaseClass##_##Method##_Benchmark)
#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \
BENCHMARK_PRIVATE_DECLARE(TestName) = \
(::benchmark::internal::RegisterBenchmarkInternal(new TestName()))
BENCHMARK_PRIVATE_DECLARE(TestName) = \
(::benchmark::internal::RegisterBenchmarkInternal(new TestName()))
// This macro will define and register a benchmark within a fixture class.
#define BENCHMARK_F(BaseClass, Method) \
BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
BENCHMARK_REGISTER_F(BaseClass, Method); \
void BaseClass##_##Method##_Benchmark::BenchmarkCase
#define BENCHMARK_F(BaseClass, Method) \
BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
BENCHMARK_REGISTER_F(BaseClass, Method); \
void BaseClass##_##Method##_Benchmark::BenchmarkCase
// Helper macro to create a main routine in a test that runs the benchmarks
#define BENCHMARK_MAIN() \