10
10
#define _LIBCPP___TYPE_TRAITS_CONJUNCTION_H
11
11
12
12
#include < __config>
13
+ #include < __type_traits/conditional.h>
14
+ #include < __type_traits/enable_if.h>
13
15
#include < __type_traits/integral_constant.h>
14
16
#include < __type_traits/is_same.h>
15
17
19
21
20
22
_LIBCPP_BEGIN_NAMESPACE_STD
21
23
22
- template <bool >
23
- struct _AndImpl ;
24
+ template <class ... >
25
+ using __expand_to_true _LIBCPP_NODEBUG = true_type ;
24
26
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 );
31
29
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 (...);
37
32
38
33
// _And always performs lazy evaluation of its arguments.
39
34
//
40
35
// However, `_And<_Pred...>` itself will evaluate its result immediately (without having to
41
36
// be instantiated) since it is an alias, unlike `conjunction<_Pred...>`, which is a struct.
42
37
// 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 )) ;
45
40
46
41
template <bool ... _Preds>
47
42
struct __all_dummy ;
@@ -51,11 +46,22 @@ struct __all : _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...
51
46
52
47
#if _LIBCPP_STD_VER >= 17
53
48
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
56
62
57
63
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;
59
65
60
66
#endif // _LIBCPP_STD_VER >= 17
61
67
0 commit comments