Skip to content

Conversation

@llvmbot
Copy link
Member

@llvmbot llvmbot commented Feb 18, 2025

Backport 0227396

Requested by: @philnik777

@llvmbot llvmbot requested a review from a team as a code owner February 18, 2025 18:19
@llvmbot llvmbot added this to the LLVM 20.X Release milestone Feb 18, 2025
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Feb 18, 2025
@llvmbot
Copy link
Member Author

llvmbot commented Feb 18, 2025

@llvm/pr-subscribers-libcxx

Author: None (llvmbot)

Changes

Backport 0227396

Requested by: @philnik777


Full diff: https://github.com/llvm/llvm-project/pull/127677.diff

1 Files Affected:

  • (modified) libcxx/include/__type_traits/conjunction.h (+24-18)
diff --git a/libcxx/include/__type_traits/conjunction.h b/libcxx/include/__type_traits/conjunction.h
index 6b6717a50a468..ad9656acd47ec 100644
--- a/libcxx/include/__type_traits/conjunction.h
+++ b/libcxx/include/__type_traits/conjunction.h
@@ -10,6 +10,8 @@
 #define _LIBCPP___TYPE_TRAITS_CONJUNCTION_H
 
 #include <__config>
+#include <__type_traits/conditional.h>
+#include <__type_traits/enable_if.h>
 #include <__type_traits/integral_constant.h>
 #include <__type_traits/is_same.h>
 
@@ -19,29 +21,22 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <bool>
-struct _AndImpl;
+template <class...>
+using __expand_to_true _LIBCPP_NODEBUG = true_type;
 
-template <>
-struct _AndImpl<true> {
-  template <class _Res, class _First, class... _Rest>
-  using _Result _LIBCPP_NODEBUG =
-      typename _AndImpl<bool(_First::value) && sizeof...(_Rest) != 0>::template _Result<_First, _Rest...>;
-};
+template <class... _Pred>
+__expand_to_true<__enable_if_t<_Pred::value>...> __and_helper(int);
 
-template <>
-struct _AndImpl<false> {
-  template <class _Res, class...>
-  using _Result _LIBCPP_NODEBUG = _Res;
-};
+template <class...>
+false_type __and_helper(...);
 
 // _And always performs lazy evaluation of its arguments.
 //
 // However, `_And<_Pred...>` itself will evaluate its result immediately (without having to
 // be instantiated) since it is an alias, unlike `conjunction<_Pred...>`, which is a struct.
 // If you want to defer the evaluation of `_And<_Pred...>` itself, use `_Lazy<_And, _Pred...>`.
-template <class... _Args>
-using _And _LIBCPP_NODEBUG = typename _AndImpl<sizeof...(_Args) != 0>::template _Result<true_type, _Args...>;
+template <class... _Pred>
+using _And _LIBCPP_NODEBUG = decltype(std::__and_helper<_Pred...>(0));
 
 template <bool... _Preds>
 struct __all_dummy;
@@ -51,11 +46,22 @@ struct __all : _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...
 
 #if _LIBCPP_STD_VER >= 17
 
-template <class... _Args>
-struct _LIBCPP_NO_SPECIALIZATIONS conjunction : _And<_Args...> {};
+template <class...>
+struct _LIBCPP_NO_SPECIALIZATIONS conjunction : true_type {};
+
+_LIBCPP_DIAGNOSTIC_PUSH
+#  if __has_warning("-Winvalid-specialization")
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Winvalid-specialization")
+#  endif
+template <class _Arg>
+struct conjunction<_Arg> : _Arg {};
+
+template <class _Arg, class... _Args>
+struct conjunction<_Arg, _Args...> : conditional_t<!bool(_Arg::value), _Arg, conjunction<_Args...>> {};
+_LIBCPP_DIAGNOSTIC_POP
 
 template <class... _Args>
-_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool conjunction_v = _And<_Args...>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool conjunction_v = conjunction<_Args...>::value;
 
 #endif // _LIBCPP_STD_VER >= 17
 

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but we need CI to be green

It turns out that the new implementation takes significantly more stack
memory for some reason.

This reverts commit 2696e4f.

(cherry picked from commit 0227396)
@tstellar tstellar merged commit 0429535 into llvm:release/20.x Feb 19, 2025
12 of 18 checks passed
@github-actions
Copy link

@philnik777 (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Projects

Development

Successfully merging this pull request may close these issues.

4 participants