src: simplify is_callable by making it a concept

Using a C++20 `concept` here makes `is_callable` much simpler
than relying on SFINAE. It is equivalent for function types,
`std::function`, lambdas, and classes with `operator()`,
regardless of argument or return types.

PR-URL: https://github.com/nodejs/node/pull/58169
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
This commit is contained in:
Tobias Nießen
2025-09-21 00:44:23 +02:00
committed by GitHub
parent 2388088fba
commit f6d6b911fa
2 changed files with 3 additions and 7 deletions

View File

@@ -111,7 +111,7 @@ struct CallLibuvFunction<ReqT, void(*)(ReqT*, Args...)> {
template <typename ReqT, typename T>
struct MakeLibuvRequestCallback {
static T For(ReqWrap<ReqT>* req_wrap, T v) {
static_assert(!is_callable<T>::value,
static_assert(!is_callable<T>,
"MakeLibuvRequestCallback missed a callback");
return v;
}

View File

@@ -661,13 +661,9 @@ struct MallocedBuffer {
};
// Test whether some value can be called with ().
template <typename T, typename = void>
struct is_callable : std::is_function<T> { };
template <typename T>
struct is_callable<T, typename std::enable_if<
std::is_same<decltype(void(&T::operator())), void>::value
>::type> : std::true_type { };
concept is_callable =
std::is_function<T>::value || requires { &T::operator(); };
template <typename T, void (*function)(T*)>
struct FunctionDeleter {