.. _spawn_group_add_clang:

tmc::spawn_group::add_clang()
------------------------------------------------------------------------------------------------
``tmc::spawn_group::add_clang()`` is a HALO-optimized method for adding awaitables to a spawn_group. It uses the ``[[clang::coro_await_elidable_argument]]`` attribute when compiled with Clang 20+.

For HALO to work, ``add_clang()`` must be awaited directly as a prvalue in a ``co_await`` expression. 

.. code-block:: cpp

   // HALO: add_clang() is directly awaited for each task
   auto sg = tmc::spawn_group<3, tmc::task<int>>();
   co_await sg.add_clang(task_int(11));
   co_await sg.add_clang(task_int(22));
   co_await sg.add_clang(task_int(33));
   auto results = co_await std::move(sg);

   // Non-HALO: add() without HALO attributes
   auto sg = tmc::spawn_group<3, tmc::task<int>>();
   sg.add(task_int(44));
   sg.add(task_int(55));
   sg.add(task_int(66));
   auto results = co_await std::move(sg);

**WARNING:** Do not use ``spawn_group::add_clang()`` in a loop, as Clang will try to reuse the same allocation for multiple active coroutines, causing crashes.

.. code-block:: cpp

   // spawn_group::add_clang() in a loop will cause a segfault!
   // Clang erroneously tries to use the same allocation for all subtasks
   auto sg = tmc::spawn_group<3, tmc::task<int>>();
   for (size_t i = 0; i < sg.capacity(); i++) {
     co_await sg.add_clang(task_int(i));
   }
   auto results = co_await std::move(sg);

   // Correct: Use add() without HALO attributes in a loop - works fine
   auto sg = tmc::spawn_group<3, tmc::task<int>>();
   for (size_t i = 0; i < sg.capacity(); i++) {
     sg.add(task_int(i));
   }
   auto results = co_await std::move(sg);

Main Documentation
------------------------------------------------------------------------------------------------
For full documentation on ``tmc::spawn_group``, including the non-HALO ``.add()`` method, see :literal_ref:`tmc::spawn_group<spawn_group>`.
