[libcxx-commits] [libcxx] [libc++] Add segmented iterator optimization to std::equal (PR #179242)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Feb 24 01:17:09 PST 2026
================
@@ -197,6 +192,58 @@ __equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&,
return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
}
+template <class _InIter1, class _Sent1, class _InIter2, class _Pred, class _Proj1, class _Proj2>
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(
+ _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+#ifndef _LIBCPP_CXX03_LANG
+ if constexpr (__has_random_access_iterator_category<_InIter1>::value &&
+ __has_random_access_iterator_category<_InIter2>::value) {
+ if constexpr (is_same<_InIter1, _Sent1>::value && __is_segmented_iterator_v<_InIter1>) {
+ using __local_iterator_t = typename __segmented_iterator_traits<_InIter1>::__local_iterator;
+ bool __is_equal = true;
+ std::__find_segment_if(__first1, __last1, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
+ if (std::__equal_iter_impl(
+ std::__unwrap_iter(__lfirst), std::__unwrap_iter(__llast), __first2, __pred, __proj1, __proj2)) {
+ __first2 += __llast - __lfirst;
+ return __llast;
+ }
+ __is_equal = false;
+ return __lfirst;
+ });
+ return __is_equal;
+ } else if constexpr (__is_segmented_iterator_v<_InIter2>) {
+ using _Traits = __segmented_iterator_traits<_InIter2>;
+ using _DiffT =
+ typename common_type<__iterator_difference_type<_InIter1>, __iterator_difference_type<_InIter2> >::type;
+
+ if (__first1 == __last1)
+ return true;
+
+ auto __local_first = _Traits::__local(__first2);
+ auto __segment_iterator = _Traits::__segment(__first2);
+
+ while (true) {
+ auto __local_last = _Traits::__end(__segment_iterator);
+ auto __size = std::min<_DiffT>(__local_last - __local_first, __last1 - __first1);
+ if (!std::__equal_iter_impl(
+ __first1, __first1 + __size, std::__unwrap_iter(__local_first), __pred, __proj1, __proj2))
+ return false;
+
+ __first1 += __size;
+ if (__first1 == __last1)
+ return true;
+
+ __local_first = _Traits::__begin(++__segment_iterator);
+ }
----------------
philnik777 wrote:
I'm not convinced this makes it more readable. I'm now looking for the condition with which the unreachable could theoretically be reached to understand why this is unreachable, but that doesn't exist.
https://github.com/llvm/llvm-project/pull/179242
More information about the libcxx-commits
mailing list