tmc::fork_tuple_clang()#

tmc::fork_tuple_clang() is a HALO-optimized version of spawn_tuple().fork() that uses the [[clang::coro_await_elidable_argument]] attribute when compiled with Clang 20+.

For HALO to work, fork_tuple_clang() must be awaited directly as a prvalue in a co_await expression. Storing the result in a variable before awaiting prevents HALO from being applied.

// HALO: fork_tuple_clang() is directly awaited
auto forked = co_await tmc::fork_tuple_clang(task_int(10), task_int(20), task_int(30));
auto results = co_await std::move(forked);

// Non-HALO: fork_tuple_clang() stored in variable
auto dummy = tmc::fork_tuple_clang(task_int(11), task_int(21), task_int(31));
auto forked = co_await std::move(dummy);
auto results = co_await std::move(forked);

// Non-HALO equivalent: spawn_tuple().fork() - due to member function
// call, this cannot be elided
auto forked = tmc::spawn_tuple(task_int(12), task_int(22), task_int(32)).fork();
auto results = co_await std::move(forked);

Main Documentation#

For the non-HALO version, see tmc::spawn_tuple().

API Reference#

template<typename ...Awaitable>
aw_fork_tuple_clang<tmc::detail::forward_awaitable<Awaitable>...> tmc::fork_tuple_clang(Awaitable&&... Awaitables)#

Similar to tmc::spawn_tuple(Awaitables...).fork() but allows the child tasks’ allocations to be elided by combining them into the parent’s allocation (HALO). This works by using specific attributes that are only available on Clang 20+. You can safely call this function on other compilers but no HALO-specific optimizations will be applied.

IMPORTANT: This returns a dummy awaitable. For HALO to work, you should not store the dummy awaitable. Instead, co_await this expression immediately, which returns the real awaitable that you can use to join the forked task later. Proper usage:

auto forked_task_tuple = co_await tmc::fork_tuple_clang(task1(), task2());
do_some_other_work();
auto result_tuple = co_await std::move(forked_task_tuple);