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

<xutility>: Generic code cannot call ranges::advance(i, s) #907

Closed
CaseyCarter opened this issue Jun 18, 2020 · 4 comments
Closed

<xutility>: Generic code cannot call ranges::advance(i, s) #907

CaseyCarter opened this issue Jun 18, 2020 · 4 comments
Labels
bug Something isn't working LWG issue needed A wording defect that should be submitted to LWG as a new issue

Comments

@CaseyCarter
Copy link
Member

The specification of the iterator & sentinel overload of ranges::advance reads:

template<input_­or_­output_­iterator I, sentinel_­for<I> S>
  constexpr void ranges::advance(I& i, S bound);
  1. Preconditions: [i, bound) denotes a range.
  2. Effects:
    (4.1) — If I and S model assignable_­from<I&, S>, equivalent to i = std​::​move(bound).
    (4.2) — …

The assignment optimization in 4.1 is just fine for callers with concrete types who can decide whether or not to call advance depending on the semantics of the assignment performed. However, since this assignment operation isn't part of the input_­or_­output_­iterator or sentinel_­for requirements its semantics are unknown for arbitrary types. Effectively, generic code is forbidden to call this overload of advance when assignable_­from<I&, S> is satisfied and non-generic code must tread lightly.

WG21 can correct this problem by either (1) making the assignment operation in question an optional part of the sentinel_for concept with well-defined semantics, or (2) instead requiring same_as<I, S> to trigger the assignment operation in bullet 4.1 above. S is semiregular, so i = std::move(s) is certainly well-formed (and has well-defined semantics thanks to semiregular) when I and S are the same type.

I'll submit an issue to the LWG outlying the above two possible fixes. Until LWG decides how they want this fixed, we should implement the safer option (2) above.

@CaseyCarter CaseyCarter added bug Something isn't working LWG issue needed A wording defect that should be submitted to LWG as a new issue labels Jun 18, 2020
@timsong-cpp
Copy link
Contributor

assignable_­from has its own semantic requirements? And pretty strong ones at that...

Are you thinking of the "satisfied but not modeled" case? I think the common_reference_with should probably root out most unintentional satisfaction?

@CaseyCarter
Copy link
Member Author

Are you thinking of the "satisfied but not modeled" case?

I'm thinking of both satisfied-but-not-modeled and satisfaction-not-computable, the usual suspects that motivate the absence of duck typing in the Standard Library.

I think the common_reference_with should probably root out most unintentional satisfaction?

I agree, and that makes option (1) slightly more attractive. It's even straightforward to specify now that we can say "assignable_from<I&, S> is either modeled or not satisfied".

@frederick-vs-ja
Copy link
Contributor

LWG-3453 has been accepted and discussed in #1446. Perhaps this issue should be closed.

@CaseyCarter
Copy link
Member Author

CaseyCarter commented May 6, 2022

LWG-3453 has been accepted and discussed in #1446. Perhaps this issue should be closed.

Yes, thanks! (I should have closed this when I submitted the LWG issue.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working LWG issue needed A wording defect that should be submitted to LWG as a new issue
Projects
None yet
Development

No branches or pull requests

3 participants