|
|
#pragma once
|
|
|
|
|
|
#include <cstddef>
|
|
|
#include <tuple>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
struct function_traits : public function_traits<decltype(&T::operator())> {
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename ClassType, typename T>
|
|
|
struct function_traits<T ClassType::*> : public function_traits<T> {
|
|
|
};
|
|
|
|
|
|
|
|
|
template <typename ClassType, typename ReturnType, typename... Args>
|
|
|
struct function_traits<ReturnType(ClassType::*)(Args...) const> : public function_traits<ReturnType(Args...)> {
|
|
|
};
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
struct function_traits<T&> : public function_traits<T> {};
|
|
|
template <typename T>
|
|
|
struct function_traits<T*> : public function_traits<T> {};
|
|
|
|
|
|
|
|
|
template <typename ReturnType, typename... Args>
|
|
|
struct function_traits<ReturnType(Args...)> {
|
|
|
|
|
|
enum { arity = sizeof...(Args) };
|
|
|
|
|
|
using ArgsTuple = std::tuple<Args...>;
|
|
|
using result_type = ReturnType;
|
|
|
|
|
|
template <size_t i>
|
|
|
struct arg
|
|
|
{
|
|
|
using type = typename std::tuple_element<i, std::tuple<Args...>>::type;
|
|
|
|
|
|
|
|
|
};
|
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
|
struct nullary_function_traits {
|
|
|
using traits = function_traits<T>;
|
|
|
using result_type = typename traits::result_type;
|
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
|
struct unary_function_traits {
|
|
|
using traits = function_traits<T>;
|
|
|
using result_type = typename traits::result_type;
|
|
|
using arg1_t = typename traits::template arg<0>::type;
|
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
|
struct binary_function_traits {
|
|
|
using traits = function_traits<T>;
|
|
|
using result_type = typename traits::result_type;
|
|
|
using arg1_t = typename traits::template arg<0>::type;
|
|
|
using arg2_t = typename traits::template arg<1>::type;
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
struct invoke_traits : public function_traits<T>{
|
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
|
struct invoke_traits<T&> : public invoke_traits<T>{
|
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
|
struct invoke_traits<T&&> : public invoke_traits<T>{
|
|
|
};
|
|
|
|
|
|
template <typename ClassType, typename ReturnType, typename... Args>
|
|
|
struct invoke_traits<ReturnType(ClassType::*)(Args...)> :
|
|
|
public function_traits<ReturnType(ClassType&, Args...)> {
|
|
|
};
|
|
|
|
|
|
template <typename ClassType, typename ReturnType, typename... Args>
|
|
|
struct invoke_traits<ReturnType(ClassType::*)(Args...) const> :
|
|
|
public function_traits<ReturnType(const ClassType&, Args...)> {
|
|
|
};
|
|
|
|