Last active
January 28, 2016 13:31
-
-
Save gazliddon/cac2b22dba3a758bea26 to your computer and use it in GitHub Desktop.
Function traits
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <tuple> | |
//////////////////////////////////////////////////////////////////////////////// | |
template<class A, template<class...> class B> struct mp_rename_impl; | |
template<template<class...> class A, class... T, template<class...> class B> | |
struct mp_rename_impl<A<T...>, B> | |
{ | |
using type = B<T...>; | |
}; | |
template<class A, template<class...> class B> | |
using mp_rename = typename mp_rename_impl<A, B>::type; | |
template<typename... Ts> | |
struct mp_list{}; | |
//////////////////////////////////////////////////////////////////////////////// | |
/* template<typename Fsig> */ | |
/* struct function_traits{ */ | |
/* }; */ | |
template<typename PF> | |
struct function_traits : public function_traits<decltype(&PF::operator() )> { | |
}; | |
template<typename ReturnType, typename... Args> | |
struct function_traits<ReturnType(Args...)>{ | |
using return_type = ReturnType; | |
using type_list = mp_list<Args...>; | |
using tuple_t = mp_rename<type_list, std::tuple>; | |
static const int arity = (sizeof...(Args)); | |
constexpr auto nargs() const {return arity;} | |
constexpr auto iseq() const { | |
return std::make_index_sequence<sizeof...(Args)>(); | |
} | |
template<size_t i> | |
struct arg { | |
using type = typename std::tuple_element<i, std::tuple<Args...>>::type; | |
}; | |
}; | |
template<typename ClassType, typename ReturnType, typename... Args> | |
struct function_traits<ReturnType(ClassType::*)(Args...) const> : public function_traits<ReturnType(Args...)> | |
{ | |
}; | |
template<typename ClassType, typename ReturnType, typename... Args> | |
struct function_traits<ReturnType(ClassType::*)(Args...)> : public function_traits<ReturnType(Args...)> | |
{ | |
}; | |
template<typename ReturnType,typename... Args> | |
struct function_traits<ReturnType(*)(Args...)> : public function_traits<ReturnType(Args...)> | |
{ | |
}; | |
template<typename FN> | |
class cFunctor : public function_traits<FN> { | |
public: | |
using ft = function_traits<FN>; | |
cFunctor (FN _fn) : mFn(_fn){ | |
} | |
template<typename TUP, typename... Ts> | |
auto applyImpl(TUP const & _tup, mp_list<Ts...> ) const { | |
return mFn( std::get<Ts>(_tup)...); | |
} | |
template<typename TUP> | |
auto apply(TUP const & _tup) const { | |
typename ft::type_list types; | |
return applyImpl(_tup, types); | |
} | |
protected: | |
FN mFn; | |
}; | |
int y(int a, int b) { | |
return 0; | |
} | |
class cTest { | |
public: | |
void func(int, int, int) ; | |
}; | |
template<typename T> | |
static constexpr auto mk_function_traits(T f) { | |
return function_traits<T>(); | |
}; | |
int main(void) { | |
using namespace std; | |
auto x = [](string y) { | |
cout << "hello " << y << endl; | |
}; | |
auto zz = [x](std::string _msg) { | |
cout << _msg << endl; | |
}; | |
cFunctor<decltype(zz)> fn(zz); | |
auto tup = std::make_tuple(std::string("hello"), 1, 2); | |
fn.apply(tup); | |
using ft_lambda = function_traits<decltype(x)>; | |
/* using ft_lambda_cap = function_traits<decltype(zz)>; */ | |
using ft_func = function_traits<decltype(&y)>; | |
using ft_class = function_traits<decltype(&cTest::func)>; | |
cout << "anon lambda: " << ft_lambda::arity << endl; | |
/* cout << "anon lambda with capture: " << ft_lambda_cap::arity << endl; */ | |
cout << "pfunc: " << ft_func::arity << endl; | |
cout << "pclass: " << ft_class::arity << endl; | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
C++14 function traits for my reference