1010#define _LIBCPP___TYPE_TRAITS_CONJUNCTION_H
1111
1212#include < __config>
13- #include < __type_traits/conditional.h>
14- #include < __type_traits/enable_if.h>
1513#include < __type_traits/integral_constant.h>
1614#include < __type_traits/is_same.h>
1715
2119
2220_LIBCPP_BEGIN_NAMESPACE_STD
2321
24- template <class ... >
25- using __expand_to_true _LIBCPP_NODEBUG = true_type ;
22+ template <bool >
23+ struct _AndImpl ;
2624
27- template <class ... _Pred>
28- __expand_to_true<__enable_if_t <_Pred::value>...> __and_helper (int );
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+ };
2931
30- template <class ...>
31- false_type __and_helper (...);
32+ template <>
33+ struct _AndImpl <false > {
34+ template <class _Res , class ...>
35+ using _Result _LIBCPP_NODEBUG = _Res;
36+ };
3237
3338// _And always performs lazy evaluation of its arguments.
3439//
3540// However, `_And<_Pred...>` itself will evaluate its result immediately (without having to
3641// be instantiated) since it is an alias, unlike `conjunction<_Pred...>`, which is a struct.
3742// If you want to defer the evaluation of `_And<_Pred...>` itself, use `_Lazy<_And, _Pred...>`.
38- template <class ... _Pred >
39- using _And _LIBCPP_NODEBUG = decltype (std::__and_helper<_Pred ...>( 0 )) ;
43+ template <class ... _Args >
44+ using _And _LIBCPP_NODEBUG = typename _AndImpl< sizeof ...(_Args) != 0 >:: template _Result<true_type, _Args ...>;
4045
4146template <bool ... _Preds>
4247struct __all_dummy ;
@@ -46,22 +51,11 @@ struct __all : _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...
4651
4752#if _LIBCPP_STD_VER >= 17
4853
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
54+ template <class ... _Args>
55+ struct _LIBCPP_NO_SPECIALIZATIONS conjunction : _And<_Args...> {};
6256
6357template <class ... _Args>
64- _LIBCPP_NO_SPECIALIZATIONS inline constexpr bool conjunction_v = conjunction <_Args...>::value;
58+ _LIBCPP_NO_SPECIALIZATIONS inline constexpr bool conjunction_v = _And <_Args...>::value;
6559
6660#endif // _LIBCPP_STD_VER >= 17
6761
0 commit comments