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:
Vy Nguyen 2021-10-26 10:38:12 -04:00 committed by GitHub
parent 365670e432
commit fca348296f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 1 deletions

View File

@ -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

View File

@ -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))

View File

@ -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<