.. _spawn_many:

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 :ref:`Awaitable Customizations <awaitable_customizations>`:
:literal_ref:`run_on()<run_on>`,
:literal_ref:`resume_on()<resume_on>`,
:literal_ref:`with_priority()<with_priority>`,
:literal_ref:`co_await<co_await>`,
:literal_ref:`fork()<fork>`,
:literal_ref:`detach()<detach>`.

Additionally, it supports a special awaitable customization (execution mode):

.. _result_each:

``.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()`.

A maximum of 63 (or 31, on 32-bit) tasks can be awaited via ``.result_each()``.

API Reference
------------------------------------------------------------------------------------------------

.. doxygenfunction:: tmc::spawn_many(AwaitableIter&& Begin)

.. doxygenfunction:: tmc::spawn_many(AwaitableRange&& Range)

.. doxygenfunction:: tmc::spawn_many(AwaitableIter&& Begin, size_t TaskCount)

.. doxygenfunction:: tmc::spawn_many(AwaitableIter&& Begin, AwaitableIter&& End)

.. doxygenfunction:: tmc::spawn_many(AwaitableIter&& Begin, AwaitableIter&& End, size_t MaxCount)
