77 std::exception_ptr exception;
78 std::coroutine_handle<promise_type> parent;
79 std::coroutine_handle<promise_type> root;
86 explicit YieldNested(Generator&& nested_) noexcept : nested(std::move(nested_)) {}
88 [[nodiscard]]
bool await_ready()
const noexcept {
return !nested.handle; }
90 std::coroutine_handle<promise_type> await_suspend(std::coroutine_handle<promise_type> h)
noexcept {
91 auto nestedHandle = nested.handle;
92 nestedInfo.parent = h;
93 if (
auto* info = h.promise().tryGetNestInfo()) {
94 nestedInfo.root = info->root;
99 nestedInfo.root.promise().setTop(nestedHandle);
100 nestedHandle.promise().setNestInfo(std::addressof(nestedInfo));
104 void await_resume() {
105 if (nestedInfo.exception) {
106 std::rethrow_exception(nestedInfo.exception);
111 std::add_pointer_t<yielded> ptr =
nullptr;
113 reinterpret_cast<uintptr_t
>(std::coroutine_handle<promise_type>::from_promise(*this).address());
116 constexpr bool await_ready()
const noexcept {
return false; }
118 constexpr std::coroutine_handle<> await_suspend(std::coroutine_handle<promise_type> h)
noexcept {
119 if (
auto* info = h.promise().tryGetNestInfo()) {
120 info->root.promise().setTop(info->parent);
124 return std::noop_coroutine();
127 constexpr void await_resume()
const noexcept {}
130 Generator get_return_object() noexcept {
return Generator{*
this}; }
132 std::suspend_always initial_suspend() noexcept {
return {}; }
134 FinalAwaiter final_suspend() noexcept {
return {}; }
136 void unhandled_exception() {
137 if (
auto* info = tryGetNestInfo()) {
138 info->exception = std::current_exception();
144 std::suspend_always yield_value(yielded val)
noexcept {
145 ptr = std::addressof(val);
148 auto yield_value(std::remove_reference_t<yielded>
const& lval)
149 requires std::is_rvalue_reference_v<yielded>
150 && std::constructible_from<std::remove_cvref_t<yielded>, std::remove_reference_t<yielded>
const&>
153 std::remove_cvref_t<yielded> storage;
154 constexpr YieldCopied(std::remove_reference_t<yielded>
const& v) : storage(v) {}
155 constexpr bool await_ready() const noexcept {
return false; }
156 constexpr void await_suspend(std::coroutine_handle<promise_type> h)
noexcept {
157 h.promise().ptr = std::addressof(storage);
159 constexpr void await_resume() const noexcept {}
161 return YieldCopied{lval};
165 auto yield_value(ElementsOf<Generator<U>&&> elements)
166 requires std::same_as<typename Generator<U>::yielded, yielded>
172 auto yield_value(ElementsOf<Generator<U>&> elements)
173 requires std::same_as<typename Generator<U>::yielded, yielded>
178 template <
class Range>
179 auto yield_value(ElementsOf<Range>&& elements) {
180 return YieldNested{Generator::makeElementGenerator(std::move(elements))};
182 void return_void() noexcept {}
185 U&& await_transform(U&&) =
delete;
188 [[nodiscard]]
NestInfo* tryGetNestInfo() const noexcept {
189 if ((data & 1U) != 0) {
190 return reinterpret_cast<NestInfo*
>(data ^ 1U);
196 [[nodiscard]] std::coroutine_handle<promise_type> getTop() const noexcept {
197 return std::coroutine_handle<promise_type>::from_address(
reinterpret_cast<void*
>(data));
200 void setNestInfo(
NestInfo* info)
noexcept { data =
reinterpret_cast<uintptr_t
>(info) | 1U; }
202 void setTop(std::coroutine_handle<promise_type> top)
noexcept {
203 data =
reinterpret_cast<uintptr_t
>(top.address());
206 friend struct iterator;
211 using iterator_category = std::input_iterator_tag;
212 using difference_type = ptrdiff_t;
213 using value_type = Generator::value;
214 using reference = Generator::reference;
215 using pointer = std::add_pointer_t<yielded>;
217 std::coroutine_handle<promise_type> handle =
nullptr;
219 iterator() =
default;
220 explicit iterator(std::coroutine_handle<promise_type> handle) noexcept : handle(handle) {}
222 iterator& operator++() {
223 handle.promise().getTop().resume();
231 void operator++(
int) { ++*
this; }
233 [[nodiscard]]
bool operator==(iterator
const& other)
const noexcept {
return handle == other.handle; }
235 [[nodiscard]] reference operator*()
const noexcept {
236 return static_cast<reference
>(*handle.promise().getTop().promise().ptr);
239 [[nodiscard]] pointer operator->()
const noexcept {
return handle.promise().getTop().promise().ptr; }