Files
cpp-template/core-library/traits/function-traits.h
T
2026-07-11 22:27:48 +02:00

62 lines
1.7 KiB
C++

#pragma once
#include <concepts>
namespace core {
template<typename T>
concept callable = requires { &T::operator(); };
template<typename T>
struct function_traits
{
using return_type = void;
using first_argument_type = void;
};
template<typename T>
requires callable<T>
struct function_traits<T>
{
using return_type = typename function_traits<decltype(&T::operator())>::return_type;
using first_argument_type = typename function_traits<decltype(&T::operator())>::first_argument_type;
};
template<typename Ret, typename Arg0, typename... Args>
struct function_traits<Ret(Arg0, Args...)>
{
using return_type = typename Ret;
using first_argument_type = typename Arg0;
};
template<typename Ret, typename Arg0, typename... Args>
struct function_traits<Ret (*)(Arg0, Args...)>
{
using return_type = typename Ret;
using first_argument_type = typename Arg0;
};
template<typename Ret, typename Class, typename Arg0, typename... Args>
struct function_traits<Ret (Class::*)(Arg0, Args...)>
{
using return_type = typename Ret;
using first_argument_type = typename Arg0;
};
template<typename Ret, typename Class, typename Arg0, typename... Args>
struct function_traits<Ret (Class::*)(Arg0, Args...) const>
{
using return_type = typename Ret;
using first_argument_type = typename Arg0;
};
template<typename T>
using return_type_t = typename function_traits<std::remove_cvref_t<T>>::return_type;
template<typename T>
using first_argument_type_t = typename function_traits<std::remove_cvref_t<T>>::first_argument_type;
template<typename T, typename Arg>
concept callable_with_argument_converted = requires(T&& callable, Arg&& arg) { callable(core::first_argument_type_t<T>{arg}); };
}