[gcc(refs/users/ppalka/heads/libstdcxx-constrained-algos)] Add better implementation of ranges::find_end for bidirectional iterators
Patrick Palka
ppalka@gcc.gnu.org
Fri Jan 17 21:44:00 GMT 2020
https://gcc.gnu.org/g:ecb9da237193936fcbbf2a0321377b005d3df0a1
commit ecb9da237193936fcbbf2a0321377b005d3df0a1
Author: Patrick Palka <ppalka@gcc.gnu.org>
Date: Wed Jan 15 12:20:25 2020 -0500
Add better implementation of ranges::find_end for bidirectional iterators
Diff:
---
libstdc++-v3/include/bits/ranges_algo.h | 39 ++++++++++++++++++++++++++++++---
1 file changed, 36 insertions(+), 3 deletions(-)
diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
index 965fe85..b89f19a 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -424,9 +424,9 @@ namespace ranges
class _Proj1 = identity, class _Proj2 = identity>
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
constexpr subrange<_Iter1>
- find_end(_Iter1 __first1, _Sent1 __last1,
- _Iter2 __first2, _Sent2 __last2,
- _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
+ __find_end(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
{
if (__first2 == __last2)
return {__last1, __last1};
@@ -452,6 +452,39 @@ namespace ranges
}
}
+ template<forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
+ forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
+ class _Pred = ranges::equal_to,
+ class _Proj1 = identity, class _Proj2 = identity>
+ requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
+ constexpr subrange<_Iter1>
+ find_end(_Iter1 __first1, _Sent1 __last1,
+ _Iter2 __first2, _Sent2 __last2,
+ _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
+ {
+ if constexpr (std::bidirectional_iterator<_Iter1>
+ && std::bidirectional_iterator<_Iter2>)
+ {
+ auto __rresult
+ = ranges::search(reverse_iterator<_Iter1>(__last1),
+ reverse_iterator<_Iter1>(__first1),
+ reverse_iterator<_Iter2>(__last2),
+ reverse_iterator<_Iter2>(__first2),
+ std::move(__pred),
+ std::move(__proj1), std::move(__proj2));
+ auto __result_first = ranges::end(__rresult).base();
+ auto __result_last = ranges::begin(__rresult).base();
+ if (__result_last == __first1)
+ return {__last1, __last1};
+ else
+ return {__result_first, __result_last};
+ }
+ else
+ return ranges::__find_end(__first1, __last1, __first2, __last2,
+ std::move(__pred),
+ std::move(__proj1), std::move(__proj2));
+ }
+
template<forward_range _Range1, forward_range _Range2,
class _Pred = ranges::equal_to,
class _Proj1 = identity, class _Proj2 = identity>
More information about the Libstdc++-cvs
mailing list