tmc::spawn_many()#
spawn_many() wraps multiple awaitables into a single awaitable, that completes when all of the wrapped awaitables complete.
The wrapped awaitables will be executed concurrently.
All overloads expect a forward iterator of awaitables, and an end iterator (sentinel), or element count.
Some overloads support a Count or MaxCount template parameter.
If you provide this parameter, any results will be returned in a std::array<Result, Count>.
Otherwise, they will be returned in a std::vector<Result>.
An overload that directly accepts a range-type (which exposes .begin() and .end() member functions) is also provided.
If the Result type is not default-constructible, each value will be wrapped into a std::optional<Result>.
Thus, the entire result type will be std::array<std::optional<Result>, Count> or std::vector<std::optional<Result>>.
Awaitable Customizations#
The resulting awaitable supports these Awaitable Customizations:
run_on(),
resume_on(),
with_priority(),
co_await,
fork(),
detach().
Receiving Results As They Complete#
To receive each result as soon as it becomes ready - rather than waiting for the whole group to complete - use tmc::mux_many. It multiplexes a set of same-typed awaitables, returns the index of each one as it completes, and additionally lets you re-arm a completed slot with a new awaitable. mux_many replaces the former .result_each() execution mode.
API Reference#
-
template<size_t Count = 0, typename AwaitableIter, typename Awaitable = std::iter_value_t<AwaitableIter>, typename Result = tmc::detail::awaitable_result_t<Awaitable>>
aw_spawn_many<Result, Count, AwaitableIter, size_t, false> tmc::spawn_many(AwaitableIter &&Begin)# The single-argument form of spawn_many() has two overloads. If
Countis non-zero (this overload), a fixed-sizestd::array<T, Count>will be allocated to return results in. The other overload (Count == 0) supports range-types.AwaitableItermust be an iterator type that implementsoperator*()andAwaitableIter& operator++().Awaitablemust be a type that can be awaited (implementsoperator co_await()orawait_ready/suspend/resume()).Submits items in range [Begin, Begin + Count) to the executor.
Note: You must ensure the iterator remains in scope until this has been
co_awaited. A temporary iterator is OK only if this isco_awaited immediately.
-
template<size_t Count = 0, typename AwaitableRange, typename AwaitableIter = tmc::detail::range_iter<AwaitableRange>::type, typename Awaitable = std::iter_value_t<AwaitableIter>, typename Result = tmc::detail::awaitable_result_t<Awaitable>>
aw_spawn_many<Result, 0, AwaitableIter, AwaitableIter, false> tmc::spawn_many(AwaitableRange &&Range)# The single-argument form of spawn_many() has two overloads. If
Countis zero (this overload), the single argument is treated as a range. The other overload (Count != 0) supports fixed-size awaitable groups.AwaitableRangemust implementbegin()andend()methods which return an iterator type. The iterator type must implementoperator*(),AwaitableIter& operator++(), andoperator==(AwaitableIter const& rhs).Awaitablemust be a type that can be awaited (implementsoperator co_await()orawait_ready/suspend/resume())Submits items in range [Range.begin(), Range.end()) to the executor.
Note: You must ensure the range remains in scope until this has been
co_awaited. A temporary range is OK only if this isco_awaited immediately.
-
template<typename AwaitableIter, typename Awaitable = std::iter_value_t<AwaitableIter>, typename Result = tmc::detail::awaitable_result_t<Awaitable>>
aw_spawn_many<Result, 0, AwaitableIter, size_t, false> tmc::spawn_many(AwaitableIter &&Begin, size_t TaskCount)# For use when the number of items to spawn is a runtime parameter.
AwaitableItermust be an iterator type that implementsoperator*()andAwaitableIter& operator++().TaskCountmust be non-zero.Awaitablemust be a type that can be awaited (implementsoperator co_await()orawait_ready/suspend/resume())Submits items in range [Begin, Begin + TaskCount) to the executor.
Note: You must ensure the iterator remains in scope until this has been
co_awaited. A temporary iterator is OK only if this isco_awaited immediately.
-
template<size_t MaxCount = 0, typename AwaitableIter, typename Awaitable = std::iter_value_t<AwaitableIter>, typename Result = tmc::detail::awaitable_result_t<Awaitable>>
aw_spawn_many<Result, MaxCount, AwaitableIter, AwaitableIter, false> tmc::spawn_many(AwaitableIter &&Begin, AwaitableIter &&End)# For use when the number of items to spawn may be variable.
AwaitableItermust be an iterator type that implementsoperator*(),AwaitableIter& operator++(), andoperator==(AwaitableIter const& rhs).Awaitablemust be a type that can be awaited (implementsoperator co_await()orawait_ready/suspend/resume())If
MaxCountis non-zero, the return type will be astd::array<Result, MaxCount>. Up toMaxCounttasks will be consumed from the iterator. If the iterator produces less thanMaxCounttasks, elements in the return array beyond the number of results actually produced by the iterator will be default-initialized. Submits items in range [Begin, min(Begin + MaxCount, End)) to the executor.If
MaxCountis zero/not provided, the return type will be a right-sizedstd::vector<Result>with size and capacity equal to the number of tasks produced by the iterator.
Submits items in range [Begin, End) to the executor.
Note: You must ensure the iterators remain in scope until this has been
co_awaited.
-
template<typename AwaitableIter, typename Awaitable = std::iter_value_t<AwaitableIter>, typename Result = tmc::detail::awaitable_result_t<Awaitable>>
aw_spawn_many<Result, 0, AwaitableIter, AwaitableIter, false> tmc::spawn_many(AwaitableIter &&Begin, AwaitableIter &&End, size_t MaxCount)# For use when the number of items to spawn may be variable.
AwaitableItermust be an iterator type that implementsoperator*(),AwaitableIter& operator++(), andoperator==(AwaitableIter const& rhs).Awaitablemust be a type that can be awaited (implementsoperator co_await()orawait_ready/suspend/resume())Up to
MaxCounttasks will be consumed from the iterator.The iterator may produce less than
MaxCounttasks.The return type will be a right-sized
std::vector<Result>with size and capacity equal to the number of tasks consumed from the iterator.
Submits items in range [Begin, min(Begin + MaxCount, End)) to the executor.
Note: You must ensure the iterators remain in scope until this has been
co_awaited.