This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.

3880. Clarify operator+= complexity for {chunk,stride}_view::iterator

Section: 26.7.29.7 [range.chunk.fwd.iter], 26.7.32.3 [range.stride.iterator] Status: C++23 Submitter: Tim Song Opened: 2023-02-09 Last modified: 2023-11-22

Priority: Not Prioritized

View all issues with C++23 status.

Discussion:

The intent was that the precondition allows the call to ranges::advance, which otherwise would have time linear in the argument of operator+=, to actually be implemented using operator+= or equivalent for all but the last step. This is at best very non-obvious and should be clarified.

[Issaquah 2023-02-10; LWG issue processing]

Move to Immediate for C++23

[2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Immediate → WP.]

Proposed resolution:

This wording is relative to N4928.

  1. Modify 26.7.29.7 [range.chunk.fwd.iter] p13 as indicated:

    constexpr iterator& operator+=(difference_type x)
      requires random_access_range<Base>;
    

    -12- Preconditions: If x is positive, ranges::distance(current_, end_) > n_ * (x - 1) is true.

    [Note 1: If x is negative, the Effects paragraph implies a precondition. — end note]

    -13- Effects: Equivalent to:

    if (x > 0) {
      ranges::advance(current_, n_ * (x - 1));
      missing_ = ranges::advance(current_, n_ * x, end_);
    } else if (x < 0) {
      ranges::advance(current_, n_ * x + missing_);
      missing_ = 0;
    }
    return *this;
    
  2. Modify 26.7.32.3 [range.stride.iterator] p14 as indicated:

    constexpr iterator& operator+=(difference_type n) requires random_access_range<Base>;
    

    -13- Preconditions: If n is positive, ranges::distance(current_, end_) > stride_ * (n - 1) is true.

    [Note 1: If n is negative, the Effects paragraph implies a precondition. — end note]

    -14- Effects: Equivalent to:

    if (n > 0) {
      ranges::advance(current_, stride_ * (n - 1));
      missing_ = ranges::advance(current_, stride_ * n, end_);
    } else if (n < 0) {
      ranges::advance(current_, stride_ * n + missing_);
      missing_ = 0;
    }
    return *this;