Skip to content

Add range-based overload for when_all #205

@mvandeberg

Description

@mvandeberg

Summary

when_any supports both variadic and range-based overloads, but when_all only has the variadic form. A range-based when_all overload should be added for parity.

Current State

when_any has three overloads (when_any.hpp):

  1. when_any(As... as) — variadic, heterogeneous tasks → variant<...>
  2. when_any(R&& awaitables) — range of non-void tasks → pair<size_t, T>
  3. when_any(R&& awaitables) — range of void tasks → size_t

when_all has one overload (when_all.hpp):

  1. when_all(As... awaitables) — variadic, heterogeneous tasks → tuple<...>

Proposed

Add range-based when_all overloads:

// Non-void range: returns vector<T>
template<IoAwaitableRange R>
    requires (!std::is_void_v<awaitable_result_t<std::ranges::range_value_t<R>>>)
[[nodiscard]] auto when_all(R&& awaitables) -> task<std::vector<T>>;

// Void range: returns void
template<IoAwaitableRange R>
    requires std::is_void_v<awaitable_result_t<std::ranges::range_value_t<R>>>
[[nodiscard]] auto when_all(R&& awaitables) -> task<void>;

Use Case

Dynamic collections of homogeneous tasks (e.g., fetching N items in parallel):

task<void> example() {
    std::vector<task<Response>> requests;
    for (auto const& url : urls)
        requests.push_back(fetch(url));

    auto responses = co_await when_all(std::move(requests));
}

This is currently not possible without the range overload, since the variadic form requires knowing the number of tasks at compile time.

Implementation Notes

  • Can reuse IoAwaitableRange concept already defined in when_any.hpp (may want to move it to a shared location)
  • Will need homogeneous state/launcher types analogous to when_any_homogeneous_state / when_any_homogeneous_launcher
  • Empty range should throw std::invalid_argument for consistency with when_any
  • Results should be returned in input order (matching variadic when_all semantics)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions