From 010a59297ecaf929c2997217725f87071187f39d Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Sat, 25 Jan 2025 12:06:47 -0800 Subject: [PATCH] work around msvc bug exposed by `__type_index` in `type_list.h` (#3487) simplify the fall-back implementation of `__type_index` to avoid causing MSVC to ICE. --- .../cuda/std/__type_traits/type_list.h | 50 +++++++++++-------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/libcudacxx/include/cuda/std/__type_traits/type_list.h b/libcudacxx/include/cuda/std/__type_traits/type_list.h index f2dc0fffe43..0e00ff9e0f0 100644 --- a/libcudacxx/include/cuda/std/__type_traits/type_list.h +++ b/libcudacxx/include/cuda/std/__type_traits/type_list.h @@ -473,29 +473,33 @@ using __type_index = __type_call<__detail::__type_index_fn<_Ip::value>, _Ts...>; namespace __detail { -template -struct __inherit_flat : _Ts... -{}; - template -struct __type_index_leaf +struct __type_tuple_elem { - using type = _Ty; + using type _CCCL_NODEBUG_ALIAS = _Ty; }; +template +struct __type_tupl; + +template +struct __type_tupl, _Ts...> : __type_tuple_elem<_Is, _Ts>... +{}; + +template +using __type_tuple = __type_tupl, _Ts...>; + template -_LIBCUDACXX_HIDE_FROM_ABI __type_index_leaf<_Ip, _Ty> __type_index_get(__type_index_leaf<_Ip, _Ty>*); +_LIBCUDACXX_HIDE_FROM_ABI __type_tuple_elem<_Ip, _Ty> __type_tuple_get(__type_tuple_elem<_Ip, _Ty>); -template -struct __type_index_large_size_fn; +template +using __type_tuple_element_t _CCCL_NODEBUG_ALIAS = + __type(__type_tuple<_Ts...>{}))>; -template -struct __type_index_large_size_fn> +struct __type_index_large_size_fn { template - using __call _CCCL_NODEBUG_ALIAS = // - __type( - static_cast<__inherit_flat<__type_index_leaf<_Is, _Ts>...>*>(nullptr)))>; + using __call _CCCL_NODEBUG_ALIAS = __type_tuple_element_t<_Ip::value, _Ts...>; }; template @@ -516,12 +520,8 @@ _CCCL_PP_REPEAT_REVERSE(_CCCL_META_UNROLL_LIMIT, _M1) # undef _M1 template -struct __type_index_select_fn // Default for larger indices -{ - template - using __call _CCCL_NODEBUG_ALIAS = - __type_call<__type_index_large_size_fn>, _Ip, _Ts...>; -}; +struct __type_index_select_fn : __type_index_large_size_fn // Default for larger indices +{}; template <> struct __type_index_select_fn // Fast implementation for smaller indices @@ -531,9 +531,19 @@ struct __type_index_select_fn // Fast implementation for smaller indices }; } // namespace __detail +# if !_CCCL_COMPILER(MSVC) + template using __type_index = __type_call<__detail::__type_index_select_fn<(_Ip::value < _CCCL_META_UNROLL_LIMIT)>, _Ip, _Ts...>; +# else // ^^^ !_CCCL_COMPILER(MSVC) ^^^ / vvv _CCCL_COMPILER(MSVC) vvv + +// Simplify the implementation for MSVC, which has trouble with the above +template +using __type_index = __detail::__type_index_large_size_fn::__call<_Ip, _Ts...>; + +# endif // !_CCCL_COMPILER(MSVC) + template using __type_index_c = __type_index, _Ts...>;