#include <iostream>
#include <string>
#include <functional>
#include <random>
#include <ctime>
template<class F>
struct function_traits;
template<class R, class... Args>
struct function_traits<R(*)(Args...)> : public function_traits<R(Args...)>
{};
template<class R, class... Args>
struct function_traits<R(Args...)>
{
using return_type = R;
static const std::size_t arity = sizeof...(Args);
template <std::size_t N>
struct argument
{
static_assert(N < arity, "error: invalid parameter index.");
using type = typename std::tuple_element<N, std::tuple<Args...>>::type;
};
};
int foo(int, int) { return 0; }
int bar(int, int, int, int) { return 0; }
template <typename F>
void benchmark(int t, F f, const std::string& name, std::ostream& os = std::cout)
{
typedef typename function_traits<F>::return_type T;
std::mt19937 rng(std::time(0));
std::uniform_int_distribution<T> uint_dist10(0, std::numeric_limits<T>::max());
os << "Evaluating " << name << " " << t << " times ...";
for(int i = 0; i < t; ++i)
f(uint_dist10(rng), uint_dist10(rng)); // Problem!
os << " done!\n";
}
int main()
{
benchmark(10, foo, "foo");
//Won't compile, obviously ...
//benchmark(10, bar, "bar");
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPHJhbmRvbT4KI2luY2x1ZGUgPGN0aW1lPgoKdGVtcGxhdGU8Y2xhc3MgRj4Kc3RydWN0IGZ1bmN0aW9uX3RyYWl0czsKCnRlbXBsYXRlPGNsYXNzIFIsIGNsYXNzLi4uIEFyZ3M+CnN0cnVjdCBmdW5jdGlvbl90cmFpdHM8UigqKShBcmdzLi4uKT4gOiBwdWJsaWMgZnVuY3Rpb25fdHJhaXRzPFIoQXJncy4uLik+Cnt9OwoKdGVtcGxhdGU8Y2xhc3MgUiwgY2xhc3MuLi4gQXJncz4Kc3RydWN0IGZ1bmN0aW9uX3RyYWl0czxSKEFyZ3MuLi4pPgp7Cgl1c2luZyByZXR1cm5fdHlwZSA9IFI7CgoJc3RhdGljIGNvbnN0IHN0ZDo6c2l6ZV90IGFyaXR5ID0gc2l6ZW9mLi4uKEFyZ3MpOwoKCXRlbXBsYXRlIDxzdGQ6OnNpemVfdCBOPgoJc3RydWN0IGFyZ3VtZW50Cgl7CgkJc3RhdGljX2Fzc2VydChOIDwgYXJpdHksICJlcnJvcjogaW52YWxpZCBwYXJhbWV0ZXIgaW5kZXguIik7CgkJdXNpbmcgdHlwZSA9IHR5cGVuYW1lIHN0ZDo6dHVwbGVfZWxlbWVudDxOLCBzdGQ6OnR1cGxlPEFyZ3MuLi4+Pjo6dHlwZTsKCX07Cn07CgppbnQgZm9vKGludCwgaW50KSB7IHJldHVybiAwOyB9CmludCBiYXIoaW50LCBpbnQsIGludCwgaW50KSB7IHJldHVybiAwOyB9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRj4Kdm9pZCBiZW5jaG1hcmsoaW50IHQsIEYgZiwgY29uc3Qgc3RkOjpzdHJpbmcmIG5hbWUsIHN0ZDo6b3N0cmVhbSYgb3MgPSBzdGQ6OmNvdXQpCnsKCXR5cGVkZWYgdHlwZW5hbWUgZnVuY3Rpb25fdHJhaXRzPEY+OjpyZXR1cm5fdHlwZSBUOwoKCXN0ZDo6bXQxOTkzNyBybmcoc3RkOjp0aW1lKDApKTsKCXN0ZDo6dW5pZm9ybV9pbnRfZGlzdHJpYnV0aW9uPFQ+IHVpbnRfZGlzdDEwKDAsIHN0ZDo6bnVtZXJpY19saW1pdHM8VD46Om1heCgpKTsKCglvcyA8PCAiRXZhbHVhdGluZyAiIDw8IG5hbWUgPDwgIiAiIDw8IHQgPDwgIiB0aW1lcyAuLi4iOwoKCWZvcihpbnQgaSA9IDA7IGkgPCB0OyArK2kpCgkJZih1aW50X2Rpc3QxMChybmcpLCB1aW50X2Rpc3QxMChybmcpKTsgLy8gUHJvYmxlbSEKCglvcyA8PCAiIGRvbmUhXG4iOwp9CgppbnQgbWFpbigpCnsKCWJlbmNobWFyaygxMCwgZm9vLCAiZm9vIik7CgoJLy9Xb24ndCBjb21waWxlLCBvYnZpb3VzbHkgLi4uCgkvL2JlbmNobWFyaygxMCwgYmFyLCAiYmFyIik7Cn0=