123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- #ifndef RTTR_FUNCTION_TRAITS_H_
- #define RTTR_FUNCTION_TRAITS_H_
- #include "rttr/detail/base/core_prerequisites.h"
- #include "rttr/detail/misc/misc_type_traits.h"
- #include "rttr/detail/misc/std_type_traits.h"
- #include <type_traits>
- #include <functional>
- #include <tuple>
- namespace rttr
- {
- namespace detail
- {
-
- template<typename T>
- struct is_function_ptr : std::integral_constant<bool, std::is_pointer<T>::value &&
- std::is_function<::rttr::detail::remove_pointer_t<T>>::value>
- {
- };
-
-
- struct helper
- {
- void operator()(...);
- };
- template <typename T>
- struct helper_composed: T, helper
- {};
- template <void (helper::*) (...)>
- struct member_function_holder
- {};
- template <typename T, typename Ambiguous = member_function_holder<&helper::operator()> >
- struct is_functor_impl : std::true_type
- {};
- template <typename T>
- struct is_functor_impl<T, member_function_holder<&helper_composed<T>::operator()> > : std::false_type
- {};
-
- template <typename T>
- struct is_functor : conditional_t<std::is_class<T>::value,
- is_functor_impl<T>,
- std::false_type>
- {};
- template<typename R, typename... Args>
- struct is_functor<R (*)(Args...)> : std::true_type {};
- template<typename R, typename... Args>
- struct is_functor<R (&)(Args...)> : std::true_type {};
- #ifndef RTTR_NO_CXX17_NOEXCEPT_FUNC_TYPE
- template<typename R, typename... Args>
- struct is_functor<R (*)(Args...) noexcept> : std::true_type {};
- template<typename R, typename... Args>
- struct is_functor<R (&)(Args...) noexcept> : std::true_type {};
- #endif
-
-
- template <typename T>
- struct function_traits : function_traits< decltype(&T::operator()) > {};
- template<typename R, typename... Args>
- struct function_traits<R (Args...)>
- {
- static RTTR_CONSTEXPR_OR_CONST size_t arg_count = sizeof...(Args);
- using return_type = R;
- using arg_types = std::tuple<Args...>;
- };
- template<typename R, typename... Args>
- struct function_traits<R (*)(Args...)> : function_traits<R (Args...)> { };
- template<typename R, typename... Args>
- struct function_traits<R (&)(Args...)> : function_traits<R (Args...)> { };
- template<typename R, typename C, typename... Args>
- struct function_traits<R (C::*)(Args...)> : function_traits<R (Args...)> { using class_type = C; };
- template<typename R, typename C, typename... Args>
- struct function_traits<R (C::*)(Args...) const> : function_traits<R (Args...)> { using class_type = C; };
- template<typename R, typename C, typename... Args>
- struct function_traits<R (C::*)(Args...) volatile> : function_traits<R (Args...)> { using class_type = C; };
- template<typename R, typename C, typename... Args>
- struct function_traits<R (C::*)(Args...) const volatile> : function_traits<R (Args...)> {using class_type = C; };
- #ifndef RTTR_NO_CXX17_NOEXCEPT_FUNC_TYPE
- template<typename R, typename... Args>
- struct function_traits<R (*)(Args...) noexcept> : function_traits<R (Args...)> { };
- template<typename R, typename... Args>
- struct function_traits<R (&)(Args...) noexcept> : function_traits<R (Args...)> { };
- template<typename R, typename C, typename... Args>
- struct function_traits<R (C::*)(Args...) noexcept> : function_traits<R (Args...)> { using class_type = C; };
- template<typename R, typename C, typename... Args>
- struct function_traits<R (C::*)(Args...) const noexcept> : function_traits<R (Args...)> { using class_type = C; };
- template<typename R, typename C, typename... Args>
- struct function_traits<R (C::*)(Args...) volatile noexcept> : function_traits<R (Args...)> { using class_type = C; };
- template<typename R, typename C, typename... Args>
- struct function_traits<R (C::*)(Args...) const volatile noexcept> : function_traits<R (Args...)> {using class_type = C; };
- #endif
- template<typename T>
- struct function_traits<std::function<T>> : function_traits<T> {};
-
-
-
- template<typename F, size_t Index>
- struct param_types
- {
- using type = typename std::tuple_element<Index, typename function_traits<F>::arg_types>::type;
- };
- template<typename F, size_t Index>
- using param_types_t = typename param_types<F, Index>::type;
-
- template<typename F>
- struct is_void_func : conditional_t< std::is_same<typename function_traits<F>::return_type, void>::value,
- std::true_type,
- std::false_type
- >
- {
- };
-
-
- template<typename F>
- using is_function = std::integral_constant<bool, std::is_member_function_pointer<F>::value ||
- std::is_function<F>::value ||
- is_functor<F>::value
- >;
-
- }
- }
- #endif
|