10struct CollectAllAwaiter {
12 using ExpectedResult =
typename Container::value_type::ExpectedResult;
14 using allocator_type =
15 typename std::allocator_traits<typename Container::allocator_type>::template rebind_alloc<ExpectedResult>;
18 std::coroutine_handle<> handle;
20 std::vector<ExpectedResult, allocator_type> results;
21 std::atomic_size_t counter;
24 CollectAllAwaiter(CollectAllAwaiter
const&) =
delete;
25 CollectAllAwaiter& operator=(CollectAllAwaiter
const&) =
delete;
27 constexpr CollectAllAwaiter(
Container&& input)
28 : tasks(std::move(input)),
29 results(tasks.get_allocator()),
30 counter(tasks.size()) {
31 results.resize(tasks.size());
33 constexpr CollectAllAwaiter(CollectAllAwaiter&&) =
default;
35 constexpr bool await_ready()
const noexcept {
return tasks.empty(); }
37 template <std::derived_from<CoroPromiseBase> P>
38 void await_suspend(std::coroutine_handle<P> h) {
40 NonNullExecutorRef exec = h.promise().exec;
41 for (
size_t i = 0; i < tasks.size(); ++i) {
42 tasks[i].launch(exec, [
this, i](
auto&& res) {
44 results[i] = std::move(res);
53 constexpr auto await_resume() {
return std::move(results); }
56class CollectAllTupleAwaiter {
58 using Input = std::tuple<T<Ts>...>;
59 using Result = std::tuple<typename T<Ts>::ExpectedResult...>;
62 std::coroutine_handle<> handle;
63 std::atomic_size_t counter{
sizeof...(Ts)};
68 CollectAllTupleAwaiter(CollectAllTupleAwaiter
const&) =
delete;
69 CollectAllTupleAwaiter& operator=(CollectAllTupleAwaiter
const&) =
delete;
71 constexpr CollectAllTupleAwaiter(T<Ts>&&... in) : tasks(std::move(in)...) {}
72 constexpr CollectAllTupleAwaiter(Input&& in) : tasks(std::move(in)) {}
73 constexpr CollectAllTupleAwaiter(CollectAllTupleAwaiter&&) =
default;
75 constexpr bool await_ready()
const noexcept {
return sizeof...(Ts) == 0; }
77 template <std::derived_from<CoroPromiseBase> P>
78 void await_suspend(std::coroutine_handle<P> h) {
80 NonNullExecutorRef exec = h.promise().exec;
81 [&]<
size_t... I>(std::index_sequence<I...>) {
83 [&](
auto& task,
auto& result) {
84 task.launch(exec, [
this, &result](
auto&& res) {
86 result = std::move(res);
92 }(std::get<I>(tasks), std::get<I>(results)),
95 }(std::index_sequence_for<Ts...>());
98 constexpr auto await_resume() {
return std::move(results); }