[gcc(refs/users/ppalka/heads/libstdcxx-constrained-algos)] Unwrap normal_iterators in ranges::equal
Patrick Palka
ppalka@gcc.gnu.org
Mon Jan 20 15:35:00 GMT 2020
https://gcc.gnu.org/g:eea2d481dbe7670ce8fba27cf45386cc5cdbf9ed
commit eea2d481dbe7670ce8fba27cf45386cc5cdbf9ed
Author: Patrick Palka <ppalka@gcc.gnu.org>
Date: Sun Jan 19 20:16:16 2020 -0500
Unwrap normal_iterators in ranges::equal
Diff:
---
libstdc++-v3/include/bits/ranges_algo.h | 25 ++++++++++++++++++----
.../testsuite/25_algorithms/equal/constrained.cc | 13 ++++++++++-
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
index fd8fd3b..ea76cac2 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -704,8 +704,8 @@ namespace ranges
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
constexpr bool
- equal(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
- _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
+ __equal(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
+ _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
{
// TODO: implement more specializations to at least have parity with
// std::equal.
@@ -721,7 +721,7 @@ namespace ranges
using _ValueType1 = iterator_traits<_Iter1>::value_type;
using _ValueType2 = iterator_traits<_Iter2>::value_type;
- constexpr bool __simple
+ constexpr bool __use_memcmp
= ((is_integral_v<_ValueType1> || is_pointer_v<_ValueType1>)
&& is_same_v<_ValueType1, _ValueType2>
&& is_pointer_v<_Iter1>
@@ -729,7 +729,7 @@ namespace ranges
&& is_same_v<_Pred, ranges::equal_to>
&& is_same_v<_Proj1, identity>
&& is_same_v<_Proj2, identity>);
- if constexpr (__simple)
+ if constexpr (__use_memcmp)
{
if (const size_t __len = (__last1 - __first1))
return !std::__memcmp(__first1, __first2, __len);
@@ -757,6 +757,23 @@ namespace ranges
}
}
+ template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
+ input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
+ typename _Pred = ranges::equal_to,
+ typename _Proj1 = identity, typename _Proj2 = identity>
+ requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
+ constexpr bool
+ equal(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
+ _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
+ {
+ return ranges::__equal(std::__niter_base(__first1),
+ std::__niter_base(__last1),
+ std::__niter_base(__first2),
+ std::__niter_base(__last2),
+ std::move(__pred),
+ std::move(__proj1), std::move(__proj2));
+ }
+
template<input_range _Range1, input_range _Range2,
typename _Pred = ranges::equal_to,
typename _Proj1 = identity, typename _Proj2 = identity>
diff --git a/libstdc++-v3/testsuite/25_algorithms/equal/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/equal/constrained.cc
index cb8f34d..b1f9977 100644
--- a/libstdc++-v3/testsuite/25_algorithms/equal/constrained.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/equal/constrained.cc
@@ -41,7 +41,7 @@ test01()
int w[] = { {1}, {1}, {1}, {1}, {1} };
VERIFY( ranges::equal(w, w+4, w+1, w+5) );
- VERIFY( ranges::equal(w, w+5, w, w+5, std::greater<int>(),
+ VERIFY( ranges::equal(w, w+5, w, w+5, ranges::greater{},
[] (int a) { return a+1; }) );
test_container<int, forward_iterator_wrapper> cx(x), cy(y);
@@ -71,9 +71,20 @@ test02()
static_assert(!ranges::equal(x, y, {}, &X::i, &X::i));
}
+void
+test03()
+{
+ std::vector<int> x = { {2}, {2}, {6}, {8}, {10}, {11} };
+ std::vector<int> y = { {2}, {2}, {6}, {8}, {10}, {11} };
+ std::vector<int> z = { {2}, {2}, {6}, {8}, {10}, {12} };
+ VERIFY( ranges::equal(x, y) );
+ VERIFY( !ranges::equal(x, z) );
+}
+
int
main()
{
test01();
test02();
+ test03();
}
More information about the Libstdc++-cvs
mailing list