Skip to content

Instantly share code, notes, and snippets.

@gazliddon
Last active January 28, 2016 13:31
Show Gist options
  • Save gazliddon/cac2b22dba3a758bea26 to your computer and use it in GitHub Desktop.
Save gazliddon/cac2b22dba3a758bea26 to your computer and use it in GitHub Desktop.
Function traits
#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;
}
@gazliddon
Copy link
Author

C++14 function traits for my reference

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment