types/traits: make func_traits more robust

This commit is contained in:
Danny Robson 2017-09-08 14:19:46 +10:00
parent fb5614ae2b
commit d79b7da067

View File

@ -209,31 +209,51 @@ struct remove_member_const<ReturnT(ClassT::*)(Args...) const> {
/// if the type is invokable the alias `return_type' will be defined for the /// if the type is invokable the alias `return_type' will be defined for the
/// return type, and the alias tuple `argument_types' will be defined for the /// return type, and the alias tuple `argument_types' will be defined for the
/// arguments; /// arguments;
namespace detail {
template <typename T>
struct func_traits { };
//-------------------------------------------------------------------------
template <typename ClassT, typename ResultT, typename ...Args>
struct func_traits<ResultT(ClassT::*)(Args...)> {
using return_type = ResultT;
using argument_types = std::tuple<Args...>;
};
//-------------------------------------------------------------------------
template <typename ResultT, typename ...Args>
struct func_traits<ResultT(*)(Args...)> {
using return_type = ResultT;
using argument_types = std::tuple<Args...>;
};
//-------------------------------------------------------------------------
template <typename ResultT, typename ...Args>
struct func_traits<ResultT(&)(Args...)> {
using return_type = ResultT;
using argument_types = std::tuple<Args...>;
};
};
//-----------------------------------------------------------------------------
template <typename T> template <typename T>
struct func_traits : public func_traits<remove_noexcept_t<T>> { }; struct func_traits : public ::detail::func_traits<
// we apply as many transforms as possible before palming it off to the
// detail class so that we don't have to write as many distinct cases.
//----------------------------------------------------------------------------- ::util::chain_t<T,
template <typename ClassT, typename ResultT, typename ...Args> std::remove_cv,
struct func_traits<ResultT(ClassT::*)(Args...) const> { std::decay,
using return_type = ResultT; remove_member_const,
using argument_types = std::tuple<Args...>; remove_noexcept
}; >
> {
// we may as well record the underlying type here. it might prove useful
//----------------------------------------------------------------------------- // to someone.
template <typename ResultT, typename ...Args> using type = T;
struct func_traits<ResultT(*)(Args...)> {
using return_type = ResultT;
using argument_types = std::tuple<Args...>;
};
//-----------------------------------------------------------------------------
template <typename ResultT, typename ...Args>
struct func_traits<ResultT(&)(Args...)> {
using return_type = ResultT;
using argument_types = std::tuple<Args...>;
}; };