mirror of
https://github.com/red0124/ssp.git
synced 2025-12-14 21:59:55 +01:00
initial commit, copy everything to new repository
This commit is contained in:
80
include/ss/function_traits.hpp
Normal file
80
include/ss/function_traits.hpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
|
||||
namespace ss {
|
||||
|
||||
////////////////
|
||||
// function traits
|
||||
////////////////
|
||||
|
||||
template <size_t N, typename T, typename... Ts>
|
||||
struct decayed_arg_n {
|
||||
static_assert(N - 1 != sizeof...(Ts), "index out of range");
|
||||
using type = typename decayed_arg_n<N - 1, Ts...>::type;
|
||||
};
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct decayed_arg_n<0, T, Ts...> {
|
||||
using type = std::decay_t<T>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct function_traits;
|
||||
|
||||
template <typename R, typename C, typename Arg>
|
||||
struct function_traits<std::function<R(C&, const Arg&) const>> {
|
||||
using arg_type = Arg;
|
||||
};
|
||||
|
||||
template <typename R, typename... Ts>
|
||||
struct function_traits<R(Ts...)> {
|
||||
using arg0 = typename decayed_arg_n<0, Ts...>::type;
|
||||
};
|
||||
|
||||
template <typename R, typename... Ts>
|
||||
struct function_traits<R(Ts...) const> : function_traits<R(Ts...)> {};
|
||||
|
||||
template <typename R, typename... Ts>
|
||||
struct function_traits<R(Ts...)&> : function_traits<R(Ts...)> {};
|
||||
|
||||
template <typename R, typename... Ts>
|
||||
struct function_traits<R(Ts...) const&> : function_traits<R(Ts...)> {};
|
||||
|
||||
template <typename R, typename... Ts>
|
||||
struct function_traits<R(Ts...) &&> : function_traits<R(Ts...)> {};
|
||||
|
||||
template <typename R, typename... Ts>
|
||||
struct function_traits<R(Ts...) const&&> : function_traits<R(Ts...)> {};
|
||||
|
||||
template <typename MemberFunction>
|
||||
struct member_wrapper;
|
||||
|
||||
template <typename R, typename T>
|
||||
struct member_wrapper<R T::*> {
|
||||
using arg_type = typename function_traits<R>::arg0;
|
||||
};
|
||||
|
||||
////////////////
|
||||
// has method
|
||||
////////////////
|
||||
|
||||
#define INIT_HAS_METHOD(method) \
|
||||
template <typename T> \
|
||||
class has_m_##method { \
|
||||
template <typename C> \
|
||||
static std::true_type test(decltype(&C::method)); \
|
||||
\
|
||||
template <typename C> \
|
||||
static std::false_type test(...); \
|
||||
\
|
||||
public: \
|
||||
constexpr static bool value = decltype(test<T>(0))::value; \
|
||||
}; \
|
||||
\
|
||||
template <typename T> \
|
||||
constexpr bool has_m_##method##_t = has_m_##method<T>::value;
|
||||
|
||||
} /* trait */
|
||||
Reference in New Issue
Block a user