mirror of
https://github.com/google/benchmark.git
synced 2025-03-14 03:10:22 +08:00
Allow template arguments to be specified directly on the BENCHMARK macro (#1262)
* Allow template arguments to be specifed directly on the BENCHMARK macro/ Use cases: - more convenient (than having to use a separate BENCHMARK_TEMPLATE) - feature parity with our internal library. * fix tests * updated docs
This commit is contained in:
parent
365670e432
commit
fca348296f
@ -483,14 +483,19 @@ template <class Q> void BM_Sequential(benchmark::State& state) {
|
||||
state.SetBytesProcessed(
|
||||
static_cast<int64_t>(state.iterations())*state.range(0));
|
||||
}
|
||||
// C++03
|
||||
BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10);
|
||||
|
||||
// C++11 or newer, you can use the BENCHMARK marcro with template parameters:
|
||||
BENCHMARK(BM_Sequential<WaitQueue<int>>)->Range(1<<0, 1<<10);
|
||||
|
||||
```
|
||||
|
||||
Three macros are provided for adding benchmark templates.
|
||||
|
||||
```c++
|
||||
#ifdef BENCHMARK_HAS_CXX11
|
||||
#define BENCHMARK_TEMPLATE(func, ...) // Takes any number of parameters.
|
||||
#define BENCHMARK(func<...>) // Takes any number of parameters.
|
||||
#else // C++ < C++11
|
||||
#define BENCHMARK_TEMPLATE(func, arg1)
|
||||
#endif
|
||||
|
@ -1207,8 +1207,15 @@ class Fixture : public internal::Benchmark {
|
||||
#endif
|
||||
|
||||
// Helpers for generating unique variable names
|
||||
#ifdef BENCHMARK_HAS_CXX11
|
||||
#define BENCHMARK_PRIVATE_NAME(...) \
|
||||
BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \
|
||||
__VA_ARGS__)
|
||||
#else
|
||||
#define BENCHMARK_PRIVATE_NAME(n) \
|
||||
BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, n)
|
||||
#endif // BENCHMARK_HAS_CXX11
|
||||
|
||||
#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
|
||||
#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
|
||||
// Helper for concatenation with macro name expansion
|
||||
@ -1219,10 +1226,18 @@ class Fixture : public internal::Benchmark {
|
||||
static ::benchmark::internal::Benchmark* BENCHMARK_PRIVATE_NAME(n) \
|
||||
BENCHMARK_UNUSED
|
||||
|
||||
#ifdef BENCHMARK_HAS_CXX11
|
||||
#define BENCHMARK(...) \
|
||||
BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
|
||||
(::benchmark::internal::RegisterBenchmarkInternal( \
|
||||
new ::benchmark::internal::FunctionBenchmark(#__VA_ARGS__, \
|
||||
&__VA_ARGS__)))
|
||||
#else
|
||||
#define BENCHMARK(n) \
|
||||
BENCHMARK_PRIVATE_DECLARE(n) = \
|
||||
(::benchmark::internal::RegisterBenchmarkInternal( \
|
||||
new ::benchmark::internal::FunctionBenchmark(#n, n)))
|
||||
#endif // BENCHMARK_HAS_CXX11
|
||||
|
||||
// Old-style macros
|
||||
#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
|
||||
|
@ -142,6 +142,33 @@ void BM_RangedFor(benchmark::State& state) {
|
||||
}
|
||||
BENCHMARK(BM_RangedFor);
|
||||
|
||||
#ifdef BENCHMARK_HAS_CXX11
|
||||
template <typename T>
|
||||
void BM_OneTemplateFunc(benchmark::State& state) {
|
||||
int arg = state.range(0);
|
||||
T sum = 0;
|
||||
for (auto _ : state) {
|
||||
sum += arg;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_OneTemplateFunc<int>)->Arg(1);
|
||||
BENCHMARK(BM_OneTemplateFunc<double>)->Arg(1);
|
||||
|
||||
template <typename A, typename B>
|
||||
void BM_TwoTemplateFunc(benchmark::State& state) {
|
||||
int arg = state.range(0);
|
||||
A sum = 0;
|
||||
B prod = 1;
|
||||
for (auto _ : state) {
|
||||
sum += arg;
|
||||
prod *= arg;
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_TwoTemplateFunc<int, double>)->Arg(1);
|
||||
BENCHMARK(BM_TwoTemplateFunc<double, int>)->Arg(1);
|
||||
|
||||
#endif // BENCHMARK_HAS_CXX11
|
||||
|
||||
// Ensure that StateIterator provides all the necessary typedefs required to
|
||||
// instantiate std::iterator_traits.
|
||||
static_assert(std::is_same<
|
||||
|
Loading…
Reference in New Issue
Block a user