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>; };
