[#race] == cobalt/race.hpp The `race` function can be used to `co_await` one <> out of a set of them. It can be called as a variadic function with multiple <> or as on a range of <>. [source,cpp] ---- cobalt::promise task1(); cobalt::promise task2(); cobalt::promise do_wait() { co_await cobalt::race(task1(), task2()); // <1> std::vector> aws {task1(), task2()}; co_await cobalt::race(aws); // <2> } ---- <1> Wait for a variadic set of <> <2> wait for a vector of <> The first parameter so `race` can be a https://en.cppreference.com/w/cpp/named_req/UniformRandomBitGenerator::[uniform random bit generator]. .Signatures of race [source, cpp] ---- extern promise pv1, pv2; std::vector> pvv; std::default_random_engine rdm{1}; // if everything returns void race returns the index std::size_t r1 = co_await race(pv1, pv2); std::size_t r2 = co_await race(rdm, pv1, pv2); std::size_t r3 = co_await race(pvv); std::size_t r4 = co_await race(rdm, pvv); // variant if not everything is void. void become monostate extern promise pi1, pi2; variant2::variant r5 = co_await race(pv1, pi1, pi2); variant2::variant r6 = co_await race(rdm, pv1, pi1, pi2); // a range returns a pair of the index and the result if non-void std::vector> piv; std::pair r7 = co_await race(piv); std::pair r8 = co_await race(rdm, piv); ---- [#interrupt_await] === Interrupt Wait When arguments are passed as rvalue reference, the race will attempt to use `.interrupt_await` on the <> to signal the awaitable to complete now and that the result will be ignored. If supported, the <> must resume the awaiting coroutine before `interrupt_await` returns. If the `race` doesn't detect the function, it will send a cancellation. This means that you can reuse race like this: [source,cpp] ---- cobalt::promise do_wait() { auto t1 = task1(); auto t2 = task2(); co_await cobalt::race(t1, t2); // <1> co_await cobalt::race(t1, t2); // <2> } ---- <1> Wait for the first task to complete <2> Wait for the other task to complete This is supported by <>, <> and <>. The `race` will invoke the functions of the `awaitable` as if used in a `co_await` expression or not evaluate them at all. [#left_race] === `left_race` The `left_race` functions are like `race` but follow a strict left-to-right scan. This can lead to starvation issues, which is why this is not the recommended default, but can be useful for prioritization if proper care is taken. [#race-outline] === Outline [source,cpp,subs=+quotes] ---- // Concept for the random number generator. include::../../include/boost/cobalt/race.hpp[tag=concept] // Variadic race with a custom random number generator template __awaitable__ race(URBG && g, Promise && ... p); // Ranged race with a custom random number generator template PromiseRange> __awaitable__ race(URBG && g, PromiseRange && p); // Variadic race with the default random number generator template __awaitable__ race(Promise && ... p); // Ranged race with the default random number generator template> __awaitable__ race(PromiseRange && p); // Variadic left race template __awaitable__ left_race(Promise && ... p); // Ranged left race template> __awaitable__ left_race(PromiseRange && p); ---- NOTE: Selecting an empty range will cause an exception to be thrown.