https://gcc.gnu.org/g:6497b8530c917e2877eb7853f03c7ca64c99c5cb

commit r16-8390-g6497b8530c917e2877eb7853f03c7ca64c99c5cb
Author: Patrick Palka <[email protected]>
Date:   Wed Apr 1 11:34:27 2026 -0400

    libstdc++/ranges: Inline hidden friends' member function helpers
    
    These helpers were needed to work around GCC's historically strict
    interpretation of friendship for hidden friends whereby they did not
    inherit the friends of the containing class.  But this has been relaxed
    in r13-465 which granted hidden friends the same access as any other
    member declaration, and <ranges> additions since then rely on this
    relaxed interpretation.  (Note that Clang also has this relaxed
    interpretation, but MSVC / EDG seem to have the strict interpretation.)
    
    This patch removes these now redundant member functions and inlines
    their logic directly into the respective friend operators, making
    things simpler and more consistent.
    
    libstdc++-v3/ChangeLog:
    
            * include/std/ranges (iota_view::_Sentinel): Remove _M_equal and
            _M_distance_from.  Inline logic into friend operators.
            (basic_istream_view::_Iterator): Remove _M_at_end.  Inline logic
            into operator==.
            (transform_view::_Sentinel): Remove __distance_from and __equal.
            Inline logic into friend operators.
            (join_view::_Sentinel): Remove __equal.  Inline logic into 
operator==.
            (lazy_split_view::_OuterIter): Remove __at_end.  Inline logic into
            operator==.
            (split_view::_Sentinel): Remove _M_equal.  Inline logic into 
operator==.
            (elements_view::_Sentinel): Remove _M_equal and _M_distance_from.
            Inline logic into friend operators.
    
    Reviewed-by: Jonathan Wakely <[email protected]>

Diff:
---
 libstdc++-v3/include/std/ranges | 74 +++++++++--------------------------------
 1 file changed, 16 insertions(+), 58 deletions(-)

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 249cc466db4f..eebb978221f1 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -752,14 +752,6 @@ namespace ranges
       struct _Sentinel
       {
       private:
-       constexpr bool
-       _M_equal(const _Iterator& __x) const
-       { return __x._M_value == _M_bound; }
-
-       constexpr auto
-       _M_distance_from(const _Iterator& __x) const
-       { return _M_bound - __x._M_value; }
-
        _Bound _M_bound = _Bound();
 
       public:
@@ -771,17 +763,17 @@ namespace ranges
 
        friend constexpr bool
        operator==(const _Iterator& __x, const _Sentinel& __y)
-       { return __y._M_equal(__x); }
+       { return __x._M_value == __y._M_bound; }
 
        friend constexpr iter_difference_t<_Winc>
        operator-(const _Iterator& __x, const _Sentinel& __y)
          requires sized_sentinel_for<_Bound, _Winc>
-       { return -__y._M_distance_from(__x); }
+       { return -(__y._M_bound - __x._M_value); }
 
        friend constexpr iter_difference_t<_Winc>
        operator-(const _Sentinel& __x, const _Iterator& __y)
          requires sized_sentinel_for<_Bound, _Winc>
-       { return __x._M_distance_from(__y); }
+       { return __x._M_bound - __y._M_value; }
 
        friend iota_view;
       };
@@ -1006,14 +998,10 @@ namespace views
 
        friend bool
        operator==(const _Iterator& __x, default_sentinel_t)
-       { return __x._M_at_end(); }
+       { return !*__x._M_parent->_M_stream; }
 
       private:
        basic_istream_view* _M_parent;
-
-       bool
-       _M_at_end() const
-       { return !*_M_parent->_M_stream; }
       };
 
       friend _Iterator;
@@ -2246,16 +2234,6 @@ namespace views::__adaptor
          using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
          using _Base = transform_view::_Base<_Const>;
 
-         template<bool _Const2>
-           constexpr auto
-           __distance_from(const _Iterator<_Const2>& __i) const
-           { return _M_end - __i._M_current; }
-
-         template<bool _Const2>
-           constexpr bool
-           __equal(const _Iterator<_Const2>& __i) const
-           { return __i._M_current == _M_end; }
-
          sentinel_t<_Base> _M_end = sentinel_t<_Base>();
 
        public:
