From 21dc3d5ffe06578c3c8ab1fd2c4233be6473dae9 Mon Sep 17 00:00:00 2001 From: tzcnt Date: Thu, 2 Jul 2026 19:02:47 -0700 Subject: [PATCH 1/9] add mux_many / mux_tuple --- include/tmc/all_headers.hpp | 2 + include/tmc/detail/tuple_helpers.hpp | 83 +++++ include/tmc/mux_many.hpp | 535 +++++++++++++++++++++++++++ include/tmc/mux_tuple.hpp | 400 ++++++++++++++++++++ 4 files changed, 1020 insertions(+) create mode 100644 include/tmc/detail/tuple_helpers.hpp create mode 100644 include/tmc/mux_many.hpp create mode 100644 include/tmc/mux_tuple.hpp diff --git a/include/tmc/all_headers.hpp b/include/tmc/all_headers.hpp index 86936690..9f14633b 100644 --- a/include/tmc/all_headers.hpp +++ b/include/tmc/all_headers.hpp @@ -27,6 +27,8 @@ #include "tmc/latch.hpp" // IWYU pragma: export #include "tmc/manual_reset_event.hpp" // IWYU pragma: export #include "tmc/mutex.hpp" // IWYU pragma: export +#include "tmc/mux_many.hpp" // IWYU pragma: export +#include "tmc/mux_tuple.hpp" // IWYU pragma: export #include "tmc/qu_mpsc_bounded.hpp" // IWYU pragma: export #include "tmc/qu_mpsc_unbounded.hpp" // IWYU pragma: export #include "tmc/qu_spsc_bounded.hpp" // IWYU pragma: export diff --git a/include/tmc/detail/tuple_helpers.hpp b/include/tmc/detail/tuple_helpers.hpp new file mode 100644 index 00000000..b4999c39 --- /dev/null +++ b/include/tmc/detail/tuple_helpers.hpp @@ -0,0 +1,83 @@ +// Copyright (c) 2023-2026 Logan McDougall +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) + +#pragma once + +// Common template helpers shared by the tuple-shaped awaitable groups +// (tmc::spawn_tuple() and tmc::mux_tuple). + +#include "tmc/detail/concepts_awaitable.hpp" // IWYU pragma: keep + +#include +#include + +namespace tmc { +namespace detail { +// Replace void with std::monostate (void is not a valid tuple element type) +template +using void_to_monostate = std::conditional_t, std::monostate, T>; + +// Get the last type of a parameter pack +// In C++26 you can use pack indexing instead: T...[sizeof...(T) - 1] +template struct last_type { + using type = typename decltype((std::type_identity{}, ...))::type; +}; + +template <> struct last_type<> { + // workaround for empty tuples - the task object will be void / empty + using type = void; +}; + +template using last_type_t = typename last_type::type; + +// Create 2 instantiations of the Variadic, one where all of the types +// satisfy the predicate, and one where none of the types satisfy the predicate. +template