On Fri, Sep 18, 2026 at 5:08 PM Tomasz Kaminski <[email protected]> wrote:
> > > On Fri, Sep 18, 2026 at 5:02 PM Jonathan Wakely <[email protected]> > wrote: > >> On Fri, 18 Sept 2026 at 15:50, Tomasz Kamiński <[email protected]> >> wrote: >> > >> > The checks against _M_current being negive were disabled for cases where >> > _Bound denotes unreachable_sentinel_t. However, _M_current has ptrdiff_t >> > type in that case, and this check are as meaningfull are for integer >> bound. >> >> The standard seems to suggest that it's OK to pass a negative bound >> for an unreachable sentinel. >> >> Preconditions: If Bound is not unreachable_sentinel_t, b ≥ 0. >> > If you mean this one: https://eel.is/c++draft/range.repeat#iterator-2 > It's an exposition-only private constructor, and a negative bound is never > passed to it as you would hit UB in constructors: > https://eel.is/c++draft/range.repeat#view-1 > Ah OK, that is everywhere, so yes, it seems that for unreachable_boudn index can go negative. I am not sure why there is a difference; specifically, why going before begin is UB only if you have specified end. But I agree; this patch is non-conforming. > >> This change would cause assertions for the code that isn't forbidden >> by the standard. Or am I missing something? >> >> >> > >> > libstdc++-v3/ChangeLog: >> > >> > * include/std/ranges (repeat_view::_Iterator::_Iterator) >> > (repeat_view::_Iterator::operator--) >> > (repeat_view::_Iterator::operator+=) >> > (repeat_view::_Iterator::operator-=): Unconditionally assert >> > on _M_current having non-negative value. >> > --- >> > Noticed that when working on extracting _Repeat_iterator (that I >> > templated with _IndexType). Worth to be separate. >> > >> > Testing on x86_64-linux. *repeat* view passed with all standard >> > modes, debug and assertions. OK for trunk? >> > >> > libstdc++-v3/include/std/ranges | 14 ++++---------- >> > 1 file changed, 4 insertions(+), 10 deletions(-) >> > >> > diff --git a/libstdc++-v3/include/std/ranges >> b/libstdc++-v3/include/std/ranges >> > index 1c0991cae13..a0ce157d4f2 100644 >> > --- a/libstdc++-v3/include/std/ranges >> > +++ b/libstdc++-v3/include/std/ranges >> > @@ -8075,10 +8075,7 @@ namespace views::__adaptor >> > constexpr explicit >> > _Iterator(const _Tp* __value, __index_type __bound = >> __index_type()) >> > : _M_value(__value), _M_current(__bound) >> > - { >> > - if constexpr (!same_as<_Bound, unreachable_sentinel_t>) >> > - __glibcxx_assert(__bound >= 0); >> > - } >> > + { __glibcxx_assert(__bound >= 0); } >> > >> > friend repeat_view; >> > >> > @@ -8112,8 +8109,7 @@ namespace views::__adaptor >> > constexpr _Iterator& >> > operator--() >> > { >> > - if constexpr (!same_as<_Bound, unreachable_sentinel_t>) >> > - __glibcxx_assert(_M_current > 0); >> > + __glibcxx_assert(_M_current > 0); >> > --_M_current; >> > return *this; >> > } >> > @@ -8129,8 +8125,7 @@ namespace views::__adaptor >> > constexpr _Iterator& >> > operator+=(difference_type __n) >> > { >> > - if constexpr (!same_as<_Bound, unreachable_sentinel_t>) >> > - __glibcxx_assert(_M_current + __n >= 0); >> > + __glibcxx_assert(_M_current + __n >= 0); >> > _M_current += __n; >> > return *this; >> > } >> > @@ -8138,8 +8133,7 @@ namespace views::__adaptor >> > constexpr _Iterator& >> > operator-=(difference_type __n) >> > { >> > - if constexpr (!same_as<_Bound, unreachable_sentinel_t>) >> > - __glibcxx_assert(_M_current - __n >= 0); >> > + __glibcxx_assert(_M_current - __n >= 0); >> > _M_current -= __n; >> > return *this; >> > } >> > -- >> > 2.55.0 >> > >> >>
