-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
<algorithm>
: ranges::minmax
should dereference iterators only once
#3366
Conversation
<algorithm>
: ranges::minmax
should dereference iterators only once
Co-authored-by: Nicole Mazzuca <[email protected]>
Co-authored-by: Alex Guteniev <[email protected]> Co-authored-by: timsong-cpp <[email protected]>
This comment was marked as resolved.
This comment was marked as resolved.
This new pattern is unusual, but I rate it only 2 squirrels out of 5. (The Standard has an example, WG21-N4928 [dcl.init.aggr]/6, where a default member initializer refers to previous members, that's at least 3 squirrels.) I probably would have commented it, but I don't think it's worth resetting testing again. It does seem to be an improvement compared to the previous version, thanks! |
Good, I found it there: libc++ also has the bug, I created: https://reviews.llvm.org/D142864 |
Approved by Mirror Universe Nicole
I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed. |
Co-authored-by: Casey Carter <[email protected]>
@StephanTLavavej |
As did I. |
Everyone's joining the commit party! (I pushed tiny comment changes and removed parameter names for the defaulted function.) |
Thanks for minimizing bugs while maximizing performance! 📉 😸 📈 |
The fix for microsoft#2900 in microsoft#3366 did not take advantage of the fact that the minimum and maximum elements of a range are always distinct except when the range has only one element. It couldn't easily do so due to the way `ranges::minmax` and `ranges::minmax_element` share the common backend `ranges::_Minmax_element_unchecked`. This PR introduces a new backend for `ranges::minmax` (`ranges::_Minmax_fn::_Minmax_fwd_unchecked`) and makes `ranges::_Minmax_element_unchecked` the private member `ranges::_Minmax_element_fn::_Minmax_element_fwd_unchecked`. Since the two are distinct, `_Minmax_fwd_unchecked` can deal in values instead of iterators, and we can unroll the first loop iteration to detect the single-element case naturally. Since no additional branch is needed, we can enable the fix for microsoft#2900 unconditionally. This refactoring is also probably a minor throughput and perf improvement, since `minmax` no longer needs to instantiate the "old" backend's return type and the new backend is tail-called. Drive-by: Fully qualify the names of ugly functions called by `ranges::minmax` and `ranges::minmax_element`.
The fix for microsoft#2900 in microsoft#3366 did not take advantage of the fact that the minimum and maximum elements of a range are always distinct except when the range has only one element. It couldn't easily do so due to the way `ranges::minmax` and `ranges::minmax_element` share the common backend `ranges::_Minmax_element_unchecked`. This PR introduces a new backend for `ranges::minmax` (`ranges::_Minmax_fn::_Minmax_fwd_unchecked`) and makes `ranges::_Minmax_element_unchecked` the private member `ranges::_Minmax_element_fn::_Minmax_element_fwd_unchecked`. Since the two are distinct, `_Minmax_fwd_unchecked` can deal in values instead of iterators, and we can unroll the first loop iteration to detect the single-element case naturally. Since no additional branch is needed, we can enable the fix for microsoft#2900 unconditionally. Drive-by: Fully qualify the names of ugly functions called by `ranges::minmax` and `ranges::minmax_element`.
Fixes #2900
After #2958 the original repro works, but the issue still exists.
I also found that if we have only one element we also have the issue.