Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@cpplearner
Copy link
Contributor

@cpplearner cpplearner commented Jan 30, 2024

Mostly tiny adjustments to better match the standard.

Also implements LWG-3894 "generator::promise_type::yield_value(ranges::elements_of<Rng, Alloc>) should not be noexcept".

Works towards #2936.

@cpplearner cpplearner requested a review from a team as a code owner January 30, 2024 10:56
@StephanTLavavej StephanTLavavej added bug Something isn't working generator C++23 generator labels Jan 30, 2024
@StephanTLavavej StephanTLavavej self-assigned this Jan 30, 2024
}

_NODISCARD _Ref operator*() const noexcept {
_NODISCARD _Ref operator*() const noexcept(is_nothrow_copy_constructible_v<_Ref>) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is constructing, but IIRC not necessarily copy constructing, a _Ref. Should this be is_nothrow_constructible_v<_Ref, decltype(*_Coro.promise()._Top.promise()._Ptr)>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the condition needs to be noexcept(static_cast<_Ref>(*_Coro.promise()._Top.promise()._Ptr)).

If _Ref is an rvalue reference, this is a cast from lvalue to rvalue reference. Such a cast is non-throwing IIUC, but is_nothrow_constructible_v is false.

The standard says noexcept(is_nothrow_copy_constructible_v<reference>), which also needs to be fixed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On further thought, I believe the logic here is "If _Ref is a reference type, this function doesn't throw, which is consistent with is_nothrow_copy_constructible_v<_Ref>. If it's not a reference type, it must be a (cv-unqualified?) object type, and _Ptr is a pointer to (const?) _Ref so the static_cast expression in fact does copy a _Ref."

What we've merged here is correct, but we should nonetheless change it in a followup to obviously agree with the Standard wording.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_nothrow_copy_constructible_v<_Ref> is correct if:

  • _Ref is an lvalue reference type.
    • In this case, the function does not throw, and is_nothrow_copy_constructible_v<_Ref> is true.
  • _Ref is an object type.
    • In this case, is_nothrow_copy_constructible_v<_Ref> is the right condition.

is_nothrow_copy_constructible_v<_Ref> is not correct if:

  • _Ref is an rvalue reference type.

In this case, the function does not throw, but is_nothrow_copy_constructible_v<_Ref> is false, because,

  • is_nothrow_copy_constructible_v<_Ref> is equivalent to is_nothrow_constructible_v<_Ref, const _Ref&>.
  • When _Ref is A&& for some object type A, const _Ref& is A&.
  • is_constructible_v<A&&, A&> is false, and so is is_nothrow_constructible_v<A&&, A&>.

So I believe that we should not follow the standard wording. We need to fix it.


_NODISCARD auto yield_value(const remove_reference_t<_Yielded>& _Val) noexcept(
is_nothrow_constructible_v<remove_cvref_t<_Yielded>, const remove_reference_t<_Yielded>&>)
is_nothrow_constructible_v<remove_cvref_t<_Yielded>, const remove_reference_t<_Yielded>&>) /* strengthened */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stylistic nitpick: We use /* strengthened */ when it's embedded in a line (especially before an opening brace), but the following requires will always be clang-formatted on a new line, so this should ideally be a C++ comment // strengthened. Not worth resetting testing though.

Comment on lines +380 to +381
_NODISCARD_FRIEND bool operator==(const _Gen_iter& _It, default_sentinel_t) noexcept /* strengthened */
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another stylistic nitpick: There's enough room for the brace here to be attached; clang-format exhibits "sticky" behavior and will preserve it. Also not worth resetting testing for this PR.

@StephanTLavavej StephanTLavavej removed their assignment Jan 31, 2024
@StephanTLavavej StephanTLavavej merged commit fb6a4cb into microsoft:feature/generator Jan 31, 2024
@StephanTLavavej
Copy link
Member

Thanks! Had a couple of formatting nitpicks that can be addressed in followup PRs, but the functional changes all look great. 😻

@cpplearner cpplearner deleted the patch-1 branch January 31, 2024 14:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working generator C++23 generator

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants