Skip to content

Commit 0227396

Browse files
committed
Revert "[libc++] Reduce std::conjunction overhead (#124259)"
It turns out that the new implementation takes significantly more stack memory for some reason. This reverts commit 2696e4f.
1 parent b284a84 commit 0227396

File tree

1 file changed

+24
-18
lines changed

1 file changed

+24
-18
lines changed

libcxx/include/__type_traits/conjunction.h

+24-18
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#define _LIBCPP___TYPE_TRAITS_CONJUNCTION_H
1111

1212
#include <__config>
13+
#include <__type_traits/conditional.h>
14+
#include <__type_traits/enable_if.h>
1315
#include <__type_traits/integral_constant.h>
1416
#include <__type_traits/is_same.h>
1517

@@ -19,29 +21,22 @@
1921

2022
_LIBCPP_BEGIN_NAMESPACE_STD
2123

22-
template <bool>
23-
struct _AndImpl;
24+
template <class...>
25+
using __expand_to_true _LIBCPP_NODEBUG = true_type;
2426

25-
template <>
26-
struct _AndImpl<true> {
27-
template <class _Res, class _First, class... _Rest>
28-
using _Result _LIBCPP_NODEBUG =
29-
typename _AndImpl<bool(_First::value) && sizeof...(_Rest) != 0>::template _Result<_First, _Rest...>;
30-
};
27+
template <class... _Pred>
28+
__expand_to_true<__enable_if_t<_Pred::value>...> __and_helper(int);
3129

32-
template <>
33-
struct _AndImpl<false> {
34-
template <class _Res, class...>
35-
using _Result _LIBCPP_NODEBUG = _Res;
36-
};
30+
template <class...>
31+
false_type __and_helper(...);
3732

3833
// _And always performs lazy evaluation of its arguments.
3934
//
4035
// However, `_And<_Pred...>` itself will evaluate its result immediately (without having to
4136
// be instantiated) since it is an alias, unlike `conjunction<_Pred...>`, which is a struct.
4237
// If you want to defer the evaluation of `_And<_Pred...>` itself, use `_Lazy<_And, _Pred...>`.
43-
template <class... _Args>
44-
using _And _LIBCPP_NODEBUG = typename _AndImpl<sizeof...(_Args) != 0>::template _Result<true_type, _Args...>;
38+
template <class... _Pred>
39+
using _And _LIBCPP_NODEBUG = decltype(std::__and_helper<_Pred...>(0));
4540

4641
template <bool... _Preds>
4742
struct __all_dummy;
@@ -51,11 +46,22 @@ struct __all : _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...
5146

5247
#if _LIBCPP_STD_VER >= 17
5348

54-
template <class... _Args>
55-
struct _LIBCPP_NO_SPECIALIZATIONS conjunction : _And<_Args...> {};
49+
template <class...>
50+
struct _LIBCPP_NO_SPECIALIZATIONS conjunction : true_type {};
51+
52+
_LIBCPP_DIAGNOSTIC_PUSH
53+
# if __has_warning("-Winvalid-specialization")
54+
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Winvalid-specialization")
55+
# endif
56+
template <class _Arg>
57+
struct conjunction<_Arg> : _Arg {};
58+
59+
template <class _Arg, class... _Args>
60+
struct conjunction<_Arg, _Args...> : conditional_t<!bool(_Arg::value), _Arg, conjunction<_Args...>> {};
61+
_LIBCPP_DIAGNOSTIC_POP
5662

5763
template <class... _Args>
58-
_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool conjunction_v = _And<_Args...>::value;
64+
_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool conjunction_v = conjunction<_Args...>::value;
5965

6066
#endif // _LIBCPP_STD_VER >= 17
6167

0 commit comments

Comments
 (0)