20 std::add_pointer_t<yielded> ptr;
21 std::exception_ptr exception;
25 std::suspend_always initial_suspend()
noexcept {
return {}; }
27 std::suspend_always final_suspend()
noexcept {
return {}; }
29 void unhandled_exception()
noexcept { exception = std::current_exception(); }
33 std::rethrow_exception(exception);
36 std::suspend_always yield_value(yielded val)
noexcept {
37 ptr = std::addressof(val);
40 auto yield_value(std::remove_reference_t<yielded>
const& lval)
41 requires std::is_rvalue_reference_v<yielded>
42 && std::constructible_from<std::remove_cvref_t<yielded>, std::remove_reference_t<yielded>
const&>
45 std::remove_cvref_t<yielded> storage;
46 constexpr YieldCopied(std::remove_reference_t<yielded>
const& v) : storage(v) {}
47 constexpr bool await_ready()
const noexcept {
return false; }
48 constexpr void await_suspend(std::coroutine_handle<promise_type> h)
noexcept {
49 h.promise().ptr = std::addressof(storage);
51 constexpr void await_resume()
const noexcept {}
53 return YieldCopied{lval};
55 void return_void()
noexcept {}
58 U&& await_transform(U&&) =
delete;
62 using iterator_category = std::input_iterator_tag;
63 using difference_type = ptrdiff_t;
64 using value_type = Generator::value;
65 using reference = Generator::reference;
66 using pointer = std::add_pointer_t<yielded>;
68 std::coroutine_handle<promise_type> handle =
nullptr;
71 explicit iterator(std::coroutine_handle<promise_type> handle) noexcept : handle(handle) {}
76 std::exchange(handle,
nullptr).promise().rethrow();
82 void operator++(
int) { ++*
this; }
84 [[nodiscard]]
bool operator==(
iterator const& other)
const noexcept {
return handle == other.handle; }
86 [[nodiscard]] reference operator*()
const noexcept {
return static_cast<reference
>(*handle.promise().ptr); }
88 [[nodiscard]] pointer operator->()
const noexcept {
return handle.promise().ptr; }