diff --git a/stl/inc/algorithm b/stl/inc/algorithm index 1c087211a7b..f73e2890dd9 100644 --- a/stl/inc/algorithm +++ b/stl/inc/algorithm @@ -9442,6 +9442,22 @@ namespace ranges { _STL_INTERNAL_STATIC_ASSERT(sentinel_for<_Se, _It>); _STL_INTERNAL_STATIC_ASSERT(indirect_strict_weak_order<_Pr, projected<_It, _Pj>>); +#if _USE_STD_VECTOR_ALGORITHMS + if constexpr (is_same_v<_Pj, identity> && _Is_min_max_optimization_safe<_It, _Pr> // + && sized_sentinel_for<_Se, _It>) { + if (!_STD is_constant_evaluated()) { + const auto _First_ptr = _STD to_address(_First); + const auto _Last_ptr = _First_ptr + (_Last - _First); + const auto _Result = __std_max_element(_First_ptr, _Last_ptr); + if constexpr (is_pointer_v<_It>) { + return _Result; + } else { + return _First + (_Result - _First_ptr); + } + } + } +#endif // _USE_STD_VECTOR_ALGORITHMS + auto _Found = _First; if (_First == _Last) { return _Found; @@ -9547,6 +9563,22 @@ namespace ranges { _STL_INTERNAL_STATIC_ASSERT(sentinel_for<_Se, _It>); _STL_INTERNAL_STATIC_ASSERT(indirect_strict_weak_order<_Pr, projected<_It, _Pj>>); +#if _USE_STD_VECTOR_ALGORITHMS + if constexpr (is_same_v<_Pj, identity> && _Is_min_max_optimization_safe<_It, _Pr> // + && sized_sentinel_for<_Se, _It>) { + if (!_STD is_constant_evaluated()) { + const auto _First_ptr = _STD to_address(_First); + const auto _Last_ptr = _First_ptr + (_Last - _First); + const auto _Result = __std_min_element(_First_ptr, _Last_ptr); + if constexpr (is_pointer_v<_It>) { + return _Result; + } else { + return _First + (_Result - _First_ptr); + } + } + } +#endif // _USE_STD_VECTOR_ALGORITHMS + auto _Found = _First; if (_First == _Last) { return _Found; @@ -9686,6 +9718,22 @@ namespace ranges { _STL_INTERNAL_STATIC_ASSERT(sentinel_for<_Se, _It>); _STL_INTERNAL_STATIC_ASSERT(indirect_strict_weak_order<_Pr, projected<_It, _Pj>>); +#if _USE_STD_VECTOR_ALGORITHMS + if constexpr (is_same_v<_Pj, identity> && _Is_min_max_optimization_safe<_It, _Pr> // + && sized_sentinel_for<_Se, _It>) { + if (!_STD is_constant_evaluated()) { + const auto _First_ptr = _STD to_address(_First); + const auto _Last_ptr = _First_ptr + (_Last - _First); + const auto _Result = __std_minmax_element(_First_ptr, _Last_ptr); + if constexpr (is_pointer_v<_It>) { + return {_Result.first, _Result.second}; + } else { + return {_First + (_Result.first - _First_ptr), _First + (_Result.second - _First_ptr)}; + } + } + } +#endif // _USE_STD_VECTOR_ALGORITHMS + min_max_result<_It> _Found{_First, _First}; if (_First == _Last) { diff --git a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp index 85f579ecb64..6b607b762a9 100644 --- a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp +++ b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp @@ -15,6 +15,10 @@ #include #include +#ifdef __cpp_lib_concepts +#include +#endif + using namespace std; #pragma warning(disable : 4984) // 'if constexpr' is a C++17 language extension @@ -194,6 +198,24 @@ void test_case_min_max_element(const vector& input) { assert(expected_min == actual_min); assert(expected_max == actual_max); assert(expected_minmax == actual_minmax); +#ifdef __cpp_lib_concepts + using ranges::views::take; + + auto actual_min_range = ranges::min_element(input); + auto actual_max_range = ranges::max_element(input); + auto actual_minmax_range = ranges::minmax_element(input); + auto actual_min_sized_range = ranges::min_element(take(input, static_cast(input.size()))); + auto actual_max_sized_range = ranges::max_element(take(input, static_cast(input.size()))); + auto actual_minmax_sized_range = ranges::minmax_element(take(input, static_cast(input.size()))); + assert(expected_min == actual_min_range); + assert(expected_max == actual_max_range); + assert(expected_minmax.first == actual_minmax_range.min); + assert(expected_minmax.second == actual_minmax_range.max); + assert(expected_min == actual_min_sized_range); + assert(expected_max == actual_max_sized_range); + assert(expected_minmax.first == actual_minmax_sized_range.min); + assert(expected_minmax.second == actual_minmax_sized_range.max); +#endif // __cpp_lib_concepts } template