[#generator] == cobalt/generator.hpp A generator is an eager coroutine that can `co_await` and `co_yield` values to the caller. [source,cpp] ---- cobalt::generator example() { printf("In coro 1\n"); co_yield 2; printf("In coro 3\n"); co_return 4; } cobalt::main co_main(int argc, char * argv[]) { printf("In main 0\n"); auto f = example(); // call and let it run until the first co_yield printf("In main 1\n"); printf("In main %d\n", co_await f); printf("In main %d\n", co_await f); return 0; } ---- Which will generate the following output In main 0 In coro 1 In main 1 In main 2 In coro 3 In main 4 [mermaid] ---- sequenceDiagram participant main; Note left of main: "In main 0" main->>+example: example() Note right of example: "In coro 1" example-->>main: co_yield 2 Note left of main: "In main 2" main-->>+example: co_await f Note right of example: "In coro 3" example->>main: co_return 3 Note left of main: "In main 4" ---- Values can be pushed into the generator, when `Push` (the second template parameter) is set to non-void: [source,cpp] ---- cobalt::generator example() { printf("In coro 1\n"); int i = co_yield 2; printf("In coro %d\n", i); co_return 4; } cobalt::main co_main(int argc, char * argv[]) { printf("In main 0\n"); auto f = example(); // call and let it run until the first co_yield printf("In main %d\n", co_await f(3)); // <1> co_return 0; } ---- <1> The pushed value gets passed through `operator()` to the result of `co_yield`. Which will generate the following output In main 0 In coro 1 In main 2 In coro 3 [#initial] === Lazy A generator can be turned lazy by awaiting initial. This `co_await` expression will produce the `Push` value. This means the generator will wait until it's awaited for the first time, and then process the newly pushed value and resume at the next co_yield. [source,cpp] ---- cobalt::generator example() { int v = co_await cobalt::this_coro::initial; printf("In coro %d\n", v); co_yield 2; printf("In coro %d\n", v); co_return 4; } cobalt::main co_main(int argc, char * argv[]) { printf("In main 0\n"); auto f = example(); // call and let it run until the first co_yield printf("In main 1\n"); // < this is now before the co_await initial printf("In main %d\n", co_await f(1)); printf("In main %d\n", co_await f(3)); return 0; } ---- Which will generate the following output In main 0 In main 1 In coro 1 In main 2 In coro 3 In main 4 [mermaid] ---- sequenceDiagram participant main; Note left of main: "In main 0" main->>+example: example() Note right of example: "In coro 1" example-->>main: co_yield 2 Note left of main: "In main 2" main-->>+example: co_await f Note right of example: "In coro 3" example->>main: co_return 3 Note left of main: "In main 4" ---- [#generator-executor] === Executor The executor is taken from the `thread_local` <> function, unless a `asio::executor_arg` is used in any position followed by the executor argument. [source, cpp] ---- cobalt::generator my_gen(asio::executor_arg_t, asio::io_context::executor_type exec_to_use); ---- [#generator-allocator] === Memory Resource The memory resource is taken from the `thread_local` <> function, unless a `std::allocator_arg` is used in any position followed by a `polymorphic_allocator` argument. [source, cpp] ---- cobalt::generator my_gen(std::allocator_arg_t, pmr::polymorphic_allocator alloc); ---- [#generator-outline] === Outline [source,cpp,subs=+quotes] ---- include::../../include/boost/cobalt/generator.hpp[tag=outline] ---- <1> This allows code like `while (gen) co_await gen:` <2> Supports <> <3> A cancelled generator maybe be resumable [#generator-promise] === Promise The generator promise has the following properties. - <> - <> - <> - <> - <> - <>