tmc::spawn_many()#
spawn_many()
wraps multiple awaitables into a single awaitable, that completes when all of the wrapped awaitables complete.
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()
.
Additionally, it supports a special awaitable customization (execution mode):
.result_each()
#
Rather than waiting for all results at once, each result will be made
available immediately as it becomes ready. Each time this is co_awaited, it will return
the index of a single ready result. The result indexes correspond to the
indexes of the originally submitted tasks in the input iterator, and the values can be
accessed using operator[]
.
Results may become ready in any order, but
when awaited repeatedly, each index from [0..task_count) will be
returned exactly once. You must await this repeatedly until all tasks
are complete, at which point the index returned will be equal to the
value of end().
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
Count
is 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.AwaitableIter
must be an iterator type that implementsoperator*()
andAwaitableIter& operator++()
.Awaitable
must be a type that can be awaited (implementsoperator co_await()
orawait_ready/suspend/resume()
)Submits items in range [Begin, Begin + Count) to the executor.
-
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
Count
is zero (this overload), the single argument is treated as a range. The other overload (Count != 0) supports fixed-size awaitable groups.AwaitableRange
must implementbegin()
andend()
functions which return an iterator type. The iterator type must implementoperator*()
,AwaitableIter& operator++()
, andoperator==(Awaitable const& rhs)
.Awaitable
must 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.
-
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.
AwaitableIter
must be an iterator type that implementsoperator*()
andAwaitableIter& operator++()
.TaskCount
must be non-zero.Awaitable
must be a type that can be awaited (implementsoperator co_await()
orawait_ready/suspend/resume()
)Submits items in range [Begin, Begin + TaskCount) to the executor.
-
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.
AwaitableIter
must be an iterator type that implementsoperator*()
andAwaitableIter& operator++()
.Awaitable
must be a type that can be awaited (implementsoperator co_await()
orawait_ready/suspend/resume()
)If
MaxCount
is non-zero, the return type will be astd::array<Result, MaxCount>
. Up toMaxCount
tasks will be consumed from the iterator. If the iterator produces less thanMaxCount
tasks, 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
MaxCount
is 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.
-
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.
AwaitableIter
must be an iterator type that implementsoperator*()
andAwaitableIter& operator++()
.Awaitable
must be a type that can be awaited (implementsoperator co_await()
orawait_ready/suspend/resume()
)Up to
MaxCount
tasks will be consumed from the iterator.The iterator may produce less than
MaxCount
tasks.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.