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 {
58 public:
59 struct promise_type;
60 private:
61 using handle = std::coroutine_handle<promise_type>;
62
63 handle handle_;
64
65 public:
72 struct promise_type {
73 bool initial_staus = false;
75 std::exception_ptr e_;
76
82
88 static std::suspend_always initial_suspend();
89
95 static std::suspend_always final_suspend() noexcept;
96
100 static void return_void();
101
109
113 void unhandled_exception();
114
120 };
121
134 generator* gen_;
135 bool end_;
136
140 iterator();
141
146 explicit iterator(generator* gen);
147 public:
148 friend coroutine;
149
155 iterator& operator++();
156
162 TYPE operator*();
163
169 bool operator!=(const iterator& other) const;
170
176 bool operator==(const iterator& other) const;
177 };
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>
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>
380
381template <typename TYPE>
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
Input iterator for generator range-based operations.
Definition coroutines.h:133
TYPE operator*()
Dereferences iterator to get current value.
Definition coroutines.h:324
iterator & operator++()
Advances iterator to next value.
Definition coroutines.h:313
bool operator!=(const iterator &other) const
Checks iterator inequality.
Definition coroutines.h:332
bool operator==(const iterator &other) const
Checks iterator equality.
Definition coroutines.h:338
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.
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
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
Exception for null pointer dereference attempts.
Definition error.h:245
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:1353
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.
Implements the coroutine promise interface for generator.
Definition coroutines.h:72
void rethrow_if_exception() const
Re-throws any captured exception.
Definition coroutines.h:292
static void return_void()
Handles coroutine completion without value.
Definition coroutines.h:273
void unhandled_exception()
Captures exceptions thrown from coroutine.
Definition coroutines.h:286
bool initial_staus
Tracks if coroutine has started execution.
Definition coroutines.h:73
generator get_return_object()
Creates the generator object from this promise.
Definition coroutines.h:255
static std::suspend_always final_suspend() noexcept
Defines final suspension behavior.
Definition coroutines.h:267
static std::suspend_always initial_suspend()
Defines initial suspension behavior.
Definition coroutines.h:261
std::suspend_always yield_value(TYPE value)
Handles value yielding from coroutine.
Definition coroutines.h:276
std::exception_ptr e_
Captured exceptions for propagation.
Definition coroutines.h:75
alternative< TYPE > value_
Storage for the current yielded value.
Definition coroutines.h:74