Skip to content

Commit 33a9784

Browse files
committed
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.
1 parent 5fb879c commit 33a9784

File tree

2 files changed

+3
-7
lines changed

2 files changed

+3
-7
lines changed

src/req_wrap-inl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ struct CallLibuvFunction<ReqT, void(*)(ReqT*, Args...)> {
111111
template <typename ReqT, typename T>
112112
struct MakeLibuvRequestCallback {
113113
static T For(ReqWrap<ReqT>* req_wrap, T v) {
114-
static_assert(!is_callable<T>::value,
114+
static_assert(!is_callable<T>,
115115
"MakeLibuvRequestCallback missed a callback");
116116
return v;
117117
}

src/util.h

+2-6
Original file line numberDiff line numberDiff line change
@@ -689,13 +689,9 @@ class NonCopyableMaybe {
689689
};
690690

691691
// Test whether some value can be called with ().
692-
template <typename T, typename = void>
693-
struct is_callable : std::is_function<T> { };
694-
695692
template <typename T>
696-
struct is_callable<T, typename std::enable_if<
697-
std::is_same<decltype(void(&T::operator())), void>::value
698-
>::type> : std::true_type { };
693+
concept is_callable =
694+
std::is_function<T>::value || requires { &T::operator(); };
699695

700696
template <typename T, void (*function)(T*)>
701697
struct FunctionDeleter {

0 commit comments

Comments
 (0)