@@ -2282,21 +2260,21 @@ namespace views::__adaptor
                       iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
            friend constexpr bool
            operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
-           { return __y.__equal(__x); }
+           { return __x._M_current == __y._M_end; }
 
          template<bool _Const2,
                   typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
            requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
            friend constexpr range_difference_t<_Base2>
            operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
-           { return -__y.__distance_from(__x); }
+           { return -(__y._M_end - __x._M_current); }
 
          template<bool _Const2,
                   typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
            requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
            friend constexpr range_difference_t<_Base2>
            operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
-           { return __y.__distance_from(__x); }
+           { return __y._M_end - __x._M_current; }
 
          friend _Sentinel<!_Const>;
        };
@@ -3300,11 +3278,6 @@ namespace views::__adaptor
          using _Parent = __detail::__maybe_const_t<_Const, join_view>;
          using _Base = join_view::_Base<_Const>;
 
-         template<bool _Const2>
-           constexpr bool
-           __equal(const _Iterator<_Const2>& __i) const
-           { return __i._M_get_outer() == _M_end; }
-
          sentinel_t<_Base> _M_end = sentinel_t<_Base>();
 
        public:
@@ -3326,7 +3299,7 @@ namespace views::__adaptor
                       iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
            friend constexpr bool
            operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
-           { return __y.__equal(__x); }
+           { return __x._M_get_outer() == __y._M_end; }
 
          friend _Sentinel<!_Const>;
        };
@@ -3501,10 +3474,6 @@ namespace views::__adaptor
          using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
          using _Base = lazy_split_view::_Base<_Const>;
 
-         constexpr bool
-         __at_end() const
-         { return __current() == ranges::end(_M_parent->_M_base) && 
!_M_trailing_empty; }
-
          // [range.lazy.split.outer] p1
          //  Many of the following specifications refer to the notional member
          //  current of outer-iterator.  current is equivalent to current_ if
@@ -3657,7 +3626,10 @@ namespace views::__adaptor
 
          friend constexpr bool
          operator==(const _OuterIter& __x, default_sentinel_t)
-         { return __x.__at_end(); };
+         {
+           return __x.__current() == ranges::end(__x._M_parent->_M_base)
+             && !__x._M_trailing_empty;
+         }
 
          friend _OuterIter<!_Const>;
          friend _InnerIter<_Const>;
@@ -4050,10 +4022,6 @@ namespace views::__adaptor
     private:
       sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
 
-      constexpr bool
-      _M_equal(const _Iterator& __x) const
-      { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
-
     public:
       _Sentinel() = default;
 
@@ -4064,7 +4032,7 @@ namespace views::__adaptor
 
       friend constexpr bool
       operator==(const _Iterator& __x, const _Sentinel& __y)
-      { return __y._M_equal(__x); }
+      { return __x._M_cur == __y._M_end && !__x._M_trailing_empty; }
     };
   };
 
@@ -4671,16 +4639,6 @@ namespace views::__adaptor
        struct _Sentinel
        {
        private:
-         template<bool _Const2>
-           constexpr bool
-           _M_equal(const _Iterator<_Const2>& __x) const
-           { return __x._M_current == _M_end; }
-
-         template<bool _Const2>
-           constexpr auto
-           _M_distance_from(const _Iterator<_Const2>& __i) const
-           { return _M_end - __i._M_current; }
-
          using _Base = elements_view::_Base<_Const>;
          sentinel_t<_Base> _M_end = sentinel_t<_Base>();
 
@@ -4708,21 +4666,21 @@ namespace views::__adaptor
                       iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
            friend constexpr bool
            operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
-           { return __y._M_equal(__x); }
+           { return __x._M_current == __y._M_end; }
 
          template<bool _Const2,
                   typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
            requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
            friend constexpr range_difference_t<_Base2>
            operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
-           { return -__y._M_distance_from(__x); }
+           { return -(__y._M_end - __x._M_current); }
 
          template<bool _Const2,
                   typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
            requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
            friend constexpr range_difference_t<_Base2>
            operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
-           { return __x._M_distance_from(__y); }
+           { return __x._M_end - __y._M_current; }
 
          friend _Sentinel<!_Const>;
        };

Reply via email to