Skip to content
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>, <xutility>: Usage of _Prefer_iterator_copies should inspect unwrapped iterators #4663

Open
StephanTLavavej opened this issue May 8, 2024 · 0 comments
Labels
performance Must go faster ranges C++20/23 ranges

Comments

@StephanTLavavej
Copy link
Member

Noticed while looking at #4660 but this is a distinct issue.

All of our uses of _Prefer_iterator_copies are inspecting iterator_t<_Rng>, which is the range's original iterator, but we're actually working with the unwrapped iterator type:

STL/stl/inc/algorithm

Lines 10417 to 10419 in 8dc4faa

if constexpr (forward_range<_Rng> && _Prefer_iterator_copies<iterator_t<_Rng>>) {
return _Minmax_fwd_unchecked(
_STD move(_UFirst), _STD move(_ULast), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj));

STL/stl/inc/xutility

Lines 7018 to 7020 in 8dc4faa

if constexpr (forward_range<_Rng> && _Prefer_iterator_copies<iterator_t<_Rng>>) {
return static_cast<range_value_t<_Rng>>(*_RANGES _Max_element_unchecked(
_STD move(_UFirst), _STD move(_ULast), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)));

STL/stl/inc/xutility

Lines 7236 to 7238 in 8dc4faa

if constexpr (forward_range<_Rng> && _Prefer_iterator_copies<iterator_t<_Rng>>) {
return static_cast<range_value_t<_Rng>>(*_RANGES _Min_element_unchecked(
_STD move(_UFirst), _STD move(_ULast), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)));

_Prefer_iterator_copies cares about both size and trivially-copyable, so wrapped vs. unwrapped is a significant difference:

STL/stl/inc/xutility

Lines 6962 to 6966 in 8dc4faa

template <class _It>
concept _Prefer_iterator_copies = // When we have a choice, should we copy iterators or copy elements?
// pre: input_iterator<_It>
sizeof(_It) <= 2 * sizeof(iter_value_t<_It>)
&& (is_trivially_copyable_v<_It> || !is_trivially_copyable_v<iter_value_t<_It>>);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Must go faster ranges C++20/23 ranges
Projects
None yet
Development

No branches or pull requests

1 participant