From f6d6b911fa3deb74e59f3cd9a5bb8dfecceabec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Sun, 21 Sep 2025 00:44:23 +0200 Subject: [PATCH] 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 --- src/req_wrap-inl.h | 2 +- src/util.h | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/req_wrap-inl.h b/src/req_wrap-inl.h index bfcb13b903..ac0ca8921a 100644 --- a/src/req_wrap-inl.h +++ b/src/req_wrap-inl.h @@ -111,7 +111,7 @@ struct CallLibuvFunction { template struct MakeLibuvRequestCallback { static T For(ReqWrap* req_wrap, T v) { - static_assert(!is_callable::value, + static_assert(!is_callable, "MakeLibuvRequestCallback missed a callback"); return v; } diff --git a/src/util.h b/src/util.h index 62ee2fe320..0c06184882 100644 --- a/src/util.h +++ b/src/util.h @@ -661,13 +661,9 @@ struct MallocedBuffer { }; // Test whether some value can be called with (). -template -struct is_callable : std::is_function { }; - template -struct is_callable::value - >::type> : std::true_type { }; +concept is_callable = + std::is_function::value || requires { &T::operator(); }; template struct FunctionDeleter {