[libcxx-commits] [libcxx] e07ca2a - [libcxx] Fix std::equal not accepting volatile types by refactoring __equal_to
Alvin Wong via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Nov 22 00:35:56 PST 2022
Author: Alvin Wong
Date: 2022-11-22T16:33:38+08:00
New Revision: e07ca2aeeb2f641e62f6ac7359472eb50111ea00
URL: https://github.com/llvm/llvm-project/commit/e07ca2aeeb2f641e62f6ac7359472eb50111ea00
DIFF: https://github.com/llvm/llvm-project/commit/e07ca2aeeb2f641e62f6ac7359472eb50111ea00.diff
LOG: [libcxx] Fix std::equal not accepting volatile types by refactoring __equal_to
Fixes https://github.com/llvm/llvm-project/issues/59021
Reviewed By: #libc, philnik
Differential Revision: https://reviews.llvm.org/D138268
Added:
Modified:
libcxx/include/__algorithm/adjacent_find.h
libcxx/include/__algorithm/comp.h
libcxx/include/__algorithm/equal.h
libcxx/include/__algorithm/find_end.h
libcxx/include/__algorithm/find_first_of.h
libcxx/include/__algorithm/is_permutation.h
libcxx/include/__algorithm/mismatch.h
libcxx/include/__algorithm/search.h
libcxx/include/__algorithm/search_n.h
libcxx/include/__algorithm/unique.h
libcxx/include/__algorithm/unique_copy.h
libcxx/include/forward_list
libcxx/include/list
libcxx/test/std/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__algorithm/adjacent_find.h b/libcxx/include/__algorithm/adjacent_find.h
index 9916d9007bb14..30df4a976f3d8 100644
--- a/libcxx/include/__algorithm/adjacent_find.h
+++ b/libcxx/include/__algorithm/adjacent_find.h
@@ -45,8 +45,7 @@ adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicat
template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
adjacent_find(_ForwardIterator __first, _ForwardIterator __last) {
- typedef typename iterator_traits<_ForwardIterator>::value_type __v;
- return std::adjacent_find(std::move(__first), std::move(__last), __equal_to<__v>());
+ return std::adjacent_find(std::move(__first), std::move(__last), __equal_to());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/comp.h b/libcxx/include/__algorithm/comp.h
index 7fa5c39cd4eb0..af8eb7b5d76b1 100644
--- a/libcxx/include/__algorithm/comp.h
+++ b/libcxx/include/__algorithm/comp.h
@@ -17,37 +17,11 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-// I'd like to replace these with _VSTD::equal_to<void>, but can't because:
-// * That only works with C++14 and later, and
-// * We haven't included <functional> here.
-template <class _T1, class _T2 = _T1>
-struct __equal_to
-{
- _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 __equal_to<_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 __equal_to<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 __equal_to<_T1, const _T1>
-{
- _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
- bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
+struct __equal_to {
+ template <class _T1, class _T2>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _T1& __x, const _T2& __y) const {
+ return __x == __y;
+ }
};
template <class _T1, class _T2 = _T1>
diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h
index b46adea4ab3f1..cf37f46aaf69e 100644
--- a/libcxx/include/__algorithm/equal.h
+++ b/libcxx/include/__algorithm/equal.h
@@ -33,9 +33,7 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first
template <class _InputIterator1, class _InputIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
- typedef typename iterator_traits<_InputIterator1>::value_type __v1;
- typedef typename iterator_traits<_InputIterator2>::value_type __v2;
- return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>());
+ return std::equal(__first1, __last1, __first2, __equal_to());
}
#if _LIBCPP_STD_VER > 11
@@ -72,11 +70,14 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first
template <class _InputIterator1, class _InputIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
- typedef typename iterator_traits<_InputIterator1>::value_type __v1;
- typedef typename iterator_traits<_InputIterator2>::value_type __v2;
- return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(),
- typename iterator_traits<_InputIterator1>::iterator_category(),
- typename iterator_traits<_InputIterator2>::iterator_category());
+ return std::__equal(
+ __first1,
+ __last1,
+ __first2,
+ __last2,
+ __equal_to(),
+ typename iterator_traits<_InputIterator1>::iterator_category(),
+ typename iterator_traits<_InputIterator2>::iterator_category());
}
#endif
diff --git a/libcxx/include/__algorithm/find_end.h b/libcxx/include/__algorithm/find_end.h
index 72b07bb2b472f..e2fee6b3c4596 100644
--- a/libcxx/include/__algorithm/find_end.h
+++ b/libcxx/include/__algorithm/find_end.h
@@ -219,9 +219,7 @@ template <class _ForwardIterator1, class _ForwardIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2) {
- using __v1 = typename iterator_traits<_ForwardIterator1>::value_type;
- using __v2 = typename iterator_traits<_ForwardIterator2>::value_type;
- return std::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+ return std::find_end(__first1, __last1, __first2, __last2, __equal_to());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/find_first_of.h b/libcxx/include/__algorithm/find_first_of.h
index 9d38b9c394a32..12f0109a616c3 100644
--- a/libcxx/include/__algorithm/find_first_of.h
+++ b/libcxx/include/__algorithm/find_first_of.h
@@ -44,9 +44,7 @@ find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIte
template <class _ForwardIterator1, class _ForwardIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of(
_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
- typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
- typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
- return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+ return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/is_permutation.h b/libcxx/include/__algorithm/is_permutation.h
index 2e17ae649b70d..005445652e9df 100644
--- a/libcxx/include/__algorithm/is_permutation.h
+++ b/libcxx/include/__algorithm/is_permutation.h
@@ -199,24 +199,23 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIt
template <class _ForwardIterator1, class _ForwardIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
- using __v1 = __iter_value_type<_ForwardIterator1>;
- using __v2 = __iter_value_type<_ForwardIterator2>;
- return std::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>());
+ return std::is_permutation(__first1, __last1, __first2, __equal_to());
}
#if _LIBCPP_STD_VER > 11
// 2+2 iterators
template <class _ForwardIterator1, class _ForwardIterator2>
-_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
-is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
- _ForwardIterator2 __last2) {
- using __v1 = __iter_value_type<_ForwardIterator1>;
- using __v2 = __iter_value_type<_ForwardIterator2>;
-
+_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(
+ _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
return std::__is_permutation<_ClassicAlgPolicy>(
- std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
- __equal_to<__v1, __v2>(), __identity(), __identity());
+ std::move(__first1),
+ std::move(__last1),
+ std::move(__first2),
+ std::move(__last2),
+ __equal_to(),
+ __identity(),
+ __identity());
}
// 2+2 iterators, predicate
diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h
index b386245a353f6..600e2cdd3da4f 100644
--- a/libcxx/include/__algorithm/mismatch.h
+++ b/libcxx/include/__algorithm/mismatch.h
@@ -35,9 +35,7 @@ template <class _InputIterator1, class _InputIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
- typedef typename iterator_traits<_InputIterator1>::value_type __v1;
- typedef typename iterator_traits<_InputIterator2>::value_type __v2;
- return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>());
+ return std::mismatch(__first1, __last1, __first2, __equal_to());
}
#if _LIBCPP_STD_VER > 11
@@ -56,9 +54,7 @@ template <class _InputIterator1, class _InputIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
- typedef typename iterator_traits<_InputIterator1>::value_type __v1;
- typedef typename iterator_traits<_InputIterator2>::value_type __v2;
- return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+ return std::mismatch(__first1, __last1, __first2, __last2, __equal_to());
}
#endif
diff --git a/libcxx/include/__algorithm/search.h b/libcxx/include/__algorithm/search.h
index f22a1bb016f1e..93771be39e35b 100644
--- a/libcxx/include/__algorithm/search.h
+++ b/libcxx/include/__algorithm/search.h
@@ -184,9 +184,7 @@ template <class _ForwardIterator1, class _ForwardIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2) {
- using __v1 = typename iterator_traits<_ForwardIterator1>::value_type;
- using __v2 = typename iterator_traits<_ForwardIterator2>::value_type;
- return std::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+ return std::search(__first1, __last1, __first2, __last2, __equal_to());
}
#if _LIBCPP_STD_VER > 14
diff --git a/libcxx/include/__algorithm/search_n.h b/libcxx/include/__algorithm/search_n.h
index b3fd911442fba..60a073565156e 100644
--- a/libcxx/include/__algorithm/search_n.h
+++ b/libcxx/include/__algorithm/search_n.h
@@ -173,8 +173,7 @@ _ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last,
template <class _ForwardIterator, class _Size, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) {
- typedef typename iterator_traits<_ForwardIterator>::value_type __v;
- return std::search_n(__first, __last, std::__convert_to_integral(__count), __value, __equal_to<__v, _Tp>());
+ return std::search_n(__first, __last, std::__convert_to_integral(__count), __value, __equal_to());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/unique.h b/libcxx/include/__algorithm/unique.h
index f2733a7e5d48b..1717a00c8a934 100644
--- a/libcxx/include/__algorithm/unique.h
+++ b/libcxx/include/__algorithm/unique.h
@@ -51,8 +51,7 @@ unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pre
template <class _ForwardIterator>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
unique(_ForwardIterator __first, _ForwardIterator __last) {
- typedef typename iterator_traits<_ForwardIterator>::value_type __v;
- return std::unique(__first, __last, __equal_to<__v>());
+ return std::unique(__first, __last, __equal_to());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/unique_copy.h b/libcxx/include/__algorithm/unique_copy.h
index e33d795ecfdc8..81fcd50f011d5 100644
--- a/libcxx/include/__algorithm/unique_copy.h
+++ b/libcxx/include/__algorithm/unique_copy.h
@@ -114,8 +114,7 @@ unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __res
template <class _InputIterator, class _OutputIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
- typedef typename iterator_traits<_InputIterator>::value_type __v;
- return std::unique_copy(std::move(__first), std::move(__last), std::move(__result), __equal_to<__v>());
+ return std::unique_copy(std::move(__first), std::move(__last), std::move(__result), __equal_to());
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 51643e9e2828c..61dde8167dfcd 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -845,7 +845,7 @@ public:
__remove_return_type remove(const value_type& __v);
template <class _Predicate> __remove_return_type remove_if(_Predicate __pred);
_LIBCPP_INLINE_VISIBILITY
- __remove_return_type unique() {return unique(__equal_to<value_type>());}
+ __remove_return_type unique() { return unique(__equal_to()); }
template <class _BinaryPredicate> __remove_return_type unique(_BinaryPredicate __binary_pred);
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
diff --git a/libcxx/include/list b/libcxx/include/list
index 4d68c5e72668b..a0c732739ca28 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -1063,7 +1063,7 @@ public:
__remove_return_type remove(const value_type& __x);
template <class _Pred> __remove_return_type remove_if(_Pred __pred);
_LIBCPP_INLINE_VISIBILITY
- __remove_return_type unique() { return unique(__equal_to<value_type>()); }
+ __remove_return_type unique() { return unique(__equal_to()); }
template <class _BinaryPred>
__remove_return_type unique(_BinaryPred __binary_pred);
_LIBCPP_INLINE_VISIBILITY
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp
index 2b13bee2a806e..dfa425d974df9 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp
@@ -24,6 +24,24 @@
#include "test_macros.h"
#include "test_iterators.h"
+template <class Iter1, class Iter2 = Iter1>
+void test_equal() {
+ int a[] = {0, 1, 2, 3, 4, 5};
+ const unsigned s = sizeof(a) / sizeof(a[0]);
+ int b[s] = {0, 1, 2, 5, 4, 5};
+
+ assert(std::equal(Iter1(a), Iter1(a + s), Iter2(a)));
+ assert(std::equal(Iter2(a), Iter2(a + s), Iter1(a)));
+ assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(b)));
+
+#if TEST_STD_VER >= 14
+ assert(std::equal(Iter1(a), Iter1(a + s), Iter2(a), Iter2(a + s)));
+ assert(std::equal(Iter2(a), Iter2(a + s), Iter1(a), Iter1(a + s)));
+ assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(a), Iter2(a + s - 1)));
+ assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(b), Iter2(b + s)));
+#endif
+}
+
#if TEST_STD_VER > 17
TEST_CONSTEXPR bool test_constexpr() {
int ia[] = {1, 3, 6, 7};
@@ -46,44 +64,20 @@ TEST_CONSTEXPR bool test_constexpr() {
int main(int, char**)
{
- int ia[] = {0, 1, 2, 3, 4, 5};
- const unsigned s = sizeof(ia)/sizeof(ia[0]);
- int ib[s] = {0, 1, 2, 5, 4, 5};
- assert(std::equal(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia+s),
- cpp17_input_iterator<const int*>(ia)));
-#if TEST_STD_VER >= 14
- assert(std::equal(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia+s),
- cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia+s)));
- assert(std::equal(random_access_iterator<const int*>(ia),
- random_access_iterator<const int*>(ia+s),
- random_access_iterator<const int*>(ia),
- random_access_iterator<const int*>(ia+s)));
-#endif
- assert(!std::equal(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia+s),
- cpp17_input_iterator<const int*>(ib)));
-#if TEST_STD_VER >= 14
- assert(!std::equal(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia+s),
- cpp17_input_iterator<const int*>(ib),
- cpp17_input_iterator<const int*>(ib+s)));
- assert(!std::equal(random_access_iterator<const int*>(ia),
- random_access_iterator<const int*>(ia+s),
- random_access_iterator<const int*>(ib),
- random_access_iterator<const int*>(ib+s)));
- assert(!std::equal(cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia+s),
- cpp17_input_iterator<const int*>(ia),
- cpp17_input_iterator<const int*>(ia+s-1)));
- assert(!std::equal(random_access_iterator<const int*>(ia),
- random_access_iterator<const int*>(ia+s),
- random_access_iterator<const int*>(ia),
- random_access_iterator<const int*>(ia+s-1)));
+ test_equal<cpp17_input_iterator<const int*> >();
+ test_equal<random_access_iterator<const int*> >();
-#endif
+ // Test all combinations of cv-qualifiers:
+ test_equal<int*>();
+ test_equal<int*, const int*>();
+ test_equal<int*, volatile int*>();
+ test_equal<int*, const volatile int*>();
+ test_equal<const int*>();
+ test_equal<const int*, volatile int*>();
+ test_equal<const int*, const volatile int*>();
+ test_equal<volatile int*>();
+ test_equal<volatile int*, const volatile int*>();
+ test_equal<const volatile int*>();
#if TEST_STD_VER > 17
static_assert(test_constexpr());
More information about the libcxx-commits
mailing list