55 return counter_.fetch_sub(1, std::memory_order_acq_rel) > 1;
62 if (
counter_.fetch_sub(1, std::memory_order_acq_rel) == 1)
73 if constexpr (std::ranges::range<T>)
74 return size(container);
76 return std::tuple_size_v<T>;
81 if constexpr (std::ranges::range<T>)
82 for (
auto &t : container)
85 std::apply([&](
auto &...tasks) { (..., tasks.start(sync)); }, container);
90 if constexpr (std::ranges::range<T>) {
91 if constexpr (std::is_void_v<typename std::ranges::range_value_t<T>::value_type>) {
93 for (
auto &
task : container)
96 std::vector<typename std::ranges::range_value_t<T>::value_type> result;
97 result.reserve(size(container));
98 for (
auto &&
task : std::forward<T>(container))
99 result.emplace_back(std::forward<
decltype(
task)>(
task).get());
104 [&]<
typename... Tasks>(Tasks &&...tasks) {
107 typename std::remove_cvref_t<Tasks>::value_type>)) {
112 decltype(std::forward<Tasks>(tasks).nonvoid_get())>...>;
113 return ret_type(std::forward<Tasks>(tasks).nonvoid_get()...);
116 std::forward<T>(container));
124 decltype(
auto)
operator co_await() & {
134 decltype(
auto)
operator co_await() && {
155 return awaitable.sync_.set_continuation(handle);
168 std::make_tuple(detail::make_synchronized_task<detail::when_all_sync>(
169 std::forward<Awaitables>(awaitables))...));
172template <std::ranges::range R>
177 std::vector<task_t> tasks;
178 tasks.reserve(size(awaitables));
179 for (
auto &&
awaitable : std::forward<R>(awaitables))
180 tasks.emplace_back(detail::make_synchronized_task<detail::when_all_sync>(
Lazy task that can later be started explicitly, and that notifies another variable (the “sync” object...
when_all_sync(when_all_sync &&other) noexcept
std::atomic< std::size_t > counter_
std::coroutine_handle continuation_
constexpr when_all_sync(std::size_t count) noexcept
bool set_continuation(std::coroutine_handle<> cont)
void notify_awaitable_completed()
On completion of each task a counter is being decremented and if the continuation is already attached...
Task that produces a value of type T: to get that value, simply await the task.
decltype(auto) make_all_results(T &&container)
decltype(auto) start_all_tasks(T &container, when_all_sync &sync)
std::size_t tasks_size(T &container)
typename remove_rvalue_reference< T >::type remove_rvalue_reference_t
decltype(std::declval< awaiter_for_t< A > >().await_resume()) await_result_t
awaitable auto when_all(Awaitables &&...awaitables)
bool await_ready() const noexcept
bool await_suspend(std::coroutine_handle<> handle)
when_all_awaitable & awaitable
when_all_awaitable(T &&tasks)
decltype(auto) await_resume() const
Return the value of the task's promise.