-
-
Notifications
You must be signed in to change notification settings - Fork 31.5k
src: simplify is_callable by making it a concept #58169
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
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.
cf9d612
to
33a9784
Compare
@@ -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>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can change type name T to is_callable T and remove this static_assertion.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #58169 +/- ##
=======================================
Coverage 90.13% 90.14%
=======================================
Files 630 630
Lines 186611 186611
Branches 36631 36634 +3
=======================================
+ Hits 168204 168220 +16
+ Misses 11192 11183 -9
+ Partials 7215 7208 -7
🚀 New features to boost your workflow:
|
std::is_same<decltype(void(&T::operator())), void>::value | ||
>::type> : std::true_type { }; | ||
concept is_callable = | ||
std::is_function<T>::value || requires { &T::operator(); }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For concepts like this, I'd prefer if we adopted a naming scheme like IsCallable
@@ -111,7 +111,7 @@ struct CallLibuvFunction<ReqT, void(*)(ReqT*, Args...)> { | |||
template <typename ReqT, typename T> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
template <typename ReqT, typename T> | |
template <typename ReqT, is_callable T> |
static_assert(!is_callable<T>, | ||
"MakeLibuvRequestCallback missed a callback"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static_assert(!is_callable<T>, | |
"MakeLibuvRequestCallback missed a callback"); |
Using a C++20
concept
here makesis_callable
much simpler than relying on SFINAE. It is equivalent for function types,std::function
, lambdas, and classes withoperator()
, regardless of argument or return types.