Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<ranges>: stride_view::iterator::operator+= could have O(N) complexity #2995

Closed
CaseyCarter opened this issue Aug 5, 2022 · 4 comments · Fixed by #3554
Closed

<ranges>: stride_view::iterator::operator+= could have O(N) complexity #2995

CaseyCarter opened this issue Aug 5, 2022 · 4 comments · Fixed by #3554
Labels
fixed Something works now, yay! ranges C++20/23 ranges

Comments

@CaseyCarter
Copy link
Member

CaseyCarter commented Aug 5, 2022

If the iterator and sentinel types of the underlying view type don't model sized_sentinel_for, the ranges::advance call depicted in the "Effects: Equivalent to" code:

if (n > 0) {
  missing_ = ranges::advance(current_, stride_ * n, end_);
}

has O(n) complexity. However, all operations on conforming random-access iterators must have O(1) complexity. This can perhaps be fixed by advancing the iterator in two steps:

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

Which has complexity O(stride_). (Admittedly icky, especially when stride_ is near n.)

Alternatively, we could additionally require sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>> for iterator to model random_access, which would ensure that the problematic advance call is O(1).

@CaseyCarter CaseyCarter added LWG issue needed A wording defect that should be submitted to LWG as a new issue ranges C++20/23 ranges labels Aug 5, 2022
@CaseyCarter
Copy link
Member Author

@tcanens @cjdb ^^^

@timsong-cpp
Copy link
Contributor

The first fix sounds good to me (and we'll need to fix this for chunk too).

I don't think the O(stride_) complexity is a problem - that's no different from operator++.

@CaseyCarter CaseyCarter changed the title <ranges>: stride_view::iterator::operator+= could have O(N) complexity <ranges>: stride_view::iterator::operator+= could have O(N) complexity Aug 9, 2022
CaseyCarter added a commit to CaseyCarter/STL that referenced this issue Aug 10, 2022
…-=)` in O(1)

Speculatively implements what will be the proposed resolution of an LWG issue filed per microsoftGH-2995 once the new working draft is out with `stride_view` and `chunk_view`. Also avoid checking the precondition when it can't be done in O(1).

Drive-by:
* inline `ranges::advance(i, n)` since it's simply `i += n` for random-access iterators
* check for overflow of `-n` when calling `*this += -n` in `operator-=`

Partially addresses microsoft#2995
@CaseyCarter CaseyCarter added the blocked on WP Waiting for a new Working Paper label Aug 10, 2022
@CaseyCarter
Copy link
Member Author

LWG isn't really equipped to track issues in things that don't appear yet in a working draft.

@hewillk
Copy link
Contributor

hewillk commented Nov 8, 2023

LWG isn't really equipped to track issues in things that don't appear yet in a working draft.

Maybe now is the time to submit an LWG?
This is LWG 3880.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed Something works now, yay! ranges C++20/23 ranges
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants