Zth (libzth)
Loading...
Searching...
No Matches
sock_factory.cpp

More complex coroutine example.

More complex coroutine example.This program will print something like this:

Fiber factory: creating 7.42921 of fiber
Fiber factory: creating 8.33466 of fiber
Fiber factory: creating 4.19363 of fiber
   Got 15.7639 of fiber, creating sock 1 (12.5)
Fiber factory: creating 8.79472 of fiber
   Waste collector: collected 3.26387 of waste (total 3.26387)
Fiber factory: creating 6.06279 of fiber
Fiber factory: creating 8.04504 of fiber
   Got 10.2564 of fiber, creating sock 2 (5)
   Waste collector: collected 5.25642 of waste (total 8.5203)
Fiber factory: creating 2.31155 of fiber
   Got 16.8398 of fiber, creating sock 3 (12.5)
Fiber factory: creating 5.54631 of fiber
   Waste collector: collected 4.33976 of waste (total 12.8601)
Fiber factory: creating 3.57323 of fiber
Fiber factory: creating 7.32052 of fiber
   Got 5.88478 of fiber, creating sock 4 (5)
   Waste collector: collected 0.884785 of waste (total 13.7448)
Fiber factory: creating 5.92226 of fiber
      Packing facility: packed set 1 with sock 1 (12.5), sock 3 (12.5), sock 2 (5), and sock 4 (5)
   Got 12.8668 of fiber, creating sock 5 (12.5)
Fiber factory: creating 4.20885 of fiber
   Waste collector: collected 0.366831 of waste (total 14.1117)
   Got 5.92226 of fiber, creating sock 6 (5)
   Waste collector: collected 0.922256 of waste (total 15.0339)
Fiber factory: creating 4.09638 of fiber
Fiber factory: creating 8.35822 of fiber
Fiber factory: creating 2.49278 of fiber
   Got 12.5671 of fiber, creating sock 7 (12.5)
Fiber factory: creating 9.02039 of fiber
   Waste collector: collected 0.0670719 of waste (total 15.101)
   Got 6.58916 of fiber, creating sock 8 (5)
   Waste collector: collected 1.58916 of waste (total 16.6902)
Fiber factory: creating 1.02409 of fiber
      Packing facility: packed set 2 with sock 5 (12.5), sock 7 (12.5), sock 6 (5), and sock 8 (5)
Fiber factory: creating 3.43832 of fiber
Fiber factory: no more fiber to create
/*
* SPDX-FileCopyrightText: 2019-2026 Jochem Rutgers
*
* SPDX-License-Identifier: CC0-1.0
*/
// This example shows how to use C++20 coroutines in Zth.
#include <zth>
#include <cstdio>
#include <random>
static zth::coro::generator<float> fiber_factory(float supply)
{
// NOLINTNEXTLINE
std::mt19937 gen{(unsigned)time(nullptr)};
std::uniform_real_distribution<float> distrib{1, 10};
while(supply > 0) {
float x = std::min(supply, distrib(gen));
printf("Fiber factory: creating %g of fiber\n", (double)x);
co_yield x;
supply -= x;
}
printf("Fiber factory: no more fiber to create\n");
}
struct Sock {
explicit Sock(float material_used_)
: str{zth::format("sock %d (%g)", ++id_next, (double)material_used_)}
, material_used{material_used_}
{}
static inline int id_next = 0;
float material_used;
};
sock_factory(zth::coro::generator<float> fiber_generator, float amount_of_fiber)
{
while(true) {
float got_fiber = 0;
while(got_fiber < amount_of_fiber)
got_fiber += co_await fiber_generator;
Sock s{amount_of_fiber};
printf(" Got %g of fiber, creating %s\n", (double)got_fiber, s.str.c_str());
co_yield s;
if(got_fiber > amount_of_fiber)
co_yield got_fiber - amount_of_fiber; // waste
}
}
{
int sets = 0;
try {
while(true) {
Sock big_left = co_await big.as<Sock>();
Sock big_right = co_await big.as<Sock>();
Sock small_left = co_await small.as<Sock>();
Sock small_right = co_await small.as<Sock>();
printf(" Packing facility: packed set %d with %s, %s, %s, and %s\n",
++sets, big_left.str.c_str(), big_right.str.c_str(),
small_left.str.c_str(), small_right.str.c_str());
}
} catch(zth::coro_already_completed const&) {
// Dispose socks in the pipeline.
if(big.valid<Sock>())
big.value<Sock>();
if(small.valid<Sock>())
small.value<Sock>();
}
co_return sets;
}
int main_fiber(int argc, char** argv)
{
float supply = 100.F;
if(argc > 1)
supply = (float)strtol(argv[1], nullptr, 10);
auto fiber_generator = fiber_factory(supply);
fiber_generator.fiber("fiber factory");
auto big_sock_factory = sock_factory(fiber_generator, 12.5F);
big_sock_factory.fiber("big sock factory");
auto small_sock_factory = sock_factory(fiber_generator, 5.F);
small_sock_factory.setName("small sock factory");
// The small sock factory is so small, it does not need its own fiber.
static float total_waste = 0.F;
while(true) {
float waste = co_await g.as<float>();
total_waste += waste;
printf(" Waste collector: collected %g of waste (total %g)\n",
(double)waste, (double)total_waste);
}
co_return total_waste;
};
zth::join(
waste_collector(big_sock_factory).fiber("waste collector 1"),
waste_collector(small_sock_factory).fiber("waste collector 2"),
packing_socks(big_sock_factory, small_sock_factory).fiber("packing facility"));
return 0;
}
A coroutine generator producing a sequence of values.
Definition coro.h:904
decltype(auto) fiber(char const *name=nullptr)
Definition coro.h:1010
decltype(auto) as() const
Definition coro.h:960
decltype(auto) value()
Definition coro.h:973
bool valid() const noexcept
Definition coro.h:966
A coroutine task producing a single result value.
Definition coro.h:515
int main_fiber(int argc, char **argv)
Definition main.cpp:11
fiber_type< F >::fiber fiber(F &&f, Args &&... args)
Create and start a new fiber.
Definition async.h:1192
std::basic_string< char, std::char_traits< char >, Config::Allocator< char >::type > string
std::string type using Config::Allocator::type.
Definition util.h:315
cow_string str(T value)
Returns an zth::string representation of the given value.
Definition util.h:497
Exception thrown when a coroutine has already completed.
Definition exception.h:36