Apply new meta-programming traits throughout the library.

The new meta-programming primitives are lower cost than the old versions. This patch removes those old versions and switches libc++ to use the new ones.

llvm-svn: 364160
This commit is contained in:
Eric Fiselier 2019-06-23 20:28:29 +00:00
parent e2291f5af9
commit 3359a17b3a
8 changed files with 179 additions and 261 deletions

View File

@ -387,7 +387,7 @@ template <bool ..._Preds>
struct __all_dummy;
template <bool ..._Pred>
using __all = is_same<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>>;
using __all = _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>>;
struct __tuple_sfinae_base {
template <template <class, class...> class _Trait,

View File

@ -529,7 +529,7 @@ inline _LIBCPP_INLINE_VISIBILITY long double hypot( long double x, long double y
template <class _A1, class _A2, class _A3>
inline _LIBCPP_INLINE_VISIBILITY
typename __lazy_enable_if
typename _EnableIf
<
is_arithmetic<_A1>::value &&
is_arithmetic<_A2>::value &&

View File

@ -2246,8 +2246,8 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
__func __f_;
template <class _Fp, bool = __lazy_and<
integral_constant<bool, !is_same<__uncvref_t<_Fp>, function>::value>,
template <class _Fp, bool = _And<
_IsNotSame<__uncvref_t<_Fp>, function>,
__invokable<_Fp&, _ArgTypes...>
>::value>
struct __callable;
@ -2556,7 +2556,7 @@ __mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>)
template <class _Ti, class ..._Uj>
inline _LIBCPP_INLINE_VISIBILITY
typename __lazy_enable_if
typename _EnableIf
<
is_bind_expression<_Ti>::value,
__invoke_of<_Ti&, _Uj...>

View File

@ -857,7 +857,7 @@ inline _LIBCPP_INLINE_VISIBILITY long double atan2(long double __lcpp_y, long do
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename std::__lazy_enable_if
typename std::_EnableIf
<
std::is_arithmetic<_A1>::value &&
std::is_arithmetic<_A2>::value,
@ -866,8 +866,8 @@ typename std::__lazy_enable_if
atan2(_A1 __lcpp_y, _A2 __lcpp_x) _NOEXCEPT
{
typedef typename std::__promote<_A1, _A2>::type __result_type;
static_assert((!(std::is_same<_A1, __result_type>::value &&
std::is_same<_A2, __result_type>::value)), "");
static_assert((!(std::_IsSame<_A1, __result_type>::value &&
std::_IsSame<_A2, __result_type>::value)), "");
return ::atan2((__result_type)__lcpp_y, (__result_type)__lcpp_x);
}
@ -952,7 +952,7 @@ inline _LIBCPP_INLINE_VISIBILITY long double fmod(long double __lcpp_x, long dou
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename std::__lazy_enable_if
typename std::_EnableIf
<
std::is_arithmetic<_A1>::value &&
std::is_arithmetic<_A2>::value,
@ -961,8 +961,8 @@ typename std::__lazy_enable_if
fmod(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
typedef typename std::__promote<_A1, _A2>::type __result_type;
static_assert((!(std::is_same<_A1, __result_type>::value &&
std::is_same<_A2, __result_type>::value)), "");
static_assert((!(std::_IsSame<_A1, __result_type>::value &&
std::_IsSame<_A2, __result_type>::value)), "");
return ::fmod((__result_type)__lcpp_x, (__result_type)__lcpp_y);
}
@ -1030,7 +1030,7 @@ inline _LIBCPP_INLINE_VISIBILITY long double pow(long double __lcpp_x, long doub
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename std::__lazy_enable_if
typename std::_EnableIf
<
std::is_arithmetic<_A1>::value &&
std::is_arithmetic<_A2>::value,
@ -1039,8 +1039,8 @@ typename std::__lazy_enable_if
pow(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
typedef typename std::__promote<_A1, _A2>::type __result_type;
static_assert((!(std::is_same<_A1, __result_type>::value &&
std::is_same<_A2, __result_type>::value)), "");
static_assert((!(std::_IsSame<_A1, __result_type>::value &&
std::_IsSame<_A2, __result_type>::value)), "");
return ::pow((__result_type)__lcpp_x, (__result_type)__lcpp_y);
}
@ -1157,7 +1157,7 @@ copysign(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename std::__lazy_enable_if
typename std::_EnableIf
<
std::is_arithmetic<_A1>::value &&
std::is_arithmetic<_A2>::value,
@ -1166,8 +1166,8 @@ typename std::__lazy_enable_if
copysign(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
typedef typename std::__promote<_A1, _A2>::type __result_type;
static_assert((!(std::is_same<_A1, __result_type>::value &&
std::is_same<_A2, __result_type>::value)), "");
static_assert((!(std::_IsSame<_A1, __result_type>::value &&
std::_IsSame<_A2, __result_type>::value)), "");
return ::copysign((__result_type)__lcpp_x, (__result_type)__lcpp_y);
}
@ -1218,7 +1218,7 @@ inline _LIBCPP_INLINE_VISIBILITY long double fdim(long double __lcpp_x, long dou
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename std::__lazy_enable_if
typename std::_EnableIf
<
std::is_arithmetic<_A1>::value &&
std::is_arithmetic<_A2>::value,
@ -1227,8 +1227,8 @@ typename std::__lazy_enable_if
fdim(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
typedef typename std::__promote<_A1, _A2>::type __result_type;
static_assert((!(std::is_same<_A1, __result_type>::value &&
std::is_same<_A2, __result_type>::value)), "");
static_assert((!(std::_IsSame<_A1, __result_type>::value &&
std::_IsSame<_A2, __result_type>::value)), "");
return ::fdim((__result_type)__lcpp_x, (__result_type)__lcpp_y);
}
@ -1239,7 +1239,7 @@ inline _LIBCPP_INLINE_VISIBILITY long double fma(long double __lcpp_x, long doub
template <class _A1, class _A2, class _A3>
inline _LIBCPP_INLINE_VISIBILITY
typename std::__lazy_enable_if
typename std::_EnableIf
<
std::is_arithmetic<_A1>::value &&
std::is_arithmetic<_A2>::value &&
@ -1249,9 +1249,9 @@ typename std::__lazy_enable_if
fma(_A1 __lcpp_x, _A2 __lcpp_y, _A3 __lcpp_z) _NOEXCEPT
{
typedef typename std::__promote<_A1, _A2, _A3>::type __result_type;
static_assert((!(std::is_same<_A1, __result_type>::value &&
std::is_same<_A2, __result_type>::value &&
std::is_same<_A3, __result_type>::value)), "");
static_assert((!(std::_IsSame<_A1, __result_type>::value &&
std::_IsSame<_A2, __result_type>::value &&
std::_IsSame<_A3, __result_type>::value)), "");
return ::fma((__result_type)__lcpp_x, (__result_type)__lcpp_y, (__result_type)__lcpp_z);
}
@ -1262,7 +1262,7 @@ inline _LIBCPP_INLINE_VISIBILITY long double fmax(long double __lcpp_x, long dou
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename std::__lazy_enable_if
typename std::_EnableIf
<
std::is_arithmetic<_A1>::value &&
std::is_arithmetic<_A2>::value,
@ -1271,8 +1271,8 @@ typename std::__lazy_enable_if
fmax(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
typedef typename std::__promote<_A1, _A2>::type __result_type;
static_assert((!(std::is_same<_A1, __result_type>::value &&
std::is_same<_A2, __result_type>::value)), "");
static_assert((!(std::_IsSame<_A1, __result_type>::value &&
std::_IsSame<_A2, __result_type>::value)), "");
return ::fmax((__result_type)__lcpp_x, (__result_type)__lcpp_y);
}
@ -1283,7 +1283,7 @@ inline _LIBCPP_INLINE_VISIBILITY long double fmin(long double __lcpp_x, long dou
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename std::__lazy_enable_if
typename std::_EnableIf
<
std::is_arithmetic<_A1>::value &&
std::is_arithmetic<_A2>::value,
@ -1292,8 +1292,8 @@ typename std::__lazy_enable_if
fmin(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
typedef typename std::__promote<_A1, _A2>::type __result_type;
static_assert((!(std::is_same<_A1, __result_type>::value &&
std::is_same<_A2, __result_type>::value)), "");
static_assert((!(std::_IsSame<_A1, __result_type>::value &&
std::_IsSame<_A2, __result_type>::value)), "");
return ::fmin((__result_type)__lcpp_x, (__result_type)__lcpp_y);
}
@ -1304,7 +1304,7 @@ inline _LIBCPP_INLINE_VISIBILITY long double hypot(long double __lcpp_x, long do
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename std::__lazy_enable_if
typename std::_EnableIf
<
std::is_arithmetic<_A1>::value &&
std::is_arithmetic<_A2>::value,
@ -1313,8 +1313,8 @@ typename std::__lazy_enable_if
hypot(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
typedef typename std::__promote<_A1, _A2>::type __result_type;
static_assert((!(std::is_same<_A1, __result_type>::value &&
std::is_same<_A2, __result_type>::value)), "");
static_assert((!(std::_IsSame<_A1, __result_type>::value &&
std::_IsSame<_A2, __result_type>::value)), "");
return ::hypot((__result_type)__lcpp_x, (__result_type)__lcpp_y);
}
@ -1427,7 +1427,7 @@ inline _LIBCPP_INLINE_VISIBILITY long double nextafter(long double __lcpp_x, lon
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename std::__lazy_enable_if
typename std::_EnableIf
<
std::is_arithmetic<_A1>::value &&
std::is_arithmetic<_A2>::value,
@ -1436,8 +1436,8 @@ typename std::__lazy_enable_if
nextafter(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
typedef typename std::__promote<_A1, _A2>::type __result_type;
static_assert((!(std::is_same<_A1, __result_type>::value &&
std::is_same<_A2, __result_type>::value)), "");
static_assert((!(std::_IsSame<_A1, __result_type>::value &&
std::_IsSame<_A2, __result_type>::value)), "");
return ::nextafter((__result_type)__lcpp_x, (__result_type)__lcpp_y);
}
@ -1458,7 +1458,7 @@ inline _LIBCPP_INLINE_VISIBILITY long double remainder(long double __lcpp_x, lon
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename std::__lazy_enable_if
typename std::_EnableIf
<
std::is_arithmetic<_A1>::value &&
std::is_arithmetic<_A2>::value,
@ -1467,8 +1467,8 @@ typename std::__lazy_enable_if
remainder(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
{
typedef typename std::__promote<_A1, _A2>::type __result_type;
static_assert((!(std::is_same<_A1, __result_type>::value &&
std::is_same<_A2, __result_type>::value)), "");
static_assert((!(std::_IsSame<_A1, __result_type>::value &&
std::_IsSame<_A2, __result_type>::value)), "");
return ::remainder((__result_type)__lcpp_x, (__result_type)__lcpp_y);
}
@ -1479,7 +1479,7 @@ inline _LIBCPP_INLINE_VISIBILITY long double remquo(long double __lcpp_x, long d
template <class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename std::__lazy_enable_if
typename std::_EnableIf
<
std::is_arithmetic<_A1>::value &&
std::is_arithmetic<_A2>::value,
@ -1488,8 +1488,8 @@ typename std::__lazy_enable_if
remquo(_A1 __lcpp_x, _A2 __lcpp_y, int* __lcpp_z) _NOEXCEPT
{
typedef typename std::__promote<_A1, _A2>::type __result_type;
static_assert((!(std::is_same<_A1, __result_type>::value &&
std::is_same<_A2, __result_type>::value)), "");
static_assert((!(std::_IsSame<_A1, __result_type>::value &&
std::_IsSame<_A2, __result_type>::value)), "");
return ::remquo((__result_type)__lcpp_x, (__result_type)__lcpp_y, __lcpp_z);
}

View File

@ -618,16 +618,16 @@ private:
}
};
template <class _Up>
using _CheckOptionalArgsCtor = conditional_t<
!is_same_v<__uncvref_t<_Up>, in_place_t> &&
!is_same_v<__uncvref_t<_Up>, optional>,
using _CheckOptionalArgsCtor = _If<
_IsNotSame<__uncvref_t<_Up>, in_place_t>::value &&
_IsNotSame<__uncvref_t<_Up>, optional>::value,
_CheckOptionalArgsConstructor,
__check_tuple_constructor_fail
>;
template <class _QualUp>
struct _CheckOptionalLikeConstructor {
template <class _Up, class _Opt = optional<_Up>>
using __check_constructible_from_opt = __lazy_or<
using __check_constructible_from_opt = _Or<
is_constructible<_Tp, _Opt&>,
is_constructible<_Tp, _Opt const&>,
is_constructible<_Tp, _Opt&&>,
@ -638,7 +638,7 @@ private:
is_convertible<_Opt const&&, _Tp>
>;
template <class _Up, class _Opt = optional<_Up>>
using __check_assignable_from_opt = __lazy_or<
using __check_assignable_from_opt = _Or<
is_assignable<_Tp&, _Opt&>,
is_assignable<_Tp&, _Opt const&>,
is_assignable<_Tp&, _Opt&&>,
@ -664,18 +664,18 @@ private:
};
template <class _Up, class _QualUp>
using _CheckOptionalLikeCtor = conditional_t<
__lazy_and<
__lazy_not<is_same<_Up, _Tp>>,
using _CheckOptionalLikeCtor = _If<
_And<
_IsNotSame<_Up, _Tp>,
is_constructible<_Tp, _QualUp>
>::value,
_CheckOptionalLikeConstructor<_QualUp>,
__check_tuple_constructor_fail
>;
template <class _Up, class _QualUp>
using _CheckOptionalLikeAssign = conditional_t<
__lazy_and<
__lazy_not<is_same<_Up, _Tp>>,
using _CheckOptionalLikeAssign = _If<
_And<
_IsNotSame<_Up, _Tp>,
is_constructible<_Tp, _QualUp>,
is_assignable<_Tp&, _QualUp>
>::value,
@ -689,10 +689,10 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
_LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
template <class _InPlaceT, class... _Args, class = enable_if_t<
__lazy_and<
is_same<_InPlaceT, in_place_t>,
is_constructible<value_type, _Args...>
template <class _InPlaceT, class... _Args, class = _EnableIf<
_And<
_IsSame<_InPlaceT, in_place_t>,
is_constructible<value_type, _Args...>
>::value
>
>
@ -700,21 +700,21 @@ public:
constexpr explicit optional(_InPlaceT, _Args&&... __args)
: __base(in_place, _VSTD::forward<_Args>(__args)...) {}
template <class _Up, class... _Args, class = enable_if_t<
template <class _Up, class... _Args, class = _EnableIf<
is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
>
_LIBCPP_INLINE_VISIBILITY
constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
: __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
template <class _Up = value_type, enable_if_t<
template <class _Up = value_type, _EnableIf<
_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
, int> = 0>
_LIBCPP_INLINE_VISIBILITY
constexpr optional(_Up&& __v)
: __base(in_place, _VSTD::forward<_Up>(__v)) {}
template <class _Up, enable_if_t<
template <class _Up, _EnableIf<
_CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
, int> = 0>
_LIBCPP_INLINE_VISIBILITY
@ -722,7 +722,7 @@ public:
: __base(in_place, _VSTD::forward<_Up>(__v)) {}
// LWG2756: conditionally explicit conversion from const optional<_Up>&
template <class _Up, enable_if_t<
template <class _Up, _EnableIf<
_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
, int> = 0>
_LIBCPP_INLINE_VISIBILITY
@ -730,7 +730,7 @@ public:
{
this->__construct_from(__v);
}
template <class _Up, enable_if_t<
template <class _Up, _EnableIf<
_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
, int> = 0>
_LIBCPP_INLINE_VISIBILITY
@ -740,7 +740,7 @@ public:
}
// LWG2756: conditionally explicit conversion from optional<_Up>&&
template <class _Up, enable_if_t<
template <class _Up, _EnableIf<
_CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
, int> = 0>
_LIBCPP_INLINE_VISIBILITY
@ -748,7 +748,7 @@ public:
{
this->__construct_from(_VSTD::move(__v));
}
template <class _Up, enable_if_t<
template <class _Up, _EnableIf<
_CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
, int> = 0>
_LIBCPP_INLINE_VISIBILITY
@ -769,11 +769,12 @@ public:
// LWG2756
template <class _Up = value_type,
class = enable_if_t
<__lazy_and<
integral_constant<bool,
!is_same_v<__uncvref_t<_Up>, optional> &&
!(is_same_v<_Up, value_type> && is_scalar_v<value_type>)
class = _EnableIf<
_And<
_IsNotSame<__uncvref_t<_Up>, optional>,
_Or<
_IsNotSame<_Up, value_type>,
_Not<is_scalar<value_type>>
>,
is_constructible<value_type, _Up>,
is_assignable<value_type&, _Up>
@ -791,7 +792,7 @@ public:
}
// LWG2756
template <class _Up, enable_if_t<
template <class _Up, _EnableIf<
_CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
, int> = 0>
_LIBCPP_INLINE_VISIBILITY
@ -803,7 +804,7 @@ public:
}
// LWG2756
template <class _Up, enable_if_t<
template <class _Up, _EnableIf<
_CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
, int> = 0>
_LIBCPP_INLINE_VISIBILITY
@ -815,7 +816,7 @@ public:
}
template <class... _Args,
class = enable_if_t
class = _EnableIf
<
is_constructible_v<value_type, _Args...>
>
@ -830,7 +831,7 @@ public:
}
template <class _Up, class... _Args,
class = enable_if_t
class = _EnableIf
<
is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
>
@ -1026,7 +1027,7 @@ template<class T>
// Comparisons between optionals
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1042,7 +1043,7 @@ operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1058,7 +1059,7 @@ operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1074,7 +1075,7 @@ operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1090,7 +1091,7 @@ operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1106,7 +1107,7 @@ operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1220,7 +1221,7 @@ operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
// Comparisons with T
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1232,7 +1233,7 @@ operator==(const optional<_Tp>& __x, const _Up& __v)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1244,7 +1245,7 @@ operator==(const _Tp& __v, const optional<_Up>& __x)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1256,7 +1257,7 @@ operator!=(const optional<_Tp>& __x, const _Up& __v)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1268,7 +1269,7 @@ operator!=(const _Tp& __v, const optional<_Up>& __x)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1280,7 +1281,7 @@ operator<(const optional<_Tp>& __x, const _Up& __v)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1292,7 +1293,7 @@ operator<(const _Tp& __v, const optional<_Up>& __x)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1304,7 +1305,7 @@ operator<=(const optional<_Tp>& __x, const _Up& __v)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1316,7 +1317,7 @@ operator<=(const _Tp& __v, const optional<_Up>& __x)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1328,7 +1329,7 @@ operator>(const optional<_Tp>& __x, const _Up& __v)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1340,7 +1341,7 @@ operator>(const _Tp& __v, const optional<_Up>& __x)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1352,7 +1353,7 @@ operator>=(const optional<_Tp>& __x, const _Up& __v)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY constexpr
enable_if_t<
_EnableIf<
is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
_VSTD::declval<const _Up&>()), bool>,
bool
@ -1365,7 +1366,7 @@ operator>=(const _Tp& __v, const optional<_Up>& __x)
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
enable_if_t<
_EnableIf<
is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
void
>

View File

@ -209,12 +209,12 @@ public:
"Attempted to default construct a reference element in a tuple");}
template <class _Tp,
class = typename enable_if<
__lazy_and<
__lazy_not<is_same<typename __uncvref<_Tp>::type, __tuple_leaf>>
, is_constructible<_Hp, _Tp>
class = _EnableIf<
_And<
_IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
is_constructible<_Hp, _Tp>
>::value
>::type
>
>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
@ -291,12 +291,12 @@ public:
: _Hp(__a) {}
template <class _Tp,
class = typename enable_if<
__lazy_and<
__lazy_not<is_same<typename __uncvref<_Tp>::type, __tuple_leaf>>
, is_constructible<_Hp, _Tp>
>::value
>::type
class = _EnableIf<
_And<
_IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
is_constructible<_Hp, _Tp>
>::value
>
>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
@ -345,9 +345,6 @@ template <class ..._Tp>
_LIBCPP_INLINE_VISIBILITY
void __swallow(_Tp&&...) _NOEXCEPT {}
template <class ..._Tp>
struct __lazy_all : __all<_Tp::value...> {};
template <class _Tp>
struct __all_default_constructible;
@ -567,19 +564,19 @@ class _LIBCPP_TEMPLATE_VIS tuple
// the UTypes... constructor should be selected instead.
// See LWG issue #2549.
template <class _Tuple>
using _PreferTupleLikeConstructor = __lazy_or<
using _PreferTupleLikeConstructor = _Or<
// Don't attempt the two checks below if the tuple we are given
// has the same type as this tuple.
is_same<typename __uncvref<_Tuple>::type, tuple>,
__lazy_and<
__lazy_not<is_constructible<_Tp..., _Tuple>>,
__lazy_not<is_convertible<_Tuple, _Tp...>>
_IsSame<__uncvref_t<_Tuple>, tuple>,
_Lazy<_And,
_Not<is_constructible<_Tp..., _Tuple>>,
_Not<is_convertible<_Tuple, _Tp...>>
>
>;
template <class _Tuple>
static constexpr bool __enable_implicit() {
return __lazy_and<
return _And<
__tuple_convertible<_Tuple, tuple>,
_PreferTupleLikeConstructor<_Tuple>
>::value;
@ -587,10 +584,10 @@ class _LIBCPP_TEMPLATE_VIS tuple
template <class _Tuple>
static constexpr bool __enable_explicit() {
return __lazy_and<
return _And<
__tuple_constructible<_Tuple, tuple>,
_PreferTupleLikeConstructor<_Tuple>,
__lazy_not<__tuple_convertible<_Tuple, tuple>>
_Not<__tuple_convertible<_Tuple, tuple>>
>::value;
}
};
@ -615,12 +612,13 @@ public:
tuple(tuple const&) = default;
tuple(tuple&&) = default;
template <class _AllocArgT, class _Alloc, bool _Dummy = true, class = typename enable_if<
__lazy_and<
is_same<allocator_arg_t, _AllocArgT>,
__lazy_all<__dependent_type<is_default_constructible<_Tp>, _Dummy>...>
template <class _AllocArgT, class _Alloc, bool _Dummy = true, class = _EnableIf<
_And<
_IsSame<allocator_arg_t, _AllocArgT>,
__dependent_type<is_default_constructible<_Tp>, _Dummy>...
>::value
>::type>
>
>
_LIBCPP_INLINE_VISIBILITY
tuple(_AllocArgT, _Alloc const& __a)
: __base_(allocator_arg_t(), __a,

View File

@ -473,9 +473,9 @@ struct _MetaBase<true> {
template <class _Tp = void>
using _EnableIfImpl _LIBCPP_NODEBUG_TYPE = _Tp;
template <class _Result, class _First, class ..._Rest>
using _OrImpl _LIBCPP_NODEBUG_TYPE = typename _MetaBase<_First::type::value != true && sizeof...(_Rest) != 0>::template _OrImpl<_First, _Rest...>;
using _OrImpl _LIBCPP_NODEBUG_TYPE = typename _MetaBase<_First::value != true && sizeof...(_Rest) != 0>::template _OrImpl<_First, _Rest...>;
template <class _Result, class _First, class ..._Rest>
using _AndImpl _LIBCPP_NODEBUG_TYPE = typename _MetaBase<_First::type::value == true && sizeof...(_Rest) != 0>::template _AndImpl<_First, _Rest...>;
using _AndImpl _LIBCPP_NODEBUG_TYPE = typename _MetaBase<_First::value == true && sizeof...(_Rest) != 0>::template _AndImpl<_First, _Rest...>;
};
template <>
@ -498,12 +498,15 @@ using _Or _LIBCPP_NODEBUG_TYPE = typename _MetaBase< sizeof...(_Rest) != 0 >::te
template <class ..._Rest>
using _And _LIBCPP_NODEBUG_TYPE = typename _MetaBase< sizeof...(_Rest) != 0 >::template _AndImpl<true_type, _Rest...>;
template <class _Pred>
struct _Not : _BoolConstant<!_Pred::type::value> {};
struct _Not : _BoolConstant<!_Pred::value> {};
template <class ..._Args>
using _FirstType _LIBCPP_NODEBUG_TYPE = typename _MetaBase<(sizeof...(_Args) >= 1)>::template _FirstImpl<_Args...>;
template <class ..._Args>
using _SecondType _LIBCPP_NODEBUG_TYPE = typename _MetaBase<(sizeof...(_Args) >= 2)>::template _SecondImpl<_Args...>;
template <template <class...> class _Func, class ..._Args>
struct _Lazy : _Func<_Args...> {};
// Member detector base
template <template <class...> class _Templ, class ..._Args>
@ -532,9 +535,6 @@ template <class _If, class _Then>
template <bool _Bp, class _If, class _Then> using conditional_t = typename conditional<_Bp, _If, _Then>::type;
#endif
template <bool, class _Tp> struct _LIBCPP_TEMPLATE_VIS __lazy_enable_if {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS __lazy_enable_if<true, _Tp> {typedef typename _Tp::type type;};
template <bool, class _Tp = void> struct _LIBCPP_TEMPLATE_VIS enable_if {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS enable_if<true, _Tp> {typedef _Tp type;};
@ -562,6 +562,14 @@ using _IsSame = _BoolConstant<
#endif
>;
template <class _Tp, class _Up>
using _IsNotSame = _BoolConstant<
#ifdef __clang__
!__is_same(_Tp, _Up)
#else
!_VSTD::is_same<_Tp, _Up>::value
#endif
>;
// addressof
#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
@ -635,83 +643,6 @@ struct __two {char __lx[2];};
// helper class:
#if !defined(_LIBCPP_CXX03_LANG)
// __lazy_and
template <bool _Last, class ..._Preds>
struct __lazy_and_impl;
template <class ..._Preds>
struct __lazy_and_impl<false, _Preds...> : false_type {};
template <>
struct __lazy_and_impl<true> : true_type {};
template <class _Pred>
struct __lazy_and_impl<true, _Pred> : integral_constant<bool, _Pred::type::value> {};
template <class _Hp, class ..._Tp>
struct __lazy_and_impl<true, _Hp, _Tp...> : __lazy_and_impl<_Hp::type::value, _Tp...> {};
template <class _P1, class ..._Pr>
struct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {};
// __lazy_or
template <bool _List, class ..._Preds>
struct __lazy_or_impl;
template <class ..._Preds>
struct __lazy_or_impl<true, _Preds...> : true_type {};
template <>
struct __lazy_or_impl<false> : false_type {};
template <class _Hp, class ..._Tp>
struct __lazy_or_impl<false, _Hp, _Tp...>
: __lazy_or_impl<_Hp::type::value, _Tp...> {};
template <class _P1, class ..._Pr>
struct __lazy_or : __lazy_or_impl<_P1::type::value, _Pr...> {};
// __lazy_not
template <class _Pred>
struct __lazy_not : integral_constant<bool, !_Pred::type::value> {};
// __and_
template<class...> struct __and_;
template<> struct __and_<> : true_type {};
template<class _B0> struct __and_<_B0> : _B0 {};
template<class _B0, class _B1>
struct __and_<_B0, _B1> : conditional<_B0::value, _B1, _B0>::type {};
template<class _B0, class _B1, class _B2, class... _Bn>
struct __and_<_B0, _B1, _B2, _Bn...>
: conditional<_B0::value, __and_<_B1, _B2, _Bn...>, _B0>::type {};
// __or_
template<class...> struct __or_;
template<> struct __or_<> : false_type {};
template<class _B0> struct __or_<_B0> : _B0 {};
template<class _B0, class _B1>
struct __or_<_B0, _B1> : conditional<_B0::value, _B0, _B1>::type {};
template<class _B0, class _B1, class _B2, class... _Bn>
struct __or_<_B0, _B1, _B2, _Bn...>
: conditional<_B0::value, _B0, __or_<_B1, _B2, _Bn...> >::type {};
// __not_
template<class _Tp>
struct __not_ : conditional<_Tp::value, false_type, true_type>::type {};
#endif // !defined(_LIBCPP_CXX03_LANG)
// is_const
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const : public false_type {};
@ -1144,7 +1075,7 @@ struct __is_referenceable_impl {
template <class _Tp>
struct __is_referenceable : integral_constant<bool,
!is_same<decltype(__is_referenceable_impl::__test<_Tp>(0)), __two>::value> {};
_IsNotSame<decltype(__is_referenceable_impl::__test<_Tp>(0)), __two>::value> {};
// add_const
@ -1249,7 +1180,7 @@ using __uncvref_t _LIBCPP_NODEBUG_TYPE = typename __uncvref<_Tp>::type;
// __is_same_uncvref
template <class _Tp, class _Up>
struct __is_same_uncvref : is_same<typename __uncvref<_Tp>::type,
struct __is_same_uncvref : _IsSame<typename __uncvref<_Tp>::type,
typename __uncvref<_Up>::type> {};
#if _LIBCPP_STD_VER > 17
@ -1282,7 +1213,7 @@ template <class _Tp> using remove_pointer_t = typename remove_pointer<_Tp>::type
template <class _Tp,
bool = __is_referenceable<_Tp>::value ||
is_same<typename remove_cv<_Tp>::type, void>::value>
_IsSame<typename remove_cv<_Tp>::type, void>::value>
struct __add_pointer_impl
{typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tp>::type* type;};
template <class _Tp> struct __add_pointer_impl<_Tp, false>
@ -1611,9 +1542,9 @@ struct __is_nothrow_convertible_helper: decltype(__is_nothrow_convertible_test<_
{ };
template <typename _Fm, typename _To>
struct is_nothrow_convertible : __or_<
__and_<is_void<_To>, is_void<_Fm>>,
__and_<is_convertible<_Fm, _To>, __is_nothrow_convertible_helper<_Fm, _To>>
struct is_nothrow_convertible : _Or<
_And<is_void<_To>, is_void<_Fm>>,
_Lazy<_And, is_convertible<_Fm, _To>, __is_nothrow_convertible_helper<_Fm, _To>>
>::type { };
template <typename _Fm, typename _To>
@ -1914,7 +1845,7 @@ struct __numeric_type
static long double __test(long double);
typedef decltype(__test(declval<_Tp>())) type;
static const bool value = !is_same<type, void>::value;
static const bool value = _IsNotSame<type, void>::value;
};
template <>
@ -2199,7 +2130,7 @@ struct _LIBCPP_TEMPLATE_VIS common_type<_Tp>
template <class _Tp, class _Up>
struct _LIBCPP_TEMPLATE_VIS common_type<_Tp, _Up>
: conditional<
is_same<_Tp, typename decay<_Tp>::type>::value && is_same<_Up, typename decay<_Up>::type>::value,
_IsSame<_Tp, typename decay<_Tp>::type>::value && _IsSame<_Up, typename decay<_Up>::type>::value,
__common_type2_imp<_Tp, _Up>,
common_type<typename decay<_Tp>::type, typename decay<_Up>::type>
>::type
@ -2770,10 +2701,10 @@ struct __is_invalid_base_to_derived_cast {
static_assert(is_reference<_To>::value, "Wrong specialization");
using _RawFrom = __uncvref_t<_From>;
using _RawTo = __uncvref_t<_To>;
static const bool value = __lazy_and<
__lazy_not<is_same<_RawFrom, _RawTo>>,
static const bool value = _And<
_IsNotSame<_RawFrom, _RawTo>,
is_base_of<_RawFrom, _RawTo>,
__lazy_not<__libcpp_is_constructible<_RawTo, _From>>
_Not<__libcpp_is_constructible<_RawTo, _From>>
>::value;
};
@ -2786,10 +2717,10 @@ template <class _ToRef, class _FromRef>
struct __is_invalid_lvalue_to_rvalue_cast<_ToRef&&, _FromRef&> {
using _RawFrom = __uncvref_t<_FromRef>;
using _RawTo = __uncvref_t<_ToRef>;
static const bool value = __lazy_and<
__lazy_not<is_function<_RawTo>>,
__lazy_or<
is_same<_RawFrom, _RawTo>,
static const bool value = _And<
_Not<is_function<_RawTo>>,
_Or<
_IsSame<_RawFrom, _RawTo>,
is_base_of<_RawTo, _RawFrom>>
>::value;
};
@ -3622,7 +3553,7 @@ struct __invokable_r
using type =
typename conditional<
!is_same<_Result, __nat>::value,
_IsNotSame<_Result, __nat>::value,
typename conditional<
is_void<_Ret>::value,
true_type,
@ -3807,8 +3738,8 @@ struct __swappable_with
typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1;
typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2;
static const bool value = !is_same<__swap1, __nat>::value
&& !is_same<__swap2, __nat>::value;
static const bool value = _IsNotSame<__swap1, __nat>::value
&& _IsNotSame<__swap2, __nat>::value;
};
template <class _Tp, class _Up>
@ -4002,19 +3933,19 @@ struct __has_operator_addressof
template <class...> using void_t = void;
template <class... _Args>
struct conjunction : __and_<_Args...> {};
struct conjunction : _And<_Args...> {};
template<class... _Args>
_LIBCPP_INLINE_VAR constexpr bool conjunction_v
= conjunction<_Args...>::value;
template <class... _Args>
struct disjunction : __or_<_Args...> {};
struct disjunction : _Or<_Args...> {};
template<class... _Args>
_LIBCPP_INLINE_VAR constexpr bool disjunction_v
= disjunction<_Args...>::value;
template <class _Tp>
struct negation : __not_<_Tp> {};
struct negation : _Not<_Tp> {};
template<class _Tp>
_LIBCPP_INLINE_VAR constexpr bool negation_v
= negation<_Tp>::value;
@ -4029,12 +3960,12 @@ struct __extract_key_first_tag {};
template <class _ValTy, class _Key,
class _RawValTy = typename __unconstref<_ValTy>::type>
struct __can_extract_key
: conditional<is_same<_RawValTy, _Key>::value, __extract_key_self_tag,
: conditional<_IsSame<_RawValTy, _Key>::value, __extract_key_self_tag,
__extract_key_fail_tag>::type {};
template <class _Pair, class _Key, class _First, class _Second>
struct __can_extract_key<_Pair, _Key, pair<_First, _Second>>
: conditional<is_same<typename remove_const<_First>::type, _Key>::value,
: conditional<_IsSame<typename remove_const<_First>::type, _Key>::value,
__extract_key_first_tag, __extract_key_fail_tag>::type {};
// __can_extract_map_key uses true_type/false_type instead of the tags.
@ -4043,7 +3974,7 @@ struct __can_extract_key<_Pair, _Key, pair<_First, _Second>>
template <class _ValTy, class _Key, class _ContainerValueTy,
class _RawValTy = typename __unconstref<_ValTy>::type>
struct __can_extract_map_key
: integral_constant<bool, is_same<_RawValTy, _Key>::value> {};
: integral_constant<bool, _IsSame<_RawValTy, _Key>::value> {};
// This specialization returns __extract_key_fail_tag for non-map containers
// because _Key == _ContainerValueTy

View File

@ -10,7 +10,7 @@
// <type_traits>
// __lazy_enable_if, __lazy_not, __lazy_and and __lazy_or
// __lazy_enable_if, __lazy_not, _And and _Or
// Test the libc++ lazy meta-programming helpers in <type_traits>
@ -19,8 +19,8 @@
#include "test_macros.h"
template <class Type>
struct Identity {
typedef Type type;
struct Identity : Type {
};
typedef std::true_type TrueT;
@ -32,7 +32,6 @@ typedef Identity<FalseT> LazyFalseT;
// A type that cannot be instantiated
template <class T>
struct CannotInst {
typedef T type;
static_assert(std::is_same<T, T>::value == false, "");
};
@ -62,32 +61,21 @@ struct HasTypeImp {
template <class Type>
struct HasType : HasTypeImp<Type>::type {};
void LazyEnableIfTest() {
{
typedef std::__lazy_enable_if<true, NextInt<0> > Result;
static_assert(HasType<Result>::value, "");
static_assert(Result::type::value == 1, "");
}
{
typedef std::__lazy_enable_if<false, CannotInst<int> > Result;
static_assert(!HasType<Result>::value, "");
}
}
void LazyNotTest() {
{
typedef std::__lazy_not<LazyTrueT> NotT;
typedef std::_Not<LazyTrueT> NotT;
static_assert(std::is_same<typename NotT::type, FalseT>::value, "");
static_assert(NotT::value == false, "");
}
{
typedef std::__lazy_not<LazyFalseT> NotT;
typedef std::_Not<LazyFalseT> NotT;
static_assert(std::is_same<typename NotT::type, TrueT>::value, "");
static_assert(NotT::value == true, "");
}
{
// Check that CannotInst<int> is not instantiated.
typedef std::__lazy_not<CannotInst<int> > NotT;
typedef std::_Not<CannotInst<int> > NotT;
static_assert(std::is_same<NotT, NotT>::value, "");
@ -96,42 +84,42 @@ void LazyNotTest() {
void LazyAndTest() {
{ // Test that it acts as the identity function for a single value
static_assert(std::__lazy_and<LazyFalseT>::value == false, "");
static_assert(std::__lazy_and<LazyTrueT>::value == true, "");
static_assert(std::_And<LazyFalseT>::value == false, "");
static_assert(std::_And<LazyTrueT>::value == true, "");
}
{
static_assert(std::__lazy_and<LazyTrueT, LazyTrueT>::value == true, "");
static_assert(std::__lazy_and<LazyTrueT, LazyFalseT>::value == false, "");
static_assert(std::__lazy_and<LazyFalseT, LazyTrueT>::value == false, "");
static_assert(std::__lazy_and<LazyFalseT, LazyFalseT>::value == false, "");
static_assert(std::_And<LazyTrueT, LazyTrueT>::value == true, "");
static_assert(std::_And<LazyTrueT, LazyFalseT>::value == false, "");
static_assert(std::_And<LazyFalseT, LazyTrueT>::value == false, "");
static_assert(std::_And<LazyFalseT, LazyFalseT>::value == false, "");
}
{ // Test short circuiting - CannotInst<T> should never be instantiated.
static_assert(std::__lazy_and<LazyFalseT, CannotInst<int>>::value == false, "");
static_assert(std::__lazy_and<LazyTrueT, LazyFalseT, CannotInst<int>>::value == false, "");
static_assert(std::_And<LazyFalseT, CannotInst<int>>::value == false, "");
static_assert(std::_And<LazyTrueT, LazyFalseT, CannotInst<int>>::value == false, "");
}
}
void LazyOrTest() {
{ // Test that it acts as the identity function for a single value
static_assert(std::__lazy_or<LazyFalseT>::value == false, "");
static_assert(std::__lazy_or<LazyTrueT>::value == true, "");
static_assert(std::_Or<LazyFalseT>::value == false, "");
static_assert(std::_Or<LazyTrueT>::value == true, "");
}
{
static_assert(std::__lazy_or<LazyTrueT, LazyTrueT>::value == true, "");
static_assert(std::__lazy_or<LazyTrueT, LazyFalseT>::value == true, "");
static_assert(std::__lazy_or<LazyFalseT, LazyTrueT>::value == true, "");
static_assert(std::__lazy_or<LazyFalseT, LazyFalseT>::value == false, "");
static_assert(std::_Or<LazyTrueT, LazyTrueT>::value == true, "");
static_assert(std::_Or<LazyTrueT, LazyFalseT>::value == true, "");
static_assert(std::_Or<LazyFalseT, LazyTrueT>::value == true, "");
static_assert(std::_Or<LazyFalseT, LazyFalseT>::value == false, "");
}
{ // Test short circuiting - CannotInst<T> should never be instantiated.
static_assert(std::__lazy_or<LazyTrueT, CannotInst<int>>::value == true, "");
static_assert(std::__lazy_or<LazyFalseT, LazyTrueT, CannotInst<int>>::value == true, "");
static_assert(std::_Or<LazyTrueT, CannotInst<int>>::value == true, "");
static_assert(std::_Or<LazyFalseT, LazyTrueT, CannotInst<int>>::value == true, "");
}
}
int main(int, char**) {
LazyEnableIfTest();
LazyNotTest();
LazyAndTest();
LazyOrTest();