60 using value_type = std::remove_reference_t<Result>;
62 using pointer = std::add_pointer_t<value_type>;
101 [[nodiscard]]
constexpr auto initial_suspend()
const noexcept {
return std::suspend_always{}; }
112 auto final_suspend()
noexcept
114 this->m_current_value =
nullptr;
115 return yield_op{this->m_consumer};
126 void unhandled_exception()
noexcept { this->m_exception = std::current_exception(); }
133 constexpr void return_void()
const noexcept {}
146 auto yield_value(value_type& value)
noexcept
148 this->m_current_value = std::addressof(value);
149 return yield_op{this->m_consumer};
165 auto yield_value(std::add_rvalue_reference_t<std::remove_cv_t<value_type>> value)
noexcept
167 this->m_current_value = std::addressof(value);
168 return yield_op{this->m_consumer};
178 [[nodiscard]]
constexpr std::add_lvalue_reference_t<value_type> value()
const noexcept
180 return *this->m_current_value;
188 [[nodiscard]]
constexpr bool finished()
const noexcept {
return this->m_current_value ==
nullptr; }
199 void rethrow_if_unhandled_exception()
201 if (this->m_exception) {
202 std::rethrow_exception(std::move(this->m_exception));
214 void set_consumer(std::coroutine_handle<> consumer)
noexcept { this->m_consumer = consumer; }
218 pointer m_current_value =
nullptr;
220 std::coroutine_handle<> m_consumer;
222 std::exception_ptr m_exception =
nullptr;
237 constexpr explicit yield_op(std::coroutine_handle<> consumer) noexcept : m_consumer(consumer) {}
246 [[nodiscard]]
constexpr bool await_ready()
const noexcept {
return false; }
256 [[nodiscard]]
constexpr auto await_suspend([[maybe_unused]] std::coroutine_handle<> h)
const noexcept
258 return this->m_consumer;
266 constexpr void await_resume()
const noexcept {}
270 std::coroutine_handle<> m_consumer;
308 constexpr advance_op() noexcept : m_promise(
nullptr), m_producer(
nullptr) {}
317 explicit advance_op(std::coroutine_handle<promise_type> producer) noexcept
318 : m_promise(std::addressof(producer.promise())), m_producer(producer)
333 [[nodiscard]]
constexpr bool await_ready()
const noexcept {
return this->m_promise ==
nullptr; }
343 constexpr std::coroutine_handle<> await_suspend(std::coroutine_handle<> consumer)
noexcept
345 this->m_promise->set_consumer(consumer);
346 return this->m_producer;
367 if (this->m_promise ==
nullptr) {
371 if (this->m_promise->finished()) {
372 this->m_promise->rethrow_if_unhandled_exception();
376 return iterator{std::coroutine_handle<promise_type>::from_promise(*this->m_promise)};
383 std::coroutine_handle<> m_producer;
399 using value_type = std::remove_reference_t<Result>;
401 using reference = std::add_lvalue_reference_t<value_type>;
403 using pointer = std::add_pointer_t<value_type>;
412 explicit iterator(std::coroutine_handle<promise_type> coroutine) noexcept : m_coroutine(coroutine) {}
426 if (detail::is_good_handle(this->m_coroutine)) {
427 return advance_op{this->m_coroutine};
444 if (detail::is_good_handle(this->m_coroutine)) [[likely]] {
445 return this->m_coroutine.promise().value();
467 friend bool operator==(
const iterator& it, [[maybe_unused]] std::default_sentinel_t sentinel)
noexcept
469 return !detail::is_good_handle(it.m_coroutine);
485 return this->m_coroutine == other.m_coroutine ||
486 (!detail::is_good_handle(this->m_coroutine) && !detail::is_good_handle(other.m_coroutine));
490 std::coroutine_handle<promise_type> m_coroutine;