...
This commit is contained in:
@@ -38,5 +38,76 @@ concept mcc_formattable =
|
||||
requires(T v, std::format_context ctx) { std::formatter<std::remove_cvref_t<T>>().format(v, ctx); };
|
||||
|
||||
|
||||
/* a callable concept and its signature traits */
|
||||
|
||||
template <typename T>
|
||||
concept mcc_is_callable = std::is_function_v<T> || (std::is_object_v<T> && requires(T) { &T::operator(); });
|
||||
|
||||
|
||||
// helper classes for callable signature deducing
|
||||
template <typename... Ts>
|
||||
struct mcc_func_traits_helper_t;
|
||||
|
||||
template <typename R>
|
||||
struct mcc_func_traits_helper_t<R> {
|
||||
using ret_t = R;
|
||||
using args_t = std::tuple<>;
|
||||
using arg1_t = void;
|
||||
static constexpr size_t arity = 0;
|
||||
};
|
||||
|
||||
template <typename R, typename Arg, typename... Args>
|
||||
struct mcc_func_traits_helper_t<R, Arg, Args...> {
|
||||
using ret_t = R;
|
||||
using args_t = std::tuple<Arg, Args...>;
|
||||
using arg1_t = Arg;
|
||||
static constexpr size_t arity = sizeof...(Args) + 1;
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct mcc_func_traits {
|
||||
// use of an empty struct here to match std::invoke_result behaivior (at least of GCC)
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct mcc_func_traits<R (*)(Args...)> : mcc_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct mcc_func_traits<R(Args...)> : mcc_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
|
||||
template <typename C, typename R, typename... Args>
|
||||
struct mcc_func_traits<R (C::*)(Args...)> : mcc_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
|
||||
template <typename C, typename R, typename... Args>
|
||||
struct mcc_func_traits<R (C::*)(Args...) const> : mcc_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
requires mcc_is_callable<F>
|
||||
struct mcc_func_traits<F> : mcc_func_traits<decltype(&F::operator())> {
|
||||
};
|
||||
|
||||
// reference/const ref and rvalue helpers
|
||||
template <typename F>
|
||||
struct mcc_func_traits<F&> : mcc_func_traits<F> {
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct mcc_func_traits<const F&> : mcc_func_traits<F> {
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct mcc_func_traits<F&&> : mcc_func_traits<F> {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using mcc_retval_t = typename mcc_func_traits<T>::ret_t;
|
||||
|
||||
template <typename T>
|
||||
using mcc_func_arg1_t = typename mcc_func_traits<T>::arg1_t;
|
||||
|
||||
|
||||
} // namespace mcc::traits
|
||||
|
||||
Reference in New Issue
Block a user