Skip to content

Commit 8fdfe3f

Browse files
authored
[libc++] Refactor ranges::{min, max, min_element, max_element} to use std::__min_element (#132418)
Previously, ranges::min_element delegated to ranges::__min_element_impl, which duplicated the definition of std::__min_element. This patch updates ranges::min_element to directly call std::__min_element, which allows removing the redundant code in ranges::__min_element_impl. Upon removal of ranges::__min_element_impl, the other ranges algorithms ranges::{min,max,max_element}, which previously delegated to ranges::__min_element_impl, have been updated to call std::__min_element instead. This refactoring unifies the implementation across these algorithms, ensuring that future optimizations or maintenance work only need to be applied in one place.
1 parent d0aa1f9 commit 8fdfe3f

File tree

5 files changed

+13
-26
lines changed

5 files changed

+13
-26
lines changed

libcxx/include/__algorithm/min_element.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2929

3030
template <class _Comp, class _Iter, class _Sent, class _Proj>
3131
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
32-
__min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) {
32+
__min_element(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
3333
if (__first == __last)
3434
return __first;
3535

libcxx/include/__algorithm/ranges_max.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef _LIBCPP___ALGORITHM_RANGES_MAX_H
1010
#define _LIBCPP___ALGORITHM_RANGES_MAX_H
1111

12-
#include <__algorithm/ranges_min_element.h>
12+
#include <__algorithm/min_element.h>
1313
#include <__assert>
1414
#include <__concepts/copyable.h>
1515
#include <__config>
@@ -57,7 +57,7 @@ struct __max {
5757
__il.begin() != __il.end(), "initializer_list must contain at least one element");
5858

5959
auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, __rhs, __lhs); };
60-
return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp_lhs_rhs_swapped, __proj);
60+
return *std::__min_element(__il.begin(), __il.end(), __comp_lhs_rhs_swapped, __proj);
6161
}
6262

6363
template <input_range _Rp,
@@ -75,7 +75,7 @@ struct __max {
7575
auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool {
7676
return std::invoke(__comp, __rhs, __lhs);
7777
};
78-
return *ranges::__min_element_impl(std::move(__first), std::move(__last), __comp_lhs_rhs_swapped, __proj);
78+
return *std::__min_element(std::move(__first), std::move(__last), __comp_lhs_rhs_swapped, __proj);
7979
} else {
8080
range_value_t<_Rp> __result = *__first;
8181
while (++__first != __last) {

libcxx/include/__algorithm/ranges_max_element.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H
1010
#define _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H
1111

12-
#include <__algorithm/ranges_min_element.h>
12+
#include <__algorithm/min_element.h>
1313
#include <__config>
1414
#include <__functional/identity.h>
1515
#include <__functional/invoke.h>
@@ -40,7 +40,7 @@ struct __max_element {
4040
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip
4141
operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
4242
auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, __rhs, __lhs); };
43-
return ranges::__min_element_impl(__first, __last, __comp_lhs_rhs_swapped, __proj);
43+
return std::__min_element(__first, __last, __comp_lhs_rhs_swapped, __proj);
4444
}
4545

4646
template <forward_range _Rp,
@@ -49,7 +49,7 @@ struct __max_element {
4949
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
5050
operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
5151
auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, __rhs, __lhs); };
52-
return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp_lhs_rhs_swapped, __proj);
52+
return std::__min_element(ranges::begin(__r), ranges::end(__r), __comp_lhs_rhs_swapped, __proj);
5353
}
5454
};
5555

libcxx/include/__algorithm/ranges_min.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef _LIBCPP___ALGORITHM_RANGES_MIN_H
1010
#define _LIBCPP___ALGORITHM_RANGES_MIN_H
1111

12-
#include <__algorithm/ranges_min_element.h>
12+
#include <__algorithm/min_element.h>
1313
#include <__assert>
1414
#include <__concepts/copyable.h>
1515
#include <__config>
@@ -54,7 +54,7 @@ struct __min {
5454
operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const {
5555
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
5656
__il.begin() != __il.end(), "initializer_list must contain at least one element");
57-
return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp, __proj);
57+
return *std::__min_element(__il.begin(), __il.end(), __comp, __proj);
5858
}
5959

6060
template <input_range _Rp,
@@ -67,7 +67,7 @@ struct __min {
6767
auto __last = ranges::end(__r);
6868
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__first != __last, "range must contain at least one element");
6969
if constexpr (forward_range<_Rp> && !__is_cheap_to_copy<range_value_t<_Rp>>) {
70-
return *ranges::__min_element_impl(__first, __last, __comp, __proj);
70+
return *std::__min_element(__first, __last, __comp, __proj);
7171
} else {
7272
range_value_t<_Rp> __result = *__first;
7373
while (++__first != __last) {

libcxx/include/__algorithm/ranges_min_element.h

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H
1010
#define _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H
1111

12+
#include <__algorithm/min_element.h>
1213
#include <__config>
1314
#include <__functional/identity.h>
1415
#include <__functional/invoke.h>
@@ -32,36 +33,22 @@ _LIBCPP_PUSH_MACROS
3233
_LIBCPP_BEGIN_NAMESPACE_STD
3334

3435
namespace ranges {
35-
36-
// TODO(ranges): `ranges::min_element` can now simply delegate to `std::__min_element`.
37-
template <class _Ip, class _Sp, class _Proj, class _Comp>
38-
_LIBCPP_HIDE_FROM_ABI constexpr _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) {
39-
if (__first == __last)
40-
return __first;
41-
42-
_Ip __i = __first;
43-
while (++__i != __last)
44-
if (std::invoke(__comp, std::invoke(__proj, *__i), std::invoke(__proj, *__first)))
45-
__first = __i;
46-
return __first;
47-
}
48-
4936
struct __min_element {
5037
template <forward_iterator _Ip,
5138
sentinel_for<_Ip> _Sp,
5239
class _Proj = identity,
5340
indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less>
5441
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip
5542
operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
56-
return ranges::__min_element_impl(__first, __last, __comp, __proj);
43+
return std::__min_element(__first, __last, __comp, __proj);
5744
}
5845

5946
template <forward_range _Rp,
6047
class _Proj = identity,
6148
indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
6249
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
6350
operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
64-
return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
51+
return std::__min_element(ranges::begin(__r), ranges::end(__r), __comp, __proj);
6552
}
6653
};
6754

0 commit comments

Comments
 (0)