[libcxx-commits] [libcxx] 88632e4 - [libc++] Refactor __less
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jun 6 13:58:59 PDT 2023
Author: Nikolas Klauser
Date: 2023-06-06T13:58:52-07:00
New Revision: 88632e48069605f5a27740a5df49f0f4e3c285ec
URL: https://github.com/llvm/llvm-project/commit/88632e48069605f5a27740a5df49f0f4e3c285ec
DIFF: https://github.com/llvm/llvm-project/commit/88632e48069605f5a27740a5df49f0f4e3c285ec.diff
LOG: [libc++] Refactor __less
This simplifies the usage of `__less` by making the class not depend on the types compared, but instead the `operator()`. We can't remove the template completely because we explicitly instantiate `std::__sort` with `__less<T>`.
Reviewed By: ldionne, #libc
Spies: arichardson, EricWF, libcxx-commits, mgrang
Differential Revision: https://reviews.llvm.org/D145285
Added:
libcxx/test/libcxx/algorithms/robust_against_using_non_transparent_comparators.pass.cpp
Modified:
libcxx/include/__algorithm/binary_search.h
libcxx/include/__algorithm/clamp.h
libcxx/include/__algorithm/comp.h
libcxx/include/__algorithm/equal_range.h
libcxx/include/__algorithm/includes.h
libcxx/include/__algorithm/inplace_merge.h
libcxx/include/__algorithm/is_heap.h
libcxx/include/__algorithm/is_heap_until.h
libcxx/include/__algorithm/is_sorted.h
libcxx/include/__algorithm/is_sorted_until.h
libcxx/include/__algorithm/lexicographical_compare.h
libcxx/include/__algorithm/lower_bound.h
libcxx/include/__algorithm/make_heap.h
libcxx/include/__algorithm/max.h
libcxx/include/__algorithm/max_element.h
libcxx/include/__algorithm/merge.h
libcxx/include/__algorithm/min.h
libcxx/include/__algorithm/min_element.h
libcxx/include/__algorithm/minmax.h
libcxx/include/__algorithm/minmax_element.h
libcxx/include/__algorithm/next_permutation.h
libcxx/include/__algorithm/nth_element.h
libcxx/include/__algorithm/partial_sort.h
libcxx/include/__algorithm/partial_sort_copy.h
libcxx/include/__algorithm/pop_heap.h
libcxx/include/__algorithm/prev_permutation.h
libcxx/include/__algorithm/push_heap.h
libcxx/include/__algorithm/set_difference.h
libcxx/include/__algorithm/set_intersection.h
libcxx/include/__algorithm/set_symmetric_difference.h
libcxx/include/__algorithm/set_union.h
libcxx/include/__algorithm/sort.h
libcxx/include/__algorithm/sort_heap.h
libcxx/include/__algorithm/stable_sort.h
libcxx/include/__algorithm/upper_bound.h
libcxx/include/forward_list
libcxx/include/list
libcxx/src/algorithm.cpp
libcxx/test/std/containers/sequences/array/compare.verify.cpp
libcxx/utils/data/ignore_format.txt
Removed:
################################################################################
diff --git a/libcxx/include/__algorithm/binary_search.h b/libcxx/include/__algorithm/binary_search.h
index 8f958c2c1ad89..0c8f5545e066e 100644
--- a/libcxx/include/__algorithm/binary_search.h
+++ b/libcxx/include/__algorithm/binary_search.h
@@ -37,8 +37,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
{
- return std::binary_search(__first, __last, __value,
- __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+ return std::binary_search(__first, __last, __value, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/clamp.h b/libcxx/include/__algorithm/clamp.h
index 336b93fd89b21..ce5740584acfb 100644
--- a/libcxx/include/__algorithm/clamp.h
+++ b/libcxx/include/__algorithm/clamp.h
@@ -37,7 +37,7 @@ _LIBCPP_INLINE_VISIBILITY constexpr
const _Tp&
clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi)
{
- return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>());
+ return _VSTD::clamp(__v, __lo, __hi, __less<>());
}
#endif
diff --git a/libcxx/include/__algorithm/comp.h b/libcxx/include/__algorithm/comp.h
index 1001e42a3169b..9474536615ffb 100644
--- a/libcxx/include/__algorithm/comp.h
+++ b/libcxx/include/__algorithm/comp.h
@@ -29,41 +29,17 @@ struct __equal_to {
template <class _Lhs, class _Rhs>
struct __is_trivial_equality_predicate<__equal_to, _Lhs, _Rhs> : true_type {};
-template <class _T1, class _T2 = _T1>
-struct __less
-{
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
- bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
-
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
- bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;}
-
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
- bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;}
-
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
- bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;}
-};
-
-template <class _T1>
-struct __less<_T1, _T1>
-{
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
- bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
-};
-
-template <class _T1>
-struct __less<const _T1, _T1>
-{
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
- bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
-};
-
-template <class _T1>
-struct __less<_T1, const _T1>
-{
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
- bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+// The definition is required because __less is part of the ABI, but it's empty
+// because all comparisons should be transparent.
+template <class _T1 = void, class _T2 = _T1>
+struct __less {};
+
+template <>
+struct __less<void, void> {
+ template <class _Tp, class _Up>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __lhs, const _Up& __rhs) const {
+ return __lhs < __rhs;
+ }
};
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/equal_range.h b/libcxx/include/__algorithm/equal_range.h
index 2075b03412e30..b731dcceb7886 100644
--- a/libcxx/include/__algorithm/equal_range.h
+++ b/libcxx/include/__algorithm/equal_range.h
@@ -75,11 +75,7 @@ equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu
template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
- return std::equal_range(
- std::move(__first),
- std::move(__last),
- __value,
- __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+ return std::equal_range(std::move(__first), std::move(__last), __value, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/includes.h b/libcxx/include/__algorithm/includes.h
index cc39f275bf448..88253e2653d27 100644
--- a/libcxx/include/__algorithm/includes.h
+++ b/libcxx/include/__algorithm/includes.h
@@ -61,13 +61,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
template <class _InputIterator1, class _InputIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
- return std::includes(
- std::move(__first1),
- std::move(__last1),
- std::move(__first2),
- std::move(__last2),
- __less<typename iterator_traits<_InputIterator1>::value_type,
- typename iterator_traits<_InputIterator2>::value_type>());
+ return std::includes(std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h
index 5bbefc94bdf2d..44a9425559ef1 100644
--- a/libcxx/include/__algorithm/inplace_merge.h
+++ b/libcxx/include/__algorithm/inplace_merge.h
@@ -246,8 +246,7 @@ inline _LIBCPP_HIDE_FROM_ABI
void
inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last)
{
- std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last),
- __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
+ std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/is_heap.h b/libcxx/include/__algorithm/is_heap.h
index 2dcb4a28e8d77..93d84d33806e1 100644
--- a/libcxx/include/__algorithm/is_heap.h
+++ b/libcxx/include/__algorithm/is_heap.h
@@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
- return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+ return _VSTD::is_heap(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/is_heap_until.h b/libcxx/include/__algorithm/is_heap_until.h
index 6ed4cb29c4234..d7131114bd60d 100644
--- a/libcxx/include/__algorithm/is_heap_until.h
+++ b/libcxx/include/__algorithm/is_heap_until.h
@@ -58,7 +58,7 @@ template<class _RandomAccessIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
- return _VSTD::__is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+ return _VSTD::__is_heap_until(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/is_sorted.h b/libcxx/include/__algorithm/is_sorted.h
index bf44f45764d56..a321c2c12dc4e 100644
--- a/libcxx/include/__algorithm/is_sorted.h
+++ b/libcxx/include/__algorithm/is_sorted.h
@@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
is_sorted(_ForwardIterator __first, _ForwardIterator __last)
{
- return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
+ return _VSTD::is_sorted(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/is_sorted_until.h b/libcxx/include/__algorithm/is_sorted_until.h
index b6683000a0690..890b93631c46e 100644
--- a/libcxx/include/__algorithm/is_sorted_until.h
+++ b/libcxx/include/__algorithm/is_sorted_until.h
@@ -48,7 +48,7 @@ template<class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
{
- return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
+ return _VSTD::is_sorted_until(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/lexicographical_compare.h b/libcxx/include/__algorithm/lexicographical_compare.h
index 0a13c5dd31c88..62b72edc80f77 100644
--- a/libcxx/include/__algorithm/lexicographical_compare.h
+++ b/libcxx/include/__algorithm/lexicographical_compare.h
@@ -52,9 +52,7 @@ bool
lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2)
{
- return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2,
- __less<typename iterator_traits<_InputIterator1>::value_type,
- typename iterator_traits<_InputIterator2>::value_type>());
+ return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/lower_bound.h b/libcxx/include/__algorithm/lower_bound.h
index 8109393757617..7a7a2995cc300 100644
--- a/libcxx/include/__algorithm/lower_bound.h
+++ b/libcxx/include/__algorithm/lower_bound.h
@@ -58,8 +58,7 @@ _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last,
template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
- return std::lower_bound(__first, __last, __value,
- __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+ return std::lower_bound(__first, __last, __value, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/make_heap.h b/libcxx/include/__algorithm/make_heap.h
index d66cfe2e5fc98..ee3b6d80f9bf6 100644
--- a/libcxx/include/__algorithm/make_heap.h
+++ b/libcxx/include/__algorithm/make_heap.h
@@ -47,8 +47,7 @@ void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
- std::make_heap(std::move(__first), std::move(__last),
- __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+ std::make_heap(std::move(__first), std::move(__last), __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/max.h b/libcxx/include/__algorithm/max.h
index 97f61f2aad6b9..5d8e64cfff39b 100644
--- a/libcxx/include/__algorithm/max.h
+++ b/libcxx/include/__algorithm/max.h
@@ -39,7 +39,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
const _Tp&
max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
{
- return _VSTD::max(__a, __b, __less<_Tp>());
+ return _VSTD::max(__a, __b, __less<>());
}
#ifndef _LIBCPP_CXX03_LANG
@@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
_Tp
max(initializer_list<_Tp> __t)
{
- return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>());
+ return *_VSTD::max_element(__t.begin(), __t.end(), __less<>());
}
#endif // _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/__algorithm/max_element.h b/libcxx/include/__algorithm/max_element.h
index f816a17fa6f08..8fd52c77723c0 100644
--- a/libcxx/include/__algorithm/max_element.h
+++ b/libcxx/include/__algorithm/max_element.h
@@ -48,8 +48,7 @@ template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
max_element(_ForwardIterator __first, _ForwardIterator __last)
{
- return _VSTD::max_element(__first, __last,
- __less<typename iterator_traits<_ForwardIterator>::value_type>());
+ return _VSTD::max_element(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/merge.h b/libcxx/include/__algorithm/merge.h
index e54e430bcb6a7..7ee7aaad716e4 100644
--- a/libcxx/include/__algorithm/merge.h
+++ b/libcxx/include/__algorithm/merge.h
@@ -60,9 +60,7 @@ _OutputIterator
merge(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
{
- typedef typename iterator_traits<_InputIterator1>::value_type __v1;
- typedef typename iterator_traits<_InputIterator2>::value_type __v2;
- return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>());
+ return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/min.h b/libcxx/include/__algorithm/min.h
index d073a16533e4d..3c0debd6b046c 100644
--- a/libcxx/include/__algorithm/min.h
+++ b/libcxx/include/__algorithm/min.h
@@ -39,7 +39,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
const _Tp&
min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
{
- return _VSTD::min(__a, __b, __less<_Tp>());
+ return _VSTD::min(__a, __b, __less<>());
}
#ifndef _LIBCPP_CXX03_LANG
@@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
_Tp
min(initializer_list<_Tp> __t)
{
- return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>());
+ return *_VSTD::min_element(__t.begin(), __t.end(), __less<>());
}
#endif // _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/__algorithm/min_element.h b/libcxx/include/__algorithm/min_element.h
index aeabd30a738f0..7d58e9835bd34 100644
--- a/libcxx/include/__algorithm/min_element.h
+++ b/libcxx/include/__algorithm/min_element.h
@@ -61,8 +61,7 @@ template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
min_element(_ForwardIterator __first, _ForwardIterator __last)
{
- return _VSTD::min_element(__first, __last,
- __less<typename iterator_traits<_ForwardIterator>::value_type>());
+ return _VSTD::min_element(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/minmax.h b/libcxx/include/__algorithm/minmax.h
index f486de2efd75b..bdcf57b101e44 100644
--- a/libcxx/include/__algorithm/minmax.h
+++ b/libcxx/include/__algorithm/minmax.h
@@ -39,7 +39,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<const _Tp&, const _Tp&>
minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b)
{
- return std::minmax(__a, __b, __less<_Tp>());
+ return std::minmax(__a, __b, __less<>());
}
#ifndef _LIBCPP_CXX03_LANG
@@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_Tp, _Tp>
minmax(initializer_list<_Tp> __t)
{
- return std::minmax(__t, __less<_Tp>());
+ return std::minmax(__t, __less<>());
}
#endif // _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/__algorithm/minmax_element.h b/libcxx/include/__algorithm/minmax_element.h
index eca460de3c182..5bcaf8354d9ff 100644
--- a/libcxx/include/__algorithm/minmax_element.h
+++ b/libcxx/include/__algorithm/minmax_element.h
@@ -94,7 +94,7 @@ minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __com
template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) {
- return std::minmax_element(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
+ return std::minmax_element(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/next_permutation.h b/libcxx/include/__algorithm/next_permutation.h
index 73e8b99ab90b6..d89768ddc194f 100644
--- a/libcxx/include/__algorithm/next_permutation.h
+++ b/libcxx/include/__algorithm/next_permutation.h
@@ -69,8 +69,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
{
- return _VSTD::next_permutation(__first, __last,
- __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
+ return _VSTD::next_permutation(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/nth_element.h b/libcxx/include/__algorithm/nth_element.h
index 9fdfb2cae64ca..c84769855cee2 100644
--- a/libcxx/include/__algorithm/nth_element.h
+++ b/libcxx/include/__algorithm/nth_element.h
@@ -249,8 +249,7 @@ void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Ra
template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) {
- std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<typename
- iterator_traits<_RandomAccessIterator>::value_type>());
+ std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/partial_sort.h b/libcxx/include/__algorithm/partial_sort.h
index 4b8e0e76b7a23..4924d5a5eb760 100644
--- a/libcxx/include/__algorithm/partial_sort.h
+++ b/libcxx/include/__algorithm/partial_sort.h
@@ -88,8 +88,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
void
partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
{
- _VSTD::partial_sort(__first, __middle, __last,
- __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+ _VSTD::partial_sort(__first, __middle, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/partial_sort_copy.h b/libcxx/include/__algorithm/partial_sort_copy.h
index 1aba07105dc87..b9635c51d5fab 100644
--- a/libcxx/include/__algorithm/partial_sort_copy.h
+++ b/libcxx/include/__algorithm/partial_sort_copy.h
@@ -79,8 +79,7 @@ _RandomAccessIterator
partial_sort_copy(_InputIterator __first, _InputIterator __last,
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last)
{
- return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last,
- __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+ return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/pop_heap.h b/libcxx/include/__algorithm/pop_heap.h
index 4187523ef9707..1dda2689320ab 100644
--- a/libcxx/include/__algorithm/pop_heap.h
+++ b/libcxx/include/__algorithm/pop_heap.h
@@ -65,8 +65,7 @@ void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp
template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
- std::pop_heap(std::move(__first), std::move(__last),
- __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+ std::pop_heap(std::move(__first), std::move(__last), __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/prev_permutation.h b/libcxx/include/__algorithm/prev_permutation.h
index 0b86ab74ee011..187f1e3e5ba30 100644
--- a/libcxx/include/__algorithm/prev_permutation.h
+++ b/libcxx/include/__algorithm/prev_permutation.h
@@ -70,8 +70,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
{
- return _VSTD::prev_permutation(__first, __last,
- __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
+ return _VSTD::prev_permutation(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/push_heap.h b/libcxx/include/__algorithm/push_heap.h
index e831162a81c9c..5f5db7963760d 100644
--- a/libcxx/include/__algorithm/push_heap.h
+++ b/libcxx/include/__algorithm/push_heap.h
@@ -69,8 +69,7 @@ void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
- std::push_heap(std::move(__first), std::move(__last),
- __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+ std::push_heap(std::move(__first), std::move(__last), __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/set_
diff erence.h b/libcxx/include/__algorithm/set_
diff erence.h
index 5a7d3bc18c911..26a300092c91f 100644
--- a/libcxx/include/__algorithm/set_
diff erence.h
+++ b/libcxx/include/__algorithm/set_
diff erence.h
@@ -66,14 +66,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_d
_InputIterator2 __first2,
_InputIterator2 __last2,
_OutputIterator __result) {
- return std::__set_
diff erence<_ClassicAlgPolicy>(
- __first1,
- __last1,
- __first2,
- __last2,
- __result,
- __less<typename iterator_traits<_InputIterator1>::value_type,
- typename iterator_traits<_InputIterator2>::value_type>()).second;
+ return std::__set_
diff erence<_ClassicAlgPolicy>(__first1, __last1, __first2, __last2, __result, __less<>()).second;
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/set_intersection.h b/libcxx/include/__algorithm/set_intersection.h
index 9fa7799aee620..f2603fe1365ac 100644
--- a/libcxx/include/__algorithm/set_intersection.h
+++ b/libcxx/include/__algorithm/set_intersection.h
@@ -89,8 +89,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_i
std::move(__first2),
std::move(__last2),
std::move(__result),
- __less<typename iterator_traits<_InputIterator1>::value_type,
- typename iterator_traits<_InputIterator2>::value_type>())
+ __less<>())
.__out_;
}
diff --git a/libcxx/include/__algorithm/set_symmetric_
diff erence.h b/libcxx/include/__algorithm/set_symmetric_
diff erence.h
index bcb09587032ba..832c3979bfd76 100644
--- a/libcxx/include/__algorithm/set_symmetric_
diff erence.h
+++ b/libcxx/include/__algorithm/set_symmetric_
diff erence.h
@@ -96,8 +96,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_symmetri
std::move(__first2),
std::move(__last2),
std::move(__result),
- __less<typename iterator_traits<_InputIterator1>::value_type,
- typename iterator_traits<_InputIterator2>::value_type>());
+ __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/set_union.h b/libcxx/include/__algorithm/set_union.h
index 4d154b81e0920..cf48adae03bed 100644
--- a/libcxx/include/__algorithm/set_union.h
+++ b/libcxx/include/__algorithm/set_union.h
@@ -92,8 +92,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_union(
std::move(__first2),
std::move(__last2),
std::move(__result),
- __less<typename iterator_traits<_InputIterator1>::value_type,
- typename iterator_traits<_InputIterator2>::value_type>());
+ __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/sort.h b/libcxx/include/__algorithm/sort.h
index 3215c52a5d9a7..24fbd2af6067f 100644
--- a/libcxx/include/__algorithm/sort.h
+++ b/libcxx/include/__algorithm/sort.h
@@ -124,8 +124,8 @@ _LIBCPP_HIDE_FROM_ABI void __sort5(_ForwardIterator __x1, _ForwardIterator __x2,
// The comparator being simple is a prerequisite for using the branchless optimization.
template <class _Tp>
struct __is_simple_comparator : false_type {};
-template <class _Tp>
-struct __is_simple_comparator<__less<_Tp>&> : true_type {};
+template <>
+struct __is_simple_comparator<__less<>&> : true_type {};
template <class _Tp>
struct __is_simple_comparator<less<_Tp>&> : true_type {};
template <class _Tp>
@@ -885,7 +885,8 @@ using __sort_is_specialized_in_library = __is_any_of<
long double>;
template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, __less<_Type>& __comp) {
+_LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, __less<>&) {
+ __less<_Type> __comp;
std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
}
@@ -934,7 +935,7 @@ void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __c
template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
- std::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+ std::sort(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/sort_heap.h b/libcxx/include/__algorithm/sort_heap.h
index ed72ff95f1c8a..a82926ed1ccac 100644
--- a/libcxx/include/__algorithm/sort_heap.h
+++ b/libcxx/include/__algorithm/sort_heap.h
@@ -50,8 +50,7 @@ void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
- std::sort_heap(std::move(__first), std::move(__last),
- __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+ std::sort_heap(std::move(__first), std::move(__last), __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 38fd2be411190..dc24218b74dd3 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -272,7 +272,7 @@ void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C
template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI
void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) {
- std::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+ std::stable_sort(__first, __last, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/upper_bound.h b/libcxx/include/__algorithm/upper_bound.h
index 96552ce1f8ac8..ef36a3cc3c273 100644
--- a/libcxx/include/__algorithm/upper_bound.h
+++ b/libcxx/include/__algorithm/upper_bound.h
@@ -47,8 +47,7 @@ __upper_bound(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp
template <class _ForwardIterator, class _Tp, class _Compare>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) {
- static_assert(is_copy_constructible<_ForwardIterator>::value,
- "Iterator has to be copy constructible");
+ static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible");
return std::__upper_bound<_ClassicAlgPolicy>(
std::move(__first), std::move(__last), __value, std::move(__comp), std::__identity());
}
@@ -56,11 +55,7 @@ upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu
template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
- return std::upper_bound(
- std::move(__first),
- std::move(__last),
- __value,
- __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>());
+ return std::upper_bound(std::move(__first), std::move(__last), __value, __less<>());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 5625a0b9b0d52..10c9c15767bdb 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -865,18 +865,18 @@ public:
_LIBCPP_HIDE_FROM_ABI __remove_return_type unique(_BinaryPredicate __binary_pred);
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
- void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
+ void merge(forward_list&& __x) {merge(__x, __less<>());}
template <class _Compare>
_LIBCPP_INLINE_VISIBILITY
void merge(forward_list&& __x, _Compare __comp)
{merge(__x, _VSTD::move(__comp));}
#endif // _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
- void merge(forward_list& __x) {merge(__x, __less<value_type>());}
+ void merge(forward_list& __x) {merge(__x, __less<>());}
template <class _Compare>
_LIBCPP_HIDE_FROM_ABI void merge(forward_list& __x, _Compare __comp);
_LIBCPP_INLINE_VISIBILITY
- void sort() {sort(__less<value_type>());}
+ void sort() {sort(__less<>());}
template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp);
_LIBCPP_HIDE_FROM_ABI void reverse() _NOEXCEPT;
diff --git a/libcxx/include/list b/libcxx/include/list
index dd56b893cf786..a762b6b3b84de 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -2101,7 +2101,7 @@ inline
void
list<_Tp, _Alloc>::merge(list& __c)
{
- merge(__c, __less<value_type>());
+ merge(__c, __less<>());
}
template <class _Tp, class _Alloc>
@@ -2163,7 +2163,7 @@ inline
void
list<_Tp, _Alloc>::sort()
{
- sort(__less<value_type>());
+ sort(__less<>());
}
template <class _Tp, class _Alloc>
diff --git a/libcxx/src/algorithm.cpp b/libcxx/src/algorithm.cpp
index 5a47558fdaeb8..af9d60a8e271e 100644
--- a/libcxx/src/algorithm.cpp
+++ b/libcxx/src/algorithm.cpp
@@ -19,9 +19,10 @@ void __sort(RandomAccessIterator first, RandomAccessIterator last, Comp comp) {
// that the default comparator is in use so that we are sure that there are no
// branches in the comparator.
std::__introsort<_ClassicAlgPolicy,
- Comp&,
+ ranges::less,
RandomAccessIterator,
- __use_branchless_sort<Comp, RandomAccessIterator>::value>(first, last, comp, depth_limit);
+ __use_branchless_sort<ranges::less, RandomAccessIterator>::value>(
+ first, last, ranges::less{}, depth_limit);
}
// clang-format off
diff --git a/libcxx/test/libcxx/algorithms/robust_against_using_non_transparent_comparators.pass.cpp b/libcxx/test/libcxx/algorithms/robust_against_using_non_transparent_comparators.pass.cpp
new file mode 100644
index 0000000000000..66b620e9cfc46
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/robust_against_using_non_transparent_comparators.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+#include <cassert>
+#include <iterator>
+
+#include "test_macros.h"
+
+template <class T>
+struct Iterator {
+ using value_type = T;
+ using pointer = value_type*;
+ using
diff erence_type = std::ptr
diff _t;
+ using iterator_category = std::forward_iterator_tag;
+ struct reference {
+ T* ptr_;
+
+ reference(T* ptr) : ptr_(ptr) {}
+
+ friend bool operator<(reference a, reference b) { return *a.ptr_ < *b.ptr_; }
+ friend bool operator<(reference a, value_type const& b) { return *a.ptr_ < b; }
+ friend bool operator<(value_type const& a, reference b) { return a < *b.ptr_; }
+
+ operator T&() const;
+ };
+
+ Iterator& operator++() {
+ ptr_++;
+ return *this;
+ }
+
+ Iterator operator++(int) {
+ Iterator tmp = *this;
+ ptr_++;
+ return tmp;
+ }
+
+ friend bool operator==(Iterator const& a, Iterator const& b) { return a.ptr_ == b.ptr_; }
+ friend bool operator!=(Iterator const& a, Iterator const& b) { return !(a == b); }
+
+ reference operator*() const { return reference(ptr_); }
+
+ explicit Iterator(T* ptr) : ptr_(ptr) {}
+ Iterator() = default;
+ Iterator(Iterator const&) = default;
+ Iterator(Iterator&&) = default;
+
+ Iterator& operator=(Iterator const&) = default;
+ Iterator& operator=(Iterator&&) = default;
+
+private:
+ T* ptr_;
+};
+
+int main() {
+ int array[5] = {1, 2, 3, 4, 5};
+ Iterator<int> first(array);
+ Iterator<int> middle(array + 3);
+ Iterator<int> last(array + 5);
+ (void)std::binary_search(first, last, 3);
+ (void)std::equal_range(first, last, 3);
+ (void)std::includes(first, last, first, last);
+ (void)std::is_sorted_until(first, last);
+ (void)std::is_sorted(first, last);
+ (void)std::lexicographical_compare(first, last, first, last);
+ (void)std::lower_bound(first, last, 3);
+ (void)std::max_element(first, last);
+ (void)std::min_element(first, last);
+ (void)std::minmax_element(first, last);
+ (void)std::upper_bound(first, last, 3);
+}
diff --git a/libcxx/test/std/containers/sequences/array/compare.verify.cpp b/libcxx/test/std/containers/sequences/array/compare.verify.cpp
index 4b001601a4fe2..e03f001469344 100644
--- a/libcxx/test/std/containers/sequences/array/compare.verify.cpp
+++ b/libcxx/test/std/containers/sequences/array/compare.verify.cpp
@@ -28,6 +28,10 @@
template <int>
struct NoCompare {};
+#if TEST_STD_VER >= 14 && TEST_STD_VER <= 17
+// expected-error@*:* 3 {{no matching function for call to object of type 'std::__less<void, void>'}}
+#endif
+
int main(int, char**) {
{
typedef NoCompare<0> T;
diff --git a/libcxx/utils/data/ignore_format.txt b/libcxx/utils/data/ignore_format.txt
index 3e9728ab6f387..4da365b1ac9ad 100644
--- a/libcxx/utils/data/ignore_format.txt
+++ b/libcxx/utils/data/ignore_format.txt
@@ -37,7 +37,6 @@ libcxx/benchmarks/unordered_set_operations.bench.cpp
libcxx/benchmarks/vector_operations.bench.cpp
libcxx/include/__algorithm/binary_search.h
libcxx/include/__algorithm/clamp.h
-libcxx/include/__algorithm/comp.h
libcxx/include/__algorithm/comp_ref_type.h
libcxx/include/__algorithm/copy_backward.h
libcxx/include/__algorithm/copy_if.h
@@ -208,7 +207,6 @@ libcxx/include/__algorithm/transform.h
libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h
libcxx/include/__algorithm/unwrap_iter.h
libcxx/include/__algorithm/unwrap_range.h
-libcxx/include/__algorithm/upper_bound.h
libcxx/include/any
libcxx/include/array
libcxx/include/__atomic/atomic_base.h
More information about the libcxx-commits
mailing list