diff --git a/libcxx/include/__algorithm/adjacent_find.h b/libcxx/include/__algorithm/adjacent_find.h --- a/libcxx/include/__algorithm/adjacent_find.h +++ b/libcxx/include/__algorithm/adjacent_find.h @@ -45,8 +45,7 @@ template _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 --- 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, but can't because: -// * That only works with C++14 and later, and -// * We haven't included here. -template -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 -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 -struct __equal_to -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 - bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;} -}; - -template -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 + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _T1& __x, const _T2& __y) const { + return __x == __y; + } }; template diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h --- a/libcxx/include/__algorithm/equal.h +++ b/libcxx/include/__algorithm/equal.h @@ -33,9 +33,7 @@ template _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 @@ template _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 --- a/libcxx/include/__algorithm/find_end.h +++ b/libcxx/include/__algorithm/find_end.h @@ -219,9 +219,7 @@ _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 --- a/libcxx/include/__algorithm/find_first_of.h +++ b/libcxx/include/__algorithm/find_first_of.h @@ -44,9 +44,7 @@ template _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 --- a/libcxx/include/__algorithm/is_permutation.h +++ b/libcxx/include/__algorithm/is_permutation.h @@ -199,24 +199,23 @@ template _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 -_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 --- a/libcxx/include/__algorithm/mismatch.h +++ b/libcxx/include/__algorithm/mismatch.h @@ -35,9 +35,7 @@ _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 @@ _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 --- a/libcxx/include/__algorithm/search.h +++ b/libcxx/include/__algorithm/search.h @@ -184,9 +184,7 @@ _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 --- a/libcxx/include/__algorithm/search_n.h +++ b/libcxx/include/__algorithm/search_n.h @@ -173,8 +173,7 @@ template _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 --- a/libcxx/include/__algorithm/unique.h +++ b/libcxx/include/__algorithm/unique.h @@ -51,8 +51,7 @@ template _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 --- a/libcxx/include/__algorithm/unique_copy.h +++ b/libcxx/include/__algorithm/unique_copy.h @@ -114,8 +114,7 @@ template 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 --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -845,7 +845,7 @@ __remove_return_type remove(const value_type& __v); template __remove_return_type remove_if(_Predicate __pred); _LIBCPP_INLINE_VISIBILITY - __remove_return_type unique() {return unique(__equal_to());} + __remove_return_type unique() { return unique(__equal_to()); } template __remove_return_type unique(_BinaryPredicate __binary_pred); #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/include/list b/libcxx/include/list --- a/libcxx/include/list +++ b/libcxx/include/list @@ -1063,7 +1063,7 @@ __remove_return_type remove(const value_type& __x); template __remove_return_type remove_if(_Pred __pred); _LIBCPP_INLINE_VISIBILITY - __remove_return_type unique() { return unique(__equal_to()); } + __remove_return_type unique() { return unique(__equal_to()); } template __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 --- 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 +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(T1(a), T1(a + s), T2(a))); + assert(std::equal(T2(a), T2(a + s), T1(a))); + assert(!std::equal(T1(a), T1(a + s), T2(b))); + +#if TEST_STD_VER >= 14 + assert(std::equal(T1(a), T1(a + s), T2(a), T2(a + s))); + assert(std::equal(T2(a), T2(a + s), T1(a), T1(a + s))); + assert(!std::equal(T1(a), T1(a + s), T2(a), T2(a + s - 1))); + assert(!std::equal(T1(a), T1(a + s), T2(b), T2(b + s))); +#endif +} + #if TEST_STD_VER > 17 TEST_CONSTEXPR bool test_constexpr() { int ia[] = {1, 3, 6, 7}; @@ -46,44 +64,23 @@ 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(ia), - cpp17_input_iterator(ia+s), - cpp17_input_iterator(ia))); + test_equal>(); + #if TEST_STD_VER >= 14 - assert(std::equal(cpp17_input_iterator(ia), - cpp17_input_iterator(ia+s), - cpp17_input_iterator(ia), - cpp17_input_iterator(ia+s))); - assert(std::equal(random_access_iterator(ia), - random_access_iterator(ia+s), - random_access_iterator(ia), - random_access_iterator(ia+s))); + test_equal>(); #endif - assert(!std::equal(cpp17_input_iterator(ia), - cpp17_input_iterator(ia+s), - cpp17_input_iterator(ib))); -#if TEST_STD_VER >= 14 - assert(!std::equal(cpp17_input_iterator(ia), - cpp17_input_iterator(ia+s), - cpp17_input_iterator(ib), - cpp17_input_iterator(ib+s))); - assert(!std::equal(random_access_iterator(ia), - random_access_iterator(ia+s), - random_access_iterator(ib), - random_access_iterator(ib+s))); - assert(!std::equal(cpp17_input_iterator(ia), - cpp17_input_iterator(ia+s), - cpp17_input_iterator(ia), - cpp17_input_iterator(ia+s-1))); - assert(!std::equal(random_access_iterator(ia), - random_access_iterator(ia+s), - random_access_iterator(ia), - random_access_iterator(ia+s-1))); -#endif + // Test all combinations of cv-qualifiers: + test_equal(); + test_equal(); + test_equal(); + test_equal(); + test_equal(); + test_equal(); + test_equal(); + test_equal(); + test_equal(); + test_equal(); #if TEST_STD_VER > 17 static_assert(test_constexpr());