ORIGINAL
Loading...
Searching...
No Matches
coroutines.h
Go to the documentation of this file.
1#ifndef ORIGINAL_COROUTINES_H
2#define ORIGINAL_COROUTINES_H
3#include "optional.h"
4#include <coroutine>
5#include <exception>
6
30namespace original {
37 class coroutine {
38 public:
56 template<typename TYPE>
57 class generator {
64 struct promise_type {
65 bool initial_staus = false;
66 alternative<TYPE> value_;
67 std::exception_ptr e_;
68
73 generator get_return_object();
74
80 static std::suspend_always initial_suspend();
81
87 static std::suspend_always final_suspend() noexcept;
88
92 static void return_void();
93
100 std::suspend_always yield_value(TYPE value);
101
105 void unhandled_exception();
106
111 void rethrow_if_exception() const;
112 };
113
125 class iterator {
126 generator* gen_;
127 bool end_;
128
132 iterator();
133
138 explicit iterator(generator* gen);
139 public:
140 friend coroutine;
141
147 iterator& operator++();
148
154 TYPE operator*();
155
161 bool operator!=(const iterator& other) const;
162
168 bool operator==(const iterator& other) const;
169 };
170
171 using handle = std::coroutine_handle<promise_type>;
172
173 handle handle_;
174
175 public:
178
179 generator(const generator&) = delete;
180 generator& operator=(const generator&) = delete;
181
187 generator(generator&& other) noexcept;
188
195 generator& operator=(generator&& other) noexcept;
196
197 generator() = default;
198
203 explicit generator(handle h);
204
210 iterator begin();
211
216 static iterator end();
217
222 [[nodiscard]] bool launched() const;
223
228 [[nodiscard]] bool hasNext() const;
229
235 [[nodiscard]] alternative<TYPE> peek() const;
236
243
248 ~generator();
249 };
250 };
251}
252
253template <typename TYPE>
256{
257 return generator{handle::from_promise(*this)};
258}
259
260template <typename TYPE>
262{
263 return std::suspend_always{};
264}
265
266template <typename TYPE>
268{
269 return std::suspend_always{};
270}
271
272template <typename TYPE>
274
275template <typename TYPE>
277{
278 if (!this->initial_staus) {
279 this->initial_staus = true;
280 }
281 this->value_ = std::move(value);
282 return std::suspend_always{};
283}
284
285template <typename TYPE>
287{
288 this->e_ = std::current_exception();
289}
290
291template <typename TYPE>
293{
294 if (this->e_)
295 std::rethrow_exception(this->e_);
296}
297
298template <typename TYPE>
300
301template <typename TYPE>
302original::coroutine::generator<TYPE>::iterator::iterator(generator* gen) : gen_(gen), end_(false)
303{
304 if (!this->gen_) {
305 this->end_ = true;
306 return;
307 }
308 ++*this;
309}
310
311template <typename TYPE>
314{
315 if (this->end_)
316 return *this;
317 if (auto gen_next = this->gen_->next(); !gen_next) {
318 this->end_ = true;
319 }
320 return *this;
321}
322
323template <typename TYPE>
325{
326 if (this->end_)
327 throw nullPointerError("Dereferencing end iterator");
328 return *this->gen_->peek();
329}
330
331template <typename TYPE>
333{
334 return !(*this == other);
335}
336
337template <typename TYPE>
339{
340 if (this->end_ && other.end_)
341 return true;
342 if (this->end_ != other.end_)
343 return false;
344 return this->gen_ == other.gen_;
345}
346
347template <typename TYPE>
349{
350 this->handle_ = other.handle_;
351 other.handle_ = nullptr;
352}
353
354template <typename TYPE>
357{
358 if (this == &other) {
359 return *this;
360 }
361
362 if (this->handle_) {
363 this->handle_.destroy();
364 }
365
366 this->handle_ = other.handle_;
367 other.handle_ = nullptr;
368 return *this;
369}
370
371template <typename TYPE>
373
374template <typename TYPE>
377{
378 return iterator{this};
379}
380
381template <typename TYPE>
384{
385 return iterator{};
386}
387
388template <typename TYPE>
390{
391 return this->handle_.promise().initial_staus;
392}
393
394template <typename TYPE>
396{
397 return this->handle_ && !this->handle_.done();
398}
399
400template <typename TYPE>
402{
403 return this->handle_.promise().value_;
404}
405
406template <typename TYPE>
409{
410 if (!this->hasNext())
411 return alternative<TYPE>{};
412
413 this->handle_.resume();
414 this->handle_.promise().rethrow_if_exception();
415
416 if (!this->hasNext())
417 return alternative<TYPE>{};
418
419 return this->handle_.promise().value_;
420}
421
422template <typename TYPE>
424{
425 if (this->handle_)
426 this->handle_.destroy();
427}
428
429#endif //ORIGINAL_COROUTINES_H
Lazy sequence generator using C++20 coroutines.
Definition coroutines.h:57
iterator begin()
Gets begin iterator for range-based operations.
Definition coroutines.h:376
generator(const generator &)=delete
Copy constructor deleted.
~generator()
Destructor cleans up coroutine resources.
Definition coroutines.h:423
generator()=default
Default constructor creates empty generator.
generator & operator=(const generator &)=delete
Copy assignment deleted.
promise_type promise_type
Promise type for coroutine protocol.
Definition coroutines.h:176
alternative< TYPE > peek() const
Peeks at current value without advancing.
Definition coroutines.h:401
bool hasNext() const
Checks if generator has more values.
Definition coroutines.h:395
bool launched() const
Checks if coroutine has been launched.
Definition coroutines.h:389
static iterator end()
Gets end iterator for range-based operations.
Definition coroutines.h:383
iterator iterator
Iterator type for range operations.
Definition coroutines.h:177
alternative< TYPE > next()
Advances generator and gets next value.
Definition coroutines.h:408
Namespace for coroutine-related utilities and generator implementation.
Definition coroutines.h:37
Unique ownership smart pointer with move semantics.
Definition ownerPtr.h:37
Main namespace for the project Original.
Definition algorithms.h:21
time::duration operator*(const time::duration &d, time::time_val_type factor)
Definition zeit.h:1319
bool operator!=(const autoPtr< T, DER, DEL > &ptr, const std::nullptr_t &null)
Inequality comparison with nullptr.
Definition autoPtr.h:755
bool operator==(const autoPtr< T, DER, DEL > &ptr, const std::nullptr_t &null)
Equality comparison with nullptr.
Definition autoPtr.h:750
Standard namespace extensions for original::alternative.
Definition allocator.h:351
Type-safe optional value container.