Skip to content

<algorithm>, <xutility>: Usage of _Prefer_iterator_copies should inspect unwrapped iterators #4663

Description

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>>);

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    fixedSomething works now, yay!performanceMust go fasterrangesC++20/23 ranges

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions