From 7f1cd609999e63b733c36f25d8d4a68b817ec9f3 Mon Sep 17 00:00:00 2001 From: Lixin Wei Date: Fri, 16 Jan 2026 15:09:04 +0800 Subject: [PATCH] fix 8-element tuple compile --- include/stdexec/__detail/__tuple.hpp | 10 +++---- test/stdexec/algos/adaptors/test_when_all.cpp | 30 +++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/include/stdexec/__detail/__tuple.hpp b/include/stdexec/__detail/__tuple.hpp index 30ad891fa..41fd937b2 100644 --- a/include/stdexec/__detail/__tuple.hpp +++ b/include/stdexec/__detail/__tuple.hpp @@ -345,7 +345,11 @@ namespace STDEXEC { constexpr auto __size = STDEXEC_REMOVE_REFERENCE(_Tuple)::__size; static_assert(_Index < __size, "Index out of bounds in __get"); - if constexpr (_Index == 0) { + // Only use __valN accessors for tuples with <= 8 elements (which have specialized storage) + // Larger tuples use __box base class and need __tup::__get + if constexpr (__size > 8) { + return __tup::__get<_Index>(static_cast<_Tuple&&>(__tupl)); + } else if constexpr (_Index == 0) { return static_cast<_Tuple&&>(__tupl).__val0; } else if constexpr (_Index == 1) { return static_cast<_Tuple&&>(__tupl).__val1; @@ -361,10 +365,6 @@ namespace STDEXEC { return static_cast<_Tuple&&>(__tupl).__val6; } else if constexpr (_Index == 7) { return static_cast<_Tuple&&>(__tupl).__val7; - } else if constexpr (_Index == 8) { - return static_cast<_Tuple&&>(__tupl).__val8; - } else { - return __tup::__get<_Index>(static_cast<_Tuple&&>(__tupl)); } } diff --git a/test/stdexec/algos/adaptors/test_when_all.cpp b/test/stdexec/algos/adaptors/test_when_all.cpp index d71f6c888..acc9994fa 100644 --- a/test/stdexec/algos/adaptors/test_when_all.cpp +++ b/test/stdexec/algos/adaptors/test_when_all.cpp @@ -62,6 +62,36 @@ namespace { wait_for_value(std::move(snd), 2, 3, 5, 7, 11); } + TEST_CASE("when_all with 8 senders", "[adaptors][when_all]") { + // 8 senders is the boundary case for the optimized tuple specializations + ex::sender auto snd = ex::when_all( + ex::just(2), + ex::just(3), + ex::just(5), + ex::just(7), + ex::just(11), + ex::just(13), + ex::just(17), + ex::just(19)); + wait_for_value(std::move(snd), 2, 3, 5, 7, 11, 13, 17, 19); + } + + TEST_CASE("when_all with 10 senders", "[adaptors][when_all]") { + // 10 senders uses the generic tuple with __box storage + ex::sender auto snd = ex::when_all( + ex::just(2), + ex::just(3), + ex::just(5), + ex::just(7), + ex::just(11), + ex::just(13), + ex::just(17), + ex::just(19), + ex::just(23), + ex::just(29)); + wait_for_value(std::move(snd), 2, 3, 5, 7, 11, 13, 17, 19, 23, 29); + } + TEST_CASE("when_all with just one sender", "[adaptors][when_all]") { ex::sender auto snd = ex::when_all(ex::just(2)); wait_for_value(std::move(snd), 2);