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>: ranges::minmax should dereference iterators only once #3366

Merged
merged 17 commits into from
Feb 3, 2023
Merged
7 changes: 6 additions & 1 deletion stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -10102,9 +10102,14 @@ namespace ranges {
if constexpr (forward_range<_Rng> && _Prefer_iterator_copies<iterator_t<_Rng>>) {
const auto _Found = _RANGES _Minmax_element_unchecked(
_STD move(_UFirst), _STD move(_ULast), _Pass_fn(_Pred), _Pass_fn(_Proj));
if (_Found.min == _Found.max) {
fsb4000 marked this conversation as resolved.
Show resolved Hide resolved
_Vty _Temp{*_Found.min};
fsb4000 marked this conversation as resolved.
Show resolved Hide resolved
return {_Temp, _Temp};
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
}
return {static_cast<_Vty>(*_Found.min), static_cast<_Vty>(*_Found.max)};
} else {
minmax_result<_Vty> _Found = {static_cast<_Vty>(*_UFirst), static_cast<_Vty>(*_UFirst)};
_Vty _Temp{*_UFirst};
minmax_result<_Vty> _Found = {_Temp, _Temp};
if (_UFirst == _ULast) {
return _Found;
}
Expand Down
11 changes: 11 additions & 0 deletions tests/std/tests/P0896R4_ranges_alg_minmax/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,16 @@ void test_gh_1893() {
ASSERT(val == "meow");
}

void test_gh_2900() {
// GH-2900: <algorithm>: ranges::minmax initializes minmax_result with the moved value
{
vector<string> v{"1"};
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
auto [min, max] = ranges::minmax(ranges::subrange{make_move_iterator(v.begin()), make_move_iterator(v.end())});
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
assert(min == "1");
assert(max == "1");
}
}

int main() {
STATIC_ASSERT((nonrange_tests(), true));
nonrange_tests();
Expand All @@ -378,4 +388,5 @@ int main() {
test_in<mm, const P>();

test_gh_1893();
test_gh_2900();
}