Last active
September 7, 2023 18:17
-
-
Save janderudder/7e32fded5faeb71f924fd9920932b589 to your computer and use it in GitHub Desktop.
Get argument and return type of function or callable object.
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
#ifndef CALLABLE_TRAITS_HPP_INCLUDED | |
#define CALLABLE_TRAITS_HPP_INCLUDED | |
#include <type_traits> | |
// synopsis | |
//////////////////////////////////////////////////////////////////////////////// | |
template <typename> | |
struct callable_traits; | |
template <typename Fn> | |
constexpr bool is_function(); | |
//////////////////////////////////////////////////////////////////////////////// | |
namespace detail | |
{ | |
template <typename...> | |
struct type_list; | |
template <> | |
struct type_list<> | |
{ | |
using type = void; | |
using next = type_list<void>; | |
}; | |
template <typename Head> | |
struct type_list<Head> { | |
using type = Head; | |
using next = type_list<void>; | |
}; | |
template <typename Head, typename...Tail> | |
struct type_list<Head, Tail...> { | |
using type = Head; | |
using next = type_list<Tail...>; | |
}; | |
} // detail | |
template <typename> | |
struct callable_traits; | |
template <typename Functor> | |
struct callable_traits | |
{ | |
private: using Fr = std::remove_pointer_t<std::remove_cvref_t<Functor>>; | |
public: | |
using return_type = callable_traits<decltype(&Fr::operator())>::return_type; | |
using argument = callable_traits<decltype(&Fr::operator())>::argument; | |
}; | |
template <typename Ret, typename... Args> | |
struct callable_traits<Ret(Args...)> | |
{ | |
using return_type = Ret; | |
using argument = detail::type_list<Args...>; | |
}; | |
template <typename Ret, typename... Args> | |
struct callable_traits<Ret(Args...) noexcept> | |
{ | |
using return_type = Ret; | |
using argument = detail::type_list<Args...>; | |
}; | |
template <typename Ret, typename... Args> | |
struct callable_traits<Ret(&)(Args...)> | |
{ | |
using return_type = Ret; | |
using argument = detail::type_list<Args...>; | |
}; | |
template <typename Ret, typename... Args> | |
struct callable_traits<Ret(&)(Args...) noexcept> | |
{ | |
using return_type = Ret; | |
using argument = detail::type_list<Args...>; | |
}; | |
template <typename Ret, typename... Args> | |
struct callable_traits<Ret(*)(Args...)> | |
{ | |
using return_type = Ret; | |
using argument = detail::type_list<Args...>; | |
}; | |
template <typename Ret, typename... Args> | |
struct callable_traits<Ret(*)(Args...) noexcept> | |
{ | |
using return_type = Ret; | |
using argument = detail::type_list<Args...>; | |
}; | |
template <typename Callable, typename Ret, typename... Args> | |
struct callable_traits<Ret (Callable::*)(Args...) const> | |
{ | |
using return_type = Ret; | |
using argument = detail::type_list<Args...>; | |
}; | |
template <typename Callable, typename Ret, typename... Args> | |
struct callable_traits<Ret (Callable::*)(Args...) const noexcept> | |
{ | |
using return_type = Ret; | |
using argument = detail::type_list<Args...>; | |
}; | |
template <typename Callable, typename Ret, typename ...Args> | |
struct callable_traits<Ret (Callable::*)(Args...)> | |
{ | |
using return_type = Ret; | |
using argument = detail::type_list<Args...>; | |
}; | |
template <typename Callable, typename Ret, typename ...Args> | |
struct callable_traits<Ret (Callable::*)(Args...) noexcept> | |
{ | |
using return_type = Ret; | |
using argument = detail::type_list<Args...>; | |
}; | |
template <typename Fn> | |
constexpr bool is_function() | |
{ | |
return std::is_function_v<std::remove_pointer_t<std::remove_cvref_t<Fn>>>; | |
} | |
#endif // CALLABLE_TRAITS_HPP_INCLUDED |
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
/* | |
launch with ./example | c++filt -t | |
*/ | |
#include "callable_traits.hpp" | |
#include <functional> | |
#include <iostream> | |
#include <string> | |
#include <string_view> | |
#include <typeinfo> | |
template <typename Callable> | |
void displayTypes(Callable&&) | |
{ | |
std::cout <<"ret: "<< typeid(typename callable_traits<Callable>::return_type).name() <<" | "; | |
std::cout <<"arg: "<< typeid(typename callable_traits<Callable>::argument::type).name() <<"\n"; | |
} | |
struct Functor | |
{ | |
std::string_view operator()() const { return "hello"; } | |
}; | |
auto fn(short, char) { return 0; } | |
int main() | |
{ | |
using namespace std; | |
auto constexpr lambda = [](double){}; | |
displayTypes(lambda); | |
double d = 1.0; | |
auto const lambdaCapture = [&d](double f){ return (float)(d += f); }; | |
displayTypes(lambdaCapture); | |
Functor functor; | |
displayTypes(functor); | |
Functor const cFunctor; | |
displayTypes(cFunctor); | |
displayTypes(fn); | |
displayTypes(&fn); | |
std::function<void(double)> fl1 {lambda}; | |
std::function<float(double)> fl2 {lambdaCapture}; | |
std::function<std::string_view()> fl3 {functor}; | |
std::function<int(short,char)> fl4 {fn}; | |
displayTypes(fl1); | |
displayTypes(fl2); | |
displayTypes(fl3); | |
displayTypes(fl4); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment