-
Notifications
You must be signed in to change notification settings - Fork 1.6k
static operator() for stateless functors
#4358
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
static operator() for stateless functors
#4358
Conversation
Co-authored-by: Casey Carter <[email protected]>
Drive-by and fixes: change `(*this)(...)` to `operator()(...)`, and use more internal static member functions.
Note: `_Synth_three_way::operator()` is specified to be non-static in [expos.only.entity], but the class itself is exposition-only, so I think it's fine to make it `static`. Drive-by: `_Cmp_cs::operator()` lacked `const` befor. IMO it should have `const` when `static` is unavailable.
Not a copy-paste mistake: `is_nothrow_default_constructible_v<_Ty>` is correct for both `_Inplace_default_construct_fn` and `_Inplace_value_construct_fn`.
…` to be `consteval` functions.
…_STATIC_CALL_OPERATOR constexpr`
| #define _STL_INTERNAL_STATIC_ASSERT(...) | ||
| #endif // ^^^ !defined(_ENABLE_STL_INTERNAL_CHECK) ^^^ | ||
|
|
||
| #ifdef __cpp_static_call_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.
No change requested: This "light up" code will result in warnings being emitted as soon as MSVC implements this feature and defines the macro. However, I think that's ok - we live in the MSVC compiler front-end devs' branch prod/fe, and they can patch our headers while checking in the feature (and we can use the macro to deal with the temporary difference between MSVC-internal and VS Preview).
This is similar to the "assert bug" pattern which I dislike so much (any code in the STL that breaks when compilers start doing the right thing), but having it happen on one rare and expected occasion is fine, and the MSVC FE lives much "closer" to us than EDG (blocking EDG code insertions is much more obnoxious for logistical reasons).
| struct _Cmp_cs { // functor to compare two character values for equality | ||
| using _Elem = typename _RxTraits::char_type; | ||
| bool operator()(_Elem _Ex1, _Elem _Ex2) { | ||
| _STATIC_CALL_OPERATOR bool operator()(_Elem _Ex1, _Elem _Ex2) _CONST_CALL_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.
No change requested: Great catch for the missing const here! 😻
|
Thanks for this surprisingly large PR - I always forgot how big the STL has grown! 😹 I pushed a few changes, including a couple of refactorings - please double-check. I've also relabeled this as a (minor) performance improvement. |
|
I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed. |
|
Thanks for powering the STL with |
Fixes #4130. This PR makes the
operator()s of stateless functorsstatic, including those of captureless lambdas, except for...operator()s that are intentionally notconstto me (e.g._Rand_urng_from_func::operator()),operator()s that explicitly specifiedconstand non-staticin the standard wording (except for that ofsynth-three-waywhere the functor itself is exposition-only),basic_format_arg::handle, because there seems a bug of Clang 17 involving calling conventions for static lambdas, which seems fixed in Clang 18.List of explicitly
constand non-staticfunctors in the standard library<memory>:std::default_deletestd::owner_lessstd::owner_hashstd::owner_equal<type_traits>:std::integral_constant<chrono>:std::chrono::clock_time_conversion<functional>:std::plusstd::minusstd::multipliesstd::dividesstd::modulusstd::negatestd::equal_tostd::not_equal_tostd::greaterstd::lessstd::greater_equalstd::less_equalstd::compare_three_waystd::ranges::equal_tostd::ranges::not_equal_tostd::ranges::greaterstd::ranges::lessstd::ranges::greater_equalstd::ranges::less_equalstd::logical_andstd::logical_orstd::logical_notstd::bit_andstd::bit_orstd::bit_xorstd::bit_notstd::identityDrive-by changes:
(*this)(...)tooperator()(...)wheneveroperator()is possiblystatic.ranges::swapneeds some special handling.static._Cmp_cs::operator()conditionallyconstorstatic- it seems unintended to me that it wasn'tconst.