35 : m_value(
nullptr), m_exception(
nullptr), m_root(this), m_parentOrLeaf(this) {}
51 m_value = std::addressof(value);
56 m_value = std::addressof(value);
61 return yield_value(generator);
66 awaitable(
promise_type* childPromise) : m_childPromise(childPromise) {}
68 bool await_ready()
noexcept {
return this->m_childPromise ==
nullptr; }
70 void await_suspend(std::coroutine_handle<promise_type>)
noexcept {}
73 if (this->m_childPromise !=
nullptr) {
74 this->m_childPromise->throw_if_exception();
82 if (generator.m_promise !=
nullptr) {
83 m_root->m_parentOrLeaf = generator.m_promise;
84 generator.m_promise->m_root = m_root;
85 generator.m_promise->m_parentOrLeaf =
this;
86 generator.m_promise->resume();
88 if (!generator.m_promise->is_complete()) {
89 return awaitable{generator.m_promise};
92 m_root->m_parentOrLeaf =
this;
95 return awaitable{
nullptr};
101 std::coroutine_handle<promise_type>::from_promise(*this).destroy();
105 if (m_exception !=
nullptr) {
106 std::rethrow_exception(std::move(m_exception));
111 return std::coroutine_handle<promise_type>::from_promise(*this).done();
115 assert(
this == m_root);
116 assert(!is_complete());
117 return *m_parentOrLeaf->m_value;
121 assert(!m_parentOrLeaf->is_complete());
123 m_parentOrLeaf->resume();
125 while (m_parentOrLeaf !=
this && m_parentOrLeaf->is_complete()) {
126 m_parentOrLeaf = m_parentOrLeaf->m_parentOrLeaf;
127 m_parentOrLeaf->resume();
132 void resume() noexcept {
133 std::coroutine_handle<promise_type>::from_promise(*this).resume();
137 std::exception_ptr m_exception;
138 promise_type* m_root;
139 promise_type* m_parentOrLeaf;
145 : m_promise(std::exchange(other.m_promise,
nullptr)) {}
148 if (
this != &other) {
149 if (m_promise !=
nullptr) {
150 m_promise->destroy();
152 m_promise = std::exchange(other.m_promise,
nullptr);
161 if (m_promise !=
nullptr) {
162 m_promise->destroy();
171 using reference = std::conditional_t<std::is_reference_v<T>, T, T&>;
179 return m_promise == other.m_promise;
183 return m_promise != other.m_promise;
187 assert(m_promise !=
nullptr);
190 if (m_promise->is_complete()) {
191 auto* temp = m_promise;
193 temp->throw_if_exception();
202 assert(m_promise !=
nullptr);
203 return static_cast<reference>(m_promise->value());
213 if (m_promise !=
nullptr) {
215 if (!m_promise->is_complete()) {
219 m_promise->throw_if_exception();
233 : m_promise(&h.promise()) {}
235 promise_type* m_promise;
Definition recursive_gen.hpp:166
iterator() noexcept
Definition recursive_gen.hpp:174
bool operator==(const iterator &other) const noexcept
Definition recursive_gen.hpp:178
iterator(promise_type *promise) noexcept
Definition recursive_gen.hpp:176
bool operator!=(const iterator &other) const noexcept
Definition recursive_gen.hpp:182
std::add_pointer_t< T > pointer
Definition recursive_gen.hpp:172
std::ptrdiff_t difference_type
Definition recursive_gen.hpp:169
reference operator*() const noexcept
Definition recursive_gen.hpp:201
iterator & operator++()
Definition recursive_gen.hpp:186
std::input_iterator_tag iterator_category
Definition recursive_gen.hpp:168
std::conditional_t< std::is_reference_v< T >, T, T & > reference
Definition recursive_gen.hpp:171
pointer operator->() const noexcept
Definition recursive_gen.hpp:206
std::remove_reference_t< T > value_type
Definition recursive_gen.hpp:170
void operator++(int)
Definition recursive_gen.hpp:199
Definition recursive_gen.hpp:32
std::suspend_always yield_value(T &value) noexcept
Definition recursive_gen.hpp:50
std::suspend_always yield_value(T &&value) noexcept
Definition recursive_gen.hpp:55
void pull() noexcept
Definition recursive_gen.hpp:120
bool is_complete() noexcept
Definition recursive_gen.hpp:110
promise_type(const promise_type &)=delete
RecursiveGenerator get_return_object() noexcept
Definition recursive_gen.hpp:40
std::suspend_always final_suspend() noexcept
Definition recursive_gen.hpp:45
void unhandled_exception() noexcept
Definition recursive_gen.hpp:48
std::suspend_never await_transform(U &&)=delete
void return_void() noexcept
Definition recursive_gen.hpp:46
promise_type() noexcept
Definition recursive_gen.hpp:34
void destroy() noexcept
Definition recursive_gen.hpp:100
std::suspend_always initial_suspend() noexcept
Definition recursive_gen.hpp:44
void throw_if_exception()
Definition recursive_gen.hpp:104
promise_type(promise_type &&)=delete
T & value() noexcept
Definition recursive_gen.hpp:114
auto yield_value(RecursiveGenerator &generator) noexcept
Definition recursive_gen.hpp:64
auto yield_value(RecursiveGenerator &&generator) noexcept
Definition recursive_gen.hpp:60
Recursive generator using C++20 coroutines with symmetric transfer.
Definition recursive_gen.hpp:30
RecursiveGenerator & operator=(RecursiveGenerator &&other) noexcept
Definition recursive_gen.hpp:147
RecursiveGenerator() noexcept
Definition recursive_gen.hpp:142
RecursiveGenerator(RecursiveGenerator &&other) noexcept
Definition recursive_gen.hpp:144
iterator begin()
Definition recursive_gen.hpp:212
~RecursiveGenerator()
Definition recursive_gen.hpp:160
RecursiveGenerator & operator=(const RecursiveGenerator &)=delete
void swap(RecursiveGenerator &other) noexcept
Definition recursive_gen.hpp:227
iterator end() noexcept
Definition recursive_gen.hpp:225
RecursiveGenerator(const RecursiveGenerator &)=delete
Python-like utilities and data structures for C++.
Definition dict.hpp:18
void swap(RecursiveGenerator< T > &a, RecursiveGenerator< T > &b) noexcept
Definition recursive_gen.hpp:238