@@ -44,12 +44,41 @@ namespace STDEXEC
4444 // __connect_await
4545 namespace __connect_await
4646 {
47- // four pointers' worth of space when compiling with Clang or MSVC; five with GCC
48- static constexpr std::size_t __num_pointers = 4 * (STDEXEC_CLANG() + STDEXEC_MSVC())
49- + 5 * STDEXEC_GCC ();
47+ # if STDEXEC_CLANG()
48+ // clang normally needs four pointer's worth of storage for the promise type
49+ // but the requirement is different when it's a CUDA compilation
50+ # if !STDEXEC_CUDA_COMPILATION()
51+ # define STDEXEC_CONNECT_AWAITABLE_NUM_POINTERS 4
52+ # elif CUDART_VERSION == 12'00'0
53+ // Clang for CUDA 12.0 only needs three pointers
54+ # define STDEXEC_CONNECT_AWAITBALE_NUM_POINTERS 3
55+ # elif CUDART_VERSION >= 12'09'0
56+ // yes, I experimentally determined this is *56* pointers
57+ # define STDEXEC_CONNECT_AWAITABLE_NUM_POINTERS 56
58+ # else
59+ # error frame size unknown for Clang with this CUDA version
60+ # endif
61+ # elif STDEXEC_GCC()
62+ // GCC needs six pointers through version 14, and five thereafter
63+ # if STDEXEC_GCC_VERSION < 15'00
64+ # define STDEXEC_CONNECT_AWAITABLE_NUM_POINTERS 6
65+ # else
66+ # define STDEXEC_CONNECT_AWAITABLE_NUM_POINTERS 5
67+ # endif
68+ # elif STDEXEC_MSVC()
69+ // this is currently a guess; I don't actually know what MSVC needs
70+ # define STDEXEC_CONNECT_AWAITABLE_NUM_POINTERS 5
71+ # else
72+ // there's no way to define a default for this
73+ # error What compiler are you using?
74+ # endif
75+
76+ static constexpr std::size_t __num_pointers = STDEXEC_CONNECT_AWAITABLE_NUM_POINTERS;
5077 static constexpr std::size_t __storage_size = __num_pointers * sizeof (void *) - 1 ;
5178 static constexpr std::size_t __storage_align = __STDCPP_DEFAULT_NEW_ALIGNMENT__;
5279
80+ # undef STDEXEC_CONNECT_AWAITABLE_NUM_POINTERS
81+
5382 // clang-format off
5483 template <class _Tp , class _Promise >
5584 concept __has_as_awaitable_member = requires (_Tp&& __t , _Promise& __promise)
0 commit comments