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;
28 : tasks(std::move(input)),
29 results(tasks.get_allocator()),
30 counter(tasks.size()) {
31 results.resize(tasks.size());
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); }
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)};
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); }