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

Reply via email to