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:
|
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));
|
|
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)));
|
|
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:
|
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>>);
|
Noticed while looking at #4660 but this is a distinct issue.
All of our uses of
_Prefer_iterator_copiesare inspectingiterator_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
STL/stl/inc/xutility
Lines 7018 to 7020 in 8dc4faa
STL/stl/inc/xutility
Lines 7236 to 7238 in 8dc4faa
_Prefer_iterator_copiescares about both size and trivially-copyable, so wrapped vs. unwrapped is a significant difference:STL/stl/inc/xutility
Lines 6962 to 6966 in 8dc4faa