#include <cstdlib>
#include <tuple>
#include <functional>
#include <iostream>
using namespace std;
// For generic types that are functors, delegate to its 'operator()'
template <typename T>
struct function_traits
: public function_traits<decltype(&T::operator())>
{};
// for pointers to member function
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const> {
//enum { arity = sizeof...(Args) };
typedef function<ReturnType (Args...)> f_type;
};
// for pointers to member function
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) > {
typedef function<ReturnType (Args...)> f_type;
};
// for function pointers
template <typename ReturnType, typename... Args>
struct function_traits<ReturnType (*)(Args...)> {
typedef function<ReturnType (Args...)> f_type;
};
template <typename L>
typename function_traits<L>::f_type make_function(L l){
return (typename function_traits<L>::f_type)(l);
}
long times10(int i) { return long(i*10); }
struct X {
double operator () (float f, double d) { return d*f; }
};
// test code
int main()
{
auto lambda = [](int i) { return long(i*10); };
typedef function_traits<decltype(lambda)> traits;
traits::f_type ff = lambda;
cout << make_function([](int i) { return long(i*10); })(2) << ", " << make_function(times10)(2) << ", " << ff(2) << endl;
cout << make_function(X{})(2,3.0) << endl;
return 0;
}
I2luY2x1ZGUgPGNzdGRsaWI+CiNpbmNsdWRlIDx0dXBsZT4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpb3N0cmVhbT4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCi8vIEZvciBnZW5lcmljIHR5cGVzIHRoYXQgYXJlIGZ1bmN0b3JzLCBkZWxlZ2F0ZSB0byBpdHMgJ29wZXJhdG9yKCknCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgZnVuY3Rpb25fdHJhaXRzCiAgICA6IHB1YmxpYyBmdW5jdGlvbl90cmFpdHM8ZGVjbHR5cGUoJlQ6Om9wZXJhdG9yKCkpPgp7fTsKCi8vIGZvciBwb2ludGVycyB0byBtZW1iZXIgZnVuY3Rpb24KdGVtcGxhdGUgPHR5cGVuYW1lIENsYXNzVHlwZSwgdHlwZW5hbWUgUmV0dXJuVHlwZSwgdHlwZW5hbWUuLi4gQXJncz4Kc3RydWN0IGZ1bmN0aW9uX3RyYWl0czxSZXR1cm5UeXBlKENsYXNzVHlwZTo6KikoQXJncy4uLikgY29uc3Q+IHsKICAgIC8vZW51bSB7IGFyaXR5ID0gc2l6ZW9mLi4uKEFyZ3MpIH07CiAgICB0eXBlZGVmIGZ1bmN0aW9uPFJldHVyblR5cGUgKEFyZ3MuLi4pPiBmX3R5cGU7Cn07CgovLyBmb3IgcG9pbnRlcnMgdG8gbWVtYmVyIGZ1bmN0aW9uCnRlbXBsYXRlIDx0eXBlbmFtZSBDbGFzc1R5cGUsIHR5cGVuYW1lIFJldHVyblR5cGUsIHR5cGVuYW1lLi4uIEFyZ3M+CnN0cnVjdCBmdW5jdGlvbl90cmFpdHM8UmV0dXJuVHlwZShDbGFzc1R5cGU6OiopKEFyZ3MuLi4pID4gewogICAgdHlwZWRlZiBmdW5jdGlvbjxSZXR1cm5UeXBlIChBcmdzLi4uKT4gZl90eXBlOwp9OwoKLy8gZm9yIGZ1bmN0aW9uIHBvaW50ZXJzCnRlbXBsYXRlIDx0eXBlbmFtZSBSZXR1cm5UeXBlLCB0eXBlbmFtZS4uLiBBcmdzPgpzdHJ1Y3QgZnVuY3Rpb25fdHJhaXRzPFJldHVyblR5cGUgKCopKEFyZ3MuLi4pPiAgewogIHR5cGVkZWYgZnVuY3Rpb248UmV0dXJuVHlwZSAoQXJncy4uLik+IGZfdHlwZTsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBMPiAKdHlwZW5hbWUgZnVuY3Rpb25fdHJhaXRzPEw+OjpmX3R5cGUgbWFrZV9mdW5jdGlvbihMIGwpewogIHJldHVybiAodHlwZW5hbWUgZnVuY3Rpb25fdHJhaXRzPEw+OjpmX3R5cGUpKGwpOwp9Cgpsb25nIHRpbWVzMTAoaW50IGkpIHsgcmV0dXJuIGxvbmcoaSoxMCk7IH0KCnN0cnVjdCBYIHsKICBkb3VibGUgb3BlcmF0b3IgKCkgKGZsb2F0IGYsIGRvdWJsZSBkKSB7IHJldHVybiBkKmY7IH0gCn07CgovLyB0ZXN0IGNvZGUKaW50IG1haW4oKQp7CiAgICBhdXRvIGxhbWJkYSA9IFtdKGludCBpKSB7IHJldHVybiBsb25nKGkqMTApOyB9OwogICAgdHlwZWRlZiBmdW5jdGlvbl90cmFpdHM8ZGVjbHR5cGUobGFtYmRhKT4gdHJhaXRzOwogICAgdHJhaXRzOjpmX3R5cGUgZmYgPSBsYW1iZGE7CgogICAgY291dCA8PCBtYWtlX2Z1bmN0aW9uKFtdKGludCBpKSB7IHJldHVybiBsb25nKGkqMTApOyB9KSgyKSA8PCAiLCAiIDw8IG1ha2VfZnVuY3Rpb24odGltZXMxMCkoMikgPDwgIiwgIiA8PCBmZigyKSA8PCBlbmRsOwogICAgY291dCA8PCBtYWtlX2Z1bmN0aW9uKFh7fSkoMiwzLjApIDw8IGVuZGw7CgogICAgcmV0dXJuIDA7Cn0=