[gcc r17-2859] libstdc++: Optimize ranges::distance for segmented iterators [PR123211]

Patrick Palka via Gcc-cvs <[email protected]> Fri, 31 Jul 2026 18:57:04 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:15505d012872ddb4c20916c41284e913727b4c80

commit r17-2859-g15505d012872ddb4c20916c41284e913727b4c80
Author: Patrick Palka <[email protected]>
Date:   Fri Jul 31 14:56:29 2026 -0400

    libstdc++: Optimize ranges::distance for segmented iterators [PR123211]
    
    For segmented iterators, ranges::distance is equivalent to the sum of
    ranges::distance of each of its segments.
    
            PR libstdc++/123211
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/ranges_base.h (__distance_fn::operator()): For
            the non-sized-sentinel overload, recursively handle segmented
            iterators via __for_each_segment.
    
    Reviewed-by: Jonathan Wakely <[email protected]>

Diff:
---
 libstdc++-v3/include/bits/ranges_base.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h
index ce1c40fc17f6..2c2b44c1ac6c 100644
--- a/libstdc++-v3/include/bits/ranges_base.h
+++ b/libstdc++-v3/include/bits/ranges_base.h
@@ -994,6 +994,17 @@ namespace ranges
       constexpr iter_difference_t<_It>
       operator()[[nodiscard]](_It __first, _Sent __last) const
       {
+	if constexpr (__segmented_iterator<_It> && same_as<_It, _Sent>)
+	  {
+	    iter_difference_t<_It> __n = 0;
+	    auto __func = [this, &__n](auto __sfirst, auto __slast) {
+	      __n += iter_difference_t<_It>(this->operator()(__sfirst, __slast));
+	      return __slast;
+	    };
+	    std::__for_each_segment(__first, __last, __func);
+	    return __n;
+	  }
+
 	iter_difference_t<_It> __n = 0;
 	while (__first != __last)
 	  {