|
Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
|
Lazy, single-pass sequence of T values produced by a coroutine.
More...
#include <ah-generator.H>
Classes | |
| class | iterator |
| Single-pass input iterator over the yielded sequence. More... | |
| struct | promise_type |
The promise type the compiler instantiates for a coroutine returning Generator<T>. More... | |
Public Types | |
| using | Handle = std::coroutine_handle< promise_type > |
Public Member Functions | |
| Generator () noexcept=default | |
Construct an empty/singular Generator (no coroutine attached). | |
| Generator (Handle h) noexcept | |
Construct from a coroutine handle (internal use by promise_type). | |
| Generator (const Generator &)=delete | |
Deleted: a Generator owns a single coroutine frame, which cannot be duplicated. | |
| Generator & | operator= (const Generator &)=delete |
| Deleted: see the copy constructor. | |
| Generator (Generator &&o) noexcept | |
| Move constructor: transfers coroutine-frame ownership. | |
| Generator & | operator= (Generator &&o) noexcept |
Move assignment: destroys any owned frame, then steals o's. | |
| ~Generator () | |
| Destroys the coroutine frame, if any, unwinding pending local state inside the (possibly still-suspended) coroutine body. | |
| iterator | begin () & |
Begin iterating: resumes the coroutine to its first co_yield. | |
Static Public Member Functions | |
| static std::default_sentinel_t | end () noexcept |
| End sentinel, per the C++20 sentinel-based range model. | |
Private Attributes | |
| Handle | handle_ {} |
Lazy, single-pass sequence of T values produced by a coroutine.
A function returning Aleph::Generator<T> and using co_yield in its body is a generator function: calling it does not run the body — it creates a suspended coroutine frame. The body advances one co_yield at a time as the sequence is iterated (range-for, begin()/operator++, or manual resume()/value()).
| T | Type of the yielded values. co_yield accepts lvalues and rvalues convertible to std::remove_reference_t<T>; the iterator exposes the currently yielded object by reference. |
co_yield. That reference is valid only until the generator is resumed again (operator++() or a second begin()), or until the Generator is destroyed. Copy or move the value out if it must survive beyond the current iteration step.Aleph::Generator<T> models a C++ input range: begin() resumes the coroutine to its first co_yield (or to completion, if the body never yields) and returns an iterator; end() returns std::default_sentinel. The iterator is single-pass — advancing it resumes the underlying coroutine, so only one iterator on a given Generator should be advanced at a time. Copying a Generator is disallowed (it owns the coroutine frame); move it instead.operator++ or begin() for the first element) — exactly where a hand-written iterator would throw.Generator (or letting it go out of scope) before it is exhausted destroys the coroutine frame and unwinds any pending stack frames inside the coroutine body — co_yield sits inside ordinary C++ control flow, so local objects along that path are destroyed normally.Generator<T> instance is not thread-safe: it owns one suspended coroutine frame with no synchronization. Distinct instances (including ones produced by concurrent calls to the same generator function) may be driven from distinct threads.Definition at line 152 of file ah-generator.H.
| using Aleph::Generator< T >::Handle = std::coroutine_handle<promise_type> |
Definition at line 208 of file ah-generator.H.
|
defaultnoexcept |
Construct an empty/singular Generator (no coroutine attached).
|
inlineexplicitnoexcept |
Construct from a coroutine handle (internal use by promise_type).
Definition at line 293 of file ah-generator.H.
Deleted: a Generator owns a single coroutine frame, which cannot be duplicated.
Move it instead.
Move constructor: transfers coroutine-frame ownership.
Definition at line 303 of file ah-generator.H.
|
inline |
Destroys the coroutine frame, if any, unwinding pending local state inside the (possibly still-suspended) coroutine body.
Definition at line 319 of file ah-generator.H.
References Aleph::Generator< T >::handle_.
|
inline |
Begin iterating: resumes the coroutine to its first co_yield.
end() if the body never yields, was already exhausted, or this is a default-constructed/moved-from Generator with no coroutine attached — an "empty/singular" Generator iterates zero times rather than throwing, matching the usual empty-range/empty- container convention). | Whatever | the coroutine body throws before its first co_yield, if anything. |
begin() is lvalue-qualified on purpose: range-for over a temporary generator is safe because the loop binds the temporary to a hidden local variable, but a direct make_generator().begin() would leave the returned iterator pointing at a destroyed coroutine frame. That direct call is therefore a compile-time error. begin() more than once while the sequence is still mid-traversal resumes the coroutine again, which is almost certainly not what you want on a single-pass sequence; iterate it exactly once. Calling it again after the sequence is exhausted is safe and simply returns end(): resuming a coroutine past its final suspend point is undefined behavior, so that case is detected and the resume is skipped instead. Definition at line 347 of file ah-generator.H.
References Aleph::and, Aleph::blossom_maximum_cardinality_matching(), and Aleph::Generator< T >::handle_.
Referenced by TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), and TEST().
|
inlinestaticnoexcept |
|
delete |
Deleted: see the copy constructor.
|
inlinenoexcept |
Move assignment: destroys any owned frame, then steals o's.
Definition at line 306 of file ah-generator.H.
References Aleph::blossom_maximum_cardinality_matching(), and Aleph::Generator< T >::handle_.
|
private |
Definition at line 362 of file ah-generator.H.
Referenced by Aleph::Generator< T >::~Generator(), Aleph::Generator< T >::begin(), and Aleph::Generator< T >::operator=().