From 5f0114783a013e42ad961994e274bb10aef0872a Mon Sep 17 00:00:00 2001 From: Sean Baxter Date: Sun, 29 Dec 2024 15:29:46 -0500 Subject: [PATCH] Added template keyword in __tuple.hpp for member name disambiguation. (#1432) * Added template keyword in __tuple.hpp for member name disambiguation. The mainline compilers accept the code as-is... for now. CWG1835 is resolved with the template kw. There's a recent patch waiting on-deck for Clang to require template in this position: https://github.com/llvm/llvm-project/pull/92957 Circle requires the token now. * add workaround for gcc * apply the workaround to nvc++ as well --------- Co-authored-by: Eric Niebler --- include/stdexec/__detail/__tuple.hpp | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/include/stdexec/__detail/__tuple.hpp b/include/stdexec/__detail/__tuple.hpp index 49b714049..07b46efd8 100644 --- a/include/stdexec/__detail/__tuple.hpp +++ b/include/stdexec/__detail/__tuple.hpp @@ -22,6 +22,19 @@ #include +#if STDEXEC_GCC() || STDEXEC_NVHPC() +// GCC (as of v14) does not implement the resolution of CWG1835 +// https://cplusplus.github.io/CWG/issues/1835.html +// See: https://godbolt.org/z/TzxrhK6ea +# define STDEXEC_NO_CWG1835 +#endif + +#ifdef STDEXEC_NO_CWG1835 +# define STDEXEC_CWG1835_TEMPLATE +#else +# define STDEXEC_CWG1835_TEMPLATE template +#endif + namespace stdexec { namespace __tup { template @@ -56,24 +69,26 @@ namespace stdexec { struct __tuple<_Idx, _Ts...> : __box<_Ts, _Is>... { template static __tuple __convert_from(__tuple<_Idx, _Us...> &&__tup) { - return __tuple{{static_cast<_Us &&>(__tup.__box<_Us, _Is>::__value)}...}; + return __tuple{ + {static_cast<_Us &&>(__tup.STDEXEC_CWG1835_TEMPLATE __box<_Us, _Is>::__value)}...}; } template static __tuple __convert_from(__tuple<_Idx, _Us...> const &__tup) { - return __tuple{{__tup.__box<_Us, _Is>::__value}...}; + return __tuple{{__tup.STDEXEC_CWG1835_TEMPLATE __box<_Us, _Is>::__value}...}; } template STDEXEC_ATTRIBUTE((host, device, always_inline)) static auto apply(_Fn &&__fn, _Self &&__self, _Us &&...__us) // noexcept(noexcept(static_cast<_Fn &&>(__fn)( static_cast<_Us &&>(__us)..., - static_cast<_Self &&>(__self).__box<_Ts, _Is>::__value...))) + static_cast<_Self &&>(__self).STDEXEC_CWG1835_TEMPLATE __box<_Ts, _Is>::__value...))) -> decltype(static_cast<_Fn &&>(__fn)( static_cast<_Us &&>(__us)..., - static_cast<_Self &&>(__self).__box<_Ts, _Is>::__value...)) { + static_cast<_Self &&>(__self).STDEXEC_CWG1835_TEMPLATE __box<_Ts, _Is>::__value...)) { return static_cast<_Fn &&>(__fn)( - static_cast<_Us &&>(__us)..., static_cast<_Self &&>(__self).__box<_Ts, _Is>::__value...); + static_cast<_Us &&>(__us)..., + static_cast<_Self &&>(__self).STDEXEC_CWG1835_TEMPLATE __box<_Ts, _Is>::__value...); } template @@ -82,7 +97,8 @@ namespace stdexec { noexcept((__nothrow_callable<_Fn, _Us..., __copy_cvref_t<_Self, _Ts>> && ...)) -> void { return ( static_cast<_Fn &&>(__fn)( - static_cast<_Us &&>(__us)..., static_cast<_Self &&>(__self).__box<_Ts, _Is>::__value), + static_cast<_Us &&>(__us)..., + static_cast<_Self &&>(__self).STDEXEC_CWG1835_TEMPLATE __box<_Ts, _Is>::__value), ...); } };