From: Louis Dionne Date: Mon, 3 May 2021 16:06:28 +0000 (-0400) Subject: [libc++] Fix template instantiation depth issues with std::tuple X-Git-Tag: llvmorg-14-init~7769 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=84f0bb619507caf7c4809400138dae1da578282a;p=platform%2Fupstream%2Fllvm.git [libc++] Fix template instantiation depth issues with std::tuple This fixes the issue by implementing _And using the short-circuiting SFINAE trick that we previously used only in std::tuple. One thing we could look into is use the naive recursive implementation for disjunctions with a small number of arguments, and use that trick with larger numbers of arguments. It might be the case that the constant overhead for setting up the SFINAE trick makes it only worth doing for larger packs, but that's left for further work. This problem was raised in https://reviews.llvm.org/D96523. Differential Revision: https://reviews.llvm.org/D101661 --- diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index 7978f7b..fd6f798 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -476,8 +476,6 @@ struct _MetaBase { using _EnableIfImpl _LIBCPP_NODEBUG_TYPE = _Tp; template using _OrImpl _LIBCPP_NODEBUG_TYPE = typename _MetaBase<_First::value != true && sizeof...(_Rest) != 0>::template _OrImpl<_First, _Rest...>; - template - using _AndImpl _LIBCPP_NODEBUG_TYPE = typename _MetaBase<_First::value == true && sizeof...(_Rest) != 0>::template _AndImpl<_First, _Rest...>; }; template <> @@ -488,8 +486,6 @@ struct _MetaBase { using _SelectApplyImpl _LIBCPP_NODEBUG_TYPE = _SecondFn<_Args...>; template using _OrImpl _LIBCPP_NODEBUG_TYPE = _Result; - template - using _AndImpl _LIBCPP_NODEBUG_TYPE = _Result; }; template using _EnableIf _LIBCPP_NODEBUG_TYPE = typename _MetaBase<_Cond>::template _EnableIfImpl<_Ret>; @@ -497,8 +493,6 @@ template using _If _LIBCPP_NODEBUG_TYPE = typename _MetaBase<_Cond>::template _SelectImpl<_IfRes, _ElseRes>; template using _Or _LIBCPP_NODEBUG_TYPE = typename _MetaBase< sizeof...(_Rest) != 0 >::template _OrImpl; -template -using _And _LIBCPP_NODEBUG_TYPE = typename _MetaBase< sizeof...(_Rest) != 0 >::template _AndImpl; template struct _Not : _BoolConstant {}; template @@ -506,6 +500,14 @@ using _FirstType _LIBCPP_NODEBUG_TYPE = typename _MetaBase<(sizeof...(_Args) >= template using _SecondType _LIBCPP_NODEBUG_TYPE = typename _MetaBase<(sizeof...(_Args) >= 2)>::template _SecondImpl<_Args...>; +template using __expand_to_true = true_type; +template +__expand_to_true<_EnableIf<_Pred::value>...> __and_helper(int); +template +false_type __and_helper(...); +template +using _And _LIBCPP_NODEBUG_TYPE = decltype(__and_helper<_Pred...>(0)); + template