35 lines
1.1 KiB
C++
35 lines
1.1 KiB
C++
// Credits to DeepSeek - I'm NOT writing all thatt
|
||
#pragma once
|
||
|
||
#include <tuple>
|
||
#include <type_traits>
|
||
|
||
// Primary template – will use the operator() of the callable
|
||
template <typename T>
|
||
struct function_traits : function_traits<decltype(&T::operator())> {};
|
||
|
||
// Specialization for function pointers
|
||
template <typename R, typename... Args>
|
||
struct function_traits<R(*)(Args...)> {
|
||
using return_type = R;
|
||
using argument_types = std::tuple<Args...>;
|
||
static constexpr std::size_t arity = sizeof...(Args);
|
||
};
|
||
|
||
// Specialization for const member function pointers (lambdas & functors)
|
||
template <typename C, typename R, typename... Args>
|
||
struct function_traits<R(C::*)(Args...) const> {
|
||
using return_type = R;
|
||
using argument_types = std::tuple<Args...>;
|
||
static constexpr std::size_t arity = sizeof...(Args);
|
||
};
|
||
|
||
// Specialization for non‑const member function pointers (rare for lambdas)
|
||
template <typename C, typename R, typename... Args>
|
||
struct function_traits<R(C::*)(Args...)> {
|
||
using return_type = R;
|
||
using argument_types = std::tuple<Args...>;
|
||
static constexpr std::size_t arity = sizeof...(Args);
|
||
};
|
||
|