mirror of
https://github.com/boostorg/cobalt.git
synced 2026-01-19 04:02:16 +00:00
86 lines
2.2 KiB
Plaintext
86 lines
2.2 KiB
Plaintext
[#tour-generator]
|
|
== Generator
|
|
|
|
A <<generator, generator>> is the only type in cobalt that can `co_yield` values.
|
|
|
|
<<generator, Generator>> are eager by default. Unlike https://en.cppreference.com/w/cpp/coroutine/generator[std::generator]
|
|
the `cobalt::generator` can `co_await` and thus is asynchronous.
|
|
|
|
[source,cpp]
|
|
----
|
|
cobalt::generator<int> my_generator()
|
|
{
|
|
for (int i = 0; i < 10; i++)
|
|
co_yield i;
|
|
co_return 10;
|
|
}
|
|
|
|
cobalt::main co_main(int argc, char * argv[])
|
|
{
|
|
// create the generator
|
|
auto g = my_generator();
|
|
while (g)
|
|
printf("Generator %d\n", co_await g);
|
|
co_return 0;
|
|
}
|
|
----
|
|
|
|
Values can be pushed into the generator, that will be returned from the `co_yield`.
|
|
|
|
[source,cpp]
|
|
----
|
|
cobalt::generator<double, int> my_eager_push_generator(int value)
|
|
{
|
|
while (value != 0)
|
|
value = co_yield value * 0.1;
|
|
co_return std::numeric_limits<double>::quiet_NaN();
|
|
}
|
|
|
|
cobalt::main co_main(int argc, char * argv[])
|
|
{
|
|
// create the generator
|
|
auto g = my_generator(5);
|
|
|
|
assert(0.5 == co_await g(4)); // result of 5
|
|
assert(0.4 == co_await g(3)); // result of 4
|
|
assert(0.3 == co_await g(2)); // result of 3
|
|
assert(0.2 == co_await g(1)); // result of 2
|
|
assert(0.1 == co_await g(0)); // result of 1
|
|
|
|
// we let the coroutine go out of scope while suspended
|
|
// no need for another co_await of `g`
|
|
|
|
co_return 0;
|
|
}
|
|
----
|
|
|
|
A coroutine can also be made lazy using <<initial, `this_coro::initial`>>.
|
|
|
|
[source,cpp]
|
|
----
|
|
cobalt::generator<double, int> my_eager_push_generator()
|
|
{
|
|
auto value = co_await this_coro::initial;
|
|
while (value != 0)
|
|
value = co_yield value * 0.1;
|
|
co_return std::numeric_limits<double>::quiet_NaN();
|
|
}
|
|
|
|
cobalt::main co_main(int argc, char * argv[])
|
|
{
|
|
// create the generator
|
|
auto g = my_generator(); // lazy, so the generator waits for the first pushed value
|
|
assert(0.5 == co_await g(5)); // result of 5
|
|
assert(0.4 == co_await g(4)); // result of 4
|
|
assert(0.3 == co_await g(3)); // result of 3
|
|
assert(0.2 == co_await g(2)); // result of 2
|
|
assert(0.1 == co_await g(1)); // result of 1
|
|
|
|
// we let the coroutine go out of scope while suspended
|
|
// no need for another co_await of `g`
|
|
|
|
co_return 0;
|
|
}
|
|
----
|
|
|